第 2 章 Servlet 编程

news2025/1/19 20:20:19

文章目录

  • 第 2 章 Servlet 编程
    • 2.1 Servlet 简介
    • 2.2 Servlet 基础
      • 2.2.1 用记事本写一个 Servlet
      • 2.2.2 Servlet 体系结构
      • 2.2.3 Servlet 接口
      • 2.2.4 Servlet 生命周期
      • 2.2.5 Servlet 生命周期示例
    • 2.3 Servlet API编程常用接口和类
      • 2.3.1 GenericServlet 类
      • 2.3.2 HttpServlet类
      • 2.3.3 ServletConfig 接口
      • 2.3.4 HttpServletRequest 接口
      • 2.3.5 HttpServletResponse接口
      • 2.3.6 ServletContext 接口

第 2 章 Servlet 编程

      Java Servlet是运行在Web服务器或应用服务器上的程序,它是来自Web浏览器或其他HTTP客户端的请求和HTTP服务器上的数据库或应用程序之间的中间层。使用Servlet,可以收集来自网页表单的用户输入,呈现来自数据库或者其他源的记录,还可以动态创建网页。本章主要内容有: (1) Servlet简介; (2) Servlet 基础;(3) Servlet API编程常用接口和类;(4) Servlet处理表单数据: (5) Servlet重定向和请求转发; ( 6) Servlet数据库访问; ( 7) Servlet异常处理;(8)异步Servlet。

2.1 Servlet 简介

      Servlet在Web服务器的地址空间内执行。这样,其没有必要再创建一个单独的进程来处理每个客户端请求。在传统的CGI中,每个请求都要启动一个新的进程,如果CGI程序本身的执行时间较短,则启动进程所需要的开销很可能反而超过了实际执行时间。而在Servlet中,每个请求由一个轻量级的Java线程(而不是重量级的操作系统进程)处理。
     在传统CGI中,如果有N个并发的对同一CGI程序的请求,则该CGI程序的代码在内存中重复装载了N次;而对于Servlet,处理请求的是N个线程,只需要一份Servlet类代码。在性能优化方面,Servlet 也比CGI有着更多的选择。
      Servlet是独立于平台的,因为它们是用Java编写的。
     Java类库的全部功能对Servlet来说都是可用的。
    Servlet对请求的处理和响应过程可分为以下几个步骤。
      (1)客户端发送请求至服务器端。
      (2)服务器将请求信息发送至Servlet。
      (3) Servlet 生成响应内容并将其传给服务器。响应内容动态生成,通常取决于客户端的请求。

      (4)服务器将响应返回给客户端。

  1. Servlet 的存在就是要为客户端服务
    Servlet的任务是得到一个客户端的请求,再发回一个响应。请求可能很简单一“ 请给我一个欢迎页面。”,也可能很复杂一“ 为我的购物车结账。”这个请求携带着一些重要的数据,Servlet 代码必须知道怎么找到和使用这个请求。响应也携带着些一信息,浏览器需要这些信息来显示一个页面,Servlet 代码必须知道怎么发送这些信息。

  2. Servlet 3.0
    Servlet 3.0作为JavaEE 6规范体系中的一员,随着Java EE6规范起一发布。该版本在前版本(Servlet2.5)的基础上提供了若干新特性,以用于简化Web应用的开发和部署。

(1)异步处理支持:有了该特性,Servlet 线程不再需要一直阻塞, 直到业务处理完毕才能再输出响应,最后才能结束该Servlet线程。在接收到请求之后,Servlet 线程可以将耗时的操作委派给另一个线程来完成,自已在不生成响应的情况下返回至容器。针对业务处理较耗时的情况,这将大大减少服务器资源的占用,并且提高并发处理速度。
(2)新增的注解支持:该版本新增了若干注解,用于简化Servlet、过滤器(Filter) 和监听器(Listener) 的声明,这使得Web.xml部署描述文件从该版本开始不再是必选的了。

  1. Servlet 与Tomcat版本支持
    以目前主流的Web服务器Tomcat (包含Servlet容器)为例,Tomcat对Servlet版本的支持关系如表2-1所示。

表2-1 Servlet与Tomcat版本支持

Servlet 版本号Tomcat 版本号Servlet版本号Tomcat版本号
Servlet2.4Tomcat5.xServlet3.0Tomcat7.x
Servlet2.4Tomcat6.xServlet3.1Tomcat8.x

2.2 Servlet 基础

2.2.1 用记事本写一个 Servlet

  1. 编写HelloServlet.java
    使用记事本编写HelloServlet.java 文件,代码如下:
import javax.servlet.ServletException;
import java.io.*;
import javax.servlet.http.*;

public class HelloServlet extends HttpServlet
{
	//重写了父类HttpServlet中的doGet()方法,用于对GET请求方法做出响应
    public void doGet(HttpServletRequest req, HttpServletResponse resp)
               throws ServletException,IOException
    {
         PrintWriter out = resp.getWriter();  //得到PrintWriter对象
         out.println("Hello Servlet");  //向客户端发送字符数据
         out.close(); 
    }
}
  1. 编译HelloSerlet.java
    把Tomcat自带的servlet-api.jar的路径加到classpath中,或者在命令行窗口中运行命令:
