05-Request&Response
Request&Response
- Request
- 获取请求数据
- Response
- 设置响应数据
1、Request
1.1、Request继承体系
- 1、Tomcat需要解析请求数据,封装为request对象,并且创建request对象传递到service方法中
- 2、使用request对象,查阅JavaEE API文档的
HttpServletRequest
接口
1.2、Request获取请求数据
1.2.1、获取请求数据的方法
-
请求行:GET /request-response-demo/req1?username=zhangsan HTTP/1.1
-
方法 说明 数据 String getMethod() 获取请求方式 GET String getContextPath() 获取虚拟路径(项目访问路径) /request-response-demo StringBuffer getRequestURL() 获取URL(统一资源定位符) http://localhost:8080/request-response-demo/req1 String getRequestURI() 获取URI(统一资源定位符) /request-response-demo/req1 String getQueryString() 获取请求参数(GET方式) username=zhangsan&password=123
-
-
请求头:User-Agent: Mozilla/5.0 Chrome/91.0.4472.106
String getHeader(String name)
:根据请求头名称,获取值
-
请求体:username=superbaby&password=123
ServletInputStream getInputStream()
:获取字节输入流BufferedReader getReader()
:获取字符输入流
1.2.2、通用方式获取请求参数
- 请求参数获取方式
- GET方式
- String getQueryString()
- POST方式
- BufferedReader getReader()
- GET方式
- 思考
- 这里的GET请求方式和POST请求方式,区别主要在于获取请求参数的方式不一样
- 那么是否有一种统一获取请求参数的方式,从而统一doGet和doPost方法内的代码?
- 在Tomcat源码中,实现了一个在获取请求方式的时候,将参数赋值给了同一个成员变量param,使得doGet和doPost方法内的请求参数方式的代码有了统一的可能
-
Map<String,String[]> getParameterMap()
:获取所有参数Map集合String getParameter(String name)
:根据名称获取参数值(单个值)String[] getParameterValues(String name)
:根据名称获取参数值(数组)
1.2.3、请求参数中文乱码处理
- Tomcat 8.0 之后,GET请求乱码的问题已经被解决,设置默认的编码方式为UTF-8,其他Tomcat的默认编码都为 ISO-8859-1;
- Request解决POST请求参数中文乱码
- 给POST方法设置输入流的编码
request.setCharacterEncoding("UTF-8")
- 给POST方法设置输入流的编码
- URL编码
- 1.将字符串按照编码方式转为二进制
- 2.每个字节转为2个16进制数并在前面加上%
1.3、Request请求转发
- 请求转发(forward):一种在服务器内部的资源跳转方式
- 实现方式
request.getRequestDispatcher("资源B路径").forward(request, response);
- 请求转发资源间共享数据:使用Request对象
void setAttribute(String name, Object o)
:存储数据到request域中Object getAttribute(String name)
:根据key,获取值void removeAttribute(String name)
:根据key,删除键值对
- 请求转发的特点
- 浏览器地址栏路径不发生变化
- 只能转发到当前服务器的内部资源
- 一次请求,可以在转发资源间使用request共享数据
2、Response
- Request:使用request对象来获取请求数据
- Response:使用response对象来设置响应数据
2.1、Response继承体系
2.2、Response设置响应数据
- 响应数据分为3个部分
- 响应行
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()
:获取字节输出流
- 响应行
2.3、Response重定向
- 重定向概念
- 跳转到下一个页面,不需要传递数据,使用重定向
- 是一种资源跳转方式
- 实现方式
- 方式1
response.setStatus(302);
response.setHeader("location", "资源B的路径");
- 方式2
response.sendRedirect("资源B的路径");
- 方式1
- 重定向的特点
- 浏览器地址栏发生变化
- 可以重定向到任意位置的资源(服务器内部、外部均可)
- 再次请求,不能在多个资源使用request共享数据
2.4、Response响应字符数据
- 实现方式
- 1.通过Response对象获取字符输出流
PrintWriter writer = response.getWriter();
- 2.输出数据
writer.write("aaa");
- 1.通过Response对象获取字符输出流
- 注意事项
- 该流不需要关闭,随着响应结束,response对象销毁,由服务器关闭
- 中文数据乱码,原因是通过Response获取的字符输出流默认编码跟Tomcat的默认编码一样都是:ISO-8859-1
- 解决方式
response.setContentType("text/html;charset=utf-8");
- 解决方式
2.5、Response响应字节数据
-
实现方式
- 1.通过Response对象获取字节输出流
ServletOutputStream outputStream = response.getOutputStream();
- 2.写数据
outputStream.write(字节数据);
- 1.通过Response对象获取字节输出流
-
IOUtils
工具类的使用-
添加依赖
-
<dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId <version>2.6</version> </dependency>
-
-
IOUtils.copy(输入流,输出流);
-
3、额外注意事项
3.1、路径问题
- 明确路径谁使用?
- 浏览器使用
/
开头是绝对路径,会缺少项目访问路径- 不加
/
是相对路径,使用当前访问路径作为参照物,不会缺少项目访问路径 - 浏览器使用的时候不加
/
- 服务器使用
- 不加
/
- 不加
- 浏览器使用
4、使用Tomcat实现用户登录和注册功能
-
LoginServlet
类-
package com.coolman.servlet; import com.coolman.mapper.UserMapper; import com.coolman.pojo.User; import com.coolman.utils.MybatisUtils; import org.apache.ibatis.session.SqlSession; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; @WebServlet("/loginServlet") public class LoginServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 在这里处理请求 // 处理html表单的POST请求发送数据,中文时存在的编码问题 request.setCharacterEncoding("utf-8"); // 1. 获取参数 String username = request.getParameter("username"); String password = request.getParameter("password"); // 2. 连接数据库 SqlSession sqlSession = MybatisUtils.openSession(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); User user = mapper.selectUser(username, password); // 3. 判断表中是否存在该用户信息 // 输出提示信息之前,需要解决response返回响应数据可能出现中文乱码的问题 response.setContentType("text/html;charset=utf-8"); PrintWriter writer = response.getWriter(); if (user != null) { // 输出字符流信息 writer.println("登录成功!"); // writer.println("<style>window.alert("恭喜您登录成功!")</style>"); } else { writer.println("登录失败!"); // writer.println("<style>window.alert("账号密码错误,登录失败!")</style>"); } sqlSession.close(); } }
-
-
RegisterServlet
类-
package com.coolman.servlet; import com.coolman.mapper.UserMapper; import com.coolman.pojo.User; import com.coolman.utils.MybatisUtils; import org.apache.ibatis.session.SqlSession; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; @WebServlet("/registerServlet") public class RegisterServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 在这里处理请求 // 处理POST请求,表单返回的数据可能出现乱码的问题 request.setCharacterEncoding("utf-8"); // 获取参数 String username = request.getParameter("username"); String password = request.getParameter("password"); // 连接数据库 SqlSession sqlSession = MybatisUtils.openSession(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); // 查询该信息是否存在数据库 User user = mapper.selectUserByUsername(username); // 解决response响应的数据可能出现乱码的问题 response.setContentType("text/html;charset=utf-8"); // 获取字符输出流 PrintWriter writer = response.getWriter(); // 考虑存在和不存在问题 if (user != null) { // 如果用户存在 writer.println("该用户已经存在,请重新注册!"); } else { // 如果用户不存在,那么就创建这个用户 User userNew = new User(); userNew.setUsername(username); userNew.setPassword(password); mapper.addUser(userNew); sqlSession.commit(); writer.println("注册成功!"); } sqlSession.close(); } }
-