Request && Response
文章目录
Request
一、继承体系
- Tomcat需要解析请求数据,封装为request对象,并将request对象传递到service方法中
- 使用request对象,查阅JavaEE API文档的HttpServletRequest接口
二、获取请求数据方法
请求数据分为三部分:
- 请求行
String getMethod()
:获取请求方式
String getContexPath()
:获取虚拟目录(项目访问路径)
StringBuilder GetRequestURL()
:获取URL(统一资源定位符)
String getRequestURI()
:获取URI(统一资源标识符)
String getQueryString()
:获取请求参数(GET方式)
示例代码:
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取请求方式
String method = req.getMethod();
System.out.println(method);
//获取虚拟目录(项目访问路径)
String contextPath = req.getContextPath();
System.out.println(contextPath);
//获取URL(统一资源定位符)
StringBuffer requestURL = req.getRequestURL();
System.out.println(requestURL);
//获取URI(统一资源标识符)
String requestURI = req.getRequestURI();
System.out.println(requestURI);
//获取请求参数(GET方式)
String queryString = req.getQueryString();
System.out.println(queryString);
String agent = req.getHeader("user-agent");
System.out.println(agent);
}
输出结果:
- 请求头
String GetHeader(String name)
:根据请求头名称,获取值
示例代码:
//获取请求头:user-agent:浏览器版本信息
String agent = req.getHeader("user-agent");
System.out.println(agent);
输出结果:
- 请求体
ServletInputStream getInputStream()
:获取字节输入流
BufferedReader getReader()
:获取字符输入流
示例代码:
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取Post请求体,请求参数
//1. 获取字符输入流
BufferedReader br = req.getReader();
//2. 读取数据
String line = br.readLine();
System.out.println(line);
}
输出结果:
三、通用方式获取请求参数
Map<String, String[]> getParameterMap()
:获取所有参数Map集合String[] getParameterValues(String name)
:根据名称获取参数值(数组)String getParameter(String name)
:根据名称获取参数值(单个值)
示例代码:
@WebServlet("/req2")
public class RequestDemo2 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//GET 逻辑请求
System.out.println("GET......");
Map<String, String[]> map = req.getParameterMap();
for (String key : map.keySet()) {
System.out.print(key+":");
String[] values = map.get(key);
for (String value : values) {
System.out.print(value+" ");
}
System.out.println();
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//POST 逻辑请求
System.out.println("POST......");
this.doGet(req, resp);
}
}
四、请求参数中文乱码处理
- 请求参数中如果存在中文数据,则会乱码
- 解决方案:
- POST:设置输入流的编码
request.setCharacterEncoding("UTF-8")
- 通用方式(GET/POST):先解码,再编码
new String(username.getBytes("ISO-8859-1"),"UTF-8")
- POST:设置输入流的编码
- URL编码:
- 将字符串按照编码方式转为二进制
- 每个字节转为2个16进制数并在前面加上%
/**
* 解决中文参数乱码问题
*/
@WebServlet("/req3")
public class RequestDemo3 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//GET: 获取参数方式:getQueryString()
//乱码原因:tomcat进行URL解码,默认的字符集ISO-8859-1
String username = request.getParameter("username");
System.out.println("解码前:"+username);
//byte[] bytes = username.getBytes(StandardCharsets.ISO_8859_1);
//username = new String(bytes, StandardCharsets.UTF_8);
username = new String(username.getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8);
System.out.println("解码后:"+username);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//POST: 获取参数方式:getReader()
//request.setCharacterEncoding("utf-8");
this.doGet(request, response);
}
}
五、请求转发
- 请求转发(Forward):一种在服务器内部的资源跳转方式
- 实现方式
getRequestDispatcher("资源路径").forward(req, resp)
- 请求转发资源间共享数据:使用Request对象
void setAttribute(String name, Object o)
:存储数据到request域中Object getAttribute(String name)
:根据key,获取值void removeAttribute(String name)
:根据key,删除该键值对
- 请求转发特点
- 浏览器地址栏路径不发生变化
- 只能转发到当前服务器的内部资源
- 一次请求,可以在转发的资源间使用request共享数据
Response
一、设置响应数据功能介绍
响应数据分为3部分:
- 响应行
void setStatus(int sc)
:设置响应状态码 - 响应头
void setHeader(String name, String value)
:设置相应头键值对 - 响应体
PrintWriter getWriter()
:获取字符输出流
ServletOutputStream getOutputStream()
:获取字节输出流
二、完成重定向
- 重定向(Redirect):一种资源跳转方式
- 实现方式:
resp.setStatus(302);
resp.setHedder("location", "资源B的路径");
resp.sendRedirect("资源B的路径")
- 重定向特点
- 浏览器地址栏路径发生变化
- 可以重定向到任意位置的资源(服务器内部外部均可)
- 两次请求,不能在多个资源中使用request共享数据
- 路径问题
- 明确路径谁使用?
- 浏览器使用:需要加虚拟目录(项目访问路径)
- 服务端使用:不需要加虚拟目录
- 明确路径谁使用?
@WebServlet("/resp1")
public class ResponseDemo1 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("resp1...");
/*//重定向
//1. 设置响应状态码为302
response.setStatus(302);
//2. 设置响应头 Location
response.setHeader("Location", "/web_demo/resp2");*/
//动态获取资源目录
String contextPath = request.getContextPath();
//简化方式完成重定向
response.sendRedirect(contextPath+"/resp2");
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request, response);
}
}
三、响应字符数据
- 使用
- 通过Response对象获取字符输出流
- 写数据
- 注意:
- 该流不需要关闭,随着响应结束,response对象销毁,由服务器关闭
- 中文数据乱码:原因是通过Response获取的字符输出流默认编码为ISO-8859-1
resp.setContentType("text/html;charset=utf-8");
/**
* 相应字符数据:设置字符数据的响应体
*/
@WebServlet("/resp3")
public class ResponseDemo3 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("resp3...");
//设置输出流编码
response.setContentType("text/html;charset=utf-8");
//1. 获取字符输出流
PrintWriter writer = response.getWriter();
//写数据
writer.write("你好");
writer.write("<h1>HELLO</h1>");
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request, response);
}
}
四、响应字节数据
-
使用
- 通过Response对象获取字节输出流
ServletOutputStream sos = response.getOutputStream();
- 写数据
outputStream.write(字节数据);
- 通过Response对象获取字节输出流
-
IOUtils工具类使用
- 导入坐标
<dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.6</version> </dependency>
- 使用
IOUtils.copy(输入流,输出流);
示例代码:
/**
* 相应字节数据:设置字节数据的响应体
*/
@WebServlet("/resp4")
public class ResponseDemo4 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("resp4...");
//1. 读取文件
FileInputStream fis = new FileInputStream("E:\\itheimaProject\\web_demo\\src\\main\\resources\\img\\a.jpg");
//2. 获取字节输出流
ServletOutputStream sos = response.getOutputStream();
//3.完成流的copy
/*byte[] buff = new byte[1024];
int len = 0;
while ((len = fis.read(buff)) != -1) {
sos.write(buff, 0, len);
}*/
IOUtils.copy(fis, sos);
fis.close();
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request, response);
}
}
声明: 本文内容整理自:黑马程序员新版JavaWeb基础教程,Java web从入门到企业实战完整版