set classpath=%classpath%;D:\software\apache-tomcat-8.0.45\lib\servlet-api.jar

      (这里,本书Tomcat的安装路径是E:\tormcat8。)

      进入HelloServlet.java 所在目录,运行命令: javac HelloServlet.java 。 编译后得到HelloServlet.class字节码文件。

  1. 部署Servlet
    在E:\tomcat8\webapps目录下,创建-一个文件夹hello,在hello目录下创建WEB-INF文件夹和Web.xml文件。Web.xml 代码如下(其中 部分表示注释):
<?xml version="1.0" encoding="UTF-8"?>                  <!--XML声明-->
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xmlns="http://xmlns.jcp.org/xml/ns/javaee" 
	xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee 
	http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" 
	id="WebApp_ID" version="3.1">      <!--声明XML Schema的名称空间-->	
	<servlet>
        <servlet-name>helloworld</servlet-name>          <!--Servlet名称-->
        <servlet-class>HelloServlet</servlet-class>    <!--Servlet完全限定名-->
    </servlet>
	<servlet-mapping>
        <servlet-name>helloworld</servlet-name>           <!--Servlet名称-->
        <url-pattern>/myhello</url-pattern>         <!--Servlet的URL路径-->
    </servlet-mapping>    
</web-app>

      在Web-INF目录下创建classes 文件夹,把前面编译得到的HelloServlet.class 复制至E:\tomcat8\webapps\hello\Web-INF\classes目录下。
在这里,hello 文件夹已成为一个Web应用,只不过是手工创建的。

  1. 访问HelloServlet
    启动Tomcat服务器,在浏览器中输入: http://localhost:8080/hello/myhello (注意,这里通过调用中的值来找寻相应的Servlet。)
    网页输出:
Hello Servlet

2.2.2 Servlet 体系结构

      Servlet3.1 API有以下4个Java包。
      ①javax.servlet: 其中包含定义Servlet和Servlet容器之间契约的类和接口。
      ②javax.servlet.http: 其中包含定义HTTP Servlet和Servlet容器之间契约的类和接口。
      ③javax.servlet.annotation:其中包含标注Servlet、 Filter、 Listener 的标注。它还为被标注元件定义元数据。
      ④javax.servlet.descriptor:其中包含提供程序化登录Web应用程序的配置信息的类型。Servlet技术的核心是Servlet,它是所有Servlet类必须直接或间接实现的一个接口。Servlet接口定义了Servlet 与Servlet 容器之间的契约,Servlet 容器将Servlet 类载入内存,并在Servlet实例上调用具体的方法。用户请求致使Servlet容器调用Servlet的Service方法,并传入一个ServletRequest 实例和一个ServletResponse 实例。ServletRequest 中封装了当前的HTTP请求。ServletResponse则表示当前用户的HTTP响应,使得将响应发回给用户变得十分容易。

2.2.3 Servlet 接口

      在Tomcat的有关Servlet API的文档中有关于Servlet接口的介绍。可以通过运行Tomcat服务器,在htp://localhost:8080/docs/servletapi/index.html页面看到。

          javax.servlet.Servlet的定义如下:

	public interface Servlet

       该接口中定义了一下 5 种方法。

        ①(init): 在Servlet实例化后,Servlet 容器会调用该方法,初始化该对象。init0方法有一个类型为ServletConfig的参数, Servlet容器通过这个参数向Servlet传递配置信息。Servlet使用ServletConfig 对象从Web应用程序的配置信息中获取以名-值对形式提供的初始化参数。
      ②service(): 容器调用service0方 法来处理客户端的请求。
      ③destroy0: Servlet 的销毁方法。容器在终止Servlet服务前调用此方法。
       ④getServletConfig0: 该方法返回容器调用init(方 法时传递给Servlet 对象的ServletConfig对象,ServletConfig 对象包含了Servlet 的初始化参数。
      ⑤getServletInf(): 返回一个String类型的字符串,其中包括了关于Servlet的信息。例如,作者、描述信息等。

2.2.4 Servlet 生命周期

      Servlet生命周期可被定义为从创建直到毁灭的整个过程。以下是Servlet遵循的过程。
      (1) Servlet 通过调用init ()方法进行初始化。
      (2) Servlet 调用service()方法来处理客户端的请求。
      (3) Servlet通过调用destroy()方法终止(结束)。
      (4) Servlet 是由JVM的垃圾回收器进行垃圾回收的。

      1. init() 方法
      init()方法被设计成只调用一一次。它在第一次创建 Servlet 时被调用,在后续每次用户请求时不再调用。Servlet创建于用户第一次调用对应于该Servlet的URL时,但也可以指定Servlet在服务器第一次启动时被加载。
      当用户调用一个Servlet时,就会创建一个Servlet实例,每一个用户请求都会产生一个新的线程,适当的时候移交给doGet()或doPost()方法。init0方法简 单地创建或加载- -些数据,这些数据将被用于Servlet的整个生命周期。

       init 方法如下:

public void init(ServletConfig config) throws ServletExeption {
    // 初始化代码...
}

      2. service() 方法
      service()方法是执行实际任务的主要方法。Servlet 容器调用service0方法来处理来自客户端(浏览器)的请求,并把格式化的响应写回客户端。每次服务器接收到一个Servlet请求时,服务器会产生一个新的线程并调用服务。servic()方法检查HTTP请求类型(GET、POST、PUT、DELETE等),根据请求类型不同分别调用doGet、doPost、 doPut、 doDelete 等方法。

public void service (ServletRequest request, ServletResponse response)
    throws ServletException, IOException {
}

       service()方法由容器调用,只需要根据来自客户端的请求类型来重写doGet()或doPost()方法即可。doGet())和 doPost()方法是每次服务请求中最常用的方法。

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

