- HttpServletRequest 是一个接口
- HttpServletRequest 接口是Servlet规范中的一员。
- HttpServletRequest 的父接口:ServletRequest
- org.apache.catalina.connector.RequestFacade 这个类实现了HttpServletRequest 接口。
- HttpServletRequest 中封装了 HTTP 的请求信息。
HttpServletRequest 接口中常用的方法:
String |
获取value数组中第一个元素 这是比较常用的 |
Map<String,String[]> |
|
Enumeration<String> |
|
String[] |
|
以上四个方法,与用户提交的数据有关。
可以思考一下:当前端发送请求信息的时候,那么数据是怎么存储的?
前端发送的数据:userName=m0001&password=123&hobby=drink&hobby=smoke
我们首先可以想到的是 Map 集合:
map<String,String>: key 存储 name,value 存储value
key value
---------------------------------------------------
userName "m0001"
password "123"
hobby "drink"
hobby " smoke"
但是这样存储当 key 重复的时候,value 会被覆盖。
我们可以采用:map<String,String[]> 这样的形式存储数据
key value
---------------------------------------------------
userName {"m0001"}
password {"123"}
hobby { "drink","smoke"}
测试方法:
public class RequestTest extends HttpServlet {
//重写 doGet
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
response.setContentType("text/html");
response.setCharacterEncoding("GBK");
PrintWriter writer = response.getWriter();
/*
userName=m0001&password=123&hobby=drink&hobby=smoke
发送的请求
*/
/*
getParameterMap() 方法
获取map集合
*/
Map<String, String[]> map = request.getParameterMap();
writer.print("<h1>遍历map集合</h1>"+ "<br>");
Set<String> set = map.keySet();
for (String s : set) {
writer.print(s + "=" + Arrays.toString(map.get(s)) + "<br>");
}
/*
getParameterNames()
获取集合中的 key
*/
Enumeration<String> key = request.getParameterNames();
writer.print("<h1>遍历集合中key</h1>"+ "<br>");
while (key.hasMoreElements()) {
String k = key.nextElement();
writer.print(k + "<br>");
}
/*
getParameterValues() 方法
获取集合中的value
*/
writer.print("<h1>遍历集合中所有的value</h1>"+ "<br>");
String[] userName = request.getParameterValues("userName");
String[] password = request.getParameterValues("password");
String[] hobby = request.getParameterValues("hobby");
writer.print(Arrays.toString(userName) + "<br>");
writer.print(Arrays.toString(password) + "<br>");
writer.print(Arrays.toString(hobby) + "<br>");
/*
getParameter() 方法
获取value数组中的第一个元素
*/
writer.print("<h1>hobby数组中第一个元素</h1>" + "<br>");
String first = request.getParameter("hobby");
writer.print(first + "<br>");
}
}
Request 对象 又叫 请求域。
- 请求域相对应用域来说,生命周期短很多,范围小很多。
- 请求域中也有 存,取,删,三个方法。
Object |
|
void |
|
void |
|
- 如果我们在 AServlet 中 向请求域中存放数据,在BServlet 中取出数据。能取出来吗?
- 不能,因为这是俩次请求。请求域存在每次请求之中。
- 那么,可不可以将AServlet 和 BServlet 都放在一次请求当中呢?
- 思考一个问题:既然我们想 把 AServlet 和 BServlet 放到一次请求当中,那么看看下面的代码行不行:
- new 一个 BServlet 对象,调用 doGet方法,将 request 和 response 传进去,这样 AServlet 和 BServlet 使用的就是一个 Request 对象。是不是就能访问到了呢?
- 这样是不行的。虽然看着能实现功能,但是我们自己所new的Servlet对象,它的生命周期不会受Tomcat 服务器的管理,无法销毁。无法被回收。
-
BSerlvet b = new BServlet() ; b.doGet(request,response);
- 我们可以使用跳转/转发 机制。
RequestDispatcher |
|
void |
RequestDispatcher中的方法:实现转发功能 |
// 第一步:获取请求转发器对象
RequestDispatcher request = req.getRequestDispatcher("/b");
// 第二步:使用RequestDispatcher中的forward方法,实现跳转
request.forward(req,resp);
// 也可以一行代码搞定
RequestDispatcher request = req.getRequestDispatcher("/b").forward(req,resp);
- 如果实现俩个Servlet共享数据?
- 使用 ServletContext 域【应用域】,可以实现,但是范围太广。生命周期太长【Tomcat 启动创建,关闭销毁】。
- 使用请求域,使用跳转/转发机制,保证俩个Servlet在同一次请求当中。即可实现共享。
- 跳转不仅能跳转到一个 Servlet 还能跳转到一个HTML 页面。
- HttpServlet 接口中的其他常用方法:
String |
|
void |
|
当我们发送POST请求时乱码问题:使用setCharacterEncoding()方法解决发送请求时乱码问题。
当我们发送GET请求出现乱码问题时:修改 Tomcat 中的 webapps\docs\config 下的 service.html 文件中 <Connector >标签中增加:URIEncoding="UTF-8"
注意:Tomcat 8 之后 默认就是UTF-8,不会出现乱码问题。
Tomcat 10 默认就是UTF-8 字符集,所以不会出现乱码问题!
当我们响应中出现乱码问题:Tomcat 10 不会出现乱码问题。
//使用response中的设置编码的方法
response.setCharacterEncoding();
String |
|
String |
|
String |
|
//获取 请求方式
String method = request.getMethod();
System.out.println(method);
//获取请求信息的URI
String uri = request.getRequestURI(); // /servlet10/a
System.out.println(uri);
// 获取Servlet的路径
String servletPath = request.getServletPath(); // /a
System.out.println(servletPath);
控制台输出结果