HttpServletRequest请求概述

本文详细介绍了HttpServletRequest对象在处理HTTP请求中的作用,包括获取请求行、请求头、请求体信息,请求参数的处理,以及使用BeanUtils工具类封装数据。还讨论了request对象的生命周期、请求转发,并解决POST请求中文乱码问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

07_Request:获取请求行信息

HttpServletRequest

HttpServletRequest接口的对象代表客户端的请求,当客户端通过HTTP协议访问Tomcat服务器时,HTTP请求中的所有信息都封装在HttpServletRequest接口的对象中,web开发人员通过这个对象的方法,可以获得客户端信息。

通过HttpServletRequest接口的对象进行的常用操作:

  • 获取请求行信息:请求方式,url,ip地址和HTTP版本。

  • 获取请求头信息:浏览器类型,ip地址等。

  • 获取请求参数或者请求体中的数据:url后面拼接的参数或者请求体中提交的参数;

获取http请求行信息的API方法

请求行主要包括:请求方式、url、 协议/版本

HttpServletRequest接口的对象提供了以下方法来获取这些信息:

方法说明
String getMethod()获取请求方式的类型 字母是大写的
StringBuffer getRequestURL()获取客户端发出请求完整URL
String getRemoteAddr()获取IP地址
String getProtocol()获取当前协议的名称和版本

说明:对于上述方法StringBuffer getRequestURL() 的返回值是StringBuffer ,它也表示字符串缓冲区,用法和StringBuilder一样,只是StringBuffer 是多线程安全的,效率低。StringBuilder是多线程不安全的,效率高

08_Request:获取请求头信息

获取http请求头信息的API方法

浏览器的请求头信息是由很多key:value形式的数据组成的

HttpServletRequest对象给我们提供了两个方法用来获取请求的头信息

方法作用
String getHeader(String name)根据请求头的key关键字获取请求头信息
Enumeration getHeaderNames()返回此请求包含的所有头信息的key,属于对枚举类型进行遍历

说明: 枚举属于一种特殊的数据类型,类似于集合,对他遍历也是类似于集合遍历方式。Enumeration类似于Iterator的迭代器。只是Iterator来迭代1.2之后的集合。而Enumeration用来迭代1.2之前集合和枚举类型的。

【说明】请求头的key关键字如下表所示:

