目录
【Request】
【Request继承体系】
- Tomcat需要解析请求数据,封装为request对象,并且创建request对象传递到service方法中
- 使用request对象,查阅JavaEE API文档的HttpServletRequest接口
【Request获取请求数据】
【请求数据分为3部分】
1、请求行:GET /HTTP/req1?username=zhangsan HTTP/1.1
- String getMethod():获取请求方式: GET
- String getContextPath():获取虚拟目录(项目访问路径)
- StringBuffer getRequestURL(): 获取URL(统一资源定位符)
- String getRequestURI():获取URI(统一资源标识符)
- 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);
//String getContextPath():获取虚拟目录(项目访问路径)
String contextPath = req.getContextPath();
System.out.println(contextPath);
//StringBuffer getRequestURL(): 获取URL(统一资源定位符)
StringBuffer url = req.getRequestURL();
System.out.println(url.toString());
//String getRequestURI():获取URI(统一资源标识符)
String uri = req.getRequestURI();
System.out.println(uri);
//String getQueryString():获取请求参数(GET方式):访问网页时在?后加上username=zhangsan&password=123
String queryString = req.getQueryString();
System.out.println(queryString);
}
2、请求头:User-Agent: Mozilla/5.0 Chrome/91.0.4472.106
- String getHeader(String name):根据请求头名称,获取值
例:
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//String getHeader(String name):根据请求头名称,获取值
String agent = req.getHeader("user-agent");
System.out.println(agent);
}
3、请求体:username=superbaby&password=123
- ServletInputStream getInputStream():获取字节输入流
- BufferedReader getReader():获取字符输入流
例:
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取post 请求体:请求参数
//获取字符输入流
BufferedReader br=req.getReader();
//读取数据
String line = br.readLine();
System.out.println(line);
}
【Request通用方式获取请求参数】
- 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 {
//获取所有参数的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();
}
//获取对应的参数值
String[] hobbies = req.getParameterValues("hobby");
for (String hobby : hobbies) {
System.out.println(hobby);
}
//根据key获取单个参数值
String username = req.getParameter("username");
String password = req.getParameter("password");
System.out.println(username);
System.out.println(password);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doGet(req, resp);
}
}
【可以使用Servlet模板创建Servlet更高效】
右键web在new中选中Servlet模板创建
【可以通过settings设置修改模板】
【注意】
如果右键web在new中没有servlet,在Project Structure中设置如图所示
【Request请求参数中文乱码处理】
【解决方案】
POST:设置输入流的编码
req.setCharacterEncoding(“UTF-8");
通用方式:(GET/POST):先编码再解码
new String(username.getBytes("ISO-8859-1"),"UTF-8");
例:
//解决中文乱码:设置编码格式
req.setCharacterEncoding("UTF-8");
//获取username
String username = req.getParameter("username");
System.out.println(username);
//GET,获取参数的方式:getQueryString
//先对乱码数据进行编码,转为字节数组
byte[] bytes = username.getBytes(StandardCharsets.ISO_8859_1);
username = new String(bytes, StandardCharsets.UTF_8);
System.out.println(username);
【URL编码】
- 将字符串按照编码方式转为二进制
- 每个字节转为2个16进制数并在前边加上%
【实现方式】
编码:URLEncoder.encode(str, "utf-8");
解码:URLDecoder.decode(s, "ISO-8859-1");
【Request请求转发】
【概述】
请求转发(forward):一种在服务器内部的资源跳转方式
【实现方式】
req.getRequestDispatcher("资源B路径").forward(req,resp);
【请求转发资源间共享数据】
使用Request对象:
- void setAttribute(String name, Object o):存储数据request域中
- Object getAttribute(String name):根据 key,获取值
- void removeAttribute(String name):根据 key,删除该键值对
【特点】
- 浏览器地址栏路径不发生变化
- 只能转发到当前服务器的内部资源
- 一次请求,可以在转发的资源间使用request共享数据
【Response】
【Response继承体系】
【Response设置响应数据功能介绍】
【响应数据分为3部分】
1、响应行:HTTP/1.1 200 OK
- void setStatus(int sc) :设置响应状态码
2、响应头:Content-Type: text/html
- void setHeader(String name, String value) :设置响应头键值对
3、响应体:<html><head>head><body></body></html>
- PrintWriter getWriter():获取字符输出流
- ServletOutputStream getOutputStream():获取字节输出流
【Response完成重定向】
【概述】
一种资源跳转方式
【实现方式】
resp.setStatus(302);
resp.setHeader(“location”,“资源B的路径");
或
resp.sendRedirect("资源B的路径");//(简化)
例:
//重定向
//设置响应状态码
response.setStatus(302);
//设置响应头
response.setHeader("Location","/HTTP/resp2");
//简化方式
response.sendRedirect("/HTTP/resp2");
【特点】
- 浏览器地址栏路径发生变化
- 可以重定向到任意位置的资源(服务器内部、外部均可)
- 两次请求,不能在多个资源使用request共享数据
【注意】
- 浏览器使用:需要加虚拟目录(项目访问路径)
- 服务端使用:不需要加虚拟目录
【Response响应字符数据】
【方法】
1、通过Response对象获取字符输出流
PrintWriter writer = resp.getWriter();
2、写数据
writer.write("aaa");
例:
//解析text为html,并且改变响应数据的字符集为utf-8
response.setContentType("text/html;charset=utf-8");
//获取字符输出流
PrintWriter writer = response.getWriter();
writer.write("aaa");
writer.write("你好");
writer.write("<h1>aaa</h1>");
【注意】
- 该流不需要关闭,随着响应结束,response对象销毁,由服务器关闭
- 中文数据乱码:原因通过Response获取的字符输出流默认编码:ISO-8859-1
resp.setContentType("text/html;charset=utf-8");
【Response响应字节数据】
【方法】
1、通过Response对象获取字节输出流
ServletOutputStream outputStream = resp.getOutputStream();
2、写数据
outputStream.write(字节数据);
例:
//读取文件
FileInputStream fis=new FileInputStream("E:\\Project\\JAVA\\Project Study\\HTTP\\Image\\reg_bg_min.jpg");
//获取response字节输出流
ServletOutputStream os=response.getOutputStream();
//完成流的copy
byte[] buff=new byte[1024];
int len=0;
while ((len= fis.read(buff))!=-1){
os.write(buff,0,len);
}
fis.close();
【使用IOUtils工具类】
1、导入坐标
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
2、使用
IOUtils.copy(输入流,输出流);
例:
//读取文件
FileInputStream fis=new FileInputStream("E:\\Project\\JAVA\\Project Study\\HTTP\\Image\\reg_bg_min.jpg");
//获取response字节输出流
ServletOutputStream os=response.getOutputStream();
//完成流的copy
IOUtils.copy(fis,os);
fis.close();