当前位置: 首页 > news >正文

动态网站Servelt基础

文章目录

  • 一、Servlet基础
    • (一)Servlet概述
      • 1、Servlet是什么
      • 2、Servlet容器
      • 3、Servlet应用程序的体系结构
    • (二)Servlet的特点
      • 1、功能强大
      • 2、可移植
      • 3、性能高效
      • 4、安全性高
      • 5、可扩展
    • (三)Servlet接口
      • 1、Servlet接口
      • 2、Servlet接口的方法
      • 3、Servlet接口中生命周期的方法
      • 4、Servlet接口的实现类
      • 5、HttpServlet类的常用方法及功能
  • 二、Servlet开发入门
    • (一)实现第一个Servlet程序
      • 1、使用IDEA完成Servlet的开发
        • (1)新建Web项目
        • (2)创建Servlet类
        • (3)启动Servlet
      • 2、课堂练习 - 创建Web项目,利用Servlet显示个人信息
    • (二)Servlet的配置
      • 1、使用web.xml配置Servlet
      • 2、@WebServlet注解属性
      • 3、给一个Servlet配置多个url
    • (三)Servlet的生命周期
      • 1、Servle生命周期 - 初始化阶段
      • 2、Servlet生命周期 - 运行阶段
      • 3、Servlet生命周期 - 销毁阶段
      • 4、案例演示Servlet生命周期
  • 三、ServletConfig和ServletContext
    • (一)ServletConfig接口
      • 1、ServletConfig接口
      • 2、案例演示ServletConfig方法调用
      • 2、案例演示获取Web应用的容器初始化参数
      • 3、实现多个Servlet对象共享数据
      • 4、案例演示多个Servlet对象共享数据
      • 5、读取Web应用下的资源文件
      • 6、案例演示读取Web应用下的资源文件
  • 四、HttpServletResponse对象
    • (一)发送状态码相关的方法
      • 1、HttpServletResponse接口—setStatus(int status)方法
      • 2、HttpServletResponse接口—sendError(int sc)方法
      • 3、HttpServletResponse接口—sendError(int code,String message)方法
    • (二)发送响应头相关的方法
    • (三)发送响应消息体相关的方法
      • 1、getOutputStream()方法
      • 2、getWriter()方法
      • 3、案例演示发送响应消息体
  • 五、HttpServletResponse应用
    • (一)实现请求重定向
      • 1、HttpServletResponse接口—sendRedirect()方法
      • 2、案例演示实现请求重定向
    • (二)动手实践:解决中文输出乱码问题
      • 1、中文乱码问题
      • 2、案例演示解决乱码问题
  • 六、HttpServletRequest对象
    • (一)获取请求行信息的相关方法
      • 1、相关方法
      • 2、案例演示
    • (二)获取请求头的相关方法
      • 1、相关方法
      • 2、案例演示
    • (三)请求转发
      • 1、getRequestDispatcher()方法
      • 2、forward()方法
      • 3、案例演示请求转发
    • (五)解决请求参数中文乱码问题
    • (六)通过Request对象传递数据
      • 1、Request对象操作属性的方法
        • (1)setAttribute()方法
        • (2)getAttribute()方法
        • (3)removeAttribute()方法
        • (4)getAttributeNames()方法
      • 2、案例演示通过Request对象传递数据

一、Servlet基础

  • 目标:掌握Servlet的概念、特点和接口

(一)Servlet概述

1、Servlet是什么

  • Servlet是运行在Web服务器端的Java应用程序,它使用Java语言编写。与Java程序的区别是,Servlet 对象主要封装了对HTTP请求的处理,并且它的运行需要Servlet容器的支持。在Java Web应用方面,Servlet 的应用占有十分重要的地位,它在Web请求的处理功能方面也非常强大。

2、Servlet容器

  • Servlet由Servlet容器提供,Servlet容器是指提供了Servlet 功能的服务器(本讲稿指Tomcat)。Servlet容器将Servlet动态地加载到服务器上。与HTTP 协议相关的Servlet使用HTTP请求和HTTP响应与客户端进行交互。因此,Servlet容器支持所有HTTP协议的请求和响应。

3、Servlet应用程序的体系结构

  • Servlet的请求首先会被HTTP服务器(如Apache)接收,HTTP服务器只负责静态HTML页面的解析,对于Servlet的请求转交给Servlet容器,Servlet容器会根据web.xml文件中的映射关系,调用相应的Servlet,Servlet将处理的结果返回给Servlet容器,并通过HTTP服务器将响应传输给客户端。

(二)Servlet的特点

  • Servlet使用Java语言编写,它不仅具有Java 语言的优点,而且还对Web的相关应用进行了封装,同时Servlet容器还提供了对应用的相关扩展,无论是在功能、性能、安全等方面都十分优秀。

1、功能强大

  • Servlet采用Java语言编写,它可以调用Java API中的对象及方法,此外,Servlet对象对Web应用进行了封装,提供了Servlet对Web应用的编程接口,还可以对HTTP请求进行相应的处理,如处理提交数据、会话跟踪、读取和设置HTTP头信息等。由于Servlet既拥有Java 提供的API,而且还可以调用Servlet封装的Servlet API编程接口,所以,它在业务功能方面十分强大。

2、可移植

  • Java语言是跨越平台的,所谓跨越平台是指程序的运行不依赖于操作系统平台,它可以运行到多个系统平台中,如目前常用的操作系统Windows、Linux和UNIX等。

3、性能高效

  • Servlet对象在Servlet容器启动时被初始化,当Servlet对象第一次被请求时,Servlet 容器将Servlet对象实例化,此时Servlet对象驻存于内存中。如果存在多个请求,Servlet 不会再被实例化,仍然由第一次被实例化的Servlet对象处理其他请求。每一个请求是一个线程,而不是一个进程。

4、安全性高

  • Servlet使用了Java的安全框架,同时Servlet容器还可以为Servlet提供额外的安全功能,它的安全性是非常高的。

5、可扩展

  • Java语言是面向对象的编程语言, Servlet由Java语言编写,所以它具有面向对象的优点。在业务逻辑处理中,可以通过封装、继承等特性扩展实际的业务需要。

(三)Servlet接口

1、Servlet接口

  • 针对Servlet技术的开发,SUN公司提供了一系列接口和类,其中最重要的是javax.servlet.Servlet接口。Servlet就是一种实现了Servlet接口的类,它由Web容器负责创建并调用,用于接收和响应用户的请求。

2、Servlet接口的方法

方法声明功能描述
void init(ServletConfig config)Servlet实例化后,Servlet容器调用该方法完成初始化工作
ServletConfig getServletConfig()用于获取Servlet对象的配置信息,返回Servlet的ServletConfig对象
String getServletInfo()返回一个字符串,其中包含关于Servlet的信息,例如,作者、版本和版权等信息
void service(ServletRequest request,ServletResponse response)负责响应用户的请求,当容器接收到客户端访问Servlet对象的请求时,就会调用此方法。容器会构造一个表示客户端请求信息的ServletRequest对象和一个用于响应客户端的ServletResponse对象作为参数传递给service()方法。在service()方法中,可以通过ServletRequest对象得到客户端的相关信息和请求信息,在对请求进行处理后,调用ServletResponse对象的方法设置响应信息
void destroy()负责释放Servlet对象占用的资源。当服务器关闭或者Servlet对象被移除时,Servlet对象会被销毁,容器会调用此方法

3、Servlet接口中生命周期的方法

  • 在Servlet接口中的5个方法中,其中init()、service()和destroy()这三个方法可以表现Servlet的生命周期,它们会在某个特定的时刻被调用。需要注意的是,Servlet容器指的就是Web服务器。

4、Servlet接口的实现类

  • 针对Servlet接口,SUN公司提供了两个默认的接口实现类:GenericServlet和HttpServlet。GenericServlet是一个抽象类,该类为Servlet接口提供了部分实现,它并没有实现HTTP请求处理。HttpServlet是GenericServlet的子类,它继承了GenericServlet的所有方法,并且为HTTP请求中的POST、GET等类型提供了具体的操作方法。

5、HttpServlet类的常用方法及功能

方法声明功能描述
protected void doGet(HttpServletRequest req, HttpServletResponse resp)用于处理GET类型的Http请求的方法
protected void doPost(HttpServletRequest req, HttpServletResponse resp)用于处理POST类型的Http请求的方法
protected void doPut(HttpServletRequest req, HttpServletResponse resp)用于处理PUT类型的Http请求的方法

二、Servlet开发入门

(一)实现第一个Servlet程序

  • 目标:掌握如何使用IDEA工具开发Servlet程序

1、使用IDEA完成Servlet的开发

  • 在实际开发中,通常都会使用IDEA(或Eclipse等)工具完成Servlet的开发,我们使用IDEA完成Servlet的开发,因为IDEA不仅会自动编译Servlet,还会自动创建web.xml文件信息,完成Servlet虚拟路径的映射。

(1)新建Web项目

  • 选择IDEA主页的“Create New Project”选项,进入新建项目的界面。
    在这里插入图片描述

  • 在New Projec界面中,选择左侧栏的“Java”选项,然后勾选”Web Application”选项。选择完毕之后,单击”Next”按钮进入填写项目信息的界面。
    在这里插入图片描述

  • 在New Projec界面中,”Project name”选项用于指项目的名称,”Project localtion”选项用于指定Web项目的根目录。项目的根目录设置为D:\web_work\chapter04,将WebDemo作为Web项目的名称。设置完成之后,单击“Finish”按钮,进入开发界面。
    在这里插入图片描述

  • 修改Artifact名称 - WebDemo
    在这里插入图片描述

  • 编辑Tomcat服务器配置
    在这里插入图片描述

  • 切换到【Server】选项卡
    在这里插入图片描述

  • 启动服务器,查看效果
    在这里插入图片描述

