1. request对象和response对象的原理
每向Tomcat发一次请求,Tomcat就会创建一个request和一个response对象,将本次请求的所有数据封装到request对象中,然后将request和response作为实参传递给对应Servlet的service方法,来处理本次请求
2. request对象继承体系结构
1 | ServletRequest -- 接口 |
3. 获取请求行
请求行格式如下:1
GET /webapp/index.html?username=abc HTTP/1.1
3.1. 获取请求方式
getMethod()返回的值只可能是以下几种:
"DELETE""HEAD""GET""OPTIONS""POST""PUT""TRACE"
1 | String method = req.getMethod(); |
3.2. 获取虚拟目录
1 | String contextPath = req.getContextPath(); |
3.3. 获取ServletPath
1 | String servletPath = req.getServletPath(); |
3.4. 获取请求URL和URI
例如访问http://localhost:8080/webapp/index.html?username=abc1
2
3
4StringBuffer url = req.getRequestURL(); // 获取请求URL http://localhost:8080/webapp/index.html
String uri = req.getRequestURI(); // 获取请求URI /webapp/index.html
System.out.println("url = " + url.toString());
System.out.println("uri = " + uri);
3.5. 获取URL中的请求参数(GET请求的参数)
1 | String queryString = req.getQueryString(); |
例如访问http://localhost:8080/hello?username=mike&password=123456,得到的queryString是username=mike&password=123456
3.6. 获取请求协议
1 | String scheme = req.getScheme(); // 获取请求的协议:如http/https/ftp |
4. 获取请求头
4.1. 获取Content-Type
1 | String contentType = req.getContentType(); |
4.2. 根据名称获取
String getHeader(String name) 注意如果不存在,则返回null1
2// 注意:请求头的name不区分大小写
String userAgent = req.getHeader("User-Agent");
4.3. 遍历请求头
1 | // 获取所有header的名称 |
5. 获取客户端信息
1 | String remoteUser = req.getRemoteUser(); // 获取当前缓存的用户,比如Spring Security做权限控制后就会将用户登录名缓存到这里 |
6. 获取服务器信息
1 | String localAddr = req.getLocalAddr(); // 获取服务器IP |
7. 通用获取请求参数
获取请求参数不区分GET/POST,可以统一用以下几种方式来获取参数的值
7.1. 根据name获取单个值
1 | String username = req.getParameter("username"); |
注意以下几种情况参数的值:1
2
3
4http://localhost:8080/hello?aaa=123 username为null
http://localhost:8080/hello?username&aaa=3 username为空字符串
http://localhost:8080/hello?username=&aaa=3 username为空字符串
http://localhost:8080/hello?username=123&aaa=3 username为"123"
7.2. 根据name获取多个值
有时候同1个name,可能有多个value,例如复选框1
2
3<input type="checkbox" name="check" value="1">
<input type="checkbox" name="check" value="2">
<input type="checkbox" name="check" value="3">
勾选之后GET提交的URL如下1
http://localhost:8080/hello?check=1&check=2&check=3
req.getParameter(name)只能获取第1个value,如果想获取多个,则使用req.getParameterValues(name)1
2
3
4String[] checks = req.getParameterValues("check");
for (String value : checks) {
System.out.println(value);
}
要注意,没有对应参数时,req.getParameterValues(name)也是返回null,在用for遍历数组时,会出现空指针异常,所以要先判断是否为null1
2
3
4
5
6String[] checks = req.getParameterValues("check");
if (checks != null) {
for (String value : checks) {
System.out.println(value);
}
}
7.3. 遍历所有请求参数
getParameterNames() 获取所有请求参数的名称1
2
3
4
5
6Enumeration<String> params = req.getParameterNames();
while (params.hasMoreElements()) {
String name = params.nextElement();
String value = req.getParameter(name);
System.out.println(name + " === " + value);
}
getParameterMap() 获取所有请求参数以及值。key是参数名,value是参数的值,因为值可能有多个,所以是数组类型1
2
3
4Map<String, String[]> map = req.getParameterMap();
map.forEach((name, values) -> {
System.out.println(name + " === " + Arrays.toString(values));
});
8. 获取请求体
只有POST请求,才有请求体。Request将请求体封装成流,想获取请求体,你首先要获取流对象,再从流对象中取数据。
你可以从Request对象获取两种流,如果数据是字符,就用字符流,如果是字节,就用字节流
BufferedReader getReader()获取字符流ServletInputStream getInputStream()获取字符流
读取完之后,流不必close(),因为流是从request中获取的,本次请求结束后,request对象会自动被销毁
读取字符示例1
2
3
4
5
6BufferedReader br = req.getReader();
String line = null;
while ((line = br.readLine()) != null) {
line = br.readLine();
System.out.println(line);
}
9. 请求转发
请求转发:一种在服务器内部的资源跳转方式
转发步骤:
- 通过request对象获取请求转发器对象:
RequestDispatcher getRequestDispatcher(String path) - 使用RequestDispatcher对象来进行转发:
forward(ServletRequest request, ServletResponse response)
1 | ("/hello") |
转发特点:
- 浏览器地址栏路径不发生变化
- 只能转发到当前服务器内部资源中。
- 转发是一次请求
10. 共享数据
共享数据:
- 域对象:一个有作用范围的对象,可以在范围内共享数据
- request域:代表一次请求的范围,一般用于请求转发的多个资源中共享数据
方法:
void setAttribute(String name,Object obj)存储数据Object getAttitude(String name)通过键获取值void removeAttribute(String name)通过键移除键值对
1 | ("/hello") |