JavaWeb开发(四)HttpServletRequest

1. HttpServletRequest

1.1. HttpServletRequest简介

在Servlet Api中,定义了一个HttpServletRequest接口,它继承自ServletRequest,专门用于封装Http的请求。由于Http请求包含请求行、请求头和请求体三部分,因此在HttpServletRequest中分别定义了接受请求头、请求行和请求体的相关方法。

1.2. 请求行

1.2.1. 获取请求行相关信息的相关方法

(1)getMethod():返回请求方法,请求方法可能是GET或者POST,也有可能是HEAD、PUT或者DELETE。

(2)getRequestURI():返回URI(URI是URL从主机和端口之后到表单数据之前的那一部分)。如http://localhost:8080/my/test1?name=备份大V\&passWord=2342的URI为"/my/test1"。

(3)getRemoteAddr():用于获取客户端的IP地址。如:0:0:0:0:0:0:0:1

(4)getLocalAddr():用于获取服务器当前接受请求的IP地址。如:0:0:0:0:0:0:0:1

(5)getRemotePort():用于获取客户端的端口号。如:8080

(6)getContextPath():用于获取RUL中的属于web应用程序的路径。

(7)getProtocol():用于获取请行中的协议名和版本。如:HTTP/1.1

javascript 复制代码
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("MyServlet收到GET请求");
        System.out.println("请求方式:" + request.getMethod());
        System.out.println("URI:" + request.getRequestURI());
        System.out.println("发出请求客户端IP地址:" + request.getRemoteAddr());
        System.out.println("服务点接收请求的IP地址:" + request.getLocalAddr());
        System.out.println("访问客户端的端口号:" + request.getRemotePort());
        System.out.println("web应用路径:" + request.getContextPath());
        System.out.println("http协议和版本:" + request.getProtocol());
    }

1.3. 请求头

获取请求头的相关方法

(1)getHeader (String name):用于获取一个指定头字段的值,如果请求头不包含此字段则返回null,如果包含多个该字段的值则返回第一个值。

(2)getIntHeader ():用于获取指定头字段的值,并且将其转化为int类型,如果不存在该字段则返回-1,如果获取的值不能转化成int类型则会发生NumberFormatException异常。

(3)getDataHeaderNames():用于获取指定头字段的值,并且将按照GMT时间格式转化成一个代表日期/时间的长整数。

(4)getHeaderNames():用于获取所有包含请求头字段的Enumerating。

javascript 复制代码
        //获取请求头
        //accept:text/html, application/xhtml+xml, image/jxr, */*
        //accept-language:zh-Hans-CN,zh-Hans;q=0.5
        //user-agent:Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko
        //accept-encoding:gzip, deflate
        //host:localhost:8080
        //connection:Keep-Alive
        //cookie:JSESSIONID=73B0F51907B51DCCEc8b-855f-ad93239cf1f0
        Enumeration<String> headerNames = request.getHeaderNames();
        while (headerNames.hasMoreElements()) {
            String element = headerNames.nextElement();
            System.out.println(element + ":" + request.getHeader(element));
        }

1.4. 请求体

获取请求参数:

(1)getParameter(String name):用于获取某个指定名称的参数值,如果请求中没有包含指定名称的参数值,则返回空串"",如果包含多个该参数的值则返回第一个出现的参数值。

(2)getParameterNames():用于返回一个包含请求消息中的所有参数名的Enumerating。

(3) getParameterMap():用于将请求中的所有参数和值装入一个map对象然后返回。

1.5. 发送响应行

sendError(int sc, String msg):使用指定的状态码发送一个错误响应至客户端。服务器默认会创建一个HTML格式的服务错误页面作为响应结果,其中包含参数msg指定的文本信息,这个HTML页面的内容类型为"text/html",保留cookies和其他未修改的响应头信息。如果一个对应于传入的错误码的错误页面已经在web.xml中声明,那么这个声明的错误页面将会优先于建议的msg参数服务于客户端。(ps:相比较上面的方法,我更倾向于前者。使用上面的方法,可以通过定制不同状态的响应结果显示于客户端,我们应该不想让客户端看到服务器创建出的简单粗暴的页面吧?)

setStatus(int sc):设置响应的状态码。这个方法被用于当响应结果正常时(例如,状态码为SC_OK或SC_MOVED_TEMPORARTLY)设置响应状态码。如果发生错误,而且来访者希望调用在web应用中定义的错误页面作为显示,那么应该使用sendError方法代替之。使用setStatus方法之后,容器会清空缓冲并设置Location响应头,保留cookies和其他响应头信息。

1.6. Servlet 生命周期

Servlet 生命周期可被定义为从创建直到毁灭的整个过程。以下是 Servlet 遵循的过程:

• Servlet 初始化后调用 init () 方法。