(2)创建Servlet类

  • 新建net.xyx.servlet包

  • 在net.xyxi.servlet包里创建ServletDemo01

  • 此时IDEA工具会自动生成Servlet代码

  • 为了更好地演示Servlet的运行效果,接下来在ServletDemo01的doGet()和doPost()方法中添加一些代码。在@WebServlet注解里设置urlPatterns属性值:urlPatterns = “/demo01”

package net.xyx.servlet;import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;/*** 功能:Servlet演示类* 作者:xyx* 日期:2023年03月12日*/
@WebServlet(name = "ServletDemo01", urlPatterns = "/demo01")
public class ServletDemo01 extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {// 获取字符输出流PrintWriter out = response.getWriter();// 输出信息out.print("<h1>Hello Servlet World~</h1>");}protected void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {doPost(request, response);}
}
  • 其实,Servlet本质上就是Java程序里嵌入了HTML页面

(3)启动Servlet

  • 启动服务器,显示首页

  • 在页面访问ServletDemo01类的url地址“localhost:8080/WebDemo/demo01”

  • 对应关系图

  • 希望显示红色消息,并且居中显示,那么就要用到样式

2、课堂练习 - 创建Web项目,利用Servlet显示个人信息

  • 创建Java Enterprise项目

  • 设置项目名称与保存位置

  • 单击【Finish】按钮

  • 查看Artifacts的名称

  • 将名称改为ShowInfo

  • 配置tomcat服务器

  • 在Deployment里删除ShowInfo后重新添加

  • 切换到【Server】选项卡,查看URL

  • 启动tomcat服务器,查看效果

  • 修改首页文件,以表格形式显示个人信息

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html><head><title>个人信息</title></head><body><table style="text-align: center" border="1" align="center" cellpadding="5"><tr><td>学号</td><td>姓名</td><td>性别</td><td>年龄</td><td>专业</td><td>班级</td><td>手机</td></tr><tr><td>20210201</td><td>陈燕文</td><td></td><td>18</td><td>软件技术专业</td><td>2021软件2班</td><td>15890456780</td></tr></table></body>
</html>
  • 启动服务器,查看结果

  • 创建net.huawei.servlet包,在包里创建InfoServlet类

package net.xyx.servlet;import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;/*** 功能:显示个人信息* 作者:xyx* 日期:2023年03月31日*/
@WebServlet(name = "InfoServlet", urlPatterns = "/info")
public class InfoServlet extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {// 获取字符输出流PrintWriter out = response.getWriter();// 往客户端输出信息out.print("<!DOCTYPE html>");out.print("<html>");out.print("<head>");out.print("<meta charset='UTF-8'");out.print("<title>个人信息</title>");out.print("</head>");out.print("<body style='text-align: center'>");out.print("<table border='1' align='center' cellpadding='5'>");out.print("<tr>");out.print("<td>学号</td>");out.print("<td>姓名</td>");out.print("<td>性别</td>");out.print("<td>年龄</td>");out.print("<td>专业</td>");out.print("<td>班级</td>");out.print("<td>手机</td>");out.print("</tr>");out.print("<tr>");out.print("<td>20210201</td>");out.print("<td>陈燕文</td>");out.print("<td></td>");out.print("<td>18</td>");out.print("<td>软件技术专业</td>");out.print("<td>2021软件2班</td>");out.print("<td>15890456780</td>");out.print("</tr>");out.print("</table>");out.print("</body>");out.print("</html>");}protected void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {doPost(request, response);}
}
  • 启动tomcat服务器,访问http://localhost:8080/ShowInfo/info

  • 页面出现中文乱码,需要设置字符编码(要查看Chrome浏览器默认的字符编码)

  • 设置响应对象字符编码为UTF-8,与浏览器当前采用的字符编码保持一致

  • 重启tomcat服务器,访问http://localhost:8080/ShowInfo/info

  • 无论浏览器当前采用什么字符编码,通过设置响应对象内容类型来要求浏览器采用指定的字符编码

  • 重启tomcat服务器,访问http://localhost:8080/ShowInfo/info

  • 查看浏览器当前使用的字符编码,已经被改成GBK了

(二)Servlet的配置

  • 目标:掌握完成Servlet的配置的两种方式:通过Web应用的配置文件web.xml来,通过@WebServlet注解来完成Servlet的配置
  • 若想让Servlet正确地运行在服务器中并处理请求信息,必须进行适当的配置,关于Servlet的配置主要有两种方式,分别是通过Web应用的配置文件web.xml来完成配置和使用@WebServlet注解的方式完成。

1、使用web.xml配置Servlet

  • 在web.xml文件中,通过标签进行注册,在标签下包含若干个子元素。
属性名类型 描述
<servlet-name>String 指定该Servlet的名称,一般与Servlet类名相同,要求唯一
<servlet-class>String 指定该Servlet类的位置,包括包名与类名
<description>String 指定该Servlet的描述信息
<display-name>String 指定该Servlet的显示名
  • 把Servlet映射到URL地址,使用标签进行映射,使用子标签指定要映射的Servlet名称,名称要和之前在标签下注册的相同;使用子标签映射URL地址,地址前必须加“/”,否则访问不到。

  • 在部署描述文件web.xml里注册了Servlet,那么就可以注释掉InfoServlet类上的注解

  • 重启tomcat服务器,访问http://localhost:8080/ShowInfo/info

2、@WebServlet注解属性

  • @WebServlet 注解用于代替web.xml文件中的等标签,该注解将会在项目部署时被容器处理,容器将根据具体的属性配置将相应的类部署为Servlet。为此,@WebServlet注解提供了一些属性。
属性声明功能描述
String name指定Servlet的name属性,等价于。如果没有显式指定,则该
Servlet的取值即为类的全限定名。
String[] value该属性等价于urlPatterns属性。urlPatterns和value属性不能同时使用。
String[] urlPatterns指定一组Servlet的URL匹配模式。等价于标签。
int loadOnStartup指定Servlet的加载顺序,等价于标签。
WebInitParam[]指定一组Servlet初始化参数,等价于标签。
boolean asyncSupported声明Servlet是否支持异步操作模式,等价于 标签。
String descriptionServlet的描述信息,等价于标签。
String displayName ervlet的显示名,通常配合工具使用,等价于 标签。
@WebServlet注解可以标注在任意一个继承了HttpServlet类的类之上,属于类级别的注解。下面使用@WebServlet注解标注InfoServlet类。
  • 在web.xml文件里注释掉对InfoServlet的注册标签

  • 重启tomcat服务器,访问http://localhost:8080/ShowInfo/info

  • 使用@WebServlet注解将InfoServlet类标注为一个Servlet。@WebServlet注解中的name属性值用于指定servlet的name属性,等价于,如果没有设置@WebServlet的name属性,其默认值是Servlet的类完整名称。urlPatterns属性值用于指定一组servlet的url的匹配模式,等价于标签。如果需要在@WebServlet注解中设置多个属性,属性之间用逗号隔开。通过@WebServlet注解能极大地简化了Servlet的配置步骤,降低了开发人员的开发难度。

3、给一个Servlet配置多个url

  • 好比一个人有多个对外联系方式

  • 启动服务器,访问http://localhost:8080/ShowInfo/info

  • 访问http://localhost:8080/ShowInfo/message

(三)Servlet的生命周期

  • 目标:掌握Servlet的三个生命周期,初始化阶段、运行阶段和销毁阶段

1、Servle生命周期 - 初始化阶段

  • 当客户端向Servlet容器发出HTTP请求访问Servlet时,Servlet容器首先会解析请求,检查内存中是否已经有了该Servlet对象,如果有,直接使用该Servlet对象;如果没有,就创建Servlet实例对象,然后通过调用init()方法完成Servlet的初始化。需要注意的是,在Servlet的整个生命周期内,它的init()方法只被调用一次。

2、Servlet生命周期 - 运行阶段

  • 这是Servlet生命周期中最重要的阶段,在这个阶段,Servlet容器会为客户端请求创建代表HTTP请求的ServletRequest对象和代表HTTP响应的ServletResponse对象,然后将它们作为参数传递给Servlet的service()方法。service()方法从ServletRequest对象中获得客户端请求信息并处理该请求,通过ServletResponse对象生成响应结果。在Servlet的整个生命周期内,对于Servlet的每一次访问请求,Servlet容器都会调用一次Servlet的service()方法,并且创建新的ServletRequest和ServletResponse对象,也就是说,service()方法在Servlet的整个生命周期中会被调用多次。

3、Servlet生命周期 - 销毁阶段

  • 当服务器关闭或web应用被移除出容器时,Servlet随着web应用的销毁而销毁。在销毁Servlet之前,Servlet容器会调用Servlet的destroy()方法,以便让Servlet对象释放它所占用的资源。在Servlet的整个生命周期中,destroy()方法也只被调用一次。需要注意的是,Servlet对象一旦创建就会驻留在内存中等待客户端的访问,直到服务器关闭,或web应用被移除出容器时Servlet对象才会销毁。

4、案例演示Servlet生命周期

  • 在WebDemo项目中创建ServletDemo02类,在ServletDemo02类中编写init()方法和destroy()方法并重写service()方法,用来案例演示Servlet生命周期方法的执行效果。
package net.xyx.servlet;import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;/*** 功能:演示Servlet生命周期* 作者:xyx* 日期:2023年03月12日*/
@WebServlet(name = "ServletDemo02", value = "/demo02")
public class ServletDemo02 extends HttpServlet {@Overridepublic void init() throws ServletException {System.out.println("init()方法被调用……");}protected void service(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {System.out.println("service()方法被调用……");response.setContentType("text/html; charset=utf-8");PrintWriter out = response.getWriter();out.print("<h1>演示Servlet生命周期~</h1>");}@Overridepublic void destroy() {System.out.println("destroy()方法被调用……");}
}
  • 启动tomcat服务器,访问http://localhost:8080/WebDemo/demo02

  • 刷新浏览器两次,两次访问ServletDemo02,查看tomcat控制台的打印结果

  • init()方法只在第一次访问时执行,service()方法则在每次访问时都被执行。

