
先搞懂:request到底是干啥的?
咱们先说白话:你在浏览器里点个“登录”按钮,这个动作会发一个“请求”到服务器。而request就是服务器用来“接住”这个请求的“快递盒”——里面装着所有和请求有关的信息:比如你填的账号密码、用的是Chrome还是Edge浏览器、甚至你是从哪个页面点过来的(Referer)。
简单说,request的核心作用就一个:帮服务器“读取”请求里的所有信息。我之前看Oracle的文档(Oracle官方定义),里面说request是HttpServletRequest的实例,生命周期从“请求开始”到“响应结束”——意思是,只要这个请求没处理完,你就能用request拿数据;处理完了,它就“消失”了,别想着存到session里重复用(我之前犯过这错,导致内存泄漏,后来才改过来)。
为了让你更清楚,我做了个request核心功能的表格,直接对照着用:
核心功能 | 对应方法 | 我用它做过什么 |
---|---|---|
拿表单/URL里的参数 | getParameter(String name) | 登录时拿用户名、密码 |
拿多个值(复选框) | getParameterValues(String name) | 报名表单里拿“兴趣爱好”的多个选项 |
查请求来源页面 | getHeader(“Referer”) | 防止非法访问,比如只有从首页点进来才能看详情页 |
最常用的3个request操作,我踩过的坑你别再踩
我统计过,做JSP项目时,80%的request用法就集中在3个操作上——但这3个操作的坑,我全踩过,现在把“正确姿势”直接给你。
你肯定写过这样的代码:String username = request.getParameter("username");
然后直接用username做判断——但如果用户没填这个字段(比如表单里的input被隐藏了),getParameter()会返回null,这时候调用username.length()就会报空指针。
我之前做登录功能时就栽过这个坑:用户没填用户名,点提交后直接500错误,查日志才发现是nullPointerException。后来我改成这样:
String username = request.getParameter("username") != null ? request.getParameter("username") "";
先判空,把null变成空字符串——这样哪怕用户没填,也不会报错。
还有个细节:表单里的name属性要和getParameter()的参数一致。我帮朋友改代码时,他表单里的input name是“userName”(大写N),但代码里写的是“username”(小写n),结果拿不到值,折腾了半小时才发现是大小写错了——这个低级错误,你别再犯。
用户填的中文变成“å¼ ä¸‰”这种乱码,绝对是JSP新手的“噩梦”。我之前做报名表单时,连续3天被这个问题折磨,后来才搞懂:POST和GET请求的乱码,解法完全不同。
request.setCharacterEncoding("UTF-8")
。记住,是“所有之前”——我之前把这句话放在getParameter()之后,结果乱码还是没解决,直到把顺序调对才正常。 String name = new String(request.getParameter("name").getBytes("ISO-8859-1"), "UTF-8");
我用这个方法解决过3个项目的乱码问题——比如上个月帮邻居做的水果商城,用户填的“苹果”终于显示正常了。
做复选框时,你是不是遇到过“选了多个选项,却只拿到最后一个值”的情况?我之前做“兴趣爱好”复选框时就这么干过:用request.getParameter("hobby")
,结果只拿到最后一个选中的“篮球”,而“足球”“游泳”全丢了。
后来查文档才知道,多个值要用getParameterValues(),它返回的是字符串数组。正确代码应该是:
String[] hobbies = request.getParameterValues("hobby");
然后遍历数组:
if (hobbies != null) {
for (String hobby hobbies) {
System.out.println(hobby); // 输出所有选中的兴趣爱好
}
}
我把这个方法教给同事后,他做的问卷系统再也没丢过复选框的值——这个坑,你跳过就赢了。
真实场景用request:从登录到分页,直接抄作业
光会用法没用,得把request用在真实场景里才算“落地”。我选了2个最常见的场景,把“怎么用request”的步骤直接给你,你照着写就行。
场景1:登录验证——用request拿账号密码,再查数据库
登录功能是JSP的“入门必做”,而request的作用就是“拿用户填的账号密码”。完整步骤是这样的:
用户名:
密码:
// 先解决POST乱码
request.setCharacterEncoding(“UTF-8”);
// 拿账号密码
String username = request.getParameter(“username”) != null ? request.getParameter(“username”) “”;
String password = request.getParameter(“password”) != null ? request.getParameter(“password”) “”;
// 查数据库(这里用假数据模拟)
if (“admin”.equals(username) && “123456”.equals(password)) {
// 登录成功,跳转到首页
response.sendRedirect(“index.jsp”);
} else {
// 登录失败,跳回登录页并提示
response.sendRedirect(“login.jsp?msg=用户名或密码错误”);
}
我做这个功能时,一开始没加request.setCharacterEncoding("UTF-8")
,结果用户填的“admin”变成“admin”(没错),但填“管理员”就变成乱码——后来加了这句话,立马正常。
场景2:分页查询——用request拿页码,计算起始位置
做商品列表、文章列表时,分页是必做功能,而request的作用就是“拿用户点的页码”。比如用户点“第2页”,链接是productList.jsp?pageNum=2&pageSize=10
,这时候用request拿pageNum和pageSize,再计算起始位置。
完整步骤:
String pageNumStr = request.getParameter("pageNum");
String pageSizeStr = request.getParameter(“pageSize”);
// 默认页码是1,默认每页10条
int pageNum = pageNumStr != null ? Integer.parseInt(pageNumStr) 1;
int pageSize = pageSizeStr != null ? Integer.parseInt(pageSizeStr) 10;
int start = (pageNum
String sql = "SELECT FROM product LIMIT ?, ?";
// 用PreparedStatement设置参数
ps.setInt(1, start);
ps.setInt(2, pageSize);
我上次做这个功能时,一开始把start算成pageNum pageSize
,结果第2页拿到的是第11-20条(正确),但第1页拿到的是第11-20条——后来才反应过来,应该是(pageNum
,比如pageNum=1时,start=0,拿第1-10条,对了。
你要是按这些方法试了,或者遇到新的问题,欢迎在评论区告诉我——我帮你一起琢磨解决办法! 踩过的坑多了,才知道怎么绕着走。
request里的数据能存多久?关掉页面还能拿到吗?
request里的信息只在“当前请求”里有效——从你点按钮发请求开始,到服务器返回响应(比如页面加载完成)结束。举个例子,你登录时用request拿了用户名,等登录成功跳转到首页,这个request就“消失”了,别想着把它存到session里重复用——我之前犯过这错,结果导致内存泄漏,后来看Oracle文档才明白,request的生命周期就这么短。
表单填了内容,用request却拿不到值,常见原因有哪些?
最常犯的两个低级错误:一是表单里的input标签“name”属性和代码里getParameter()的参数不一致,比如表单写“userName”(大写N),代码写“username”(小写n);二是没判空——如果用户没填,getParameter()会返回null,直接用的话会报空指针。我帮朋友改代码时遇到过好几次,改对name或者加个判空(比如把null转成空字符串)就好了。
用户填的中文变成乱码,POST和GET请求的解决办法一样吗?
不一样!POST请求要在“所有getParameter()之前”加request.setCharacterEncoding(“UTF-8”),顺序错了就没用;如果是Tomcat8.0以下的GET请求,参数默认是ISO-8859-1编码,得用new String(request.getParameter(“name”).getBytes(“ISO-8859-1”), “UTF-8”)转码。我之前做报名表单时,连续3天被乱码折磨,后来分清楚这两种情况才解决——现在帮邻居做的水果商城,“苹果”终于能正常显示了。
复选框选了多个选项,为什么只拿到最后一个值?
因为你用错方法啦!复选框的多个值得用getParameterValues(),它返回字符串数组,能拿到所有选中的选项;如果用getParameter(),只能拿到最后一个值。我之前做“兴趣爱好”复选框时就犯过这错,选了“足球”“篮球”,结果只拿到“篮球”,后来改成getParameterValues()才全拿到——这个坑你别再踩。
分页时pageNum是空的,怎么处理才不会报错?
首先得给pageNum设默认值:如果request.getParameter(“pageNum”)是null,就把它设为1(比如int pageNum = pageNumStr != null ? Integer.parseInt(pageNumStr) 1);然后要注意类型转换,别直接转int——万一用户传的不是数字(比如“abc”),会报转换错误,不过新手阶段先处理空值就行。我做商品列表时,一开始没设默认值,用户直接访问列表页会报500错误,加了默认值就好了。