• Servlet 调用 service() 方法来处理客户端的请求。

• Servlet 销毁前调用 destroy() 方法。

• 最后,Servlet 是由 JVM 的垃圾回收器进行垃圾回收的。

现在让我们详细讨论生命周期的方法。

1.6.1. init() 方法

init 方法被设计成只调用一次。它在第一次创建 Servlet 时被调用,在后续每次用户请求时不再调用。因此,它是用于一次性初始化,就像 Applet 的 init 方法一样。

Servlet 创建于用户第一次调用对应于该 Servlet 的 URL 时,但是您也可以指定 Servlet 在服务器第一次启动时被加载。

当用户调用一个 Servlet 时,就会创建一个 Servlet 实例,每一个用户请求都会产生一个新的线程,适当的时候移交给 doGet 或 doPost 方法。init() 方法简单地创建或加载一些数据,这些数据将被用于 Servlet 的整个生命周期。

init 方法的定义如下:

javascript 复制代码
public void init() throws ServletException {
  // 初始化代码...
}

1.6.2. service() 方法

service() 方法是执行实际任务的主要方法。Servlet 容器(即 Web 服务器)调用 service() 方法来处理来自客户端(浏览器)的请求,并把格式化的响应写回给客户端。

每次服务器接收到一个 Servlet 请求时,服务器会产生一个新的线程并调用服务。service() 方法检查 HTTP 请求类型(GET、POST、PUT、DELETE 等),并在适当的时候调用 doGet、doPost、doPut,doDelete 等方法。

下面是该方法的特征:

javascript 复制代码
public void service(ServletRequest request, 
                    ServletResponse response) 
      throws ServletException, IOException{
}

service() 方法由容器调用,service 方法在适当的时候调用 doGet、doPost、doPut、doDelete 等方法。所以,您不用对 service() 方法做任何动作,您只需要根据来自客户端的请求类型来重写 doGet() 或 doPost() 即可。

doGet() 和 doPost() 方法是每次服务请求中最常用的方法。下面是这两种方法的特征。

1.6.3. doGet() 方法

GET 请求来自于一个 URL 的正常请求,或者来自于一个未指定 METHOD 的 HTML 表单,它由 doGet() 方法处理。

javascript 复制代码
public void doGet(HttpServletRequest request,
                  HttpServletResponse response)
    throws ServletException, IOException {
    // Servlet 代码
}

1.6.4. doPost() 方法

POST 请求来自于一个特别指定了 METHOD 为 POST 的 HTML 表单,它由 doPost() 方法处理。

javascript 复制代码
public void doPost(HttpServletRequest request,
                   HttpServletResponse response)
    throws ServletException, IOException {
    // Servlet 代码

1.6.5. destroy() 方法

destroy() 方法只会被调用一次,在 Servlet 生命周期结束时被调用。destroy() 方法可以让您的 Servlet 关闭数据库连接、停止后台线程、把 Cookie 列表或点击计数器写入到磁盘,并执行其他类似的清理活动。

在调用 destroy() 方法之后,servlet 对象被标记为垃圾回收。destroy 方法定义如下所示:

javascript 复制代码
  public void destroy() {
    // 终止化代码...
  }

1.6.6. 架构图

下图显示了一个典型的 Servlet 生命周期方案。

• 第一个到达服务器的 HTTP 请求被委派到 Servlet 容器。

• Servlet 容器在调用 service() 方法之前加载 Servlet。

• 然后 Servlet 容器处理由多个线程产生的多个请求,每个线程执行一个单一的 Servlet 实例的 service() 方法。

相关推荐
tazj2 小时前
IDEA中Lombok不能使用,找不到get方法
java·ide·intellij-idea
lishiming03089 小时前
TestEngine with ID ‘junit-jupiter‘ failed to discover tests 解决方法
java·junit·intellij-idea
Cikiss13 小时前
Tomcat解析
java·服务器·后端·servlet·tomcat
Future72819 小时前
idea启动不了
java·ide·intellij-idea
发奋图强_lee19 小时前
idea 的 springboot项目spring-boot-devtools 自动编译 配置热部署
java·spring boot·intellij-idea
晚安~~2 天前
旅游管理系统|Java|SSM|VUE| 前后端分离
java·开发语言·tomcat·maven
码上就位2 天前
如何在IDEA一个窗口中导入多个项目
java·ide·intellij-idea
全栈老实人_2 天前
记忆旅游系统|Java|SSM|VUE| 前后端分离
java·开发语言·tomcat·maven
我命由我123452 天前
23.Java 时间日期扩展(新时间日期、新时间日期格式化与解析、时间戳、计算时间日期差、时间矫正器、时区)
java·开发语言·后端·java-ee·intellij-idea·intellij idea·后端开发