  • 如果想将ServletDemo02移除,可以在IDEA中停止WebDemo项目,此时,Servlet容器会调用ServletDemo02的destroy()方法,在IDEA控制台打印出“destroy()方法被调用……”信息。

  • 打个比方:我们只能诞生一次(init()方法),死亡一次(destroy()方法),中间可以换很多次工作,给社会提供不同的服务(service()方法)。

三、ServletConfig和ServletContext

(一)ServletConfig接口

  • 目标:掌握如何使用ServletConfig获取配置信息的方法

1、ServletConfig接口

  • 在Servlet运行期间,经常需要一些配置信息,例如,文件使用的编码等,这些信息都可以在@WebServlet注解的属性中配置。当Tomcat初始化一个Servlet时,会将该Servlet的配置信息封装到一个ServletConfig对象中,通过调用init(ServletConfig config)方法将ServletConfig对象传递给Servlet。ServletConfig定义了一系列获取配置信息的方法。
方法说明功能描述
String getInitParameter(String name)根据初始化参数名返回对应的初始化参数值
Enumeration getInitParameterNames()返回一个Enumeration对象,其中包含了所有的初始化参数名
ServletContext getServletContext()返回一个代表当前Web应用的ServletContext对象
String getServletName()返回Servlet的名字

2、案例演示ServletConfig方法调用

  • 以getInitParameter()方法为例讲解ServletConfig方法的调用
  • 在WebDemo项目的net.huawei.servlet包里创建ServletDemo03类
package net.xyx.servlet;import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;/*** 功能:演示ServletConfig方法的调用* 作者:xyx* 日期:2023年03月31日*/
@WebServlet(name = "ServletDemo03", urlPatterns = "/demo03",initParams = {@WebInitParam(name="encoding", value = "utf-8"),@WebInitParam(name="text-color", value = "red"),@WebInitParam(name="font-size", value= "25")})
public class ServletDemo03 extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {// 设置响应对象内容类型response.setContentType("text/html; charset=utf-8");// 获取打印输出流PrintWriter out = response.getWriter();// 获取Servlet配置对象ServletConfig config = getServletConfig();// 获取初始化参数名枚举对象Enumeration<String> initParams = config.getInitParameterNames();// 遍历初始化参数名枚举对象,输出参数名及其值while (initParams.hasMoreElements()) {String initParam = initParams.nextElement();out.print(initParam + " : " + config.getInitParameter(initParam) + "<br />");}}protected void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {doPost(request, response);}
}

启动tomcat服务器,访问http://localhost:8080/WebDemo/demo03

(二)ServletContext接口
目标:掌握ServletContext接口的使用方法
1、获取Web应用程序的初始化参数
当Servlet容器启动时,会为每个Web应用创建一个唯一的ServletContext对象代表当前Web应用。ServletContext对象不仅封装了当前Web应用的所有信息,而且实现了多个Servlet之间数据的共享。
在web.xml文件中,可以配置Servlet的初始化信息,还可以配置整个Web应用的初始化信息。Web应用初始化参数的配置方式具体如下所示。

参数名
参数值


参数名
参数值

1
2
3
4
5
6
7
8

  • <context-param>元素位于根元素<web-app>中,它的子元素<param-name><param-value>分别用来指定参数的名字和参数值。可以通过调用ServletContext接口中定义
  • getInitParameterNames()和getInitParameter(String name)方法,分别获取参数名和参数值。

2、案例演示获取Web应用的容器初始化参数

  • 在WebDemo项目的web.xml文件中,配置容器初始化参数信息和Servlet信息
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaeehttp://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"version="4.0"><context-param><param-name>college</param-name><param-value>泸州职业技术学院</param-value></context-param><context-param><param-name>address</param-name><param-value>泸州市龙马潭区长桥路2号</param-value></context-param><context-param><param-name>secretary</param-name><param-value>何杰</param-value></context-param><context-param><param-name>president</param-name><param-value>谢鸿全</param-value></context-param>
</web-app>
  • 在net.huawei.servlet包里创建ServletDemo04
package net.xyx.servlet;import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;/*** 功能:获取Web应用的容器初始化参数* 作者:xyx* 日期:2023年03月31日*/
@WebServlet(name = "ServletDemo04", urlPatterns = "/demo04")
public class ServletDemo04 extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {// 设置响应对象内容类型response.setContentType("text/html; charset=utf-8");// 获取打印输出流PrintWriter out = response.getWriter();// 获取Servlet容器对象ServletContext context = getServletContext();// 获取容器的初始化参数名枚举对象Enumeration<String> paramNames = context.getInitParameterNames();// 通过循环遍历显示全部参数名与参数值while (paramNames.hasMoreElements()) {// 获取参数名String name = paramNames.nextElement();// 按参数名获取参数值String value = context.getInitParameter(name);// 输出参数名和参数值out.print(name + " : " + value + "<br />");}}protected void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {doPost(request, response);}
}
  • 启动tomcat服务器,访问http://localhost:8080/WebDemo/demo04

3、实现多个Servlet对象共享数据

  • 由于一个Web应用中的所有Servlet共享同一个ServletContext对象,所以ServletContext对象的域属性可以被该Web应用中的所有Servlet访问。ServletContext接口中定义了用于增加、删除、设置ServletContext域属性的四个方法。
方法说明功能描述
Enumeration getAttributeNames()返回一个Enumeration对象,该对象包含了所有存放在ServletContext中的所有域属性名
Object getAttibute(String name)根据参数指定的属性名返回一个与之匹配的域属性值
void removeAttribute(String name)根据参数指定的域属性名,从ServletContext中删除匹配的域属性
void setAttribute(String name,Object obj)设置ServletContext的域属性,其中name是域属性名,obj是域属性值

4、案例演示多个Servlet对象共享数据

  • 在net.xyx.servlet包里创建ServletDemo05
package net.xyx.servlet;import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;/*** 功能:写入域属性* 作者:xyx* 日期:2023年03月31日*/
@WebServlet(name = "ServletDemo05", urlPatterns = "/demo05")
public class ServletDemo05 extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {// 设置响应对象内容类型response.setContentType("text/html; charset=utf-8");// 获取Servlet容器对象ServletContext context = getServletContext();// 写入域属性context.setAttribute("id", "20210201");context.setAttribute("name", "陈雅雯");context.setAttribute("gender", "女");context.setAttribute("age", "18");context.setAttribute("major", "软件技术专业");context.setAttribute("class", "2021软件2班");context.setAttribute("telephone", "15890903456");// 获取打印输出流PrintWriter out = response.getWriter();// 输出提示信息out.print("<h3>成功地写入了域属性~</h3>");}protected void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {doPost(request, response);}
}
  • 在net.xyx.servlet包里创建ServletDemo06
package net.xyxx.servlet;import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;/*** 功能:读取域属性* 作者:xyx* 日期:2023年03月31日*/
@WebServlet(name = "ServletDemo06", urlPatterns = "/demo06")
public class ServletDemo06 extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {// 设置响应对象内容类型response.setContentType("text/html; charset=utf-8");// 获取打印输出流PrintWriter out = response.getWriter();// 获取Servlet容器对象ServletContext context = getServletContext();// 获取全部域属性名枚举对象Enumeration<String> attributeNames = context.getAttributeNames();// 通过循环显示域属性名与域属性值while (attributeNames.hasMoreElements()) {// 获取域属性名String name = attributeNames.nextElement();// 获取域属性值Object value = context.getAttribute(name);// 输出域属性名与域属性值out.print(name + " : " + value + "<br />");}}protected void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {doPost(request, response);}
}
  • 启动tomcat服务器,先访问http://localhost:8080/WebDemo/demo05

  • 再访问http://localhost:8080/WebDemo/demo06

  • 有很多域属性不是我们写入的,如果我们只想显示我们写入的域属性,那么我们就要修改一下ServletDemo06的代码

  • 重启服务器,访问http://localhost:8080/WebDemo/demo05

  • 再访问http://localhost:8080/WebDemo/demo06

5、读取Web应用下的资源文件

  • ServletContext接口定义了一些读取Web资源的方法,这些方法是依靠Servlet容器来实现的。
  • Servlet容器根据资源文件相对于Web应用的路径,返回关联资源文件的IO流、资源文件在文件系统的绝对路径等。
方法说明功能描述
Set getResourcePaths(String path)返回一个Set集合,集合中包含资源目录中子目录和文件的路径名称。参数path必须以正斜线(/)开始,指定匹配资源的部分路径
String getRealPath(String path)返回资源文件在服务器文件系统上的真实路径(文件的绝对路径)。参数path代表资源文件的虚拟路径,它应该以正斜线(/)开始,“/”表示当前Web应用的根目录,如果Servlet容器不能将虚拟路径转换为文件系统的真实路径,则返回null
URL getResource(String path)返回映射到某个资源文件的URL对象。参数path必须以正斜线(/)开始,“/”表示当前Web应用的根目录
InputStream getResourceAsStream(String path)返回映射到某个资源文件的InputStream输入流对象。参数path传递规则和getResource()方法完全一致

6、案例演示读取Web应用下的资源文件

  • 在net.xyx.servlet包里创建属性文件 - college.properties
name = 泸州职业技术学院
address = 泸州市龙马潭区长桥路2号
secretary = 何杰
president = 谢鸿全
  • 在net.xyxservlet包里创建ServletDemo07
package net.xyx.servlet;import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Properties;/*** 功能:读取资源文件* 作者:xyx* 日期:2023年03月13日*/
@WebServlet(name = "ServletDemo07", urlPatterns = "/demo07")
public class ServletDemo07 extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {// 设置内容类型response.setContentType("text/html; charset=utf-8");// 获取Servlet容器对象ServletContext context = getServletContext();// 获取打印输出流PrintWriter out = response.getWriter();// 读取资源文件,得到字节输入流InputStream in = context.getResourceAsStream("/WEB-INF/classes/net/huawei/servlet/college.properties");// 创建属性对象(Map接口的实现类)Properties pros = new Properties();// 属性对象加载资源文件的资源文件输入流pros.load(in);// 往客户端输出属性值out.println("name = " + pros.getProperty("name") + "<br />");out.println("address = " + pros.getProperty("address") + "<br />");out.println("secretary = " + pros.getProperty("secretary") + "<br />");out.println("president = " + pros.getProperty("president") + "<br />");}protected void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {doPost(request, response);}
}
  • 启动tomcat服务器,访问http://localhost:8080/WebDemo/demo07

