zl程序教程

您现在的位置是:首页 >  其他

当前栏目

HttpServletRequest接口详解

接口 详解 HttpServletRequest
2023-06-13 09:11:54 时间
一般情况下,浏览器(客户端)通过 HTTP 协议来访问服务器的资源,Servlet 主要用来处理 HTTP 请求。

Servlet 处理 HTTP 请求的流程如下:

Servlet 处理HTTP请求


Servlet 容器接收到来自客户端的 HTTP 请求后,容器会针对该请求分别创建一个 HttpServletRequest 对象和 HttpServletReponse 对象。 容器将 HttpServletRequest 对象和 HttpServletReponse 对象以参数的形式传入 service() 方法内,并调用该方法。 在 service() 方法中 Servlet 通过 HttpServletRequest 对象获取客户端信息以及请求的相关信息。 对 HTTP 请求进行处理。 请求处理完成后,将响应信息封装到 HttpServletReponse 对象中。 Servlet 容器将响应信息返回给客户端。 当 Servlet 容器将响应信息返回给客户端后,HttpServletRequest 对象和 HttpServletReponse 对象被销毁。

通过以上流程可以看出, HttpServletRequest 和 HttpServletReponse 是 Servlet 处理 HTTP 请求流程中最重要的两个对象。HttpServletRequest 对象用于封装 HTTP 请求信息,HttpServletReponse 对象用于封装 HTTP 响应信息。

下面我们将对 HttpServletRequest 进行详细介绍。

HttpServletRequest 接口

在 Servlet API 中,定义了一个 HttpServletRequest 接口,它继承自 ServletRequest 接口。HttpServletRequest 对象专门用于封装 HTTP 请求消息,简称 request 对象。

HTTP 请求消息分为请求行、请求消息头和请求消息体三部分,所以 HttpServletRequest 接口中定义了获取请求行、请求头和请求消息体的相关方法。

获取请求行信息

HTTP 请求的请求行中包含请求方法、请求资源名、请求路径等信息,HttpServletRequest 接口定义了一系列获取请求行信息的方法,如下表。


该方法用于获取请求行中的资源名称部分,即位于 URL 的主机和端口之后,参数部分之前的部分。
返回当前 Servlet 所在的应用的名字(上下文)。对于默认(ROOT)上下文中的 Servlet,此方法返回空字符串 。
该方法用于获取客户端的完整主机名,如果无法解析出客户机的完整主机名,则该方法将会返回客户端的 IP 地址。

为了更好地理解这些方法,下面通过案例演示这些方法的使用。

创建一个名称为 httpServletRequestDemo 的项目,在 net.biancheng.www 包中创建一个名为 RequestLine 的 Servlet 类,代码如下。


package net.biancheng.www;

import java.io.IOException;

import java.io.PrintWriter;

import javax.servlet.ServletException;

import javax.servlet.annotation.WebServlet;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;


