• Servlet


    1 Servlet

    1.1 概念

    • Servlet 是 JavaEE 规范之一。 规范就是接口
    • Servlet 是 JavaWeb 三大组件之一。 三大组件分别是: Servlet 程序、 Filter 过滤器、 Listener 监
      听器。
    • Servlet服务于HTTP协议的服务端的一个小程序,“接收请求,解析请求,根据请求执行业务逻辑,
      做出响应”

    1.2 实现功能

    • 处理表单提交:Servlet 可以接收来自客户端的表单数据,并进行验证、处理和存储。
    • 认证与授权:Servlet 可以实现用户认证和权限控制,限制某些资源只允许特定的用户或用户组访问。
    • 数据库操作:Servlet 可以连接数据库,并执行查询、插入、更新等数据库操作。
    • 文件上传和下载:Servlet 可以接收客户端上传的文件,并将文件保存到服务器,或者提供文件下载功能。

    1.3 Servlet 的生命周期

    • 执行 Servlet 构造器方法
    • 执行 init 初始化方法
      • 第一、 二步, 是在第一次访问, 的时候创建 Servlet 程序会调用。
    • 执行 service 方法
      • 第三步, 每次访问都会调用。
    • 执行 destroy 销毁方法
      • 第四步, 在 web 工程停止的时候调用。
    public HelloServlet() {
    	System.out.println("构造函数");
    }
    @Override
    public void init() throws ServletException {
    	System.out.println("初始化");
    }
    @Override
    public void destroy() {
    	System.out.println("销毁方法");
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    解决中文乱码问题

    -Dfile.encoding=UTF-8 -Dconsole.encoding=UTF-8
    
    • 1

    1.4 入门案例

    1.4.1 基于注解的配置

    引入依赖

    创建HttpServlet

    //@WebServlet("/hello")
    public class HelloServlet extends HttpServlet {
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
           BufferedReader reader = new BufferedReader(new InputStreamReader(req.getInputStream()));
           String line = null;
           while ((line = reader.readLine()) != null){
               System.out.printf("POST方法 =" + line);
           }
            reader.close();
        }
    
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            System.out.println(this.getInitParameter("helloconfig1"));
            System.out.println(this.getInitParameter("helloconfig2"));
    
    
            System.out.println("QueryString = " + req.getQueryString());
            resp.getWriter().print(req.getQueryString());
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    表单访问

    <h4>geth4>
    <form action="http://localhost:8080/servlet-demo/hello" method="get">
    	<input type="text" name="username" value="mickey"><br>
    	<input type="text" name="password" value="123456"><br>
    	<input type="submit" value="提交">
    form>
    <h4>posth4>
    <form action="http://localhost:8080/servlet-demo/hello" method="post">
    	<input type="text" name="username" value="mickey"><br>
    	<input type="text" name="password" value="123456"><br>
    	<input type="submit" value="提交">
    form>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    1.4.2 基于XML配置

    web.xml

    <servlet>
    	<servlet-name>helloservlet-name>
    	<servlet-class>com.lxs.demo.servlet.HelloServletservlet-class>
    servlet>
    <servlet-mapping>
    	<servlet-name>helloservlet-name>
    	<url-pattern>/hellourl-pattern>
    servlet-mapping>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    执行地址到Servlet的关系

    1.5 GET 和 POST 请求的分发处理

    1.5.1 GET 请求

    • 用途:GET 请求用于从服务器获取资源,通常用于获取数据。
    • 参数传递:GET 请求将参数以查询字符串的形式附加在 URL 的末尾,例如http://example.com/pathparam1=value1¶m2=value2。
    • 数据长度限制:由于参数在 URL 中可见,GET 请求对数据长度有限制,因为 URL 的长度受到浏览器或服务器的限制。
    • 安全性:GET 请求的参数和数据会暴露在 URL 中,不适合传输敏感数据,因为它们可以被缓存、浏览器历史记录等捕捉到。

    1.5.2 POST 请求

    • 用途:POST 请求用于向服务器发送数据,通常用于提交表单、上传文件等操作。
    • 参数传递:POST 请求将参数作为请求的主体发送,而不是附加在 URL 上。参数可以通过表单数据、JSON 或其他格式进行编码。
    • 数据长度限制:POST 请求对数据长度没有明确的限制,最大限制取决于服务器的配置。
    • 安全性:POST 请求对参数和数据的传输提供了更高的安全性,因为它们不会暴露在 URL 中,而是作为请求的主体进行传输。

    1.5.3 案例

    String method = req.getMethod();
    long lastModified;
    if (method.equals("GET")) {
    	lastModified = this.getLastModified(req);
    	if (lastModified == -1L) {
    		this.doGet(req, resp);
    	} else {
    		long ifModifiedSince;
    		try {
    			ifModifiedSince = req.getDateHeader("If-ModifiedSince");
    		} catch (IllegalArgumentException var9) {
    			ifModifiedSince = -1L;
    		}
    		if (ifModifiedSince < lastModified / 1000L * 1000L) {
    			this.maybeSetLastModified(resp, lastModified);
    			this.doGet(req, resp);
    		} else {
    			resp.setStatus(304);
    		}
    	}
    } else if (method.equals("HEAD")) {
    	lastModified = this.getLastModified(req);
    	this.maybeSetLastModified(resp, lastModified);
    	this.doHead(req, resp);
    } else if (method.equals("POST")) {
    	this.doPost(req, resp);
    } else if (method.equals("PUT")) {
    	this.doPut(req, resp);
    } else if (method.equals("DELETE")) {
    	this.doDelete(req, resp);
    } else if (method.equals("OPTIONS")) {
    	this.doOptions(req, resp);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    1.6 Servelt类继承体系

    1.7 配置详解

    1.7.1 注解与注释

    • 注解(Annotation)是一种提供给程序读取的信息,它可以用于在 Java 代码中添加元数据。它可以应用于类、方法、变量、参数等各种程序元素上。通过使用注解,开发人员可以为程序元素添加附加信息,如说明、配置、运行时行为等。Java 中内置了多种注解,也可以自定义注解来满足特定的需求。注解通常由编译器和框架处理,以自动化地完成日常编码任务。
    • 注释(Comment)是一种提供给程序员看的信息,它用于在代码中添加解释、说明、调试信息等,以让其他开发人员更好地理解代码意图。注释可以用于单行或多行,常见的注释类型有单行注释(//)和多行注释(/* */)。注释不参与程序编译和执行,只是一种辅助性的文本信息。

    1.7.2 注解的格式

    • @开头的 如:@Override
    • @WebServlet注解配置Servlet
      • 从Servlet3.0开始,配置Servlet支持注解方式,但还是保留了配置web.xml方式
        • (1)Servlet类上使用@WebServlet注解进行配置
        • (2)web.xml文件中配置

    1.7.3 @WebServlet常用属性

    属性类型是否必须说明
    asyncSupportedboolean指定Servlet是否支持异步操作模式
    displayNameString指定Servlet显示名称
    initParamswebInitParam[]配置初始化参数
    loadOnStartupint标记容器是否在应用启动时就加载这个Servlet,等价于配置文件中的标签
    nameString指定Servlet名称
    urlPatterns/valueString[]这两个属性作用相同,指定Servlet处理的url
    <servlet>
    	<servlet-name>aservlet-name>
    	<servlet-class>
    		
    		com.yhp.web.SelectServlet
    	servlet-class>
    	<load-on-startup>1load-on-startup>
    servlet>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    loadOnStartup属性

    标记容器是否在启动应用时就加载Servlet,默认不配置或数值为负数时表示客户端第一次请求Servlet时再加载;0或正数表示启动应用就加载,正数情况下,数值越小,加载该Servlet的优先级越高

    实例://斜杠必须

    @WebServlet(value="/test1",loadOnStartup=1)
    
    • 1
    name属性

    可以指定也可以不指定,通过getServletName()可以获取到,若不指定,则为Servlet的完整类名,如:cn.edu.njit.servlet.UserServlet

    urlPatterns/value属性

    String[]类型,可以配置多个映射,如:urlPatterns={“/user/test”,“/user/example”}

    实例://斜杠必须

    @WebServlet(loadOnStartup=1,urlPatterns= {"/test1","/test2"})
    
    • 1
    使用注解方式注意

    根元素中不能配置属性metadata-complete=“true”,否则无法加载Servlet。metadata-complete属性表示通知Web容器是否寻找注解,默认不写或者设置false,容器会扫描注解,为Web应用程序构建有效的元数据;metadata-complete=“true”,会在启动时不扫描注解(annotation)。如果不扫描注解的话,用注解进行的配置就无法生效,例如:@WebServlet

    urlPatterns的常用规则
    • /*或者/:拦截所有
      • 如果放行特定的请求比如静态资源html,css,jpg
    <servlet-mapping>
    <servlet-name>defaultservlet-name>
    <url-pattern>*.jpgurl-pattern>
    servlet-mapping>
    
    • 1
    • 2
    • 3
    • 4
    • *.do:拦截指定后缀
    • /user/login:拦截路径

    2 ServletConfig类

    ServletConfig 类是 Java Servlet API 提供的一个接口,用于提供关于 Servlet 配置信息的访问和管理。每个 Servlet 实例都有其对应的 ServletConfig 实例。

    2.1 常用方法

    • String getInitParameter(String name): 获取指定名称的初始化参数的值。
    • Enumeration getInitParameterNames(): 获取所有初始化参数的名称的枚举。
    • ServletContext getServletContext(): 获取当前 Servlet 的上下文对象 ServletContext。
    • String getServletName(): 获取当前 Servlet 的名称。

    2.2 作用

    • 获取初始化参数:通过 getInitParameter(String name) 方法,Servlet 可以根据指定的参数名称获取对应的初始化参数值。这些初始化参数通常在部署描述符(如 web.xml 文件)或注解中配置,可以用来传递配置信息给 Servlet。
    • 获取所有初始化参数名:使用 getInitParameterNames() 方法,Servlet 可以获取所有初始化参数的名称的枚举。这样,在不知道具体初始化参数名的情况下,可以遍历所有参数名进行处理。
    • 获取 Servlet 上下文对象:通过 getServletContext() 方法,Servlet 可以获取当前 Servlet 的上下文对象 ServletContext。ServletContext 提供了许多有关 Web 应用程序环境的信息和功能,如访问其他资源、共享数据等。
    • 获取 Servlet 名称:使用 getServletName() 方法,Servlet 可以获取当前 Servlet 的名称。该名称可以在部署描述符(如 web.xml 文件)中配置,用于标识 Servlet 的身份。

    2.3 案例

    web.xml 中的配置

    <servlet>
    	<display-name>欢迎servletdisplay-name>
    	<servlet-name>helloservlet-name>
    	<servlet-class>com.lxs.demo.servlet.HelloServletservlet-class>
    	
    	<init-param>
    		<param-name>helloConfig1param-name>
    		<param-value>hello servlet config value 1param-value>
    	init-param>
    	<init-param>
    		<param-name>helloConfig2param-name>
    		<param-value>hello servlet config value 2param-value>
    	init-param>
    		<load-on-startup>100load-on-startup>
    servlet>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    Servlet

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    	//得到配置的int-parameter参数
    	System.out.println(this.getInitParameter("helloConfig1"));
    	System.out.println(this.getInitParameter("helloConfig2"));
    	System.out.println("queryString = " + request.getQueryString());
    	response.getWriter().print("hello servlet response = " +
    	request.getQueryString());
    }
    @Override
    public void init(ServletConfig config) throws ServletException {
    	//得到配置的int-parameter参数
    	super.init(config); //重写后必须写,否则this.getInitParameter方法报错空指针
    	System.out.println(config.getInitParameter("helloConfig1"));
    	System.out.println(config.getInitParameter("helloConfig2"));
    	System.out.println("Hello Servlet 初始化");
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    3 ServletContext类

    ServletContext 类是 Java Servlet API 中的一个接口,代表了一个 Web 应用程序的上下文环境。每个 Web 应用程序都有一个对应的 ServletContext 实例,它是在应用程序启动时由 Servlet 容器创建的,并在整个应用程序的生命周期中存在。

    3.1 常用的功能和作用

    • 获取初始化参数:使用 getInitParameter(String name) 方法,可以获取指定名称的初始化参数的值。这些初始化参数通常在部署描述符(如 web.xml 文件)中配置,用于传递给整个 Web 应用程序或特定的 Servlet。
    • 获取所有初始化参数名:通过 getInitParameterNames() 方法,可以获取所有初始化参数的名称的枚举。可以通过遍历这些参数名来获取和处理所有的初始化参数。
    • 获取上下文路径:使用 getContextPath() 方法,可以获取当前 Web 应用程序的上下文路径。上下文路径是部署 Web 应用程序的 URL 路径的一部分,用于唯一标识该应用程序。
    • 获取真实路径:通过 getRealPath(String path) 方法,可以将给定的相对路径转换为在服务器文件系统中的真实路径。这对于访问 Web 应用程序中的静态资源文件很有用。
    • 访问资源文件:通过 getResource(String path) 或 getResourceAsStream(String path) 方法,可以获取位于 Web 应用程序中的资源文件的 URL 或输入流。这些资源可以是 HTML 文件、图像、配置文件等。
    • 共享数据:ServletContext 提供了一种在整个应用程序范围内共享数据的机制。通过 setAttribute(String name, Object value) 和 getAttribute(String name) 方法,可以将数据存储在 ServletContext 中,并在不同的 Servlet 或请求之间共享。
    • 动态注册和访问 Servlet:通过 addServlet(String servletName, String className) 和 getServlet(String name) 方法,可以在运行时动态注册和访问 Servlet。

    3.2 ServletContext 对象

    • application 对象:application 是 ServletContext 的别名,两者指代同一个对象。它表示整个 Web 应用程序的上下文环境,在整个应用程序的生命周期内存在,并且可以通过 getServletContext() 方法获取。
    • session 对象:session 表示用户与 Web 应用程序之间的一次会话。与 ServletContext 不同,session 是与每个用户相关联的,用于跟踪用户的状态和存储用户特定的数据,通常用于在多个请求之间共享数据。session 对象可以通过 HttpServletRequest 的 getSession() 方法获取。
    • request 对象:request 是一个代表客户端发送给服务器的 HTTP 请求的对象。它包含了所有与请求相关的信息,如请求参数、请求头、请求方式等。request 对象是针对每个请求创建的,与特定的用户和特定的请求相关联。request 对象可以通过 doGet() 或 doPost() 方法的参数获取。
    • page 对象:page 对象是 JSP 页面中的一个隐式对象,它代表正在处理的当前 JSP 页面。与 ServletContext 不同,page 对象是与每个 JSP 页面相关联的,用于访问和操作页面的属性和方法,如获取页面参数、设置页面作用域等。

    3.3 java web域对象

    • ServletContext 域对象:也称为应用程序域(Application Scope),它代表整个 Web 应用程序的上下文环境。在 ServletContext 中存储的数据可以在整个应用程序中共享。例如,可以将数据库连接池、应用程序配置信息等存储在 ServletContext 中。
    • HttpSession 域对象:该对象代表一个用户与服务器之间的会话。每个用户都有自己独立的 HttpSession 对象,可以用于在多个请求之间共享数据。例如,可以将用户登录信息、购物车内容等存储在 HttpSession 中。
    • HttpServletRequest 域对象:该对象代表客户端发送的 HTTP 请求。在 HttpServletRequest 中存储的数据只在当前请求中有效,无法在其他请求或会话中共享。例如,在表单提交时,可以通过 HttpServletRequest 获取表单参数。
    • PageContext 域对象:主要用于 JSP 页面中,代表正在处理的当前 JSP 页面。在 PageContext 中存储的数据在当前页面的生命周期内有效,不会在其他页面或会话中共享。例如,在 JSP 页面中可以将变量存储在 PageContext 中,以供页面使用。

    4 HttpServletRequest 类

    HttpServletRequest 类是 Java Servlet API 提供的一个接口,用于表示客户端发出的 HTTP 请求。它提供了访问和操作 HTTP 请求的方法,包括获取请求信息、请求参数、请求头等。

    4.1 常用方法和功能

    4.1.1 获取请求信息

    • getMethod(): 获取请求的 HTTP 方法(GET、POST等)。
    • getRequestURI(): 获取请求的 URI(Uniform Resource Identifier)。
    • getQueryString(): 获取请求的查询字符串部分。
    • getProtocol(): 获取请求的协议(如 “HTTP/1.1”)。
    • getRemoteAddr(): 获取客户端的 IP 地址。
    • getLocale(): 获取客户端的首选语言环境。

    4.1.2 获取请求参数

    • getParameter(String name): 根据参数名获取单个请求参数的值。
    • getParameterMap(): 获取所有请求参数的映射表。
    • getParameterValues(String name): 获取同名参数的多个值。

    4.1.3 获取请求头信息

    • getHeader(String name): 根据头部名称获取单个请求头的值。
    • getHeaderNames(): 获取所有请求头名称的枚举。

    4.1.4 获取会话信息

    • getSession(): 获取与此请求关联的 HttpSession 对象。

    4.1.5 请求转发与重定向

    • getRequestDispatcher(String path): 获取用于请求转发或包含其他资源的 RequestDispatcher 对象。
    • sendRedirect(String path): 发送重定向响应到指定的 URL。

    4.2 案例

    @WebServlet("/request")
    public class RequestServlet extends HttpServlet {
    	@Override
    	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    		System.out.println("-----------------请求行-----------------------");
    		//1. 请求行相关的方法
    		System.out.println("getRequestURI = " + request.getRequestURI());
    		System.out.println("getRequestURL = " + request.getRequestURL());
    		System.out.println("getMethod = " + request.getMethod());
    		System.out.println("getProtocol()" + request.getProtocol());
    		System.out.println("-----------------请求头-----------------------");
    		//请求头
    		Enumeration<String> heads = request.getHeaderNames();
    		while (heads.hasMoreElements()) {
    			String h = heads.nextElement(); //请求头的名字
    			String v = request.getHeader(h); //值
    			System.out.println(h + ": " + v);
    		}
    		System.out.println("-----------------请求体-----------------------");
    		//请求体
    		// BufferedReader in = new BufferedReader(new InputStreamReader(request.getInputStream()));
    		// System.out.println(in.readLine());
    		//请求参数
    		System.out.println("username = " +
    		request.getParameter("username")); //得的get和post的参数
    		System.out.println("password = " +
    		request.getParameter("password"));
    		//多个同名参数得到数组
    		String[] ids = request.getParameterValues("ids");
    		System.out.println("ids = " + Arrays.toString(ids));
    		System.out.println("--------------");
    		//得到所有的参数
    		Map<String, String[]> paramMap = request.getParameterMap();
    		for (Map.Entry<String, String[]> entry : paramMap.entrySet()) {
    			System.out.println("key = " + entry.getKey() + " value = " +
    			Arrays.toString(entry.getValue()));
    		}
    		System.out.println("--------------");
    		//得到所有的参数名
    		Enumeration<String> names = request.getParameterNames();
    		while (names.hasMoreElements()) {
    			String n = names.nextElement(); //请求头的名字
    			String v = request.getParameter(n);
    			System.out.println(n + ": " + v);
    		}
    	}
    	@Override
    	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    		doPost(request, response);
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51

    4.3 中文乱码问题

    4.3.1 Get 请求的中文乱码解决

    get的默认编码utf-8,以前老版本tomcat中get编码是iso-8859-1

    // 获取请求参数
    String username = req.getParameter("username");
    //1 先以 iso8859-1 进行编码
    //2 再以 utf-8 进行解码
    username = new String(username.getBytes("iso-8859-1"), "UTF-8");
    
    • 1
    • 2
    • 3
    • 4
    • 5

    4.3.2 POST 请求的中文乱码解决

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException,IOException {
    	// 设置请求体的字符集为 UTF-8, 从而解决 post 请求的中文乱码问题
    	req.setCharacterEncoding("UTF-8");
    	System.out.println("-------------doPost------------");
    	// 获取请求参数
    	String username = req.getParameter("username");
    	String password = req.getParameter("password");
    	String[] hobby = req.getParameterValues("hobby");
    	System.out.println("用户名: " + username);
    	System.out.println("密码: " + password);
    	System.out.println("兴趣爱好: " + Arrays.asList(hobby));
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    4.4 请求转发

    请求转发是指, 服务器收到请求后, 从一次资源跳转到另一个资源的操作叫请求转发。

    public class Servlet1 extends HttpServlet {
    	@Override
    	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    		// 获取请求的参数(办事的材料)查看
    		String username = req.getParameter("username");
    		System.out.println("在Servlet1(柜台1)中查看参数(材料):" + username);
    		// 给材料 盖一个章,并传递到Servlet2(柜台 2)去查看
    		req.setAttribute("key1","柜台1的章");
    		// 问路:Servlet2(柜台 2)怎么走
    /**
    * 请求转发必须要以斜杠打头,/ 斜杠表示地址为:http://ip:port/工程名/ , 映射
    到IDEA代码的web目录
    * */
    RequestDispatcher requestDispatcher = req.getRequestDispatcher("/servlet2"); // RequestDispatcher requestDispatcher = req.getRequestDispatcher("http://www.baidu.com"); // 走向Sevlet2(柜台 2) requestDispatcher.forward(req,resp); } }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    public class Servlet2 extends HttpServlet {
    	@Override
    	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    		// 获取请求的参数(办事的材料)查看
    		String username = req.getParameter("username");
    		System.out.println("在Servlet2(柜台2)中查看参数(材料):" + username);
    		// 查看 柜台1 是否有盖章
    		Object key1 = req.getAttribute("key1");
    		System.out.println("柜台1是否有章:" + key1);
    		// 处理自己的业务
    		System.out.println("Servlet2 处理自己的业务 ");
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    4.5 request作用域

    request:在一次请求中可以访问的作用,当前的servlet和当前servlet转发的servlet可以访问

    //request作用域存
    request.setAttribute("requestKey3", "hello servlet3 attribute value1");
    //request作用域取
    request.getAttribute("requestKey3")
    
    • 1
    • 2
    • 3
    • 4

    5 HttpServletResponse 类

    HttpServletResponse 类是 Java Servlet API 提供的一个接口,用于表示服务器对客户端发起的 HTTP 请求所做出的响应。它提供了访问和操作 HTTP 响应的方法,包括设置响应状态、设置响应头、向客户端发送数据等。

    5.1 常用方法和功能

    5.1.1 设置响应信息

    • setStatus(int sc): 设置响应的状态码(如 200、404、500 等)。
    • sendError(int sc): 发送一个错误状态的响应码。
    • setContentType(String type): 设置响应的内容类型(MIME 类型)。
    • setCharacterEncoding(String charset): 设置响应的字符编码。

    5.1.2 设置响应头

    • addHeader(String name, String value): 添加一个响应头。
    • setHeader(String name, String value): 设置一个响应头,如果已存在则覆盖。

    5.1.3 向客户端发送数据

    • getWriter(): 获取用于将字符数据发送到客户端的 PrintWriter 对象。
    • getOutputStream(): 获取用于将二进制数据发送到客户端的 ServletOutputStream 对象。
    • sendRedirect(String location): 发送重定向响应到指定的 URL。

    5.1.4 设置缓存和重定向

    • setBufferSize(int size): 设置响应缓冲区大小。
    • setCharacterEncoding(String charset): 设置响应的字符编码。
    • setContentLength(int len): 设置响应内容的长度。
    • sendRedirect(String location): 发送重定向响应到指定的 URL。

    5.2 案例

    @WebServlet("/response")
    public class ResponseServlet extends HttpServlet {
    	@Override
    	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    	response.setContentType("text/html; charset=UTF-8"); //设置响应字符集的响应头
    	System.out.println("-----------------响应行-----------------------");
    	response.setStatus(HttpServletResponse.SC_OK);
    	// response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
    	//重定向到500
    	System.out.println("-----------------响应头-----------------------");
    	response.addHeader("user-name", "mickey");
    	System.out.println("-----------------响应体-----------------------");
    	response.getWriter().print("hello response body-- 中文响应体");
    	}
    	@Override
    	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    		doPost(request, response);
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    5.2 响应的乱码解决

    方案一:

    // 设置服务器字符集为 UTF-8
    resp.setCharacterEncoding("UTF-8");
    // 通过响应头, 设置浏览器也使用 UTF-8 字符集
    resp.setHeader("Content-Type", "text/html; charset=UTF-8");
    
    • 1
    • 2
    • 3
    • 4

    方案二:

    // 它会同时设置服务器和客户端都使用 UTF-8 字符集, 还设置了响应头
    // 此方法一定要在获取流对象之前调用才有效
    resp.setContentType("text/html; charset=UTF-8");
    
    • 1
    • 2
    • 3

    5.3 请求重定向

    请求重定向, 是指客户端给服务器发请求, 然后服务器告诉客户端说。 我给你一些地址。 你去新地址访问。 叫请求重定向(因为之前的地址可能已经被废弃)
    请求重定向方案一:

    // 设置响应状态码 302 , 表示重定向, (已搬迁)
    resp.setStatus(302);
    // 设置响应头, 说明 新的地址在哪里
    resp.setHeader("Location", "http://localhost:8080");
    
    • 1
    • 2
    • 3
    • 4

    请求重定向方案二:

    resp.sendRedirect("http://localhost:8080");
    
    • 1

    5.4 转发和重定向的区别

    5.4.1 转发(Forwarding)

    • 转发是服务器内部的操作,客户端并不知道转发的过程。
    • 在转发中,请求从一个 Servlet 被发送到另一个 Servlet 或 JSP 页面。
    • 转发是直接将请求转发给目标资源,目标资源再返回响应给客户端。
    • 转发可以共享同一个请求对象,在多个 Servlet 之间传递数据。
    • 转发使用的方法是 getRequestDispatcher() 方法,使用目标资源的路径进行转发。

    5.4.2 重定向(Redirecting)

    • 重定向是通过发送特殊的响应来告诉客户端发起新的请求。
    • 在重定向中,服务器返回一个状态码和新的 URL,客户端根据新的 URL 再次发起请求。
    • 重定向是间接地将请求发送给目标资源,客户端会收到一个新的 URL。
    • 重定向不能共享同一个请求对象,它会创建一个全新的请求对象。
    • 重定向使用的方法是 sendRedirect() 方法,使用目标 URL 进行重定向。

    5.4.3 主要区别

    • 地址栏显示:转发地址栏不会改变,而重定向会显示新的 URL。
    • 请求次数转发只需要一次请求,而重定向需要两次请求
    • 数据共享:转发可以共享同一个请求对象,方便在多个 Servlet 之间传递数据;重定向不能共享请求对象,需要使用其他方式传递数据。
    • 资源位置:转发是服务器内部操作,目标资源可以是当前 Servlet 上下文中的任何位置;重定向是通过客户端发起新的请求,目标资源必须是一个完整的 URL。
  • 相关阅读:
    grpc和protobuf在一起
    Semantic Kernel 入门系列:🍋Connector连接器
    MyBatis快速上手与知识点总结
    redis学习(008 实战:黑马点评:缓存介绍)
    信息学奥赛一本通:1410:最大质因子序列
    aarch64 麒麟v10系统使用docker部署nvidia_gpu_exporter监控GPU
    Go语言开发小技巧&易错点100例(十三)
    重试组件 Spring Retry
    【Linux】操作题大全
    基于STM32的智能健康监测手环
  • 原文地址:https://blog.csdn.net/qq_58216564/article/details/132996075