  • 属性文件的路径问题

  • 读取属性文件得到的字节流编码是ISO-8859-1,需要做一个转码处理

  • 重启tomcat服务器,先访问http://localhost:8080/WebDemo/demo07

  • 在Web项目开发中开发者可能需要获取资源的绝对路径。通过调用getRealPath(String path)方法获取资源文件的绝对路径。

  • 在net.xyx.servlet包里创建ServletDemo08类

package net.xyx.servlet;import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;/*** 功能:获取资源的绝对路径* 作者:xyx* 日期:2023年03月13日*/
@WebServlet(name = "ServletDemo08", urlPatterns = "/demo08")
public class ServletDemo08 extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {// 获取Servlet容器对象ServletContext context = getServletContext();// 获取打印输出流PrintWriter out = response.getWriter();// 创建资源路径字符串String path = "/WEB-INF/classes/net/huawei/servlet/college.properties";// 获取资源绝对路径String realPath = context.getRealPath(path);// 输出资源绝对路径out.println("college.properties: " + realPath);}protected void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {doPost(request, response);}
}
  • 重启tomcat服务器,访问http://localhost:8080/WebDemo/demo08

四、HttpServletResponse对象

(一)发送状态码相关的方法

  • 目标:掌握HttpServletResponse接口定义的3个发送状态码的方法
    当Servlet向客户端回送响应消息时,需要在响应消息中设置状态码,状态码代表着客户端请求服务器的结果。为此,HttpServletResponse接口定义了3个发送状态码的方法。

1、HttpServletResponse接口—setStatus(int status)方法

  • setStatus(int status)方法用于设置HTTP响应消息的状态码,并生成响应状态行。由于响应状态行中的状态描述信息直接与状态码相关,而HTTP版本由服务器确定,所以,只要通过setStatus(int status)方法设置了状态码,即可实现状态行的发送。例如,正常情况下,Web服务器会默认产生一个状态码为200的状态行。

2、HttpServletResponse接口—sendError(int sc)方法

  • sendError(int sc)方法用于发送表示错误信息的状态码,例如,404状态码表示找不到客户端请求的资源。

3、HttpServletResponse接口—sendError(int code,String message)方法

  • sendError(int code, String message)方法除了设置状态码,还会向客户端发出一条错误信息。服务器默认会创建一个HTML格式的错误服务页面作为响应结果,其中包含参数message指定的文本信息,这个HTML页面的内容类型为“text/html”,保留cookies和其他未修改的响应头信息。如果一个对应于传入的错误码的错误页面已经在web.xml中声明,那么这个声明的错误页面会将优先建议的message参数服务于客户端。

(二)发送响应头相关的方法

  • 目标:掌握HttpServletResponse接口设置HTTP响应头字段的方法
方法说明功能描述
void addHeader(String name, String value)用来设置HTTP协议的响应头字段,其中,参数name用于指定响应头字段的名称,参数value用于指定响应头字段的值。addHeader()方法可以增加同名的响应头字段
void setHeader(String name, String value)用来设置HTTP协议的响应头字段,其中,参数name用于指定响应头字段的名称,参数value用于指定响应头字段的值。setHeader()方法则会覆盖同名的头字段
void addIntHeader(String name, int value)专门用于设置包含整数值的响应头。避免了调用addHeader()方法时,需要将int类型的设置值转换为String类型的麻烦
void setIntHeader(String name, int value)专门用于设置包含整数值的响应头。避免了调用setHeader()方法时,需要将int类型的设置值转换为String类型的麻烦
void setContentLength(int len)该方法用于设置响应消息的实体内容的大小,单位为字节。对于HTTP协议来说,这个方法就是设置Content-Length响应头字段的值
void setContentType(String type)该方法用于设置Servlet输出内容的MIME类型,对于HTTP协议来说,就是设置Content-Type响应头字段的值。例如,如果发送到客户端的内容是jpeg格式的图像数据,就需要将响应头字段的类型设置为“image/jpeg”。需要注意的是,如果响应的内容为文本,setContentType()方法的还可以设置字符编码,如:text/html;charset=UTF-8
void setLocale(Locale loc)该方法用于设置响应消息的本地化信息。对HTTP来说,就是设置Content-Language响应头字段和Content-Type头字段中的字符集编码部分。需要注意的是,如果HTTP消息没有设置Content-Type头字段,setLocale()方法设置的字符集编码不会出现在HTTP消息的响应头中,如果调用setCharacterEncoding()或setContentType()方法指定了响应内容的字符集编码,setLocale()方法将不再具有指定字符集编码的功能
void setCharacterEncoding(String charset)该方法用于设置输出内容使用的字符编码,对HTTP 协议来说,就是设置Content-Type头字段中的字符集编码部分。如果没有设置Content-Type头字段,setCharacterEncoding方法设置的字符集编码不会出现在HTTP消息的响应头中。setCharacterEncoding()方法比setContentType()和setLocale()方法的优先权高,setCharacterEncoding()方法的设置结果将覆盖setContentType()和setLocale()方法所设置的字符码表
  • 需要注意的是,addHeader()、setHeader()、addIntHeader()、setIntHeader()方法都是用于设置各种头字段的,而setContetType()、setLoacale()和setCharacterEncoding()方法用于设置字符编码,这些设置字符编码的方法可以有效解决中文字符乱码问题。

(三)发送响应消息体相关的方法

  • 目标:掌握发送响应消息体相关的方法getOutputStream()和getWriter()
  • 由于在HTTP响应消息中,大量的数据都是通过响应消息体传递的,所以,ServletResponse遵循IO流传递大量数据的设计理念。在发送响应消息体时,定义了两个与输出流相关的方法。

1、getOutputStream()方法

  • getOutputStream()方法所获取的字节输出流对象为ServletOutputStream类型。由于ServletOutputStream是OutputStream的子类,它可以直接输出字节数组中的二进制数据。所以,要想输出二进制格式的响应正文,就需要调用getOutputStream()方法。

2、getWriter()方法

getWriter()方法所获取的字符输出流对象为PrintWriter类型。由于PrintWriter类型的对象可以直接输出字符文本内容,所以,要想输出内容为字符文本的网页文档,需要调用getWriter()方法。

3、案例演示发送响应消息体

  • 创建net.xyx.response包

  • 在net.xyx.response包里创建PrintServlet01类

package net.huawei.response;import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;/*** 功能:演示响应体输出字节流* 作者:xyx* 日期:2023年04月07日*/
@WebServlet(name = "PrintServlet01", urlPatterns = "/print01")
public class PrintServlet01 extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {// 定义字符串数据String data = "欢迎访问泸州职业技术学院~";// 获取字节输出流对象OutputStream out = response.getOutputStream();// 往客户端输出信息out.write(data.getBytes());}protected void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {doPost(request, response);}
}
  • 重启tomcat服务器,访问http://localhost:8080/WebDemo/print01

  • 在net.xyx.response包里创建PrintServlet02

package net.xyx.response;import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;/*** 功能:演示响应体打印字符流* 作者:xyx* 日期:2023年04月07日*/
@WebServlet(name = "PrintServlet02", urlPatterns = "/print02")
public class PrintServlet02 extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {// 定义字符串数据String data = "欢迎访问泸州职业技术学院~";// 获取打印字符流PrintWriter out = response.getWriter();// 往客户端输出信息out.println(data);}protected void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {doPost(request, response);}
}
  • 重启tomcat服务器,访问http://localhost:8080/WebDemo/print02

  • 为了解决页面中文乱码问题,要修改代码

  • 重启tomcat服务器,访问http://localhost:8080/WebDemo/print02

五、HttpServletResponse应用

(一)实现请求重定向

  • 目标:掌握HttpServletResponse接口的sendRedirect()方法,实现请求重定向
    在某些情况下,针对客户端的请求,一个Servlet类可能无法完成全部工作。这时,可以使用请求重定向来完成。所谓请求重定向,指的是Web服务器接收到客户端的请求后,可能由于某些条件限制,不能访问当前请求URL所指向的Web资源,而是指定了一个新的资源路径,让客户端重新发送请求。

1、HttpServletResponse接口—sendRedirect()方法

  • 为了实现请求重定向,HttpServletResponse接口定义了一个sendRedirect()方法,该方法用于生成302响应码和Location响应头,从而通知客户端重新访问Location响应头中指定的URL。
    sendRedirect()方法的完整声明:public void sendRedirect(java.lang.String location) throws java.io.IOException
  • 需要注意的是,参数location可以使用相对URL,Web服务器会自动将相对URL翻译成绝对URL,再生成Location头字段。
  • sendRedirect()方法的工作原理

2、案例演示实现请求重定向

  • 创建登录页面 - login.html
<!DOCTYPE html>
<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>用户登录</title></head><body><form action="login" method="post"><fieldset><legend>用户登录</legend><table cellpadding="2" align="center"><tr><td align="right">用户名:</td><td><input type="text" name="username"/></td></tr><tr><td align="right">密码:</td><td><input type="password" name="password"/></td></tr><tr><td colspan="2" align="center"><input type="submit" value="登录"/><input type="reset" value="重置"/></td></tr></table></fieldset></form></body>
</html>
  • 创建欢迎页面 - welcome.html
<!DOCTYPE html>
<html lang="en"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>登录成功</title></head><body><h3 style="text-align: center">欢迎你,登录成功~</h3></body>
</html>
  • 在net.xyx.response包里创建LoginServlet类,处理用户登录请求
package net.xyx.response;import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;/*** 功能:登录处理程序* 作者:xyx* 日期:2023年04月07日*/
@WebServlet(name = "LoginServlet", urlPatterns = "/login")
public class LoginServlet extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {// 设置响应体内容类型response.setContentType("text/html; charset=utf-8");// 获取登录表单提交的用户名和密码String username = request.getParameter("username");String password = request.getParameter("password");// 判断是否登录成功,决定重定向到不同页面if ("howard".equals(username) && "903213".equals(password)) {// 重定向到欢迎页面response.sendRedirect("/WebDemo/welcome.html");} else {// 重定向到登录页面response.sendRedirect("/WebDemo/login.html");}}protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doPost(request, response);}
}
  • 重启tomcat服务器,访问http://localhost:8080/WebDemo/login.html

