Request & Response
Request
- Request 获取请求数据
Request 继承体系
Tomcat 需要解析浏览器请求, 封装为 request 对象,并且创建 request 对象传到 sevice 方法中
当我们的Servlet类实现的是Servlet接口的时候,service方法中的参数是ServletRequest和ServletResponse
当我们的Servlet类继承的是HttpServlet类的时候,doGet和doPost方法中的参数就变成HttpServletRequest和HttpServletReponse
Request 获取请求数据
请求行
String getMethod()
: 获取请求方式GET
String getContextPath()
: 获取虚拟目录(项目访问路径)/request-demo
StringBuffer getRequestURL()
: 获取统一资源定位符http://localhost:8080/request-demo/req1
String getRequestURI()
: 获取 URI (统一资源标识符)request-demo/req1
String getQueryString()
: 获取请求参数(GET 方式)username=zhangsan
请求头
String getHeader(name: String)
: 根据请求头名称获取值
请求体 (POST)
ServletInputStream getInputStream()
获取请求体字节输入流BufferedReader getReader()
: 获取请求体字符输入流
获取的流不用手动关闭,随 request 对象销毁而自动关闭
统一获取请求参数
由于 GET 方式的请求参数在请求头中, POST 方式的请求参数在请求体中,上述方法获取请求参数对应的方法不同,而使用 request 的以下方法可以统一获取请求参数
Map<String, String[]> getParameterMap()
获取所有参数 Map 集合String[] getParameterValues(String var1)
根据参数名称获取参数值(数组)String getParameter(String var1)
根据参数名称获取单个参数值
处理中文请求参数乱码
- 由于浏览器 URL 编码使用 UTF-8 格式编码,而 tomcat7 以及之前的版本解码 URL 使用 ISO-8859-1 解码,在请求中含有中文字符时会出现乱码
- tomcat8.0 及以后使用 UTF-8 格式解码,无需处理乱码
URL 编码
URL 编码会将字符转换为可通过因特网传输的格式。
URL 只能使用 ASCII 字符集来通过因特网进行发送。
对于非 ASCII 字符,将字符按照编码格式转为二进制,在每个字节转成两个16进制数并在前面加
%
http://localhost/webDemo/?username=%E5%BC%A0%E4%B8%89
- URL 不能包含空格。URL 编码通常使用 + 来替换空格。
POST 处理乱码
在获取参数前设置字符输入流编码
1 |
|
GET 处理乱码
- 由于 GET 方式获取请求不使用字符输入流,上述设置无法解决 GET 参数乱码问题
1 |
|
一句代码解决 ( GET POST 均可使用)
1 |
|
Request 请求转发
请求转发:一种在服务器内部的资源跳转方式
实现方式
需求:用户请求资源A,资源A处理完将请求转发给资源B处理
1
2//在资源A的doGet()中调用
request.getRequestDispatcher("资源B路径").forward(request,response);
转发时共享数据
1 |
|
1 |
|
Response
使用 Response 对象设置响应数据
Response 继承结构与 Request 类似
Response 设置响应数据
调用 response 相应方法设置响应数据
- 响应行
HTTP/1.1 200 OK
void setStatus(int sc)
: 设置响应状态码
- 响应头
Content-Type:text/html
void setHeader(String name, String value)
: 设置响应头键值对
- 响应体
printWriter()
: 获取字符输出流ServletOutputStream getOutputStream()
: 获取字节输出流
Response 完成重定向
重定向(Redirct):一种资源跳转方式
使用场景:用户请求资源A,但资源A无法完成请求,资源A将请求重定向到资源B
服务器向浏览器发起重定向响应, 状态码为 302,浏览器访问响应响应头中 Location 对应 URL
1 |
|
- 与请求转发不同,重定向资源路径需要加上虚拟目录
重定向与请求转发对比
重定向特点
- 浏览器地址栏发生变化
- 可以重定向到任意资源,既能重定向到服务器内部,也能重定向到服务器外部
- 两次请求,不能在多个资源使用 request 共享数据
请求转发特点
- 浏览器地址栏不发生变化
- 只能转发到当前服务器内部资源
- 一次请求,多个资源共享 request 数据
路径问题
- 明确路径给谁使用
- 给浏览器使用:需要添加虚拟目录(项目访问路径)
- 给服务器使用: 不需要添加虚拟目录
- 使用虚拟目录时使用
request.getContextPath()
动态获取目录
Response 响应字符数据
获取字符输出流
1
PrintWriter writer = response.getWriter();
写数据
1
write.write("<h1>aaa</h1>");//浏览器当作纯文本输出
若需浏览器解析为 HTML ,需设置头信息
1
response.setHeader("content-type","text/html");
write 流不需要手动关闭,随 response 销毁自动关闭
输出中文数据需要设置流的编码
1
2//设置响应头的同时设置输出流的字符集
response.setContentType("text/html;charset=utf-8");
Response 响应字节数据
获得字节输出流
1
ServletOutputStream outputStream = response.getOutputStream();
读取文件
1
FileInputStream fis = new FileInputStream("a.jpg");
拷贝字节流
- 直接拷贝
1
2
3
4
5byte[] buf = new byte[1024];
int length = 0;
while((length = fis.read(buf))!=-1) {
outputStream.write(buf);
}使用工具类
在
pom.xml
中导入 commons-io1
2
3
4
5
6
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>调用 copy 方法
1
IOUtils.copy(fis,outputStream);
关闭文件
1
fis.close()