Request

备注:该技术博客的内容是我根据技术视频整理与总结的(并非复制粘贴)。原视频源于黑马JavaWeb课程

一、Request原理

首先,我们要掌握request和response对象的原理

  1. 1.requestresponse对象是由服务器创建的。我们来使用他们呢
  2. 2.request对象是来获取请求消息,response对象是来设置响应消息

这样才能更好地指导这两个对象怎么去学习,他们是做什么的。我们通过画图的方式来讲解:
Request - 图1

  1. 首先,请求会携带请求消息找demo1资源,可以找到
  2. 因为我们在服务器端有一个Servlet配置的urlpatten是/demo1 (@WebServlet(“/demo1”))
  3. 所以找到了这个类,然后Tomcat会自动执行service方法
  4. 我们聊聊这个过程:
  5. 1.Tomcat服务器会根据请求url中的资源路径(/demo1)去创建对应的SerlvetDemo1对象
  6. 2.Tomcat服务器会创建两个对象,分别是requestresponse对象。request对象中封装请求消息数据
  7. 3.tomcatrequestresponse两个对象传递service方法,并且去调用service方法
  8. 4.我们可以来操作通过request对象获取请求消息数据,可以通过response对象设置响应消息数据
  9. 5.服务器在给浏览器做出响应之前会从response对象中去拿程序员设置的响应消息数据

接下来,我们来学request对象获取请求消息
但是学习它之前我们先说一说request继承体系结构

二、Request继承体系结构

  1. ServletRequest --接口
  2. | 继承关系
  3. HttpServlet Request --接口
  4. | 实现关系
  5. org.apache.catalina.connector.RequestFacade

org.apache.catalina.connector.RequestFacade是一个类,实现了HTTPServlet接口
这个类是Tomcat编写的,Tomcat将来通过这个类来创建Request对象,并且传递给service方法。

三、Request对象的功能

获取请求消息数据

  1. 获取请求行数据
  1. 请求行:
  2. GET /day14/demo1?name=zhangsan HTTP/1.1
  3. 获取数据方法:
  4. 1.获取请求方式:GET
  5. String getMehtod()
  6. 2.获取虚拟目录(重点掌握):/day14
  7. String getContextPath()
  8. 3.获取Servlet路径:/demo1
  9. String getServletPath()
  10. 4.获取get方式的请求参数:name=zhangsan
  11. String getQueryString()
  12. 5.获取请求的URI(重点掌握):/day14/demo1
  13. String getRequestURI(): /day14/demo1
  14. StringBuffer getRequestURL(): http://localhost/day14/demo1
  15. URL:统一资源定位符 http://localhost/day14/demo1 (相当于中华人民共和国)
  16. URI:统一资源标识符 /day14/demo1 (相当于共和国)
  17. 6.获取协议及版本: HTTP/1.1
  18. String getProtocol()
  19. 7.获取客户机的IP地址:
  20. String getRemoteAddr()

代码演示:

  1. package cn.itcast.web.request;
  2. import javax.servlet.ServletException;
  3. import javax.servlet.annotation.WebServlet;
  4. import javax.servlet.http.HttpServlet;
  5. import javax.servlet.http.HttpServletRequest;
  6. import javax.servlet.http.HttpServletResponse;
  7. import javax.swing.*;
  8. import java.io.IOException;
  9. /**
  10. * 演示Request对象获取请求行数据
  11. */
  12. @WebServlet("/requestDemo1")
  13. public class RequestDemo1 extends HttpServlet {
  14. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  15. }
  16. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  17. //1.获取请求方式:
  18. String method = request.getMethod();
  19. System.out.println(method);
  20. //2.获取虚拟目录(重点掌握):
  21. String contextPath = request.getContextPath();
  22. System.out.println(contextPath);
  23. //3.获取Servlet路径:
  24. String servletPath = request.getServletPath();
  25. System.out.println(servletPath);
  26. //4.获取get方式的请求参数:
  27. String queryString = request.getQueryString();
  28. System.out.println(queryString);
  29. //5.获取请求的URI(重点掌握):
  30. String requestURI = request.getRequestURI();
  31. StringBuffer requestURL = request.getRequestURL();
  32. System.out.println(requestURI);
  33. System.out.println(requestURL);
  34. //6.获取协议及版本:
  35. String protocol = request.getProtocol();
  36. System.out.println(protocol);
  37. //7.获取客户机的IP地址:
  38. String remoteAddr = request.getRemoteAddr();
  39. System.out.println(remoteAddr);
  40. }
  41. }

