1、主要内容

1.1 是什么?

  • HttpServletRequest是一个接口,Servlet规范中重要的接口之一
  • HttpServletRequest接口的实现类是Web容器负责的,Tomcat服务器有自己的实现。程序员还是只需要面向HttpServletRequest接口调用方法即可,不需要关心具体的实现类

    1.2 继承关系

  • public interface HttpServletRequest extends ServletRequest

    1.3 对象中封装了哪些信息?


  • HttpServletRequest一般对象的名字叫做:request;

  • HttpServletRequest对象代表一次请求,一次请求对应一个request对象,100个请求对应100个request对象,所以request对象的生命周期是短暂的;
  • 什么是一次请求?到目前为止,我们可以这样理解一次请求:在网页上点击超链接,到最终网页停下来,这就是一次完整的请求【如果是重定向,那这个操作就不止是一次请求了】;
  • HttpServletRequest对象封装了HTTP请求协议的全部内容:
    • 请求方式
    • URI
    • 协议版本号
    • 表单提交的数据

……

1.4 如何获取信息?

  • 获取用户信息,表单提交的这些数据被自动封装在request对象中

image.png
image.png

  • 格式:username=admin&password=123&sex=boy&interest=sport&interest=music&grade=gz&introduce=ok
  • 表单提交的数据会自动封装在request对象中,request对象中有一个Map集合,存储这些数据,Map集合的key是name,value是一个字符串类型的一维数组

Map
key value(value是数组)
—————————————————-
username {“admin”}
password {“123”}
sex {“boy”}
interest {“sport”,”music”}
grade {“gz”}
introduce {“ok”}

2、常用方法

2.1 常用方法如下

  1. /*获取浏览器提交的数据(从表单)*/
  2. String getParameter(String name) //获取key对应的一维数组的首元素(使用最多)
  3. String[] getParameterValues(String name)//返回String数组,数组包含key对应的多个value值,
  4. //适合取checkbox复选框中的数据
  5. Map<String,String[]> getParameterMap()//获取整个Map集合
  6. Enumeration<String> getParameterNames()//获取所有的Map集合中所有的key
  7. /*获取路径、URL、URI、IP*/
  8. String getContextPath() //获取上下文路径(web项目根路径)
  9. String getMethod() //获取浏览器请求方式(GET\POST...)
  10. String getRequestURI() //获取请求的URI
  11. StringBuffer getRequestURL() //获取请求的URL
  12. String getServletPath() //获取请求的ServletPath,即servlet对应的请求路径(<url-pattern>)
  13. String getRemoteAddr() //获取客户端IP地址
  14. /*从一次请求对应的HttpServletRequest对象范围中增删查数据*/
  15. void setAttribute(String name, Object o) //从此次请求对应的request对象范围中存储数据
  16. Object getAttribute(String name) //从此次请求对应的request对象范围中获取数据
  17. void removeAttribute(String name) //从此次请求对应的request对象范围中删除数据
  18. /*请求转发器*/
  19. RequestDispatcher getRequestDispatcher(String path) //获取请求转发器,让转发器对象指向某个资源
  20. /*编码*/
  21. void setCharacterEncoding(String env) 覆盖此请求正文中使用的字符编码的名称
  22. /**/
  23. HttpSession getSession() 返回与此请求关联的当前会话,或者如果该请求没有会话,则创建一个。
  24. Cookie[] getCookies() 返回一个数组,其中包含Cookie 客户端与此请求一起发送的所有对象。

2.2 HttpServletRequest是个怎样的范围?

  • HttpServletRequest类型的变量通常命名为:request,代表当前的本次请求
  • 一次请求对应一个request对象,100个请求对应100个请求对象,请求范围是极小的!
  • request只能完成在同一次请求中传递数据,也就是说,在第一次请求中存储的数据是无法在第二次请求中获取的!
  • 要解决这个不同请求对应的不同request对象之间无法共享数据的问题,需要使用请求转发技术!

**

3、请求转发