public void doGet (HttpServletRequestrequest, HttpServletResponse response)
    throws ServletException, IOException {
    // Servlet代码
}

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

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

      5. destroy() 方法
      destroy()方法只会被调用一-次,在Servlet 生命周期结束时被调用。destroy()方法可以让Servlet关闭数据库连接、停止后台线程、把Cookie列表或单击计数器写入磁盘中,并执行其他类似的清理活动。在调用destroy()方法之后,servlet 对象被标记为垃圾回收。destroy()方法定义如下所示:

public void destroy () {
    //清理代码...
}

2.2.5 Servlet 生命周期示例

       Servlet实质,上就是Java类,我们将使用Eclipse来开发Servlet,以进行Servlet 的学习。

       1. 创建Dynamic Web Project

      在Eclipse中选择“File-→New→Projet…“选项,在弹出的“New Project” 对话框中选择Web中的"Dynamic Web Project",如图2-1所示。在弹出的“New Dynamic Web Project"对话框中,设定工程名为“ServletDemo",如图2-2所示(此处所使用的Eclipse版本详见本书资源tools文件夹下 eclpse-jee-oxygen-R-win32.zip,将其解压缩后双击eclipse.exe即)。

在这里插入图片描述

在这里插入图片描述

       在如图2-3所示的ServletDemo工程目录结构中,右击src 文件夹,创建Package 名为““ com.mialab.servlet demo”再在com.mialab.servlet demo包中创建Servlet。

在这里插入图片描述

       2. 开发Servlet
       我们在com.mialab.servlet_demo包中创建LifeServlet。右击com.mialab.servlet _demo包,选择“New- +Servlet"选项,弹出“Create Servlet"对话框,在此对话框中输入Servlet的名称"LifeServlet",如图2-4 所示。单击“Next”按钮后,选中“init"、 “destroy”等method,如图2-5所示。

在这里插入图片描述

在这里插入图片描述

      如果servlet-api.jar未加入ClassPath (或者Java Build Path),便会出现如图2-6所示的错误。我们只需把鼠标指针移入代码错误处,如把鼠标指针移入“HttpServlet” 中,稍停片刻,便会弹出一个错误信息提示框,如图2-7所示,单击“Fix project setup…"超链接。

在这里插入图片描述

在这里插入图片描述

       在弹出的"Project Setup Fixes” 对话框中,把E:tomcat8\lib 中的servlet-apijar 加入ServletDemo工程的Build Path,如图2-8所示。

在这里插入图片描述

LifsServlet.java 主要代码如下:

package com.mialab.servlet_demo;

import java.io.IOException;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class LifeServlet
 */
@WebServlet(asyncSupported = true, urlPatterns = { "/LifeServlet" })
public class LifeServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public LifeServlet() {
        super();
        // TODO Auto-generated constructor stub
		System.out.println(this.getClass().getName() + "的构造方法被调用");
    }

	/**
	 * @see Servlet#init(ServletConfig)
	 */
	public void init(ServletConfig config) throws ServletException {
		// TODO Auto-generated method stub
		System.out.println(this.getClass().getName() + "的init()方法被调用");
	}

	/**
	 * @see Servlet#destroy()
	 */
	public void destroy() {
		// TODO Auto-generated method stub
		System.out.println(this.getClass().getName() + "的destroy()方法被调用");
	}

	/**
	 * @see HttpServlet#service(HttpServletRequest request, HttpServletResponse response)
	 */
	//protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
	//}

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		response.getWriter().append("Served at: ").append(request.getContextPath());
		System.out.println(this.getClass().getName() + "的doGet()方法被调用");
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}
}

      3. 部署并测试
       在Eclipse中部署并运行LifeServlet.启动Eclipse中配置好的Tomcat,访问LifeServlet的URL为http://localhost:8080/ServletDemo/LifeServlet。

在这里插入图片描述

      (可参见第1章: Eclipse 自动部署项目到 Tomcat 的 webapps 目录。也可以右击 LifeServlet.java ,在弹出的快捷菜单中选择“Run As→Run on Server”选项。)

     Eclipse中的控制台将输出:

com.mialab.servlet_demo.LifeServlet的构造方法被调用
com.mialab.servlet_demo.LifeServletinit()方法被调用
com.mialab.servlet_demo.LifeServletdoGet()方法被调用

      打开命令行窗口,在E:\tomcat8\bin路径下输入shutdown命令,关闭Tomcat服务器,如图2-9所示。