输出结果如下:

  1. GET
  2. /day14
  3. /requestDemo1
  4. name=zhangsan
  5. /day14/requestDemo1
  6. http://localhost/day14/requestDemo1
  7. HTTP/1.1
  8. 0:0:0:0:0:0:0:1
  1. 获取请求头数据
  1. 获取方法:
  2. 1.(重点掌握)String getHeader(String name):通过请求头的名称获取请求头的值
  3. 2.Enumeration<String> getHeaderNames():获取所有的请求头名称

代码演示:

  1. package cn.itcast.web.request;
  2. import javax.servlet.ServletException;
  3. import javax.servlet.annotation.WebServlet;
  4. import javax.servlet.http.HttpServlet;
  5. import javax.servlet.http.HttpServletRequest;
  6. import javax.servlet.http.HttpServletResponse;
  7. import java.io.IOException;
  8. @WebServlet("/requestDemo4")
  9. public class RequestDemo4 extends HttpServlet {
  10. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  11. }
  12. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  13. //演示获取请求头数据:referer
  14. String referer = request.getHeader("referer");
  15. System.out.println(referer);//http://localhost/day14/login.html
  16. //防盗链
  17. if (referer != null){
  18. if (referer.contains("/day14")){
  19. //正常访问
  20. System.out.println("播放电影...");
  21. }else{
  22. //盗链
  23. System.out.println("想看电影吗?来优酷吧....");
  24. }
  25. }
  26. }
  27. }
  1. 获取请求体数据
  1. 请求体:只有POST请求方式,才有请求体,在请求体中封装了POST请求的请求参数
  2. 获取请求体步骤:
  3. 1.获取流对象
  4. BufferedReader getReader():获取字符输入流,只能操作字符数据 (此博客演示这个方法)
  5. ServletInputSream getInputStream():获取字节输入流,可以操作任何类型数据(在文件上传知识点后讲解)
  6. 2.再从流对象中拿数据

代码展示:

  1. package cn.itcast.web.request;
  2. import javax.servlet.ServletException;
  3. import javax.servlet.annotation.WebServlet;
  4. import javax.servlet.http.HttpServlet;
  5. import javax.servlet.http.HttpServletRequest;
  6. import javax.servlet.http.HttpServletResponse;
  7. import java.io.BufferedReader;
  8. import java.io.IOException;
  9. @WebServlet("/requestDemo5")
  10. public class RequestDemo5 extends HttpServlet {
  11. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  12. //获取请求消息体--请求参数
  13. //1.获取字符流
  14. BufferedReader br = request.getReader();
  15. //2.读取数据
  16. String line = null;
  17. while ((line = br.readLine()) != null){
  18. System.out.println(line);
  19. }
  20. }
  21. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  22. }
  23. }

四、其他功能

  1. 获取请求参数通用方式:不论get还是post请求方式都可以使用下列方式方法来获取请求参数。
  1. 1.String getParameter(String name):根据参数名称获取参数值 (常用)
  2. 2.String[] getParameterValues(String name):根据参数名称获取数值的数组
  3. 3.Enumeration<String> getParameterNames():获取所有请求的参数名称
  4. 4.Map<String,String[]> getParameterMap():获取所有参数的map集合 (常用)