public class RequestLine extends HttpServlet { private static final long serialVersionUID = 1L; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType( text/html;charset=UTF-8 PrintWriter writer = response.getWriter(); writer.println( 请求方式: + request.getMethod() + br/ + 客户端的 IP 地址: + request.getRemoteAddr() + br/ + 应用名字(上下文): + request.getContextPath() + br/ + URI: + request.getRequestURI() + br/ + 请求字符串: + request.getQueryString() + br/ + Servlet所映射的路径: + request.getServletPath() + br/ + 客户端的完整主机名: + request.getRemoteHost() + br/ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response);

启动 Tomcat 服务器,在地址栏中输入 http://localhost:8080/httpServletRequestDemo/RequestLine?a=1 b=2 ,访问 RequestLine,结果如下图。

requestLine 获取请求头信息

当浏览器发送请求时,需要通过请求头向服务器传递一些附加信息,例如客户端可以接收的数据类型、压缩方式、语言等。为了获取请求头中的信息, HttpServletRequest 接口定义了一系列用于获取 HTTP 请求头字段的方法,如下表所示。


该方法用于获取一个指定头字段的值。
如果请求消息中包含多个指定名称的头字段,则该方法返回其中第一个头字段的值。
该方法返回指定头字段的所有值的枚举集合,
在多数情况下,一个头字段名在请求消息中只出现一次,但有时可能会出现多次。

为了更好地理解这些方法,下面通过案例演示这些方法的使用。

在 net.biancheng.www 包中创建一个名为 RequestHeader 的 Servlet 类,代码如下。


package net.biancheng.www;

import java.io.IOException;

import java.io.PrintWriter;

import java.util.Enumeration;

import javax.servlet.ServletException;

import javax.servlet.annotation.WebServlet;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

@WebServlet( /RequestHeader )

public class RequestHeader extends HttpServlet {

 private static final long serialVersionUID = 1L;

 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

 response.setContentType( text/html;charset=UTF-8 

 PrintWriter writer = response.getWriter();

 //获得所有请求头字段的枚举集合

 Enumeration String headers = request.getHeaderNames();

 while (headers.hasMoreElements()) {

 //获得请求头字段的值

 String value = request.getHeader(headers.nextElement());

 writer.write(headers.nextElement() + : + value + br/ 

 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

 doGet(request, response);

}

启动 Tomcat 服务器,在地址栏中输入 http://localhost:8080/httpServletRequestDemo/RequestHeader ,访问 RequestHeader ,结果如下图。

requestHeader 获取 form 表单的数据

在实际开发中,我们经常需要获取用户提交的表单数据,例如用户名和密码等。为了方便获取表单中的请求参数,ServletRequest 定义了一系列获取请求参数的方法,如下表所示。


以字符串数组的形式返回指定参数名的所有参数值(HTTP 请求中可以有多个相同参数名的参数)。

为了更好地理解这些方法,下面通过案例演示这些方法的使用。

在 httpServletRequestDemo 的 WebContent 目录下,创建 form.html,代码如下。


 !DOCTYPE html 

 html 

 head 

 meta charset= UTF-8 

 title Insert title here /title 

 /head 

 body 

 form action= /httpServletRequestDemo/RequestParam method= post 

 table border= 1 width= 50% 

 td colspan= 2 align= center 编程帮wwww.biancheng.net /td 

 /tr 

 td 输入姓名 /td 

 td input type= text name= username / /td 

 /tr 

 td 输入密码 /td 

 td input type= password name= password / /td 

 /tr 

 td 选择性别 /td 

 td input type= radio name= sex value= male / 男 input

 type= radio name= sex value= female / 女 /td 

 /tr 

 td 选择使用的语言 /td 

 td input type= checkbox name= language value= JAVA / JAVA

 input type= checkbox name= language value= C / C语言 input

 type= checkbox name= language value= PHP / PHP input

 type= checkbox name= language value= Python / Python /td 

 /tr 

 td 选择城市 /td 

 td select name= city 

 option value= none --请选择-- /option 

 option value= beijing 北京 /option 

 option value= shanghai 上海 /option 

 option value= guangzhou 广州 /option 

 /select /td 

 /tr 

 td colspan= 2 input type= submit value= 提交 / /td 

 /tr 

 /table 

 /form 

 /body 

 /html 

在 net.biancheng.www 包中,创建一个名为 RequestParam 的 Servlet 类,代码如下。


package net.biancheng.www;

import java.io.IOException;

import java.io.PrintWriter;

import java.util.Arrays;

import java.util.Map;

import java.util.Set;

import javax.servlet.ServletException;

import javax.servlet.annotation.WebServlet;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

@WebServlet( /RequestParam )

public class RequestParam extends HttpServlet {

 private static final long serialVersionUID = 1L;

 protected void doGet(HttpServletRequest request, HttpServletResponse response)

 throws ServletException, IOException {

 response.setContentType( text/html;charset=UTF-8 

 PrintWriter writer = response.getWriter();

 // 获取内容,做其他操作

 // 获取姓名

 String username = request.getParameter( username 

 // 获取密码

 String password = request.getParameter( password 

 // 获取性别

 String sex = request.getParameter( sex 

 // 获取城市

 String city = request.getParameter( city 

 // 获取语言

 String[] languages = request.getParameterValues( language 

 writer.write( 用户名: + username + br/ + 密码: + password + br/ + 性别: + sex + br/ + 城市: + city

 + br/ + 使用过的语言: + Arrays.toString(languages) + br/ 

 protected void doPost(HttpServletRequest request, HttpServletResponse response)

 throws ServletException, IOException {

 doGet(request, response);

}

启动 Tomcat 服务器,在地址栏中输入 http://localhost:8080/httpServletRequestDemo/form.html ,即可访问 form.html,结果如下图。

form 图

在表单中填写信息后,点击提交,结果如下图。

表单参数 中文乱码问题

如果在 form 表单输入框中输入中文,例如在输入姓名时,填写 编程帮默认用户 ,点击提交后就会出现乱码问题,如下图所示。

HttpServletRequest接口详解

 

根据请求方式的不同,请求一般可以被分为两种:GET 请求和 POST 请求。这两种请求方式都可能会产生中文乱码问题,下面我们分别对它们产生乱码的原因及其解决方案进行介绍。

POST 请求

乱码的原因:POST 提交的数据在请求体中,其所使用的编码格式时页面一致(即 utf-8)。request 对象接收到数据之后,会将数据放到 request 缓冲区,缓冲区的默认字符集是 ISO-8859-1(该字符集不支持中文),两者使用的字符集不一致导致乱码。

解决方案:在获取请求参数之前设置 request 缓冲区字符集为 utf-8 ,代码如下。


//修改request缓冲区的字符集为UTF-8

request.setCharacterEncoding( utf-8 

// 获取用户名

String username = request.getParameter( username 

GET 请求

乱码的原因:Get 请求将请求数据附加到 URL 后面作为参数,浏览器发送文字时采用的编码格式与页面编码保持一致(utf-8)。如果 Tomcat 没有设置字符集,接收 URL 时默认使用 ISO-8859-1 进行解码,ISO-8859-1 不兼容中文,无法正确解码,导致出现乱码。

需要注意的是,在 Tomcat 8 中已解决了 get 方式提交请求中文乱码的问题,使用 Tomcat 8 及以上版本的同学不必再考虑此问题了,如果您使用的是 Tomcat 7 或更早的版本,出现乱码问题可以使用如下的方案解决。

解决方案:解决 GET 请求中文乱码问题,有以下 3 种解决方案。

1. 修改 tomcat/conf/server.xml 中的配置,代码如下。


 Connector port= 80 protocol= HTTP/1.1 

 connectionTimeout= 20000 

 redirectPort= 8443 URIEncoding= UTF-8 / 

2. 使用 URLEncoder 和 URLDecoder 进行编码和解码的操作(逆向编解码)。 


//得到TOMCAT通过ISO8859-1解码的字符串

String username = request.getParameter( username 

//对字符串使用ISO8859-1进行编码,得到最初浏览器使用UTF-8编码的字符串

username = URLEncoder.encode(username, ISO8859-1 

//将使用UTF-8编码的字符串使用UTF-8进行解码,得到正确的字符串

username = URLDecoder.decode(username, UTF-8 

3. 使用 String 的构造方法:String(byte[] bytes, String charset) ,对字节数组(bytes)按照指定的字符集(charset)进行解码,返回解码后的字符串,解决乱码问题(推荐使用)。


 //获取姓名

String username = request.getParameter( username 

//使用String的构造方法解决乱码的问题

username = new String(username.getBytes( ISO-8859-1 ), UTF-8 

21018.html

javaServlet