Eclipse中的控制台将输出:

在这里插入图片描述

2.3 Servlet API编程常用接口和类

2.3.1 GenericServlet 类

       GenericServlet 类的部分源码如下:

package javax.servlet;
...
public abstract class GenericServlet implements Servlet, ServletConfig,
		java.io.Serializable {
    ...
    //用 transient 关键字标记的成员变量不参与序列化过程
    private transient ServletConfig config;

    @Override
    public ServletConfig getServletConfig() {
        return config;
    }
    @Override
    public ServletContext getServletContext() {
        return getServletConfig().getServletContext();
    }
    @Override
    public String getInitParameter (String name) {
        return getServletConfig().getInitParameter(name) ;
    }
    @Override
    public void init (ServletConfig config) throws ServletException {
        this.config = config;
        this.init();
    }
    public void init() throws ServletException {
        // NOOP by default
    }
    ...
}

       GenericServlet类是一个抽象类, 实现了Servlet 和ServletConfig接口,其作用如下。

      (1)将init方法中的ServletConfig 赋给一个类中成员(ServletConfig config),以便可以通过调用get ServletConfig来获取。(关于transient关键字的说明: Java 的serialization提供了一种持久化对象实例的机制。当持久化对象时,可能有一个特殊的对象数据成员,我们不想用serialization机制来保存它。为了在一个特定对象的域上关闭serialization,可以在这个域前加上关键字transient。当一个对象被序列化的时候,transient 型变量的值不包括在序列化的表示中,然而,非transient型的变量是被包括进去的。)

       (2)为Servlet接口中的所有方法提供默认的实现。

       (3)可以通过覆盖没有参数的init 方法来编写初始化代码,ServletConfig 则仍然由GenericServlet实例保存。

       (4)开发者可以在不用获得ServletConfig 对象的情况下直接调用ServletConfig 的方法,如上述代码中的getServletContext()方法。

【示例】使用 GenericServlet 类

      关于使用GenericServlet类的示例,可参见MyGenericServlet.java的代码(源码包资源第2章ServletDemo工程中的src/com.mialab.servlet_demo包),访问MyGenericServlet的URL是 http://ocalhost:8080/ServletDemo/generic。

在这里插入图片描述

2.3.2 HttpServlet类

      HttpServlet类扩展了GenericServlet 类,其部分代码如下:

package javax .servlet.http;
...
    public abstract class HttpServlet extends GenericServlet {
        ...
        private static final String METHOD DELETE = "DELETE";
        private static final String METHOD HEAD = "HEAD"; 
        private static final String METHOD GET= "GET";
        private static final String METHOD OPTIONS = "OPTIONS";
        private static final String METHOD POST = "POST";
        private static final String METHOD PUT = "PUT";
        private static final String METHOD TRACE = "TRACE";

        protected void doGet (HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException{
            ...
        }
        protected void doPost (HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
            ...
        }
        //添加新的Service方法
        protected void service (HttpServletRequestreq, HttpServletResponseresp)
            throws ServletException, IOException {
            String method = req.getMethod();
            if (method.equals(METHOD_GET)) {
                ...
                    doGet (req, resp);
            } else if (method.equals(METHOD_HEAD)) {
                ...
                    doHead (req, resp);
            } else if (method.equals(METHOD_POST)) {
                doPost (req, resp);
            }else {...
                  }
        }
        //覆盖的Service方法
        @Override
        public void service (ServletRequest req, ServletResponse res)
            throws ServletException, IOException {
            HttpServletRequest request;
            HttpServletResponse response;
            try {
                request F (HttpServletRequest) req;
                response = (HttpServletResponse) res;
            } catch (ClassCastException e) {
                throw new ServletException ("non-HTTP request or response") ;
            }
            service request, response);
        }

    }

      HttpServlet覆盖了GenericServlet 中的Service 方法,并添加了一个新Service 方法。
       新Service方法接收的参数是HttpServletRequest 和HttpServletResponse,而不是Servlet-Request和ServletResponse。
      原始的Service 方法将Servlet 容器的request 和response 对象分别转换成HttpServlet-Request和HtpServletResponse,并调用新的Service方法。
       HttpServlet中的Service 方法会检验用来发送请求的HTTP方法(通过调用request.getMethod来实现)并调用以下方法之一 : doGet、 doPost、doHead、doPut、doTrace、doOptions和doDelete。在这7种方法中,doGet 和doPost是最常用的。所以,不再需要覆盖Service方法了,只须覆盖doGet或者doPost即可。

2.3.3 ServletConfig 接口

       Tomcat初始化一个Servlet 时,会将该Servlet的配置信息封装到一个ServletConfig 对象中,通过调用init(ServletConfig config)方法将ServletConfig对象传递给Servlet。

      ServletConfig接口的常用方法如表2-2所示。

​ 表 2-2 ServletConfig 接口的常用方法

方法说明功能描述
ServletContext getServletContext()获取ServletContext对象
String getServletName()返回当前Servlet的名称
String getInitParameter(String name)根据初始化参数名称返回对应的初始化参数值
Enumeration getInitParameterNames()返回一个Enumeration对象,其中包含了所有的初始化参数名

