Request
Request : 使用request对象来获取请求数据
Request继承体系
1.Tomcat需要解析请求数据,封装为Request对象,并且创建request对象传递到service方法中
2.使用request对象,查阅JavaEE API文档的HttpServletRequest接口
Request获取请求数据
获取请求行
请求行组成格式:
GET/request-demo/req1?username=zhangsan HTTP/1.1
常用方法
String getMethod():获取请求方式 GET
Strng getContextPath():获取虚拟目录(项目访问路径) /request-demo
StringBuffer getRequestURL():获取URL(统一资源定位符) http://localhost:8080/request-demo/req1
String getRequestURI() : 获取URI(统一资源标识符) /request-demo/req1
String getQueryString() : 获取请求参数(GET方式) username=zhangsan&password=123
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// String getMethod():获取请求方式 GET
String method = req.getMethod();
System.out.println(method);
// Strng getContextPath():获取虚拟目录(项目访问路径) /request-demo
String contextPath = req.getContextPath();
System.out.println(contextPath);
// StringBuffer getRequestURL():获取URL(统一资源定位符) http://localhost:8080/request-demo/req1
StringBuffer url = req.getRequestURL();
System.out.println(url);
// String getRequestURI() : 获取URI(统一资源标识符) /request-demo/req1
String uri = req.getRequestURI();
System.out.println(uri);
// String getQueryString() : 获取请求参数(GET方式) username=zhangsan&password=12
String queryString = req.getQueryString();
System.out.println(queryString);
//String getHeader(String name):根据请求头名称,获取值
String agent = req.getHeader("user-agent");
System.out.println(agent);
}
获取请求头
请求头组成格式:
User-Agent:Mozilla/5.0 Chrome/91.0.4472.106
String getHeader(String name):根据请求头名称,获取值
获取请求体(post方式)
请求体格式:
username=zhangsan&password=123
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);
}
通用方式获取请求参数
GET方式:
String getQueryString()
POST方式:
BufferedReader getReader()
思考:
GET请求方式和POST请求方式,区别主要在于获取请求参数的方式不一样,是否可以提供一种统一获取请求参数的方式,从而统一doGet和doPost方法内的代码
Map<String,String[]> getParameterMap():获取所有参数Map集合
String[] getParameterValues(String name):根据名称获取参数值(数组)
String getParameter(String name):根据名称获取参数值(单个值) //常用
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//GET 请求逻辑
//System.out.println("get...");
//1.获取所有请求参数的Map集合
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();
}
System.out.println("----------------");
//2.根据key获取参数值 数组
String[] hobbies = req.getParameterValues("hobby");
for (String hobby : hobbies) {
System.out.println(hobby);
}
//3.根据key获取单个参数值
String username = req.getParameter("username");
String password = req.getParameter("password");
System.out.println(username);
System.out.println(password);
}
请求参数中文乱码
POST解决方案 : 设置输入流的编码
//解决乱码 POST getReader() 编码
request.setCharacterEncoding("UTF-8"); //设置字符输入流的编码
GET解决方案 : 先解码,再编码(通用)
new String(username.getBytes("ISO-8859-1"),"UTF-8");
Request请求转发(forward)
概述:一种在服务器内部的资源跳转方式
实现方式:
req.getRequestDispatcher("资源B路径").forward(req,resp)
请求转发资源间共享数据:使用Request对象
void setAtrribute(String name,Object o);//存储数据到request域中
Object getAtrribute(String name);//根据key,获取值
void removeAtrribute(String name);//根据key,删除该键值对
请求转发特点
- 浏览器地址栏路径不发生变化
- 只能转发到当前服务器的内部资源
- 一次请求,可以在转发的资源间使用request共享数据
response
Response : 使用response对象来设置响应数据
Response设置响应数据
响应行
格式 : HTTP/1.1 200 OK
void setStatus(int sc); //设置响应状态码
响应头
Content-Type : text/html
void setHeader(String name,String value);//设置响应头键值对
响应体
<html><head></head><body></body></html>
PrintWriter getWriter(); //获取字符输出流
ServletOutputStream getOutputStream(); //获取字节输出流
Response完成重定向
重定向(Redirect) : 一种资源跳转方式
实现方式:
resp.setStatus(302);
resp.setHeader("location","资源B的路径");
resp.sendRedirect("资源B的路径");
重定向特点
- 浏览器地址栏路径发生变化
- 可以重定向到任意位置的资源(服务器内部、外部均可)
- 两次请求,不能再多个资源之间使用request共享数据
请求转发特点
- 浏览器地址栏路径不发生变化
- 只能转发到当前服务器的内部资源
- 一次请求,可以在转发的资源之间使用request共享数据
路径问题
有些路径需要加虚拟目录,有些路径不需要加虚拟目录,如何区分?
明确路径谁使用?
- 浏览器使用 : 需要加虚拟目录(项目访问路径)
- 服务器使用 : 不需要加虚拟目录
动态获取虚拟目录
//动态获取虚拟目录
String contextPath = request.getContextPath();
response.sendRedirect(contextPath+"/resp2");
Response响应字符数据
1.通过Response对象获取字符输出流
PrintWriter writer = response.getWriter();
2.写数据
writer.write("aaa");
注意
- 该流不需要关闭,随着响应结束,response对象销毁,由服务器关闭
- 中文数据乱码:原因是Response获取的字符输出流默认编码是ISO-8859-1
//设置输出流的编码
response.setContentType("text/html;charset=utf-8");
Response响应字节数据
1.通过Response对象获取字节输出流
//获取字节输出流 os
ServletOutputStream os = response.getOutputStream();
2.写数据
os.write(字节数据);
IOUtils工具类使用
1.导入坐标
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.5</version>
</dependency>
2.使用
IOUtils.copy(fis,os);