3.1 forward【转发】

  1. 获取请求转发器对象
  2. 调用请求转发器的forward()方法即可完成转发 ```java /* /a路径对应AServlet,/b路径对应BServlet,

    通过request对象的getRequestDispatcher方法获取请求转发器对象, 然后调用请求转发器对象的forward方法进行转发

    以下代码是从AServlet转发到BServlet */

//获取请求转发器,以下转发器指向了BServlet RequestDispatcher requestDispatcher = request.getRequestDispatcher(“/b”); //调用请求转发器的forward() requestDispatcher.forward(request,response);

//也可以合并 request.getRequestDispatcher(“/b”).forward(request,response);

  1. <a name="HEnDr"></a>
  2. #### 3.2 实例
  3. ```java
  4. /*AServlet*/
  5. public class AServlet extends HttpServlet {
  6. @Override
  7. protected void doGet(HttpServletRequest request, HttpServletResponse response)
  8. throws ServletException, IOException {
  9. User user = new User(111, "admin");
  10. request.setAttribute("user",user); //向request范围中存数据
  11. //转发
  12. request.getRequestDispatcher("/b").forward(request,response);
  13. }
  14. }
  15. /*BServlet*/
  16. public class BServlet extends HttpServlet {
  17. @Override
  18. protected void doGet(HttpServletRequest request, HttpServletResponse response)
  19. throws ServletException, IOException {
  20. response.setContentType("text/html;charset=UTF-8");
  21. PrintWriter writer = response.getWriter();
  22. Object user = request.getAttribute("user"); //从request范围中取数据
  23. writer.print(user);
  24. }
  25. /*
  26. 1. 浏览器向AServlet发出访问请求;
  27. 2. AServlet调用forward()方法,在服务器端将请求转发给BServlet;
  28. 3. 最终由BServlet做出响应
  29. */
  30. }

请求转发.png

4、关于范围对象的选择

  • ServletContext应用范围,可以跨用户传递数据
  • ServletRequest请求范围,只能在同一个请求中传递数据【可以跨servlet传递数据,但是这几个servlet必须在同一个请求当中】
  • 优先选择request范围
  • 请求转发可以跨Servlet(跨请求)传递数据,一次请求对应的Servlet中的request对象的数据,可以传递给请求转发的另一个Servlet的request对象
  • 请求转发,是一次请求

5、程序中乱码解决方案

5.1 乱码经常出现在什么位置?

  • 数据保存过程中的乱码
  • 数据展示过程中的乱码
  • 数据传递过程中的乱码

5.2 数据保存过程中的乱码

  • 数据保存到数据库表中的时候,数据出现乱码
  • 导致数据保存过程中的乱码包括以下两种情况:

    • 前一种情况:在保存之前,数据本身就是乱码,保存到数据库表中的时候一定是乱码
    • 第二种情况:保存之前,数据不是乱码,但是由于数据库本身数据库不支持简体中文,保存之后出现乱码

      5.3 数据展示过程中的乱码

  • 最终显示到网页上的数据出现中文乱码

  • 怎么解决?
    • 经过执行Java程序之后,Java程序负责向浏览器响应的时候,中文乱码
      • Java程序中设置响应的内容类型,以及对应的字符字符集response.setContentType(“text/html;charset=UTF-8”);
    • 没有经过Java程序,直接访问的是静态页面
      • 文件编码时字符集,与浏览器解析时使用的字符集要一致,例如文件编码时使用的字符集是UTF-8,那么可以在网页文件中使用<meta content=”**text/html;**charset=UTF-8”>标签来指定网页编码时使用的字符集

5.4 数据传递过程中的乱码【以Tomcat 7为例】


  • 将数据从浏览器发送给服务器的时候,服务器接收到的数据时乱码
  • 万能解决方案:

乱码_3.png

//获取乱码字符
String name = request.getParameter("name");
//将乱码字符通过错误的ISO-8859-1编码方式重新还原回去
byte[] bytes = name.getBytes("ISO-8859-1");
//再通过正确的编码方式进行解码
name = new String(bytes, "UTF-8");
  • 只适用于POST请求

乱码_4.png

//设置字符编码方式
request.setCharacterEncoding("UTF-8");
//获取正确的字符
String name = request.getParameter("name");
  • 只适用于GET请求

乱码_5.png