【示例】 ServletConfig 接口的使用。

ServletConfigDemoServlet.java主要代码如下:

package com.mialab.servlet_demo;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletConfig;
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 ServletConfigDemoServlet extends HttpServlet { 
	private ServletConfig servletConfig;
	
	@Override
    public void init(ServletConfig config) throws ServletException {
    	this.servletConfig = config;
    	System.out.println("-----------" + servletConfig + "-----------");
	}
    
    @Override
    public ServletConfig getServletConfig() {
        return servletConfig;
    }
    
    @Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// 使用ServletConfig对象获取初始化参数
		ServletConfig servletConfig = getServletConfig();
		System.out.println("-----------" + servletConfig + "-----------");
		String poet = servletConfig.getInitParameter("poet");
		String poem = servletConfig.getInitParameter("poem");
		// 设置响应到客户端的文本类型为HTML
		response.setContentType("text/html;charset=UTF-8");
		// 获取输出流
		PrintWriter out = response.getWriter();
		out.print("<p>获取ServletConfigDenoServlet的初始化参数:");
		out.println("</p><p>poet参数的值:" + poet);
		out.println("</p><p>poem参数的值:" + poem + "</p>");		
		out.append("Served at:").append(request.getContextPath());
	}

}

       Web.xml中关于ServletConfigDemoServlet 的配置如下:

<servlet>
    <servlet-name>myServletConfig</servlet-name>
    <servlet-class>com.mialab.servlet_demo.ServletConfigDemoServlet</servlet-class>
    <init-param>
        <param-name>poet</param-name>
        <param-value>纳兰容若</param-value>
    </init-param>
    <init-param>
        <param-name>poem</param-name>
        <param-value>我是人间惆怅客</param-value>
    </init-param>
</servlet>
<servlet-mapping>
    <servlet-name>myServletConfig</servlet-name>
    <url-pattern>/myServletConfig</url-pattern>
</servlet-mapping>

        访问 ServletConfigDemoServlet 的 URL:

http://localhost:8080/ServletDemo/myServletConfig

       输出结果:

获取ServletConfigDemoServlet的初始化参数:
poet参数的值:纳兰容若
poem参数的值:我是人间惆怅客
Served at: /ServletDemo

最后报错不知道为什么,看到的大佬帮解答下 (_)/

2.3.4 HttpServletRequest 接口

       HttpServletRequest接口继承自ServletRequest接口,专门用来封装HTTP请求消息。由于HTTP请求消息分为请求行、请求消息头和请求消息体3部分,故而在HttpServletRequest接口中定义了获取请求行、请求消息头和请求消息体的相关方法,以及存取请求域属性的方法。
       1. 获取请求行信息
        HTTP_请求报文的请求行由请求方法、请求URL和请求协议及版本组成。HttpServletRequest接口对请求行各部分信息的获取方法如表2-3所示。

                                                                      表 2 - 3 获取请求的相关方法

方法说明功能描述
String getMethod()用于获取 HTTP 请求消息中的请求方式(如GET、POST等)
String getRequestURI()用于获取请求行中资源名称部分,即位于URL的主机和端口之后、参数部分之前的部分
String getQueryString()用于获取请求行中的参数部分,也就是资源路径后面(? )以后的所有内容。其只对GET有效
String getProtocol()获取请求行中的协议名和版本
String getContextPath()获取请求URL中属于Web应用程序的路径。这个路径以“/"开头,表示整个Web站点的根目录,路径结尾不含 “/”
String getServletPath()获取Servlet所映射的路径
String getRemoteAddr()用于获取请求客户端的IP地址
String getRemoteHost()用于获取请求客户端的完整主机名
String getScheme()用于获取请求的协议名,如 HTTP 等
StringBuffer getRequestURL()获取客户端发出请求时的完整URL,包括协议、服务器名、端口号、资源路径等信息,但不包括后面的查询参数部分

      【示例】使用HttpServletRequest接口获取请求行信息。

       关于使用 HttpServletRequest 接口获取请求行信息的示例,可参见RequestLineServet.java的代码(源码包见本书资源第2章 ServletDemo 工程中的 src/com.mialab.servlet_demo 包),访问 RequestLineServletURL 是http://localhost:8080/ServletDemo/RequestLineServlet

       2. 获取请求消息头

       当请求Servlet时,需要通过请求头向服务器传递附加信息。HTTP常见的请求头如表2-4 所示。

                                                                       表2-4 HTTP 常见的请求头

请求头名称说明
Host初始 URL 中的主机和端口
Connection表示是否需要持久连接
Accpet浏览器可以接收的 MIME 连接
Accpet-Charset浏览器发给服务器,声明浏览器支持的编码类型
Content-LengthContent-Length用于描述HTTP消息实体的传输长度。在HTTP协议中,消息实体长度和消息实体的传输长度是有区别的,例如,在GZIP压缩下,消息实体长度是压缩前的长度,消息实体的传输长度是GZIP压缩后的长度
Cache-Control指定请求和响应遵循的缓存机制
User-AgentUser Agent的中文名为用户代理,简称UA,它是一一个特殊字符串头,使得服务器能够识别客户使用的操作系统及版本、CPU类型、浏览器类型及版本、浏览器渲染引擎、浏览器语言、浏览器插件等
Cache-Type表示请求内容的MIME类型
Cookie表示客户端的 Cookie 信息,即告诉服务器,上次访问时,服务器写了哪些 cookie 到客户端