请求头key请求头value
referer浏览器通知服务器,当前请求来自何处,如果是直接访问,则不会有这个头。
If-modified-Since浏览器通知服务器,本地缓存的最后变更时间。与另一个响应头组合控制浏览器页面的缓存。
cookie与会话有关技术,用于存放浏览器缓存的cookie信息。
user‐agent浏览器通知服务器,客户端浏览器与操作系统相关信息
connection保持连接状态。Keep-Alive 连接中,close 已关闭
host请求的服务器主机名
content-length请求体的长度
content-type如果是POST请求,会有这个头,默认值为application/x-www-form-urlencoded,表示请求体内容使用url编码
accept浏览器可支持的MIME类型。文件类型的一种描述方式。
mime格式浏览器请求数据的类型,例如: text/html ,html文件 text/css,css文件 text/javascript,js文件 image/*,所有图片文件
accept-encoding浏览器通知服务器,浏览器支持的数据压缩格式。如:GZIP压缩
accept-language浏览器通知服务器,浏览器支持的语言。各国语言(国际化i18n)

09_Request:获取请求体信息

获取http请求体信息的API方法

学习完了对请求行和请求头的内容,最后一部分就是请求体了,在请求体中,包含的是用户通过浏览器发送的请求参数,因此,我们主要学习的就是获取请求参数的方法

首先,观察一下浏览器中的请求数据是怎么提交的:

get请求:get请求提交的数据是拼接在url后面的,如下图所示:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qUbgbvqL-1650854650098)(D:/BaiduNetdiskDownload/Java/08-JavaWeb/Day29_JavaWeb/01_讲义/imgs/1529912593623.png)]

post请求:post请求的数据是在请求体中发送到后台的

【请求体】
username: lisi
password: 1234

通过对比,发现数据传递的格式都是:name=value

获取请求参数的方法:

方法名描述
String getParameter(String name)getParameter获得指定参数名对应的值。如果没有返回null,如果值有多个获得第一个。 例如:username=jack。注意:参数name是form表单中的name属性值。
String[] getParameterValues(name)getParameterValues[] 获取请求数据key相同的多个数据.一般获取的是复选框。例如: 爱好(复选框选项)。
Map<String,String[]> request.getParameterMap();获得表单中所有的数据,key表示input标签name的属性值:,value是一个数组,表示input输入框的值

说明:

Map<String, String[]> parameterMap = request.getParameterMap()的返回值是一个Map集合,用来获取用户输入的所有值。

Map集合的key:表单的name属性值

Map集合的value:以String类型的数组形式存储表单提交的每一项的值

小结

  • 当根据参数的name获取的value值是一个时,使用:String getParameter(String name)
  • 当根据参数的name获取的value值是多个时,使用:String[] getParameterValues(String name)
  • 把所有的请求数据封装到Map集合,使用:Map getParameterMap()

10_Request:使用工具类封装请求体数据

BeanUtils工具类介绍

BeanUtils 是 Apache commons组件的成员之一,主要用于简化JavaBean封装数据的操作。它可以给JavaBean封装一个字符串数据,也可以将一个表单提交的所有数据封装到JavaBean中

注意:form表单中的name属性名javaBean的属性名要保持一致

小结

  • 在开发中,通常使用HttpServletRequest对象获取到请求数据后,会把请求数据封装到JavaBea对象中
  • 为了方便开发,借用第三方工具类:BeanUtils实现 请求数据封装到Bean
    • 步骤:
      • 1、把BeanUtils需要jar文件,导入到WEB-INF目录下的lib文件夹
        • 把jar文件添加到classpath
      • 2、获取浏览器所有的请求数据
        • Map getParameterMap()
      • 3、使用BeanUtils工具类中的API方法
        • BeanUtils.populate( javabean对象, map对象 )
          • map对象: 存放所有的请求数据
    • 细节:form表单控件的name属性的值和JavaBean类中的属性名保持致

11_Request:request的生命周期

Request对象的生命周期

request对象生命周期如下图所示:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Yc3hwPlO-1650854650099)(D:/BaiduNetdiskDownload/Java/08-JavaWeb/Day29_JavaWeb/01_讲义/imgs/request生命周期.bmp)]

【一次请求和响应的完整流程】
1、浏览器向servlet发送请求
2、tomcat收到请求后,创建Request和Response两个对象,并将请求数据封装到request对象中,然后传递给Servlet
3、Servlet接收到请求后,调用doget或者dopost方法。处理浏览器的请求信息,然后通过Response返回tomcat服务器信息
4、tomcat接收到返回的信息,返回给浏览器。
5、浏览器接收到返回消息后,tomcat销毁Request和Response两个对象,同时销毁这两个对象所获得的信息。
  • 创建:浏览器给tomcat服务器发送请求后,tomcat创建request对象封装请求数据
  • 销毁:tomcat服务器给浏览器响应信息结束后销毁request对象

特点:浏览器每次给服务器发送请求,服务器都会为这次请求创建一个新的request对象

小结

  • request对象的生命周期范围: 一次请求和一次响应之间
    • 请求时,创建request对象
    • 响应结束,销毁request对象

12_Request:request域对象

Request域对象介绍

问:什么是域对象?

在web中需要用对象来存储数据、获取数据和移除数据,就使用域对象来实现。域对象是一个容器,这种容器主要用于servlet与servlet之间的数据传输使用的 .

今天讲解的request域对象,就可以在一次请求中的多个servlet之间进行数据共享.

request域对象,一个存储数据的区域对象。是把request当成一个容器来存储数据,request域存储数据主要是用于在两个servlet之间传递数据。

request作为域对象,常用的方法如下:

方法说明
void setAttribute(String name, Object o)往request域中设置值
Object getAttribute(String name)从request域中根据name取值,这里的name和setAttribute()方法中的第一个参数name一致
void removeAttribute(String name)从request域中移除值,这里的name和setAttribute()方法中的第一个参数name一致

以上三个方法都是操作request中域对象中的数据,与请求参数无关。

getParameter()方法和getAttribute()方法的区别:

  • getParameter()方法获取的是浏览器提交的数据(是表单提交的数据);

  • getAttribute()方法获取的是request域中的数据(即获取的都是通过request.setAttribute()设置的值);

13_Request:请求转发

请求转发介绍

我们上面学习了域对象的一种request,主要是负责向request域对象中存储数据,然后以key作为键将数据取出。这种使用存储和获取数据的方式在开发中最为常见的就是请求转发。

请求转发:可以从某个servlet到某个html等静态资源,还可以去其他的servlet中。我们之前使用到的请求都是从页面发出,然后请求到Servlet。其实,在Servlet中。请求也可以从一个Servlet发起,然后请求到另一个Servlet或静态页面。这项技术叫做请求转发。

请求转发的描述可以参考如下图:

请添加图片描述

请求转发API

请求转发需要借助以下两个方法实现:

方法说明
RequestDispatcher getRequestDispatcher(String path)获取请求转发器(该方法需要使用request对象调用)。参数:path指定指向资源的路径名的 String。如果该路径名是相对的,那么它必须是相对于当前 servlet 的。
void forward(ServletRequest request, ServletResponse response)将请求转发到另一个资源(Servlet)上。参数:request表示客户端对 servlet 发出的请求的 ServletRequest 对象 response 表示 servlet 向客户端返回的响应的 ServletResponse 对象。

当要实现Servlet1转发Servlet2时:

第1步:获取请求转发器对象 RequestDispatcher

  • 知道转发的路径

第2步:使用请求转发器对象,调用方法进行请求转发 forward()

  • 需要把request对象,response对象一起交给Servlet2
    • ServletRequest
      • 子接口:HttpServletRequest
    • ServletResponse
      • 子接口:HttpServletResponse

小结

  1. 转发是Tomcat服务器内部的跳转行为(和浏览器没有关系)
  2. 从一个Servlet转发到另一个资源(静态或动态),**能够实现跳转,但是浏览器地址栏地址没有发生改变。**因为对浏览器来说本质上就只有一次请求;
  3. 请求转发的时候,共享request域中的数据;
  4. 无论转发多少次,都是只有一次请求,同时会有一次响应;
  • 三层体系
    • web
      • 技术:Servlet
      • 功能:
        • 接收浏览器发送的数据
        • 把接收的数据封装到JavaBean对象中
        • 实例化service层的对象,并调用业务层对象的方法
          • 把JavaBean作为参数传递给业务层
        • 基于业务层方法的执行结果,判断:
          • 成功:进入到success.html页面
          • 失败:进入到error.html页面
    • service
      • 定义用户登录功能
        • 接收web层传递的JavaBean对象
        • 实例化dao层对象,并把JavaBean对象传递给dao层
        • 基于dao层中的功能返回值进行业务逻辑处理
    • dao
      • 技术:mybatis
      • 功能:
        • 连接数据库
        • sql语句
        • 发送sql,接收结果
        • 返回结果给service层

17_解决中文乱码

post请求中文乱码问题

注意:如果将login.html页面中的form表单改为post提交,此时在登录页面提交汉字的时候,使用request接收数据的时候会出现中文乱码问题。form表单代码:

 <form class="form-signin" action="/loginServlet" method="post">

在开发中,存在多种不同的编码表:

  • ASCII码表:美国信息标准交换码
  • ISO-8859-1 :拉丁码表(欧洲)
    • 包含了ASCII码表
  • big5 //繁体中文
  • GB2312 //简体中文
  • GBK //简体中文
  • 国际计算机协议,提出统一的编码表:UTF-8

乱码产生原因

原因:Tomcat8只对于get请求处理了乱码问题。post请求并没有处理乱码。所以我们要手动进行处理。在进行手动处理乱码之前,我们要知道乱码是如何产生的。

请添加图片描述

乱码发生过程总结如下:

请添加图片描述

解决post请求乱码

默认情况下,tomcat服务器使用的的编码方式:iso-8859-1,而html页面是utf-8,我们可以采用先编码在解码的方式来处理。先将从页面获取的数据编码为iso-8859-1,然后在使用UTF-8进行解码。

代码如下:

@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 {
        //获取用户名和密码
        String username = request.getParameter("username");
        //方式一:
        //编码
//        String encodeUsername = URLEncoder.encode(username, "iso-8859-1");
		//解码
//        username = URLDecoder.decode(encodeUsername, "utf-8");
        //方式二:
        //编码
//        byte[] bytes = username.getBytes("iso-8859-1");
		//解码
//        username = new String(bytes, "utf-8");
        //方式二变为一行代码
        username = new String(username.getBytes("iso-8859-1"), "utf-8");
        String password = request.getParameter("password");
        System.out.println("username = " + username);
        System.out.println("password = " + password);
		//封装数据 javabean
        User2 user = new User2();
        user.setUsername(username);
        user.setPassword(password);
        //进行登陆业务操作
        UserService service = new UserService();
        boolean result = service.login(user);
        if (result){
            //登陆成功
            //转发跳转success.html
            request.getRequestDispatcher("/success.html").forward(request,response);
        }else {
            //登陆失败
           request.getRequestDispatcher("/error.html").forward(request,response);
        }
    }
}

说明:

1、URLEncoder属于java.net包下的类,专门用来对HTML表单进行编码的。该类中的静态方法:

static String encode(String s, String enc) 使用特定的编码方案将字符串转换为指定的编码格式。
	参数:
		s 要编码的字符串
		enc 使用的编码表

2、URLDecoder属于java.net包下的类,专门用来对HTML表单进行解码的。该类中的静态方法:

static String decode(String s, String enc) 使用特定的编码方案解码指定字符串。  
参数:
	s 要解码的字符串
	enc 使用的编码表

控制台输出结果:username = 柳岩

注意:上述代码是可以解决post请求,可是如果换成get请求又会出现乱码。因为Tomcat8已经对于get请求处理了乱码问题。换句话说get请求方式我们拿到的已经是正确的数据了,如果在使用iso-8859-1编码,然后使用utf-8解码,又会导致乱码。所以我们可以使用另一种方式来解决post乱码。即使用request对象中的方法:setCharacterEncoding(String chasetName)

代码:

 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");
        System.out.println("username = " + username);
        System.out.println("password = " + password);
		//封装数据 javabean
        User2 user = new User2();
        user.setUsername(username);
        user.setPassword(password);
        //进行登陆业务操作
        UserService service = new UserService();
        boolean result = service.login(user);
        if (result){
            //登陆成功
            //转发跳转success.html
            request.getRequestDispatcher("/success.html").forward(request,response);
        }else {
            //登陆失败
           request.getRequestDispatcher("/error.html").forward(request,response);
        }

控制台输出结果:username = 柳岩.

注意:

  • request.setCharacterEncoding(“utf-8”); 处理乱码一定放在获取数据的代码之前,一般我们都放在方法第一句话。先设置编码,在获取数据。
  • request.setCharacterEncoding(“utf-8”); 表示设置请求编码集,只对请求体中的数据有效。而post具有请求体,get有请求体,请求体没有数据,所以只对post有效,get无效。

小结

  • 当浏览器是GET请求时,在Tomcat中已解决了中文乱码问题

  • 当浏览器是POST请求时,Tomcat没有解决中文乱码问题

    • 使用request对象中的方法,来解决中文乱码

    • request.setCharacterEncoding("utf-8");  //仅对POST请求有效
      
    • 必须保证设置字符集的代码放在doGet()或doPost()方法中的第一行位置

d(password);
//进行登陆业务操作
UserService service = new UserService();
boolean result = service.login(user);
if (result){
//登陆成功
//转发跳转success.html
request.getRequestDispatcher(“/success.html”).forward(request,response);
}else {
//登陆失败
request.getRequestDispatcher(“/error.html”).forward(request,response);
}


控制台输出结果:username = 柳岩.

**注意:**

- request.setCharacterEncoding("utf-8"); 处理乱码一定放在获取数据的代码之前,一般我们都放在方法第一句话。先设置编码,在获取数据。
- request.setCharacterEncoding("utf-8"); 表示设置请求编码集,==只对请求体中的数据有效==。而post具有请求体,get有请求体,请求体没有数据,所以只对post有效,get无效。





**小结**

- 当浏览器是GET请求时,在Tomcat中已解决了中文乱码问题

- 当浏览器是POST请求时,Tomcat没有解决中文乱码问题

  - 使用request对象中的方法,来解决中文乱码

  - ~~~java
    request.setCharacterEncoding("utf-8");  //仅对POST请求有效
    ~~~

  - ==必须保证设置字符集的代码放在doGet()或doPost()方法中的第一行位置==







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值