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() 方法。

相关推荐
字节全栈_rJF1 天前
性能测试 —— Tomcat监控与调优:status页监控_tomcat 自带监控
java·tomcat
XYu123012 天前
Spring Boot 热部署实现指南
java·ide·spring boot·intellij-idea
刘大浪2 天前
如何获取Springboot项目运行路径 (idea 启动以及打包为jar均可) 针对无服务器容器新建上传文件路径(适用于win 与 linunix)
spring boot·intellij-idea·jar
UVCuttt3 天前
三天急速通关JavaWeb基础知识:Day 1 后端基础知识
java·servlet·java-ee·tomcat
码农幻想梦3 天前
蓝桥云课下载(jdk11、eclipse、idea)
android·eclipse·intellij-idea
红虾程序员4 天前
HTML一般标签和自闭合标签介绍
前端·pycharm·html·intellij-idea·html5
Future_yzx4 天前
selenium自动化测试框架——面试题整理
java·selenium·intellij-idea
电脑玩家粉色男孩5 天前
IDEA创建&修改gitee仓库
java·gitee·intellij-idea
码农研究僧5 天前
IDEA 中 Maven 依赖变灰并带斜线的解决方法及原理分析
java·maven·intellij-idea·pom依赖包
阳光阿盖尔5 天前
【javaweb项目idea版】蛋糕商城(可复用成其他商城项目)
java·servlet·intellij-idea·javaweb·商城·蛋糕商城·购物商城