HttpServletRequest接口中定义的用于获取HTTP请求头字段的方法,如表2-5所示。

​ 表 2- 5 获取请求消息头的方法

请求头名称说明
String getHeader(String name)用于获取一个指定头字段的值
Enumeration getHeaderNames()用于获取一个包含所有请求头字段的 Enumeration 对象
Enumeration getHeaders(String name)返回一个Enumeration 集合对象,该集合对象由请求消息中出现的某个指定名称的所有头字段值组成
int getIntHeader(String name)用于获取指定名称的头字段,并将其值转换为int 类型
Cookie[] getCookies()返回一个数组包含客户端请求的所有 Cookie 对象,如果没有发送任何信息,则这个方法返回 null
String getContentType()用于获取 Content-Type 头字段的值
int getContentLength()用于获取 Content-Length 头字段的值
String getCharacterEncoding()用于返回请求消息的实体部分的字符集编码,通常是从 Content-Type 头字段中提取

       【示例】使用HttpServletRequest接口获取请求头信息。

       使用HttpServletRequest接口获取请求头信息的示例,可参见RequestHeadInfoServlet.java的代码(源码第2章ServletDemo 工程src.com.mialab.servlet demo 包),访问 RequestLineServlet 的 URL 是 http://locahost:8080/ServletDemo/RequestHeadInfoServlet。

       3. 获取请求参数

       在实际开发中,经常需要获取用户提交的表单数据。为了方便获取表单中的请求参数,在HttpServletRequest接口的父类ServletRequest 接口中定义了一系列获取请求参数的方法,如表2-6所示。

                                                          表 2 - 6 获取请求参数的方法

方法说明功能描述
String getParameter(String name)用于获取某个指定名称的参数值
Enumeration getParameterNames()返回一个包含请求消息中所有参数名的Enumeration对象
String[] getParameterValues(String name)根返回由name指定的用户请求参数对应的一组值
Map getParameterMap()用于将请求消息中的所有参数名和值装进一个 Map对象中返回

      【示例】使用HttpServletRequest接口获取请求参数。
       关于使用 HttpServletRequest 接口获取请求参数的示例,可参见 RequestParaServlet.java 和person_ info.html( 源码包见第2章的ServletDemo工程),先访问person_info.html,填写个人信息,再提交给RequestParaServlet处理。

2.3.5 HttpServletResponse接口

       HttpServletResponse接口继承自ServletResponse 接口,专门用来封装HTTP响应消息。由于HTTP响应消息分为状态行、响应消息头、消息体三部分,于是在HttpServletResponse接口中也相应定义了向客户端发送响应状态码、响应消息头、响应消息体的方法。

       1. 响应状态码

       HTTP协议响应报文的响应行,由报文协议和版本,以及状态码和状态描述构成。

       当Servlet向客户端回送响应消息时,需要在响应消息中设置状态码。常见的响应状态码如下: 200表示请求成功; 500 表示服务器内部错误; 404 表示请求的资源(网页等)不存在;302表示资源(网页等)暂时转移到其他URL等。

       HttpServletResponse按口提供的设置状态码开生成啊应状态行的万法有以下儿种。
       (1) setStatus(int status)方法: setStatus(int status)方法用于设置HTTP响应消息的状态码,并生成响应状态行。正常情况下,Web服务器会默认产生一个状态码为200的状态行。
       (2) sendError(int sc)方法和sendError(int sc, String msg)方法:第1个方法只是发送错误信息的状态码;而第2个方法除了发送状态码外,还可以增加一条用于提示说明的文本信息,该文本信息将出现在发送给客户端的正文内容中。
      要说明的是,在实际开发中,一般不需要人为地修改设置状态码,容器会根据程序的运行状况自动响应发送响应的状态码。

       2. 响应消息头

       HttpServletResponse接口中定义了-一些设置HTTP响应头字段的方法,如表2-8所示。

表 2 - 8 设置响应头字段的方法

方法功能描述
void setContentType(String type)设置Servlet输出内容的MIME类型
void setContentI ength(int len)设置响应消息的实体内容的大小,单位为字节
void setHeader(String name, String value)设置HTTP协议的响应头字段。name指定响应头字段的名称, value 指定响应头字段的值
void setCharacterEncoding(String charset)设置HTTP协议的响应头字段。name 指定响应头字段的名称, value 指定响应头字段的值
void addCookie(Cookie cookie)为Set-Cookie消息头增加-一个值,Set-Cookie 消息头表示应该记录下来的Cookie,即把Cookie发送给客户端
void setLocale(Locale loc)用于设置响应消息的本地化信息。对HTTP来说,就是设置Content-Language响应头字段和Content-Type头字段中的字符集编码部分

       【示例】响应消息头