代码演示这四个方法:

  1. 第一个方法:
  2. @WebServlet("/requestDemo6")
  3. public class RequestDemo6 extends HttpServlet {
  4. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  5. //post 获取请求参数
  6. //根据参数名称获取参数值
  7. String username = request.getParameter("username");
  8. System.out.println("post");
  9. System.out.println(username);
  10. }
  11. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  12. //get 获取请求参数
  13. /*//根据参数名称获取参数值
  14. String username = request.getParameter("username");
  15. System.out.println("get");
  16. System.out.println(username);*/
  17. this.doPost(request,response);
  18. }
  19. }
  20. ================================================================================
  21. 第二个方法:
  22. @WebServlet("/requestDemo6")
  23. public class RequestDemo6 extends HttpServlet {
  24. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  25. //post 获取请求参数
  26. //根据参数名称获取参数值
  27. String username = request.getParameter("username");
  28. /*System.out.println("post");
  29. System.out.println(username);*/
  30. //根据参数获取参数值的数组
  31. String[] hobbies = request.getParameterValues("hobby");
  32. for (String hobby : hobbies) {
  33. System.out.println(hobby);
  34. }
  35. }
  36. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  37. //get 获取请求参数
  38. /*//根据参数名称获取参数值
  39. String username = request.getParameter("username");
  40. System.out.println("get");
  41. System.out.println(username);*/
  42. this.doPost(request,response);
  43. }
  44. }
  45. ================================================================================
  46. 第三个方法:
  47. @WebServlet("/requestDemo6")
  48. public class RequestDemo6 extends HttpServlet {
  49. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  50. //post 获取请求参数
  51. //根据参数名称获取参数值
  52. String username = request.getParameter("username");
  53. /*System.out.println("post");
  54. System.out.println(username);*/
  55. //根据参数获取参数值的数组
  56. String[] hobbies = request.getParameterValues("hobby");
  57. /*for (String hobby : hobbies) {
  58. System.out.println(hobby);
  59. }*/
  60. //获取所有请求的参数名称
  61. Enumeration<String> parameterNames = request.getParameterNames();
  62. while (parameterNames.hasMoreElements()){
  63. String name = parameterNames.nextElement();
  64. System.out.println(name);
  65. String value = request.getParameter(name);
  66. System.out.println(value);
  67. System.out.println("------------------------------------");
  68. }
  69. }
  70. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  71. //get 获取请求参数
  72. /*//根据参数名称获取参数值
  73. String username = request.getParameter("username");
  74. System.out.println("get");
  75. System.out.println(username);*/
  76. this.doPost(request,response);
  77. }
  78. }
  79. ================================================================================
  80. 第四个方法:
  81. @WebServlet("/requestDemo6")
  82. public class RequestDemo6 extends HttpServlet {
  83. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  84. //post 获取请求参数
  85. //根据参数名称获取参数值
  86. String username = request.getParameter("username");
  87. /*System.out.println("post");
  88. System.out.println(username);*/
  89. //根据参数获取参数值的数组
  90. String[] hobbies = request.getParameterValues("hobby");
  91. /*for (String hobby : hobbies) {
  92. System.out.println(hobby);
  93. }*/
  94. //获取所有请求的参数名称
  95. Enumeration<String> parameterNames = request.getParameterNames();
  96. /*while (parameterNames.hasMoreElements()){
  97. String name = parameterNames.nextElement();
  98. System.out.println(name);
  99. String value = request.getParameter(name);
  100. System.out.println(value);
  101. System.out.println("------------------------------------");*/
  102. //获取所有参数的map集合
  103. Map<String, String[]> parameterMap = request.getParameterMap();
  104. //遍历
  105. Set<String> keyset = parameterMap.keySet();
  106. for (String name : keyset) {
  107. //根据键获取值
  108. String[] values = parameterMap.get(name);
  109. System.out.println(name);
  110. for (String value : values) {
  111. System.out.println(value);
  112. }
  113. System.out.println("-----------------------");
  114. }
  115. }
  116. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  117. //get 获取请求参数
  118. /*//根据参数名称获取参数值
  119. String username = request.getParameter("username");
  120. System.out.println("get");
  121. System.out.println(username);*/
  122. this.doPost(request,response);
  123. }
  124. }
  1. 请求转发:一种在服务器内部的资源跳转方式
  1. 1.步骤:
  2. 1.通过request对象来获取请求转发器对象:RequestDispatcher getRequestDispatcher(String path)
  3. 2.使用RequestDispatcher对象来进行转发:forward(ServletRequest request,ServletResponse response)
  4. 2.特点:
  5. 1.浏览器地址栏路径不发生变化
  6. 2.只能转发到当前的服务器内部资源中
  7. 3.转发是一次请求