  • 在login.html页面填写用户名“howard”,密码“903213”

  • 单击登录按钮,跳转到欢迎页面

  • 录屏操作演示

(二)动手实践:解决中文输出乱码问题

  • 目标:掌握如何解决中文输出乱码问题

1、中文乱码问题

  • 由于计算机中的数据都是以二进制形式存储的,所以,当传输文本时,就会发生字符和字节之间的转换。字符与字节之间的转换是通过查码表完成的,将字符转换成字节的过程称为编码,将字节转换成字符的过程称为解码,如果编码和解码使用的码表不一致,就会导致乱码问题。

2、案例演示解决乱码问题

在net.xyx.response包里创建ChineseServlet

package net.xyx.response;import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;/*** 功能:演示解决中文乱码问题* 作者:xyx* 日期:2023年03月13日*/
@WebServlet(name = "ChineseServlet", urlPatterns = "/chinese")
public class ChineseServlet extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {        // 创建数据字符串String data = "欢迎访问泸州职业技术学院~";// 获取打印字符输出流PrintWriter out = response.getWriter();// 在页面输出信息out.println(data);        }protected void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {doPost(request, response);}
}```
- 重启tomcat服务器,访问`http://localhost:8080/WebDemo/chinese`
![在这里插入图片描述](https://img-blog.csdnimg.cn/3753008021754cc7920353c6cc2bf59c.png)- 浏览器显示的内容都是“???~”,说明发生了乱码问题。此处产生乱码的原因是response对象的字符输出流在编码时,采用的是ISO-8859-1的字符码表,该码表并不兼容中文,会将“欢迎访问泸州职业技术学院”编码为“63 63 63 63 63 63 63 63 63 63 63 63”(在ISO-8859-1的码表中查不到的字符就会显示63)。当浏览器对接收到的数据进行解码时,会采用默认的码表GB2312,将“63 ”解码为“?”,因此,浏览器将“欢迎访问泸州职业技术学院”十二个字符显示成了“???”。- 解决页面乱码问题- `HttpServletResponse`接口提供了一个`setCharacterEncoding()`方法,该方法用于设置字符的编码方式,接下来对`ChineseServlet`类进行修改,在代码String data = "欢迎访问泸州职业技术学院~";前增加一行代码,设置字符编码使用的码表为utf-8。
![在这里插入图片描述](https://img-blog.csdnimg.cn/32a6839c1db04258ab530e61cfaf0016.png)- 重启tomcat服务器,访问`http://localhost:8080/WebDemo/chinese`![在这里插入图片描述](https://img-blog.csdnimg.cn/48e9a1a0e1f546668a6d10a43571a91e.png)- 浏览器中显示的乱码虽然不是`“????????????~`”,但也不是需要输出的“欢迎访问泸州职业技术学院~”,这是由于浏览器解码错误导致的。`response`对象的字符输出流设置的编码方式为UTF-8,而浏览器使用的解码方式是GBK。
![在这里插入图片描述](https://img-blog.csdnimg.cn/add083a55c9e4b7aa610a2d40b99db2d.png)- 将`response`对象的字符输出流设置的编码方式改为GBK
![在这里插入图片描述](https://img-blog.csdnimg.cn/840004418f7445d8aa98e20b05f76f9d.png)- 重启tomcat服务器,访问`http://localhost:8080/WebDemo/chinese`
![在这里插入图片描述](https://img-blog.csdnimg.cn/4e1e71fe15cf45478753ea9452820329.png)- 一种更好的方法来解决页面中文乱码问题,直接要求浏览器按照某种字符编码来显示中文
![在这里插入图片描述](https://img-blog.csdnimg.cn/14e0758fdc5845a9b6e78c6496bbeeb0.png)`response.setContentType("text/html;charset=utf-8")`;让浏览器采用utf-8字符编码- 重启tomcat服务器,访问`http://localhost:8080/WebDemo/chinese`
![在这里插入图片描述](https://img-blog.csdnimg.cn/444bdde3831445ea904f78df7f79a7e0.png)- 当然也可以换种方式来解决
```xml
// 设置HttpServletResponse使用utf-8编码
response.setCharacterEncoding("utf-8"); 
// 通知浏览器使用utf-8解码
response.setHeader("Content-Type", "text/html;charset=utf-8"); 

六、HttpServletRequest对象

(一)获取请求行信息的相关方法

  • 目标:掌握使用HttpServletRequest接口中的方法获取请求行

1、相关方法

方法声明功能描述
String getMethod( )该方法用于获取HTTP请求消息中的请求方式(如GET、POST等)
String getRequestURI( )该方法用于获取请求行中资源名称部分,即位于URL的主机和端口之后、参数部分之前的数据
String getQueryString( )该方法用于获取请求行中的参数部分,也就是资源路径后面问号(?)以后的所有内容
String getProtocol( )该方法用于获取请求行中的协议名和版本,例如HTTP/1.0或HTTP/1.1
String getContextPath( )该方法用于获取请求URL中属于Web应用程序的路径,这个路径以“/”开头,表示相对于整个Web站点的根目录,路径结尾不含“/”。如果请求URL属于Web站点的根目录,那么返回结果为空字符串(“”)
String getServletPath( )该方法用于获取Servlet的名称或Servlet所映射的路径
String getRemoteAddr( )该方法用于获取请求客户端的IP地址,其格式类似于“192.168.0.3”
String getRemoteHost( )该方法用于获取请求客户端的完整主机名,其格式类似于“pc1.itcast.cn”。需要注意的是,如果无法解析出客户机的完整主机名,该方法将会返回客户端的IP地址
int getRemotePort()该方法用于获取请求客户端网络连接的端口号
String getLocalAddr()该方法用于获取Web服务器上接收当前请求网络连接的IP地址
String getLocalName()该方法用于获取Web服务器上接收当前网络连接IP所对应的主机名
int getLocalPort()该方法用于获取Web服务器上接收当前网络连接的端口号
String getServerName()该方法用于获取当前请求所指向的主机名,即HTTP请求消息中Host头字段所对应的主机名部分
int getServerPort()该方法用于获取当前请求所连接的服务器端口号,即如果HTTP请求消息中Host头字段所对应的端口号部分
String getScheme()该方法用于获取请求的协议名,例如http、https或ftp
StringBuffer getRequestURL()该方法用于获取客户端发出请求时的完整URL,包括协议、服务器名、端口号、资源路径等信息,但不包括后面的查询参数部分。注意,getRequestURL()方法返回的结果是StringBuffer类型,而不是String类型,这样更便于对结果进行修改

2、案例演示

创建net.xyx.request包,在包里创建RequestLineServlet

package net.xyx.request;import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;/*** 功能:输出请求行的相关信息* 作者:xyx* 日期:2023年03月13日*/
@WebServlet(name = "RequestLineServlet", urlPatterns = "/request")
public class RequestLineServlet extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {// 设置响应体内容类型response.setContentType("text/html;charset=utf-8");// 获取字符输出流PrintWriter out = response.getWriter();// 获取并输出请求行的相关信息out.println("getMethod: " + request.getMethod() + "<br />");out.println("getRequestURI: " + request.getRequestURI() + "<br />");out.println("getQueryString: " + request.getQueryString() + "<br />");out.println("getProtocol: " + request.getProtocol() + "<br />");out.println("getContextPath: " + request.getContextPath() + "<br />");out.println("getPathInfo: " + request.getPathInfo() + "<br />");out.println("getPathTranslated: " + request.getPathTranslated() + "<br />");out.println("getServletPath: " + request.getServletPath() + "<br />");out.println("getRemoteAddr: " + request.getRemoteAddr() + "<br />");out.println("getRemoteHost: " + request.getRemoteHost() + "<br />");out.println("getRemotePort: " + request.getRemotePort() + "<br />");out.println("getLocalAddr: " + request.getLocalAddr() + "<br />");out.println("getLocalName: " + request.getLocalName() + "<br />");out.println("getLocalPort: " + request.getLocalPort() + "<br />");out.println("getServerName: " + request.getServerName() + "<br />");out.println("getServerPort: " + request.getServerPort() + "<br />");out.println("getScheme: " + request.getScheme() + "<br />");out.println("getRequestURL: " + request.getRequestURL() + "<br />");}protected void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {doPost(request, response);}
}
  • 重启tomcat服务器,访问http://localhost:8080/WebDemo/request
    在这里插入图片描述

  • getContextPath: /WebDemo + getServletPath: /request = getRequestURI: /WebDemo/request

  • getScheme: http + “:” + getServerName: localhost + “:” + getServerPort: 8080 + getRequestURI: /WebDemo/request = getRequestURL: - - -http://localhost:8080/WebDemo/request

  • URI: Uniform Resource Identifier 统一资源标识符

  • URL: Uniform Resource Locator 统一资源定位器
    演示请求字符串
    在这里插入图片描述

package net.xyx.request;import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;/*** 功能:输出请求行的相关信息* 作者:xyx* 日期:2023年04月14日*/
@WebServlet(name = "RequestLineServlet", urlPatterns = "/request")
public class RequestLineServlet extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {// 设置响应体内容类型response.setContentType("text/html; charset=utf-8");// 获取字符输出流PrintWriter out = response.getWriter();// 获取并输出请求行的相关信息out.println("getMethod: " + request.getMethod() + "<br />");out.println("getRequestURI: " + request.getRequestURI() + "<br />");out.println("getQueryString: " + request.getQueryString() + "<br />");out.println("getProtocol: " + request.getProtocol() + "<br />");out.println("getContextPath: " + request.getContextPath() + "<br />");out.println("getPathInfo: " + request.getPathInfo() + "<br />");out.println("getPathTranslated: " + request.getPathTranslated() + "<br />");out.println("getServletPath: " + request.getServletPath() + "<br />");out.println("getRemoteAddr: " + request.getRemoteAddr() + "<br />");out.println("getRemoteHost: " + request.getRemoteHost() + "<br />");out.println("getRemotePort: " + request.getRemotePort() + "<br />");out.println("getLocalAddr: " + request.getLocalAddr() + "<br />");out.println("getLocalName: " + request.getLocalName() + "<br />");out.println("getLocalPort: " + request.getLocalPort() + "<br />");out.println("getServerName: " + request.getServerName() + "<br />");out.println("getServerPort: " + request.getServerPort() + "<br />");out.println("getScheme: " + request.getScheme() + "<br />");out.println("getRequestURL: " + request.getRequestURL() + "<br />");// 在控制台输出请求字符串的信息if (request.getQueryString() != null) {String strQuery = request.getQueryString();String[] queries = strQuery.split("&");for (String query : queries) {String[] fields = query.split("=");System.out.println(fields[0] + " : " + fields[1]);}}}protected void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {doPost(request, response);}
}
  • 重启tomcat服务器,访问http://localhost:8080/WebDemo/request?username=howard&password=903213
    在这里插入图片描述

还可以将查询字符串继续按=进行拆分
在这里插入图片描述

(二)获取请求头的相关方法

  • 目标:掌握使用HttpServletRequest接口获取HTTP请求头字段的方法

1、相关方法

方法声明功能描述
String getHeader(String name)该方法用于获取一个指定头字段的值,如果请求消息中没有包含指定的头字段,getHeader()方法返回null;如果请求消息中包含有多个指定名称的头字段,getHeader()方法返回其中第一个头字段的值
Enumeration getHeaders(String name)该方法返回一个Enumeration集合对象,该集合对象由请求消息中出现的某个指定名称的所有头字段值组成。在多数情况下,一个头字段名在请求消息中只出现一次,但有时候可能会出现多次
Enumeration getHeaderNames()该方法用于获取一个包含所有请求头字段的Enumeration对象
int getIntHeader(String name)该方法用于获取指定名称的头字段,并且将其值转为int类型。需要注意的是,如果指定名称的头字段不存在,返回值为-1;如果获取到的头字段的值不能转为int类型,将发生NumberFormatException异常
long getDateHeader(String name)该方法用于获取指定头字段的值,并将其按GMT时间格式转换成一个代表日期/时间的长整数,这个长整数是自1970年1月1日0点0分0秒算起的以毫秒为单位的时间值
String getContentType() 该方法用于获取Content-Type头字段的值,结果为String类型
int getContentLength()
String getCharacterEncoding()该方法用于返回请求消息的实体部分的字符集编码,通常是从Content-Type头字段中进行提取,结果为String类型

2、案例演示

  • 在net.xyx.request包里创建RequestHeadersServlet
package net.xyx.request;import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;/*** 功能:演示获取请求头的信息* 作者:xyx* 日期:2023年04月14日*/
@WebServlet(name = "RequestHeaderServlet", urlPatterns = "/header")
public class RequestHeaderServlet extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {// 设置响应体内容类型response.setContentType("text/html; charset=utf-8");// 获取字符输出流PrintWriter out = response.getWriter();// 获取请求头名枚举对象Enumeration<String> headerNames = request.getHeaderNames();// 遍历所有请求头,并通过getHeader()方法获取一个指定名称的头字段while (headerNames.hasMoreElements()) {// 获取头字段名称String headerName = headerNames.nextElement();// 输出头字段名称及其值out.println(headerName + " : " + request.getHeader(headerName) + "<br />");}}protected void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {doPost(request, response);}
}
  • 重启tomcat服务器,访问http://localhost:8080/WebDemo/header
    在这里插入图片描述

  • 按F12键,通过开发者工具查看请求头信息
    在这里插入图片描述

(三)请求转发

  • 目标:掌握使用HttpServletRequest接口将请求转发

1、getRequestDispatcher()方法

  • Servlet之间可以相互跳转,利用Servlet的跳转可以很容易地把一项任务按模块分开,例如,使用一个Servlet实现用户登录,然后跳转到另外一个Servlet实现用户资料修改。Servlet的跳转要通过RequestDispatcher接口的实例对象实现。HttpServletRequest接口提供了getRequestDispatcher()方法用于获取RequestDispatcher对象,getRequestDispatcher()方法的具体格式: RequestDispatcher getRequestDispatcher(String path)
  • getRequestDispatcher()方法返回封装了某条路径所指定资源的RequestDispatcher对象。其中,参数 path 必须以“/”开头,用于表示当前 Web 应用的根目录。需要注意的是,WEB-INF目录中的内容对RequestDispatcher对象也是可见的。因此,传递给getRequestDispatcher(String path)方法的资源可以是 WEB-INF 目录中的文件。

2、forward()方法

  • 获取到RequestDispatcher对象后,如果当前 Web 资源不想处理请求,RequestDispatcher接口提供了一个forward()方法,该方法可以将当前请求传递给其他 Web 资源对这些信息进行处理并响应给客户端,这种方式称为请求转发。forward()方法的具体格式:forward(ServletRequest request,ServletResponse response)
  • forward()方法用于将请求从一个 Servlet 传递给另一个 Web 资源。在 Servlet 中,可以对请求做一个初步处理,然后通过调用forward()方法,将请求传递给其他资源进行响应。需要注意的是,该方法必须在响应提交给客户端之前被调用,否则将抛出IllegalStateException异常。
    当浏览器访问Servlet1时,可以通过forward()方法将请求转发给其他Web资源,其他Web资源处理完请求后,直接将响应结果返回到浏览器。

3、案例演示请求转发

在net.xyx.request包里创建RequestForwardServlet类,将数据保存在request对象里,然后转发给另一个Servlet来处理

package net.xyx.request;import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;/*** 功能:演示请求转发* 作者:xyx* 日期:2023年03月13日*/
@WebServlet(name = "RequestForwardServlet", urlPatterns = "/forward")
public class RequestForwardServlet extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {// 设置响应体内容类型response.setContentType("text/html;charset=utf-8");// 设置请求对象属性request.setAttribute("message", "欢迎访问泸州职业技术学院~");// 获取请求派发器对象(参数是请求转发的Servlet的url)RequestDispatcher dispatcher = request.getRequestDispatcher("/result");// 请求转发给url为`/result`的Servletdispatcher.forward(request, response);}protected void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {doPost(request, response);}
}

在net.xyx.request包里创建ResultServlet类,用于获取RequestForwardServlet类中存储在request对象中的数据并输出

package net.xyx.request;import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;/*** 功能:处理转发的请求* 作者:xyx* 日期:2023年03月13日*/
@WebServlet(name = "ResultServlet", urlPatterns = "/result")
public class ResultServlet extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {// 设置响应体内容类型response.setContentType("text/html;charset=utf-8");// 获取字符输出流PrintWriter out = response.getWriter();// 获取请求转发保存在request对象里的数据String message = (String) request.getAttribute("message");// 输出获取的信息if (message != null) {out.println("转发来的消息:" + message);}}protected void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {doPost(request, response);}
}

对应关系图

重启tomcat服务器,访问http://localhost:8080/WebDemo/forward

注意:地址栏中显示的仍然是RequestForwardServlet的请求路径,但是浏览器却显示出了ResultServlet中要输出的内容。这是因为请求转发是发生在服务器内部的行为,从RequestForwardServlet到ResultServlet属于一次请求,在一次请求中可以使用request 属性进行数据共享(同一请求转发)。

(四)获取请求参数
目标:掌握使用HttpServletRequest接口获取请求参数
1、相关方法
方法声明 功能描述
String getParameter(String name) 该方法用于获取某个指定名称的参数值,如果请求消息中没有包含指定名称的参数,getParameter()方法返回null;如果指定名称的参数存在但没有设置值,则返回一个空串;如果请求消息中包含有多个该指定名称的参数,getParameter()方法返回第一个出现的参数值
String[] getParameterValues(String name) 该方法用于返回一个String类型的数组,HTTP请求消息中可以有多个相同名称的参数(通常由一个包含有多个同名的字段元素的form表单生成),如果要获得HTTP请求消息中的同一个参数名所对应的所有参数值,那么就应该使用getParameterValues()方法
Enumeration getParameterNames() 该方法用于返回一个包含请求消息中所有参数名的Enumeration对象,在此基础上,可以对请求消息中的所有参数进行遍历处理
Map getParameterMap() 该方法用于将请求消息中的所有参数名和值装入进一个Map对象中返回
2、案例演示
创建注册页面 - register.html

用户注册 新用户注册
用户名:
密码:
性别: 男 女
兴趣: 看电影 敲代码 玩游戏

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

  • 在net.xyx.request包里创建RquestParamsServlet类,用于获取注册表单提交的数据
package net.xyx.request;import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;/*** 功能:获取请求参数* 作者:XYX* 日期:2023年04月14日*/
@WebServlet(name = "RequestParamsServlet", urlPatterns = "/register")
public class RequestParamsServlet extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {       // 设置响应体内容类型response.setContentType("text/html; charset=utf-8");// 获取字符输出流PrintWriter out = response.getWriter();// 获取注册表单提交的数据String username = request.getParameter("username");String password = request.getParameter("password");String gender = request.getParameter("gender");String[] interests = request.getParameterValues("interest");// 输出获取的表单数据out.println("姓名:" + username + "<br />");out.println("密码:" + password + "<br />");out.println("性别:" + gender + "<br />");out.print("兴趣:");for (int i = 0; i < interests.length; i++) {out.println(interests[i]);}}protected void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {doPost(request, response);}
}

对应关系图

在这里插入图片描述

重启tomcat服务器,访问http://localhost:8080/WebDemo/register.html,填写表单数据
在这里插入图片描述

单击【注册】按钮
在这里插入图片描述

(五)解决请求参数中文乱码问题

  • 目标:掌握如何解决请求参数的中文乱码

  • HttpServletRequest接口中,提供了一个setCharacterEncoding()方法,该方法用于设置request对象的解码方式

  • 修改ResquestParamsServlet类,添加一行代码,设置请求对象的字符编码
    在这里插入图片描述

  • 重启tomcat服务器,访问http://localhost:8080/WebDemo/register.html,填写表单数据
    在这里插入图片描述

  • 单击【注册】按钮,页面没有中文乱码
    录屏演示注册操作

(六)通过Request对象传递数据

  • 目标:掌握使用ServletRequest接口操作属性

1、Request对象操作属性的方法

(1)setAttribute()方法

  • setAttribute()方法用于将一个对象与一个name关联后存储进ServletRequest对象中,其完整声明:public void setAttribute(String name,Object o);
    setAttribute()方法的参数列表的第一个参数接收的是一个String类型的name,第二个参数接收的是一个Object类型的对象o。需要注意的是,如果ServletRequest对象中已经存在指定名称的属性,setAttribute()方法将会先删除原来的属性,然后再添加新的属性。如果传递给setAttribute()方法的属性值对象为null,则删除指定名称的属性,这时的效果等同于removeAttribute()方法。

(2)getAttribute()方法

  • getAttribute()方法用于从ServletRequest对象中返回指定名称的属性对象,其完整声明:public Object getAttribute(String name);

(3)removeAttribute()方法

  • removeAttribute()方法用于从ServletRequest对象中删除指定名称的属性,其完整声明:public void removeAttribute(String name);

(4)getAttributeNames()方法

  • getAttributeNames()方法用于返回一个包含ServletRequest对象中的所有属性名的Enumeration对象,在此基础上,可以对ServletRequest对象中的所有属性进行遍历处理。其完整声明:public Enumeration getAttributeNames();
    需要注意,只有属于同一个请求中的数据才可以通过ServletRequest对象传递数据。

2、案例演示通过Request对象传递数据

在net.xyx.request包里创建RquestServlet01

package net.xyx.request;import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;/*** 功能:设置请求对象属性,请求转发* 作者:xyx* 日期:2023年04月14日*/
@WebServlet(name = "RequestServlet01", urlPatterns = "/request01")
public class RequestServlet01 extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {// 设置响应体内容类型response.setContentType("text/html; charset=utf-8");// 设置请求对象属性request.setAttribute("id", "20210201");request.setAttribute("name", "陈燕文");request.setAttribute("gender", "女");request.setAttribute("age", "18");request.setAttribute("major", "软件技术专业");request.setAttribute("class", "2021级软件2班");request.setAttribute("phone", "15890903456");// 获取请求派发器对象(参数是请求转发的Servlet的url)RequestDispatcher dispatcher = request.getRequestDispatcher("/request02");// 请求转发给url为`/request02`的Servletdispatcher.forward(request, response);}protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doPost(request, response);}
}
  • net.xyx.request包里创建RquestServlet02
package net.xyx.request;import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;/*** 功能:获取请求转发的数据* 作者:xyx* 日期:2023年04月14日*/
@WebServlet(name = "RequestServlet02", urlPatterns = "/request02")
public class RequestServlet02 extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {// 设置响应体内容类型response.setContentType("text/html; charset=utf-8");// 获取字符输出流PrintWriter out = response.getWriter();// 获取请求对象属性名枚举对象Enumeration<String> attributes = request.getAttributeNames();// 获取请求转发保存在request对象里的数据并输出while (attributes.hasMoreElements()) {// 获取属性名String attribute = attributes.nextElement();// 输出属性名及其值out.println(attribute + " : " + request.getAttribute(attribute) + "<br />");}// 删除请求对象的属性while (attributes.hasMoreElements()) {// 获取属性名String attribute = attributes.nextElement();// 删除属性request.removeAttribute(attribute);}}protected void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {doPost(request, response);}
}
  • 启动服务器,访问http://localhost:8080/WebDemo/request01
    在这里插入图片描述

  • 修改RequestServlet02,只显示学生信息

package net.huawei.request;import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;/*** 功能:获取请求转发的数据* 作者:xyx* 日期:2023年04月14日*/
@WebServlet(name = "RequestServlet02", urlPatterns = "/request02")
public class RequestServlet02 extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {// 设置响应体内容类型response.setContentType("text/html; charset=utf-8");// 获取字符输出流PrintWriter out = response.getWriter();// 获取请求转发保存在request对象里的数据并输出out.println("学号:" + request.getAttribute("id") + "<br />");out.println("姓名:" + request.getAttribute("name") + "<br />");out.println("性别:" + request.getAttribute("gender") + "<br />");out.println("年龄:" + request.getAttribute("age") + "<br />");out.println("专业:" + request.getAttribute("major") + "<br />");out.println("班级:" + request.getAttribute("class") + "<br />");out.println("手机:" + request.getAttribute("phone") + "<br />");// 删除请求对象的属性request.removeAttribute("id");request.removeAttribute("name");request.removeAttribute("gender");request.removeAttribute("age");request.removeAttribute("major");request.removeAttribute("class");request.removeAttribute("phone");}protected void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {doPost(request, response);}
}
  • 启动服务器,访问http://localhost:8080/WebDemo/request01

相关文章:

动态网站Servelt基础

文章目录 一、Servlet基础&#xff08;一&#xff09;Servlet概述1、Servlet是什么2、Servlet容器3、Servlet应用程序的体系结构 &#xff08;二&#xff09;Servlet的特点1、功能强大2、可移植3、性能高效4、安全性高5、可扩展 &#xff08;三&#xff09;Servlet接口1、Servl…...

Docker 网络

Docker 网络实现原理 Docker使用Linux桥接&#xff0c;在宿主机虚拟一个Docker容器网桥(docker0)&#xff0c;Docker启动一个容器时会根据Docker网桥的网段分配给容器一个IP地址&#xff0c;称为Container-IP&#xff0c;同时Docker网桥是每个容器的默认网关。因为在同一宿主机…...

Tomcat的优化

Tomcat的优化 一、Tomcat 优化Tomcat 配置文件参数优化 二、系统内核优化三、Tomcat 配置 JVM 参数&#xff1a;参数含义 一、Tomcat 优化 Tomcat默认安装下的缺省配置并不适合生产环境&#xff0c;它可能会频繁出现假死现象需要重启&#xff0c;只有通过不断压测优化才能让它…...

一个问题来对比文心一言和chatgpt

问题&#xff1a; 请注意&#xff0c; 孩子不会说话&#xff0c;他无法用语言来回复妈妈的问题&#xff0c; 请生成以下剧本&#xff1a;一个妈妈和一岁不会说话的婴儿的日常vlog的剧本 文心一言 场景一&#xff1a;早晨 &#xff08;妈妈和孩子在客厅里醒来&#xff09; 妈妈&…...

防雪崩利器之Hystrix

Hystrix作为一个容错组件&#xff0c;本文从它的作用、熔断设计、工作流程和应用方面一一道来&#xff0c;帮助大家了解如何使用。 1、什么是灾难性雪崩效应 要讲Hystrix&#xff0c;我们就要讲一种场景&#xff0c;在微服务架构中&#xff0c;如果底层服务出现故障&#xff0…...

机器学习复习(上)

严正声明&#xff1a;本文的答案是ChatGPT的回答&#xff0c;仅供参考&#xff0c;不代表就是正确答案&#xff01;&#xff01;&#xff01; 1.解释什么是过拟合和欠拟合&#xff0c;如何降低过拟合? 过拟合&#xff08;overfitting&#xff09;指的是一个模型在训练数据上表…...

node笔记_express结合formidable实现前后端的文件上传

文章目录 ⭐前言⭐安装http请求的文件解析依赖库&#x1f496; 安装 formidable&#x1f496; node formidable接受formData上传参数 ⭐上传的页面搭建&#x1f496; vue2 element upload&#x1f496; node 渲染 上传文件 ⭐后端生成api上传文件到指定目录&#x1f496;完整的…...

CKA 09_Kubernetes工作负载与调度 资源调度 三类QoS request 资源需求 limit 资源限额

文章目录 1. 资源调度1.1 准备工作1.2 为什么需要 request 和 limit1.3 内存限制1.3.1 Brustable1.3.2 Guaranteed1.3.3 BestEffort1.3.4 当容器申请的资源超出 limit 和 request 1.4 CPU限制 1. 资源调度 1.1 准备工作 Kubernetes 采用 request 和 limit 两种限制类型来对资源…...

【pytorch】维度变换

【pytorch】维度变换 View操作unSqueeze操作图片处理的一个案例squeeze 维度删减操作维度扩展-expand维度扩展-repeat矩阵的转置操作-transpose View操作 将一个四维的张量&#xff08;b x c x h x w&#xff09;转换成一个二维的张量 对于四张图片 将每一张图像用一行向量进…...

vue3中的nextTick()

目录 nextTick() 方法用法回调函数方式使用await方式使用 实现原理使用nextTick() 方法时的注意事项 nextTick() 方法 nextTick() 方法是一个非常强大的工具&#xff0c;是一个等待下一次 DOM 更新刷新的工具方法。用于将一个函数以异步的方式推迟到下一个 DOM 更新周期执行。…...

高效学习传感器|霍尔式传感器

01、霍尔式传感器的工作原理 1●霍尔效应 霍尔式传感器的物理基础是霍尔效应。如图1所示&#xff0c;在一块长度为l、宽度为b、厚度为d的长方体导电板上&#xff0c;左、右、前、后侧面都安装上电极。在长度方向上通入电流I&#xff0c;在厚度方向施加磁感应强度为B的磁场。 ■…...

2023年前端面试高频考点HTML5+CSS3

目录 浏览器的渲染过程⭐⭐⭐ CSS 、JS 阻塞 DOM 解析和渲染 回流&#xff08;重排&#xff09;和重绘⭐⭐ 选择器 ID选择器、类选择器、标签选择器&#xff08;按优先级高到低排序&#xff09;⭐⭐ 特殊符号选择器&#xff08;&#xff1e;,,~&#xff0c;空格&#xff0…...

企业开源测试项目实战(附全套实战项目教程+视频+源码)

接口测试项目 1. No matching distribution found for itypes1.1.0 Could not find a version that satisfies the requirement itypes1.1.0 (from -r requirements.txt (line 8)) (from versions: ) No matching distribution found for itypes1.1.0 (from -r requirements.…...

信创办公–基于WPS的EXCEL最佳实践系列 (创建表格)

信创办公–基于WPS的EXCEL最佳实践系列 &#xff08;创建表格&#xff09; 目录 应用背景操作步骤1、新建空白工作簿并命名为“奖牌榜”2、使用模板新建工作簿3、新增一张工作表&#xff0c;并将工作簿的标签更改为红色4、复制与隐藏工作表5、添加工作簿属性值6、更改工作簿主题…...

四、HAL_驱动机械按键

1、开发环境。 (1)KeilMDK&#xff1a;V5.38.0.0 (2)STM32CubeMX&#xff1a;V6.8.1 (3)MCU&#xff1a;STM32F407ZGT6 2、机械按键简介 (1)按键内部是机械结构&#xff0c;也就是内部是没有电路的。按键按下内部引脚导通&#xff0c;松开内部断开。 3、实验目的&原理…...

机器学习实战六步法之数据收集方法(四)

要落地一个机器学习的项目&#xff0c;是有章可循的&#xff0c;通过这六个步骤&#xff0c;小白也能搞定机器学习。 看我闪电六连鞭&#xff01;&#x1f923; 数据收集 数据是机器学习的基础&#xff0c;没有数据一切都是空谈&#xff01;数据集的数据量和数据的质量往往决…...

神经网络:CNN中的filter,kernel_size,strides,padding对输出形状的影响

输入数据在经过卷积层后&#xff0c;形状一般会发生改变&#xff0c;而形状的变化往往与以下四个超参数有关。 1&#xff0c;filter&#xff08;out_channel&#xff09; 该超参数控制着输入数据经过卷积层中需要与几个卷积核进行运算&#xff0c;而输入数据与每个卷积核进行…...

Spring Boot集成Redisson布隆过滤器案例

1 什么是布隆过滤器 布隆过滤器实际上是一个非常长的二进制向量(bitmap)和一系列随机哈希函数。那什么又叫哈希函数呢&#xff1f;哈希函数指将哈希表中元素的关键键值通过一定的函数关系映射为元素存储位置的函数。&#xff08;HashMap源码&#xff09; 布隆过滤器的优点&…...

使用 VSCode SSH 公网远程连接本地服务器开发 - cpolar内网穿透

文章目录 前言视频教程1、安装OpenSSH2、vscode配置ssh3. 局域网测试连接远程服务器4. 公网远程连接4.1 ubuntu安装cpolar内网穿透4.2 创建隧道映射4.3 测试公网远程连接 5. 配置固定TCP端口地址5.1 保留一个固定TCP端口地址5.2 配置固定TCP端口地址5.3 测试固定公网地址远程 转…...

portraiture宿主插件最新v4中文版本下载及使用教程

自拍怎么可以不修图呢&#xff1f;如果要修图的话&#xff0c;磨皮就是其中非常重要的一环。皮肤看起来细腻光滑了&#xff0c;整个人的颜值都会瞬间拉高。下面就让我们介绍一下磨皮用什么软件好用&#xff0c;什么软件可以手动磨皮的相关内容。portraiture是ps人像修图中常用的…...

一. ATR技术指标的定义与运用

一. ATR的定义 1. 什么是ATR ATR英文全名是Average true range&#xff0c;翻译过来就是平均真实波幅&#xff0c;这个指标主要用来衡量最近N天TR(真实波幅)的平均值。 2. ATR相关计算公式 T R [ ( 最高价 − 最低价 ) &#xff0c; ( 前一次收盘价 − 最高价 ) &#xff0…...

linux find帮助文档

以下是完整的find命令帮助文档&#xff1a; 用法&#xff1a;find [-H] [-L] [-P] [-D debugopts] [-Olevel] [起始路径…] [表达式] 选项&#xff1a; -H 跟随命令行符号链接 -L 跟随所有符号链接 -P 不跟随任何符号链接&#xff08;默认&#xff09; -D debugopts 调试标志…...

搜索与图论(acwing算法基础)

文章目录 DFS排列数字n皇后 BFS走迷宫 拓扑序列单链表树与图的深度优先搜索模拟队列有向图的拓扑序列 bellman-ford有边数限制的最短路 spfaspfa求最短路spfa判断负环 FloydFloyd求最短路 PrimPrim算法求最小生成树 KruskalKruskal算法求最小生成树 染色法判定二分图染色法判定…...

【数据结构】何为数据结构。

&#x1f6a9; WRITE IN FRONT &#x1f6a9; &#x1f50e; 介绍&#xff1a;"謓泽"正在路上朝着"攻城狮"方向"前进四" &#x1f50e;&#x1f3c5; 荣誉&#xff1a;2021|2022年度博客之星物联网与嵌入式开发TOP5|TOP4、2021|2022博客之星T…...

【P57】JMeter 保存响应到文件(Save Responses to a file)

文章目录 一、保存响应到文件&#xff08;Save Responses to a file&#xff09;参数说明二、准备工作三、测试计划设计 一、保存响应到文件&#xff08;Save Responses to a file&#xff09;参数说明 可以将结果树保存到文件 使用场景&#xff1a;当结果太大&#xff0c;使…...

Visual Studio 2022 v17.6 正式发布

Visual Studio 17.6 正式发布&#xff0c;这个最新版本提供了一系列强大的工具和功能&#xff0c;旨在使你能够制作出最先进的应用程序。 提高生产力 通过 Visual Studio 2022&#xff0c;目标是帮助你在更短的时间内完成 IDE 内的所有开发任务&#xff0c;在这个版本中&…...

std::chrono时间处理

std::chrono是C11引入的标准库&#xff0c;用于时间的计算和处理。它按照ISO8601标准定义了多个时间类&#xff0c;例如&#xff1a;duration&#xff08;持续时间&#xff09;、time_point&#xff08;时间点&#xff09;和clock&#xff08;时钟&#xff09;。以下是一些常见…...

ieda codeformatV2.xml

ieda codeformatV2.xml 目录概述需求&#xff1a; 设计思路实现思路分析1.codeformatV22.codeformatV23.codeformatV24.codeformatV25.数据处理器 拓展实现 参考资料和推荐阅读 Survive by day and develop by night. talk for import biz , show your perfect code,full busy&…...

Hbase

java客户端 导入maven依赖 XML<dependencies> <dependency> <groupId>org.apache.zookeeper</groupId> <artifactId>zookeeper</artifactId> <version>3.4.6</version> </dependency>…...

[golang 微服务] 5. 微服务服务发现介绍,安装以及consul的使用,Consul集群

一.服务发现介绍 引入 上一节讲解了使用 gRPC创建微服务,客户端的一个接口可能需要调用 N个服务,而不同服务可能存在 不同的服务器,这时&#xff0c;客户端就必须知道所有服务的 网络位置&#xff08;ipport&#xff09;&#xff0c;来进行连接服务器操作,如下图所示: 以往的做…...

dedecms 做电商网站/谷歌浏览器下载官网

最近在学习微信小程序&#xff08;重新学习微信小程序&#xff09;&#xff0c;在设计首页布局的时候&#xff0c;新认识了一种布局方式display:flex 1 .guide-top{2 height: 36%;3 display: flex; /*flex弹性布局*/4 flex-direction: column; /*排列方向…...

网站建设方案项目书/小红书seo软件

一、是什么 在以前文章 (opens new window)中,我们了解到生命周期定义 生命周期(Life Cycle)的概念应用很广泛,特别是在经济、环境、技术、社会等诸多领域经常出现,其基本涵义可以通俗地理解为“从摇篮到坟墓”(Cradle-to-Grave)的整个过程 跟Vue一样,React整个组件…...

济南市建设工程招标网官网/开封网站seo

解决H5页面在安卓Android系统上软键盘顶起布局问题参考文章&#xff1a; &#xff08;1&#xff09;解决H5页面在安卓Android系统上软键盘顶起布局问题 &#xff08;2&#xff09;http://www.cnblogs.com/xiongyilin/p/9235116.html 备忘一下。...

小网站开发用哪些技术/免费网页模板网站

jsoup爬虫技术精通面向云的开发人员是否需要以人为本以及以技术为导向&#xff1f; 根据Devops Institute的最新报告&#xff0c;情况似乎确实如此。 在招聘方面&#xff0c;该研究发现&#xff0c;企业在寻找软技能和寻找技术技能方面具有平等的平衡。 这种理想的平衡既可以从…...

怎么做网站扫描/百度扫一扫识别图片在线

电脑垃圾如果能够清理得好&#xff0c;能很大程度上延缓电脑“老去”的时间。相同的电脑&#xff0c;有的人用几年还是很流畅&#xff0c;有些人刚用了三个月就变卡变慢了。这其中的影响因素有很多&#xff0c;电脑垃圾算是一种最容易解决的影响因素。电脑垃圾如果能够清理得好…...

公司变更股东要交税吗/北京seo顾问服务

在上周的 Vue.js 伦敦大会上&#xff0c;Vue.js 作者尤雨溪简要介绍了 Vue 下一个主要版本要发布的内容&#xff0c;9 月 30 日&#xff0c;尤雨溪在 medium 个人博客上发布了 Vue 3.0 的开发路线&#xff0c;我们不妨看看 Vue 3.0 将会有怎样的发展。 兼容 按照尤雨溪的说法…...