关于响应消息头示例,可参见ResponseHeadServlet.java的代码(源码见第2章ServletDemo工程的src/com.mialab.servlet _demo包),访问ResponseHeadServlet的URL是http://ocahost:.8080/ServletDemo/ResponseHeadServlet

       3. 响应消息体

       HttpServletResponse接口提供了两个获取不同类型输出流对象的方法,如表2-9所示。

                                     表 2-9 HttpServletResponse 接口获取不同类型输出对象的方法

方法功能描述
ServletOutputStream getOutputStream()返回字节输出流对象 ServletOutputStream
PrintWriter getWriter()返回字符输出流对象

       【示例】响应消息体。

       响应消息体示例,可参见ResponsePicServlet.java的代码(第2章ServletDemo 工程的src/com.mialab.servlet_demo包),访问 ResponsePicServlet 的 URL 是 http://localhost:8080/ServletDemo/ResponsePicServlet

没跑出来

2.3.6 ServletContext 接口

       Servlet 容器在启动一个 Web 应用时,会为该应用创建一个唯一的 ServletContext 对象供该应用中的所有Servlet 对象共享。Servlet 对象可以通过 ServletContext 对象来访问容器中的各种资源。获得 ServletContext 对象可以使用以下两种方式。

       ① 通过 ServletConfig 接口的 getServletContext() 方法获得 ServletContext 对象。
      ② 通过GenericServlet 抽象类的 getServletContext() 方法获得 ServletContext 对象,实质上该方法也调用了ServletConfig 的 getServletContext() 方法。

      该方法也调用了 ServletConfig 的 getServletContext() 方法。

       1. 获取 Web 应用的初始化参数

       ServletContext 接口中定义了获取 Web 应用范围的初始化参数的方法。

       (1)方法声明: public String getInitParameter(String name)

       作用:放回 Web 应用范围指定的初始化值。在 Web.xml 中使用 元素表示应用范围内的初始化参数。

       (2)方法声明: public Enumeration getInitParaNames(String name)。

作用:返回 Web 应用范围内指定的初始化参数值。在 Web.xml 中使用 元素表示应用范围内的初始化参数。

       作用:返回一个包含所有初始化参数名称的 Enumeration 对象。

【示例】使用 ServletConext 接口获取 Web 应用的初始化参数。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/574367.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

使用object.defineProperty来更新数据示例

Object.defineProperty() 方法会直接在一个对象上定义一个新属性&#xff0c;或者修改一个对象的现有属性&#xff0c;并返回此对象。 Object.defineProperty&#xff08;&#xff09;可以为对象的属性添加特性&#xff0c;每一个被添加过的属性&#xff0c;都会拥有属于自己的…

公司来了个00后,真是卷死了呀,辞职信已经写好了·····

人们都说00后躺平了&#xff0c;但是有一说一&#xff0c;该卷的还是卷。这不&#xff0c;三月份春招我们公司来了个00后&#xff0c;工作没两年&#xff0c;跳槽到我们公司起薪20K&#xff0c;都快接近我了。 后来才知道人家是个卷王&#xff0c;从早干到晚就差搬张床到工位睡…

chatgpt赋能python:Python单行命令:while

Python单行命令&#xff1a;while 介绍 在Python中&#xff0c;while循环是一种重复执行代码块的结构&#xff0c;只要满足循环条件&#xff0c;就会一直循环下去。而单行命令则是指一行代码就完成了某个任务。在Python语言中&#xff0c;我们可以使用单行命令在 while循环中…

springcloud高频面试题

springcloud的组件有哪些 注册中心&#xff1a;euraka、nacos、zookeeper 注册中心及配置中心&#xff1a;nacos 远程调用&#xff1a;feign、dubbo 负载均衡&#xff1a;ribbon 服务熔断&#xff1a;hystrix、sentinel 网关&#xff1a;zuul、gateway eureka注册中心的作用 …

JAVA面试八股整理——基础部分

JAVA 基础 JVM JDK JRE JVM java虚拟机&#xff0c;针对不同的系统&#xff0c;使用相同的字节码会给出相同结果。一次编译&#xff0c;随处可运行 JDK Java SDK 提供给开发者使用&#xff0c;创建和编译Java程序。包含了JRE&#xff0c;同时包含了其它工具&#xff08;jav…

Deepin 23的最佳新功能和亮点

Deepin是一个基于Linux的操作系统&#xff0c;以其美观、简洁和易用的用户界面而闻名。Deepin 23是Deepin操作系统的最新版本&#xff0c;引入了许多令人兴奋的新功能和亮点&#xff0c;为用户提供了更好的体验和更多的功能。 本文将详细介绍Deepin 23的最佳新功能和亮点。 1…

教你彻底卸载MySQL 并重装(保姆级教程 )

前言&#xff1a;都是自己踩过的坑&#xff08;其他博主也有&#xff0c;不过我的特殊&#xff0c;按步骤走完重新安装仍要输入原密码&#xff0c;本篇主要解决和我问题类似的情况&#xff09;&#xff0c;跟着以下步骤走就行。 步骤一&#xff1a;关闭MySQL服务 右击【计算机】…