代码演示:

  1. //RequestDemo8类
  2. @WebServlet("/requestDemo8")
  3. public class RequestDemo8 extends HttpServlet {
  4. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  5. System.out.println("demo8888被访问了...");
  6. //转发到demo9资源
  7. /*RequestDispatcher requestDispatcher = request.getRequestDispatcher("/requestDemo9");
  8. requestDispatcher.forward(request,response);*/
  9. request.getRequestDispatcher("/requestDemo9").forward(request,response);
  10. }
  11. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  12. this.doPost(request,response);
  13. }
  14. }
  15. =========================================================================================
  16. //RequestDemo9类
  17. @WebServlet("/requestDemo9")
  18. public class RequestDemo9 extends HttpServlet {
  19. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  20. System.out.println("demo9999被访问了...");
  21. }
  22. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  23. this.doPost(request,response);
  24. }
  25. }
  1. 共享数据
  1. 域对象:一个有作用范围的对象,可以在范围内共享数据。
  2. request域:代表一次请求的范围,一般用于请求转发的多个资源中共享数据
  3. 方法:
  4. 1.void setAttribute(String name,Object obj):存储数据
  5. 2.Object getAttribute(String name):通过键获取值
  6. 3.void remove Attribute(String name):通过键移除键值对
  7. 1234567

代码演示:

  1. //RequestDemo8类
  2. @WebServlet("/requestDemo8")
  3. public class RequestDemo8 extends HttpServlet {
  4. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  5. System.out.println("demo8888被访问了...");
  6. //转发到demo9资源
  7. /*RequestDispatcher requestDispatcher = request.getRequestDispatcher("/requestDemo9");
  8. requestDispatcher.forward(request,response);*/
  9. //存储数据到request域中
  10. request.setAttribute("msg","hello");
  11. request.getRequestDispatcher("/requestDemo9").forward(request,response);
  12. /*request.getRequestDispatcher("http://www.itcast.cn").forward(request,response);*/
  13. }
  14. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  15. this.doPost(request,response);
  16. }
  17. }
  18. =========================================================================================
  19. //RequestDemo9类
  20. @WebServlet("/requestDemo9")
  21. public class RequestDemo9 extends HttpServlet {
  22. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  23. //获取数据
  24. Object msg = request.getAttribute("msg");
  25. System.out.println(msg);
  26. System.out.println("demo9999被访问了...");
  27. }
  28. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  29. this.doPost(request,response);
  30. }
  31. }
  1. 获取ServletContext对象(有个印象即可)
  1. 1.ServletContext getServletContext()
  2. 1

代码如下:

  1. @WebServlet("/requestDemo10")
  2. public class RequestDemo10 extends HttpServlet {
  3. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  4. ServletContext servletContext = request.getServletContext();
  5. System.out.println(servletContext);
  6. }
  7. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  8. this.doPost(request,response);
  9. }
  10. }

五、解决中文乱码问题:

  1. get方式:tomcat8以上的版本已经将get方式乱码问题解决了
  2. post方式:会乱码
  3. 解决:在获取参数前,设置request的编码 request.setCharacterEncoding("urf-8");

代码演示如下:

  1. @WebServlet("/requestDemo7")
  2. public class RequestDemo7 extends HttpServlet {
  3. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  4. //1.设置流的编码
  5. request.setCharacterEncoding("utf-8");
  6. //获取请求参数username
  7. String username = request.getParameter("username");
  8. System.out.println(username);
  9. }
  10. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  11. this.doPost(request,response);
  12. }
  13. }