【笔记】Servlet的请求对象和响应对象

前言

Servlet的请求对象和响应对象

Request请求对象

  • 解析从客户端传递的请求数据

req:请求对象

解析请求行

获取请求方式

1
req.getMethod();

获取访问路径

  • http://example.com/dir/file?key=value中的/dir
1
req.getContextPath();

获取完整请求路径

  • 返回StringBuffer

  • http://example.com/dir/file?key=value中的http://example.com/dir/file

1
req.getRequestURL();

获取当前项目的请求路径

  • http://example.com/dir/file?key=value中的/dir/file
1
req.getRequestURI();

获取请求参数

  • http://example.com/dir/file?key=value中的key=value
1
req.getQueryString();
Request中的通用方法处理请求参数
获取所有请求参数
1
Map<String, String[]> map = req.getParameterMap();
根据指定参数名获取一个参数值

<key>:请求参数名

1
String value = req.getParameter("<key>")
根据指定参数名获取所有参数值
  • 如果有多个同名的请求参数,那么所有请求值会作为字符串数组返回
1
String[] values = req.getParameterValues("<key>");
解决请求参数的中文乱码
  • 由于Tomcat8之前默认使用的URL解码方式是ISO-8859-1,而前端URL编码方式是UTF-8,所以出现了中文乱码
  • Tomcat8及之后使用的URL解码方式是UTF-8,所以不需要解决中文乱码
Get请求或Post请求
  • 先将ISO-8859-1的数据转换成字节数组,再将字节数组根据UTF-8编码转换成字符串

value:通过req.getParameter("")获取的出现中文乱码的参数值

1
2
byte[] bytes = value.getBytes("ISO-8859-1");
String str = new String(bytes, "utf-8");
1
2
byte[] bytes = value.getBytes(StandardCharsets.ISO_8859_1);
String str = new String(bytes, StandardCharsets.UTF_8 );
Post请求
  • 因为Post请求参数的处理方式是字符输入流,所以只需要在处理请求参数之前,修改字符输入流的字符编码为UTF-8即可解决中文乱码
1
req.setCharacterEncoding("UTF-8");

解析请求头

<key>:根据请求头的键获取值

1
req.getHeader("<key>");

解析请求体

字符输入流

  • 返回BufferedReader对象
1
2
BufferedReader br = req.getReader();
String line = br.readLine();

字节输入流

  • 返回ServletInputStream对象
1
req.getInputStream();

请求转发

  • 请求转发时,客户端地址栏不发生改变
  • 请求转发只能转发给服务器内部资源
  • 整个过程经历1次请求1次响应
  • 请求转发时,可以通过request携带数据

<url>:请求转发的目标资源路径,不需要加虚拟目录
req:请求对象
resp:响应对象

1
req.getRequestDispatcher("<url>").forward(req, resp);

请求转发时携带数据

存储数据

<key>:键
<value>:值

1
req.setAttribute("<key>", <value>);
获取数据
1
req.getAttribute("<key>");
删除数据
1
req.removeAttribute("<key>");

Response响应对象

  • 设置发送给客户端的相应数据

resp:响应对象

设置响应行

设置状态码

<code>:int类型的状态码

1
resp.setStatus(<code>);

设置响应头

<key>:键
<value>:值

1
setHeader("<key>", "<value>");

设置响应体

字符输出流

<str>:需要响应的数据

1
2
PrintWriter pw = getWriter();
pw.write("<str>");
  • 输出流不需要关闭,当resp对象被销毁时会自动被关闭
设置响应头
  • 如果响应的数据是需要被渲染的HTML代码,需要提前设置响应头
1
2
3
resp.setHeader("content-type", "text/html");
PrintWriter pw = getWriter();
pw.write("<str>");
1
2
3
resp.setContentType("text/html");
PrintWriter pw = getWriter();
pw.write("<str>");
解决中文乱码
  • Tomcat响应数据的默认编码是ISO-8859-1,而浏览器默认编码是UTF-8,所以会出现中文乱码
1
2
3
resp.setHeader("content-type", "text/html;charset=utf-8");
PrintWriter pw = getWriter();
pw.write("<str>");
1
2
3
resp.setContentType("text/html;charset=utf-8");
PrintWriter pw = getWriter();
pw.write("<str>");

字节输出流

<value>:字节数据

1
2
ServletOutputStream sos = resp.getOutputStream();
sos.write(<value>);
响应文件

<file>:文件路径

1
2
3
4
5
6
7
8
FileInputStream fis = new FileInputStream("<file>");
ServletOutputStream sos = resp.getOutputStream();
byte[] buff = new byte[1024];
int len = 0;
while ((len = fis.read(buff)) != -1) {
sos.write(buff, 0, len);
}
fis.close();
利用工具类
  • 利用工具类完成文件拷贝
pom.xml
1
2
3
4
5
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
1
import org.apache.commons.io.IOUtils
1
2
3
4
FileInputStream fis = new FileInputStream("<file>");
ServletOutputStream sos = resp.getOutputStream();
IOUtils.copy(fis, os);
fis.close();

重定向

  • 重定向时,客户端地址栏会发生改变
  • 重定向时,服务器内部资源和外部资源都可以被重定向
  • 整个过程经历2次请求2次响应
  • 重定向时,不可以通过request携带数据

<url>:响应重定向的目标资源路径,需要加虚拟目录

1
2
resp.setStatus(302);
resp.setHeader("location", "<url>");
1
resp.sendRedirect("<url>");
  • 为了解耦合,可以动态拼接虚拟路径
1
resp.sendRedirect(req.getContextPath + "<url>");

完成

参考文献

哔哩哔哩——黑马程序员