@Transactional @Aysnc 循环依赖 事务同步问题

文章目录 学习链接场景最初版本TestControllerTestService问题 Lazy版本 事务同步报错版本&#xff1a;TestServiceLazy正常启动版本&#xff08;有问题&#xff09;Lazy 注册事务同步 学习链接 Async学习及循环依赖 场景 我们要做的事情很简单&#xff1a; 现在我们需要…

高校智能用电管理系统的应用探讨

摘 要&#xff1a;随着现代科学技术的发展&#xff0c;在高校中开始广泛应用智能化技术&#xff0c;改善学生宿舍的用电管理模式&#xff0c;提高宿舍的管理水平&#xff0c;有利于实现高校宿舍用电管理的科学化。本文主要阐述传统高校宿舍用电管理模式&#xff0c;设计高校智能…

tektronix泰克TDS3054B数字荧光示波器

TDS3054B示波器体积小巧、便于携带、可用电池供电&#xff0c;所以可在任何需要的地方使用。安装电池 后&#xff0c;其重量还不到5 公斤。即便是在现场工作&#xff0c;也可通过选购的插入式热敏打印机当场打印测量 结果。 用户还可通过选购的应用模块轻而易举地使TDS3000B 系…

Web3小白科普系列:加密社区行业黑话全解(第一弹)

加密货币的快速发展创造了属于自己的全新语言&#xff0c;其中充满了黑话和首字母缩写&#xff0c;可能会让新手不知所措。本期《Web3小白科普系列&#xff1a;加密社区行业黑话全解》旨在解释加密世界中经常使用的、旁人难以解读的术语。我们将深入探究流行俚语的起源和含义&a…

专转本大忌,老实说这样备考真的考不上

&#xff08;1&#xff09;目标院校定太高&#xff0c;报考全凭主观臆断&#xff0c;没有深入了解学校专业和今年的考情&#xff0c;结果自身实力不够导致错失升本的机会。 &#xff08;2&#xff09;盲目追求学习时间却不追求效率&#xff0c;经常熬夜通宵学习&#xff0c;结…

开发工具---Eclipse 教程Ⅰ

Eclipse 是一个开放源代码的、基于 Java 的可扩展开发平台。 Eclipse 是 Java 的集成开发环境&#xff08;IDE&#xff09;&#xff0c;当然 Eclipse 也可以作为其他开发语言的集成开发环境&#xff0c;如C&#xff0c;C&#xff0c;PHP&#xff0c;和 Ruby 等。 Eclipse 附带…

JavaScript面向对象编程

在这里插入代码片## 1. 构造函数和new命令 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" con…

PLX31-EIP-MBS 以太网/IP到Modbus串行

PLX31-EIP-MBS ProSoft Technology的EtherNet/IP to Modbus串行通信网关允许在EtherNet/IP PACs或设备与支持Modbus的PACs或设备之间进行高速双向数据传输。 EtherNet/IP PACs包括Rockwell Automation ControlLogix和CompactLogix&#xff0c;以及几款施耐德电气控制器。Mod…

NameServer总结

NameServer是一个注册中心&#xff0c;提供服务注册和服务发现的功能。NameServer可以集群部署&#xff0c;集群中每个节点都是对等的关系&#xff08;没有像ZooKeeper那样在集群中选举出一个Master节点&#xff09;&#xff0c;节点之间互不通信。服务注册 Broker启动的时候会…

Eclipse教程Ⅲ

Eclipse 菜单 Eclipse 查看的菜单栏通常包含以下几个菜单&#xff1a; File 菜单Edit 菜单Navigate 菜单Search 菜单Project 菜单Run 菜单Window 菜单Help 菜单 通过 Eclipse 插件你可以添加新的菜单和菜单项。 菜单描述 菜单名描述FileFile 菜单运行你打开文件&#xff0c;…

同余方程 乘法逆元 扩展欧几里得算法 5.26

同余方程 乘法逆元 扩展欧几里得算法 526 同余方程 乘法逆元 扩展欧几里得算法_哔哩哔哩_bilibili 给定整数a,b,m&#xff0c;求解同余方程axb(mod m). 如果x存在整数解&#xff0c;则输出任意一个&#xff1b; 如果不存在&#xff0c;则输出none 例&#xff1a; 8x4(mod…

动态线程池 dynamic-tp 源码

目录 1. 介绍 2. Spring 环境整合配置源码 2.1 DtpBeanDefinitionRegistrar 2.2 DtpPostProcessorRegistrar 2.3 ApplicationContextHolder 2.4 DtpBaseBeanConfiguration 2. 动态线程池 DtpLifecycle 生命周期源码 3. 动态线程池 DtpRegistry 注册源码 4. 动态线程池…

基于51单片机的两路数字电压表Protues仿真设计

目录 一、设计背景 1.1、数字电压表的发展历程 1.2、课题的意义和目的 二、实现功能 三、仿真演示 四、部分程序展示 一、设计背景 1.1、数字电压表的发展历程 数字电压表简称DVM&#xff0c;它是采用数字化测量技术设计的电压表。从性能来看&#xff1a;数字电压表的发展从…