Java Web程序设计学习笔记

Java Web学习程序设计笔记

作者email:yihang_0913@qq.com

定稿时间:2023年5月21日15:33:39

目 录

文章目录

0. Java Web 基础知识

Java Web是指使用Java语言编写Web应用程序的技术和框架。Java Web应用程序通常由Servlet、JSP、JavaBean、JavaServer Pages Standard Tag Library (JSTL)、JavaServer Faces (JSF)、Enterprise JavaBean (EJB)、Java Persistence API (JPA)、Spring Framework等技术和框架组合而成。

在Java Web应用程序中,Servlet是最基本的组件,它用于处理HTTP请求和响应。Servlet通常由Java类实现,它们可以通过HTTP协议与客户端进行通信,并生成动态的Web页面。

  1. JSP是JavaServer Pages的简称,它是一种基于标记的技术,允许在Web页面中嵌入Java代码。JSP页面可以包含HTML、CSS、JavaScript等内容,并且可以通过JavaBean和JSTL来访问和处理数据。
  2. JavaBean是一种用于组织和封装数据的Java类,通常用于在Web应用程序中处理表单提交和数据持久化等任务。
  3. JSTL是JavaServer Pages Standard Tag Library的简称,它提供了一组标签和函数,用于简化JSP页面的开发和维护。
  4. JSF是JavaServer Faces的简称,它是一种基于组件的Web框架,提供了一套标准的UI组件和事件处理模型,可以用于构建复杂的Web应用程序。
  5. EJB是Enterprise JavaBean的简称,它是一种用于构建分布式应用程序的Java组件模型,提供了许多服务,例如事务管理、安全性、持久化等。
  6. JPA是Java Persistence API的简称,它是一种用于管理Java对象与关系数据库之间映射的技术,提供了一套标准的API和注解,可以使得Java开发人员更加方便地访问和管理数据库。
  7. Spring Framework是一个基于Java的开源框架,用于构建企业级应用程序。它提供了许多模块,例如IoC容器、AOP、数据访问、Web开发等,可以帮助Java开发人员更加高效地开发和维护Web应用程序。

Java Web技术和框架的发展,使得Java开发人员可以更加方便地构建高效、安全和可扩展的Web应用程序。

0.1. 应用程序模型

应用程序模型是指用于构建应用程序的基本框架和架构。不同的应用程序模型具有不同的特点和应用场景,可以根据应用程序的需求和特点选择合适的模型。

0.1.1. B/S应用程序模型

B/S,即浏览器/服务器,是一种基于Web浏览器和Web服务器的应用程序模型。在B/S模型中,客户端使用Web浏览器作为用户界面,通过Internet或局域网与服务器通信,服务器提供数据和应用逻辑的处理。

8-ARF6-CZE-P-UF-9-BN4-J.png

B/S模型的主要优点包括:

  1. 可跨平台和可移植性:由于Web浏览器是跨平台的,可以在不同的操作系统和设备上运行,因此B/S模型的应用程序可以在不同的平台和设备上运行,具有良好的可移植性。

  2. 可维护性和可扩展性:Web应用程序的所有数据和应用逻辑都存储在服务器上,因此可以集中管理和维护。此外,Web应用程序可以通过添加新的Web页面和Web服务来扩展功能。

  3. 简化部署和升级:Web应用程序的所有组件都存储在服务器上,因此可以通过简单的部署和更新过程来更新应用程序。

  4. 易于远程访问:由于Web浏览器可以通过Internet访问服务器上的Web应用程序,因此B/S模型的应用程序可以在不同的地理位置和设备上访问,具有良好的远程访问性。

  5. 安全性:Web应用程序可以通过HTTPS协议加密数据传输,确保数据的安全性。此外,Web应用程序可以通过身份验证和授权机制来保护资源和数据的安全性。

B/S模型已经成为当今Web应用程序开发的主要模型之一,广泛应用于电子商务、社交网络、在线教育、企业管理等领域。

0.1.2. C/S应用程序模型

C/S,即客户端/服务器,是一种应用程序模型,其中客户端应用程序和服务器应用程序相互通信。在C/S模型中,客户端应用程序通常是本地计算机上的桌面应用程序,而服务器应用程序运行在远程服务器上。

OHIP-01-V-RIO50-D79-U2-S.png

C/S模型的主要优点包括:

  1. 高性能:由于客户端和服务器之间的通信是通过局域网或广域网进行的,因此C/S模型的应用程序具有较高的性能和响应速度。
  2. 可靠性:由于客户端和服务器之间的通信是基于TCP/IP协议进行的,因此C/S模型的应用程序具有良好的可靠性和稳定性。
  3. 功能强大:客户端应用程序通常具有更丰富和更复杂的用户界面和功能,可以提供更好的用户体验和交互性。
  4. 安全性:由于客户端和服务器之间的通信是基于加密和身份验证机制进行的,因此C/S模型的应用程序具有较高的安全性。
  5. 离线操作:由于客户端应用程序可以在本地计算机上运行,因此C/S模型的应用程序可以在离线状态下进行操作。

C/S模型的缺点包括:

  1. 可移植性差:由于客户端应用程序通常是特定于操作系统和设备的,因此C/S模型的应用程序在不同的平台和设备上运行时需要进行适当的修改和调整。
  2. 部署和维护困难:由于客户端应用程序需要在本地计算机上安装和维护,因此C/S模型的应用程序部署和维护成本较高。
  3. 难以远程访问:由于客户端应用程序需要在本地计算机上运行,因此C/S模型的应用程序在远程访问时需要进行适当的配置和管理。

C/S模型通常用于需要高性能和强功能的应用程序,如游戏、图形处理、科学计算等领域。

1. Http协议

HTTP协议(HyperText Transfer Protocol)由三个部分组成:请求部分、响应部分和消息体。

  1. 请求部分:HTTP请求由请求行、请求头和空行三部分组成。请求行包含了请求方法、请求URI和协议版本等信息,请求头包含了请求的附加信息,如Host、User-Agent、Accept等。空行是为了区分请求头和消息体而存在的空行。
  2. 响应部分:HTTP响应由状态行、响应头和空行三部分组成。状态行包含了协议版本、状态码和状态信息等信息,响应头包含了响应的附加信息,如Server、Content-Type、Content-Length等。空行是为了区分响应头和消息体而存在的空行。
  3. 消息体:HTTP消息体是请求和响应的实际内容,可以是文本、二进制数据或其他数据类型。消息体的内容和格式由请求和响应的业务逻辑决定,例如,在HTTP POST请求中,消息体通常包含了要提交的表单数据或上传的文件内容。

1.1. HTTP请求头字段

HTTP请求头字段是HTTP请求中用于描述请求的元数据,它包含了请求的各种信息,如请求方法、请求URI、协议版本、请求头、请求体等。常见的HTTP请求头字段包括:

  1. Host:指定请求的主机名和端口号。
  2. User-Agent:指定发送请求的用户代理程序,如浏览器、爬虫等。
  3. Accept:指定可接受的响应内容类型,如text/html、application/json等。
  4. Accept-Language:指定可接受的响应内容语言,如en-US、zh-CN等。
  5. Accept-Encoding:指定可接受的响应内容编码方式,如gzip、deflate等。
  6. Connection:指定是否保持连接,常见的取值有keep-alive和close。
  7. Referer:指定发送请求的源地址,用于防止CSRF攻击。
  8. Cookie:指定请求中包含的cookie信息。
  9. Authorization:指定请求的授权信息,如Basic认证、Bearer认证等。
  10. Content-Type:指定请求体的内容类型,如application/json、multipart/form-data等。
  11. Content-Length:指定请求体的长度。
  12. If-Modified-Since:指定请求的条件,只有当资源被修改后才返回响应。
  13. Range:指定请求资源的部分内容,用于支持断点续传等功能。

1.2. http响应内容

HTTP响应内容是指Web服务器返回给客户端的HTTP响应报文中的实体部分,它包括HTTP响应头和HTTP响应体两个部分。

HTTP响应头包含了一系列的HTTP头部字段,用于描述响应的元数据信息,例如响应的状态码、内容类型、字符集、缓存控制等。HTTP响应头通常以一行一行的文本形式出现,每行以一个冒号分隔键值对,多行以回车换行符(CRLF)作为分隔符。

HTTP响应体是指HTTP响应报文中的实体部分,它包含了Web服务器返回给客户端的实际内容。HTTP响应体的格式和内容取决于响应的内容类型,例如HTML、CSS、JavaScript、JSON、二进制文件等。HTTP响应体通常以一段二进制数据的形式出现,可以通过HTTP响应头中的Content-Type字段来确定其格式和编码。

客户端可以通过HTTP请求访问Web服务器上的资源,例如HTML页面、图片、视频、API接口等。Web服务器会根据请求的URL和请求头部字段来确定要返回的内容,并将其封装在HTTP响应报文中发送给客户端。客户端收到HTTP响应报文后,会根据HTTP响应头和HTTP响应体来进行相应的处理,例如渲染页面、解析JSON数据、播放视频等。

1.3. HTTP状态码

HTTP状态码是指Web服务器返回给客户端的HTTP响应报文中的状态码部分,它用于描述HTTP请求的处理结果。HTTP状态码由三位数字组成,第一位数字表示响应的类型,后两位数字表示具体的响应状态。

HTTP状态码主要分为以下五类:

  • 1xx(信息性状态码):表示请求已经被接受,需要继续处理。
  • 2xx(成功状态码):表示请求已经被成功处理。
  • 3xx(重定向状态码):表示需要进行进一步的操作,例如重定向到另一个URL。
  • 4xx(客户端错误状态码):表示客户端发送的请求有误,无法被服务器所理解或处理。
  • 5xx(服务器错误状态码):表示服务器在处理请求时发生了错误。

常见的HTTP状态码包括:

  • 200 OK:表示请求成功,服务器已经成功处理了该请求,并返回了响应结果。
  • 301 Moved Permanently:表示请求的资源已经永久移动到了新的URL,客户端应该使用新的URL重新发送请求。
  • 404 Not Found:表示请求的资源不存在,服务器无法找到客户端请求的资源。
  • 500 Internal Server Error:表示服务器在处理请求时发生了未知的错误。

HTTP状态码提供了一种标准化的方式,用于描述HTTP请求的处理结果。客户端可以根据HTTP状态码来判断请求是否成功,并做出相应的处理,例如重试、重定向、提示用户等。Web开发人员也可以根据HTTP状态码来诊断和修复服务器端的错误,提高Web应用程序的稳定性和可靠性。

1.4. 八种HTTP方法(也称为HTTP动词)

HTTP(Hypertext Transfer Protocol)是一种用于传输数据的协议,它定义了浏览器和Web服务器之间的通信规则。HTTP协议定义了八种HTTP方法(也称为HTTP动词),用于描述对Web服务器资源的不同操作。这些HTTP方法包括:

  1. GET:用于获取指定资源的信息,通常用于请求页面、图片、视频、文本等静态内容。
  2. POST:用于向Web服务器提交数据,通常用于提交表单、上传文件等操作。
  3. PUT:用于更新指定资源的信息,通常用于更新文件、图片等静态内容。
  4. DELETE:用于删除指定资源,通常用于删除文件、图片等静态内容。
  5. HEAD:和GET方法类似,但只返回响应头部分,用于获取资源的元数据信息,例如文件大小、修改时间等。
  6. OPTIONS:用于查询Web服务器支持的HTTP方法和功能,通常用于调试和测试Web服务器。
  7. TRACE:用于回显客户端发送的请求,通常用于调试和测试Web服务器。
  8. CONNECT:用于与Web服务器建立一条持久化的TCP连接,通常用于HTTPS加密连接。

2. Tomcat应用

Tomcat是一个基于Java开发的Web服务器和Servlet容器,它实现了Java Servlet、JavaServer Pages (JSP)、Java Expression Language (EL)和WebSocket等Java技术。以下是一些Tomcat的概念和相关知识点:

  1. Servlet容器:Tomcat是一个Servlet容器,它可以加载和执行Java Servlet和JSP等Web组件,提供Web服务和动态内容的生成。
  2. Web应用程序:Tomcat通过Web应用程序(Web Application)来组织和管理Web资源和组件,例如HTML、CSS、JavaScript、Servlet、JSP等文件。每个Web应用程序都包含一个或多个Web模块(Web Module),可以独立部署和管理。
  3. 端口:Tomcat默认使用8080端口提供HTTP服务,可以通过配置文件修改端口号。同时,Tomcat还支持SSL加密协议和HTTPS端口,以提供更高的安全性和可靠性。
  4. 配置文件:Tomcat的配置文件包括server.xml、web.xml等,用于配置Tomcat服务器、Web应用程序和Servlet等相关参数。
  5. 虚拟主机:Tomcat支持多个虚拟主机,可以在同一台服务器上通过不同的域名或IP地址提供不同的Web服务。每个虚拟主机都可以拥有自己的Web应用程序和配置文件,互相独立。
  6. Tomcat管理工具:Tomcat提供了多种管理工具,例如Web管理界面、命令行工具、JMX接口等,可以方便地对Tomcat服务器和Web应用程序进行管理和监控。

Tomcat是一个广泛使用的Web服务器和Servlet容器,具有开源、免费、轻量级、易用、可扩展、高性能和安全等优点。开发人员需要了解Tomcat的相关概念和知识点,以便更好地使用和管理Tomcat服务器,提供高质量的Web服务。

以下是一些Tomcat的特点和优势:

  1. 开源免费:Tomcat是一个开源的软件,可以免费获取和使用。它不仅可以在Linux和Windows等操作系统上运行,还支持多种编程语言和开发框架。
  2. 轻量级易用:Tomcat具有轻量级和易用的特点,它可以快速部署和配置,并且可以方便地与其他开源软件集成。
  3. 可扩展性强:Tomcat支持多种插件和扩展,可以扩展其功能和性能,例如支持SSL、JNDI、JMX等技术。
  4. 高性能可靠:Tomcat具有高性能和可靠性,它可以支持高并发和大规模Web应用程序,并提供了多种负载均衡和故障恢复机制。
  5. 安全性好:Tomcat具有良好的安全性,它支持多种安全机制和认证方式,可以保护Web应用程序和服务器的安全性。

2.1. 如何使用Tomcat

以下是在Windows操作系统上安装、配置和启动Tomcat的基本步骤:

  1. 下载Tomcat二进制包

从Apache Tomcat官网(https://tomcat.apache.org/)下载最新版本的Tomcat二进制包,选择适合自己操作系统和硬件架构的版本。

  1. 安装Tomcat

将下载的Tomcat二进制包解压到本地磁盘上的任意目录,例如D盘的“D:\Tomcat”。

  1. 配置环境变量

将Tomcat的“bin”目录添加到系统的环境变量中,以便在任何目录下都可以启动、关闭和管理Tomcat服务器。

  1. 启动Tomcat

在命令行下进入Tomcat的“bin”目录,执行“startup.bat”(Windows)或“startup.sh”(Linux)脚本,启动Tomcat服务器。

  1. 访问Tomcat默认页面

在浏览器中输入“http://localhost:8080/”(默认端口为8080),访问Tomcat的默认页面。如果能够正常访问,说明Tomcat已经成功安装和配置。

3. Servlet

Servlet是 Java EE*(Java Platform, Enterprise Edition)*规范中的一部分,用于处理Web应用程序中的HTTP请求和响应。Servlet可以接收来自客户端的请求,并生成响应,从而实现Web应用程序的业务逻辑。

Servlet通常被部署在Servlet容器中,例如Tomcat、Jetty等。Servlet容器负责在Web服务器上管理Servlet的生命周期、处理HTTP请求和响应、维护会话等。Servlet容器还提供了一些额外的功能,例如安全性、JNDI*(Java Naming and Directory Interface)支持、JSP(JavaServer Pages)*支持等。

Servlet的核心接口是javax.servlet.Servlet,所有的Servlet都必须实现这个接口。Servlet接口定义了以下方法:

  1. init(ServletConfig config):在Servlet被初始化时调用,用于读取配置信息、创建资源等。
  2. service(ServletRequest request, ServletResponse response):处理请求并生成响应。
  3. destroy():在Servlet被销毁时调用,用于释放资源等清理工作。
  4. getServletConfig():获取ServletConfig对象。
  5. getServletInfo():获取Servlet的描述信息。

ServletConfig接口则定义了获取Servlet初始化参数、获取ServletContext等方法。

Servlet技术可以用于处理HTTP请求和响应,实现Web应用程序的业务逻辑。使用Servlet技术可以使得Web应用程序更加灵活、可扩展和可维护。同时,Servlet技术还提供了一些额外的功能,例如会话管理、安全性、JNDI支持、JSP支持等,使得开发Web应用程序更加方便和高效。

3.1. Servlet配置

在Java Web应用程序中,Servlet是一种用于处理HTTP请求和响应的Java组件。为了使Servlet能够被Web容器正确地加载和调用,需要在Web应用程序中进行Servlet的配置。

以下是一些常见的Servlet配置方式:

  1. 在web.xml文件中进行配置web.xml文件是Java Web应用程序的配置文件,通常位于WEB-INF目录下。

在web.xml文件中,可以使用和元素来配置Servlet。

例如,以下是一个简单的web.xml文件,配置了一个名为MyServlet的Servlet:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
         version="3.0">

  <servlet>
    <servlet-name>MyServlet</servlet-name>
    <servlet-class>com.example.MyServlet</servlet-class>
  </servlet>
  
  <servlet-mapping>
    <servlet-name>MyServlet</servlet-name>
    <url-pattern>/myservlet</url-pattern>
  </servlet-mapping>

</web-app>
  1. 使用注解进行配置

除了在web.xml文件中进行配置,还可以使用注解对Servlet进行配置。例如,可以使用@WebServlet注解指定Servlet的URL映射、初始化参数等信息。

以下是一个使用@WebServlet注解配置的Servlet示例:

@WebServlet(name = "MyServlet", urlPatterns = { "/myservlet" })
public class MyServlet extends HttpServlet {
    // Servlet implementation
}

通过使用注解,可以使Servlet的配置更加简洁和易于理解。

3.2. Servlet生命周期

这些HTTP方法是HTTP协议的核心部分,它们用于定义Web应用程序的功能和行为,同时也可以通过Web服务器的配置文件进行控制和限制。Web开发人员可以根据不同的业务需求,选择合适的HTTP方法来实现不同的功能和交互效果。同时,也需要注意HTTP方法的安全性和可靠性,避免出现安全漏洞和性能问题。Servlet是Java Web应用程序中的一种Java类,用于处理客户端(通常是Web浏览器)发送的HTTP请求并生成HTTP响应。Servlet的生命周期是指Servlet实例从创建到销毁的整个过程,包括以下几个阶段:

加载阶段:Web容器启动时,会根据web.xml配置文件中的Servlet配置信息,加载相应的Servlet类,并创建Servlet实例。

  1. 初始化阶段:在Servlet实例创建后,Web容器会调用Servlet的init()方法来初始化Servlet实例,通常用于读取配置文件、初始化数据库连接等操作。init()方法只会在Servlet实例创建时调用一次。
  2. 处理请求阶段:在Servlet实例初始化完成后,Web容器会调用Servlet的service()方法来处理客户端发送的HTTP请求。service()方法会根据HTTP请求方法(GET、POST等)调用相应的doXXX()方法来处理请求并生成HTTP响应。doXXX()方法可以重载多个,用于处理不同类型的HTTP请求。
  3. 销毁阶段:当Servlet实例不再需要时,Web容器会调用Servlet的destroy()方法来销毁Servlet实例,通常用于释放资源、关闭数据库连接等操作。destroy()方法只会在Servlet实例销毁时调用一次。

在Servlet的整个生命周期中,可以通过覆盖相应的方法来实现自定义的业务逻辑。例如,在init()方法中可以读取Web应用程序的配置文件,而在destroy()方法中可以关闭打开的资源。同时,也需要注意Servlet的线程安全性和性能影响,避免出现多线程竞争和性能瓶颈问题。

3.3. ServletConfig接口

ServletConfig接口是Java Servlet规范中的一个接口,它用于获取Servlet的配置信息,并提供了一些方法来访问Servlet配置参数。每个Servlet实例都有一个对应的ServletConfig对象,用于在Servlet运行时获取配置信息。

ServletConfig接口定义了以下方法:

  1. getInitParameter(String name):获取指定名称的初始化参数值。
  2. getInitParameterNames():获取所有初始化参数名的枚举。
  3. getServletName():获取Servlet的名称。
  4. getServletContext():获取Servlet所在的ServletContext对象。

这些方法可以通过Servlet实例的getServletConfig()方法来获取ServletConfig对象,并在Servlet运行时获取相应的配置信息。例如,可以在Servlet的init()方法中使用getInitParameter()方法获取初始化参数,或者使用getServletContext()方法获取ServletContext对象。

ServletConfig接口还可以通过web.xml配置文件来配置Servlet初始化参数。例如,可以在web.xml中添加如下配置:

<servlet>
    <servlet-name>MyServlet</servlet-name>
    <servlet-class>com.example.MyServlet</servlet-class>
    <init-param>
        <param-name>param1</param-name>
        <param-value>value1</param-value>
    </init-param>
    <init-param>
        <param-name>param2</param-name>
        <param-value>value2</param-value>
    </init-param>
</servlet>

上述配置中,MyServlet是Servlet的名称,com.example.MyServlet是Servlet的类名,param1和param2是初始化参数名,value1和value2是初始化参数值。在Servlet实例化后,可以通过getInitParameter()方法获取这些初始化参数的值。

总之,ServletConfig接口提供了一种获取Servlet配置信息的标准方式,可以方便地获取和使用Servlet配置参数,以及配置Servlet的初始化参数。

3.4. ServletContext接口

ServletContext 是 Servlet 上下文对象,代表着整个 Web 应用程序,包括了所有的 Servlet、JSP、HTML 页面以及其他的资源。在 Web 应用程序启动时,容器会创建一个 ServletContext 对象,并将其作为一个全局变量保存在内存中,这样所有的 Servlet 都可以通过 getServletContext() 方法获取到该对象。所以,ServletContext 对象是在整个应用程序中都可以共享的。

ServletContext是在Web应用程序启动时创建的,当Servlet容器启动时,它会为每个Web应用程序创建一个ServletContext对象,并将其作为一个参数传递给所有的Servlet和JSP。当Web应用程序关闭时,ServletContext对象也会被销毁。

以下是ServletContext接口的一些常用方法:

  1. getInitParameter(String name):获取指定名称的初始化参数的值。
  2. getInitParameterNames():获取所有初始化参数名称的枚举。
  3. getServletContextName():获取ServletContext的名称。
  4. getRealPath(String path):将指定的虚拟路径转换为实际路径。
  5. getRequestDispatcher(String path):获取用于转发请求的RequestDispatcher对象。
  6. log(String message):在Servlet日志中记录指定的消息。
  7. setAttribute(String name, Object object):将一个对象绑定到ServletContext中的指定名称。
  8. getAttribute(String name):获取ServletContext中指定名称的对象。
  9. removeAttribute(String name):从ServletContext中删除指定的对象。

ServletContext接口可以帮助我们更好地管理Web应用程序的配置信息和共享数据,同时也可以帮助我们处理请求和响应,实现Web应用程序的业务逻辑。

3.4.1. ServletContext接口获取Web应用程序的初始化参数

在web.xml文件中,可以使用元素来配置Web应用程序的初始化参数。例如,以下代码展示了如何配置一个名为encoding的初始化参数,它的值为UTF-8:

<context-param>
    <param-name>encoding</param-name>
    <param-value>UTF-8</param-value>
</context-param>

在Servlet中,可以使用ServletContext对象来获取Web应用程序的初始化参数,例如:

// 获取ServletContext对象
ServletContext context = this.getServletContext();

// 获取名为encoding的初始化参数的值
String encoding = context.getInitParameter("encoding");

在上面的代码中,getInitParameter()方法用于获取名为encoding的初始化参数的值。如果找不到该参数,则返回null。

3.4.2. ServletContext接口存储和获取共享数据

ServletContext接口提供了一些方法,可以存储和获取共享数据。其中,存储数据的方法包括:

  • setAttribute(String name, Object obj):将一个名为name的对象obj存储在ServletContext中。
  • removeAttribute(String name):从ServletContext中删除名为name的对象。

获取数据的方法包括:

  • getAttribute(String name):返回名为name的对象。
  • getAttributeNames():返回所有存储在ServletContext中的对象的名称。

ServletContext中存储的对象是在整个Web应用程序中共享的,可以被所有Servlet访问和修改。因此,在使用ServletContext存储数据时,需要注意数据的线程安全性和同步问题。

3.4.3. 使用ServletContext接口读取Web应用下的资源文件

ServletContext是一个Web应用程序的上下文对象,它可以在整个Web应用程序中共享数据。通过ServletContext可以获取应用程序的初始化参数、获取应用程序的资源、获取Servlet的上下文路径等信息。可以使用ServletContext接口来读取Web应用下的资源文件,具体步骤如下:

​ 1.获取ServletContext对象:

在Servlet中,可以通过调用getServletContext()方法来获取ServletContext对象,代码如下:

ServletContext context = getServletContext();

​ 2.获取资源文件的真实路径:

可以通过调用ServletContext对象的getRealPath()方法来获取资源文件的真实路径,该方法接收一个相对路径参数,返回资源文件的绝对路径。例如,如果想获取Web应用下的一个名为"test.txt"的文件,可以使用如下代码:

String filePath = context.getRealPath("/test.txt");

​ 3.使用资源文件:

获取到资源文件的真实路径后,可以使用Java IO流或其他相关工具类来读取和处理资源文件,例如:

try (FileReader reader = new FileReader(filePath)) {
    // 读取文件内容并进行处理
} catch (IOException e) {
    // 处理读取文件异常
}

需要注意的是,获取资源文件的真实路径可能会因为服务器和应用程序的不同而有所差异,因此在实际开发中,应该根据具体情况进行测试和调整。同时,还需要注意文件路径的斜杠方向,不同的操作系统和服务器可能有不同的斜杠方向。

3.5. HttpServletRequest对象

HttpServletRequest是Java Servlet API中的一个接口,代表了客户端向服务器发送的HTTP请求。它提供了一系列方法,用于获取HTTP请求的各种信息,如请求方法、请求URI、请求参数、请求头、请求体等。HttpServletRequest对象通常由Servlet容器创建,并作为参数传递给Servlet的service()方法。

HttpServletRequest接口包含了许多方法,常用的方法包括:

  1. getMethod():获取HTTP请求的方法,如GET、POST、PUT、DELETE等。
  2. getRequestURI():获取HTTP请求的URI,不包括参数部分。
  3. getQueryString():获取HTTP请求的查询字符串部分,即URI中的参数部分。
  4. getParameter():获取HTTP请求的参数值,可以根据参数名获取参数值,也可以获取参数值数组。
  5. getHeader():获取HTTP请求头的值,可以根据头部名称获取对应的值。
  6. getInputStream():获取HTTP请求的输入流,用于读取请求体的内容。
  7. getCookies():获取HTTP请求中的Cookie信息,返回一个Cookie数组。
  8. getSession():获取HTTP请求对应的Session对象,如果不存在则创建一个新的Session对象。

HttpServletRequest对象的作用非常重要,它可以帮助开发人员获取客户端的请求信息,从而进行相应的业务逻辑处理。在Java Web应用程序中,HttpServletRequest通常是Servlet或JSP页面的重要参数之一,开发人员可以通过它获取请求的信息,进行相应的业务逻辑处理,并生成响应结果返回给客户端。

3.6. HttpServletResponse对象

在Java Web应用程序中,HttpServletResponse是一个用于封装HTTP响应的Java对象。HttpServletResponse对象通常由Servlet容器创建,并在Servlet中使用,用于生成HTTP响应和发送响应数据到客户端。

以下是一些常见的HttpServletResponse方法:

  1. setContentType():设置响应内容的类型。例如,可以设置为"text/html"表示响应内容是HTML格式的文本。
response.setContentType("text/html");
  1. setCharacterEncoding():设置响应内容的字符编码。例如,可以设置为"UTF-8"表示响应内容是使用UTF-8编码的文本。
response.setCharacterEncoding("UTF-8");
  1. getWriter():获取一个用于向客户端发送字符数据的PrintWriter对象。可以使用该对象写入响应内容。
PrintWriter out = response.getWriter();
out.println("Hello, world!");
  1. sendRedirect():将请求重定向到其他URL。例如,可以将请求重定向到另一个Servlet或者JSP页面。
response.sendRedirect("http://example.com");
  1. setStatus():设置响应的HTTP状态码。例如,可以设置为404表示“未找到”错误。
response.setStatus(HttpServletResponse.SC_NOT_FOUND);

HttpServletResponse对象还提供了其他许多方法,例如addHeader()用于添加响应头、setBufferSize()用于设置响应缓冲区大小等。

需要注意的是,HttpServletResponse对象通常只能在Servlet中使用,并且在Servlet执行完毕后将由Servlet容器负责将响应发送到客户端。

3.6.1. HttpServletResponse与HttpServletRequest的区别

HttpServletRequestHttpServletResponse 都是 Servlet API 中的接口,分别表示客户端发起的 HTTP 请求和服务器端返回的 HTTP 响应。它们之间的主要区别在于:

  1. 作用对象不同:HttpServletRequest 代表客户端发起的请求,而 HttpServletResponse 代表服务器返回的响应。
  2. 提供的方法不同:HttpServletRequest 提供了许多方法,如 getParameter()getSession() 等,用于获取请求参数或会话信息等。而 HttpServletResponse 则提供了一些方法,如 setStatus()setHeader() 等,用于设置响应状态码或响应头信息等。
  3. 示例用途不同:在 Servlet 中,通常需要使用 HttpServletRequest 对象来获取请求参数、请求头信息等,并进行相应的处理和逻辑判断。而 HttpServletResponse 则通常用于设置响应状态码、响应头信息等,并向客户端发送响应数据。

例如,下面的代码片段演示了如何使用 HttpServletRequestHttpServletResponse 来处理客户端请求和服务器响应:

protected void doGet(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
    // 从请求中获取参数
    String name = request.getParameter("name");
    
    // 设置响应头
    response.setContentType("text/html;charset=UTF-8");
    
    // 向客户端发送响应数据
    PrintWriter out = response.getWriter();
    out.println("<html>");
    out.println("<head><title>Hello, " + name + "!</title></head>");
    out.println("<body><h1>Hello, " + name + "!</h1></body>");
    out.println("</html>");
}

总之,HttpServletRequestHttpServletResponse 都是 Servlet API 中的重要接口,它们可以协同工作来处理客户端请求和服务器响应,并实现各种 Web 应用程序的功能和交互。

4. MVC设计模式

OT7-9-M8-D8-4-FZ3-C-2-I7-ELN.png

MVC是一种软件设计模式,它将一个应用程序分成三个核心部分:模型(Model),视图(View)和控制器(Controller)。这三个部分分别负责应用程序的不同方面,使得应用程序更加易于维护和扩展。

MVC中的三个部分:

  1. 模型(Model):模型是应用程序中处理数据和业务逻辑的部分。它负责管理数据的状态和处理数据的操作。在MVC中,模型通常是一个类或一组类,用于表示应用程序中的数据结构和处理数据的方法。模型还可以包括与数据存储相关的代码,例如,数据库查询和更新操作。
  2. 视图(View):视图是应用程序中负责呈现数据的部分。它通常是用户所看到的界面,例如,网页或移动应用程序界面。视图可以包括HTML、CSS、JavaScript等,用于呈现和交互式操作数据。
  3. 控制器(Controller):控制器是应用程序中连接模型和视图的部分。它接收来自视图的输入并将其传递给模型进行处理,同时还可以更新视图以反映模型的变化。在MVC中,控制器通常是一个类或一组类,用于处理来自视图的请求,并将其转发给适当的模型进行处理。控制器还可以处理来自模型的响应,并更新视图以反映数据的变化。

使用MVC设计模式可以使应用程序更加模块化、易于维护和扩展。MVC的核心思想是将不同的职责分离开来,使得每个部分都有明确的职责和作用。模型负责处理数据,视图负责呈现数据,控制器负责处理用户请求和更新视图。这种分离使得应用程序的不同部分可以独立开发、测试和维护。同时,它还可以促进团队协作,因为每个部分都有明确定义的职责和作用,不同的团队成员可以专注于自己擅长的领域,从而提高开发效率。

总之,MVC是一种广泛应用于软件开发中的设计模式,它将应用程序分成三个核心部分:模型、视图和控制器。使用MVC可以使应用程序更加模块化、易于维护和扩展,同时促进团队协作和提高开发效率。

4.1. Java Web 应用程序设计结构

这些是 Java Web 应用程序中常见的包和模块:

  • DAO (Data Access Object):数据访问对象,封装了与数据库的交互操作,提供了对数据的持久化操作。
  • Model:模型,用于表示应用程序中的数据结构,通常与数据库中的表对应。
  • Service:服务层,提供业务逻辑处理,调用 DAO 层实现数据操作。
  • Servlet:Java Servlet,是运行在服务器端的 Java 应用程序,处理客户端请求并生成响应。
  • Utils:工具类,提供一些常用的工具方法,例如日期处理、加密解密等。

以上这些是常见的模块和包,它们通常会按照层次结构组织在一起,形成一个完整的 Java Web 应用程序。其中 DAO、Model、Service 通常被归类为业务逻辑层 (BLL),Servlet 属于表示层 (UI),而 Utils 则是一个辅助工具类库。

在MVC模式中,通常使用以下的项目结构:

app/
├── WEB-INF/
│   ├── classes/
│   │   ├── model/
│   │   ├── view/
│   │   ├── controller/
│   │   └── ...
│   ├── lib/
│   ├── web.xml
│   └── jsp/
│       ├── index.jsp
│       ├── view1.jsp
│       ├── view2.jsp
│       └── ...
└── ...

其中,各个部分的职责和功能如下:

  1. 模型(Model):模型是应用程序中的数据和业务逻辑部分,它负责处理数据的读取、存储和处理。在项目结构中,模型通常存放在WEB-INF/classes/model目录下,由Java类来实现。
  2. 视图(View):视图是应用程序中的用户界面部分,它负责展示数据和处理用户的输入。在项目结构中,视图通常存放在WEB-INF/jsp目录下,由JSP页面来实现。
  3. 控制器(Controller):控制器是应用程序中的业务逻辑和用户操作部分,它负责接收用户的请求并调用模型和视图来处理请求。在项目结构中,控制器通常存放在WEB-INF/classes/controller目录下,由Java类来实现。

在项目结构中,还有一些其他的目录和文件:

  1. WEB-INF/lib目录:用于存放应用程序所需要的依赖库(如JAR文件)。
  2. WEB-INF/web.xml文件:是Web应用程序的配置文件,它包含了应用程序的配置信息和URL映射规则。
  3. WEB-INF/jsp目录:存放JSP页面,用于实现视图部分。
  4. WEB-INF/classes目录:存放Java类文件,用于实现模型和控制器部分。

4.2. JavaBean编程规范

JavaBean是一种符合Java语言约定的可重用软件组件的编程规范。

按照JavaBean规范编写的Java类,具有以下特点:

  1. 公共的无参构造函数:JavaBean必须提供一个无参构造函数,这样才能通过反射实例化该类。
  2. 私有的属性:JavaBean的属性必须是私有的,并且提供getter和setter方法来访问和修改属性值。
  3. 可序列化:JavaBean必须实现Serializable接口,以便它的状态可以在网络上传输或者持久化到磁盘中。
  4. 简单的命名规范:JavaBean的类名必须以大写字母开头,并且属性名和getter/setter方法名必须符合JavaBean的命名规范。

JavaBean通常用于构建可重用的、易于维护的组件,比如图形用户界面(GUI)、数据库访问、网络编程等。在Java开发中,JavaBean已经成为一种常见的编程规范和标准。

一个简单的JavaBean例子如下:

import java.io.Serializable;

public class Person implements Serializable {

    private String name;
    private int age;

    public Person() {}

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

这个类符合JavaBean规范,因为它有一个无参构造函数、私有的属性、getter和setter方法,并且实现了Serializable接口。这个JavaBean表示一个人的基本信息,可以用于在不同的应用程序中进行传输和存储。例如,在一个Web应用程序中,我们可以使用这个JavaBean来表示用户的信息,然后将它存储到Session中或者在不同的页面之间传递。

4.3. JavaServer Pages(JSP)

JSP(JavaServer Pages)是一种用于创建动态Web页面的Java技术。JSP可以将Java代码嵌入到HTML页面中,使得页面可以根据用户请求和业务逻辑生成动态内容。与静态HTML页面相比,JSP具有更高的灵活性和可维护性。

JSP页面通常包含HTML、CSS和JavaScript代码,以及嵌入在标签中的Java代码片段或表达式。在JSP页面中,可以使用Java标准标签库(JSTL)、EL表达式(Expression Language)等技术来简化Java代码的编写和页面的渲染。

JSP页面可以被编译为Java Servlet,因此它们可以运行在支持Servlet的Web服务器上。当用户请求一个JSP页面时,Web服务器会自动将JSP页面编译成Java Servlet,并执行相应的Java代码来生成动态内容,最终将生成的HTML页面发送给用户的Web浏览器。

JSP技术是Java Web开发中的重要组成部分,它与其他Java Web技术(如Servlet、JavaServer Faces等)一起,构成了Java Web应用程序的基础框架。

4.3.1. JSP基本语法

JSP基本语法包括:注释、变量定义和输出、控制流语句、循环语句、函数定义和调用等。这些语法可以帮助JSP开发人员更方便地编写动态Web页面,并实现与用户的交互和数据处理。以下是JSP的一些基本语法示例:

  1. JSP注释:
<%-- 这是一个JSP注释 --%>
  1. 定义变量:
<% int age = 20; %>
  1. 输出变量值:
<%= age %>
  1. 控制流语句(if-else):
<%
    if (age >= 18) {
%>
        <p>You are an adult.</p>
<%
    } else {
%>
        <p>You are still a minor.</p>
<%
    }
%>
  1. 循环语句(for循环):
<%
    for (int i = 1; i <= 10; i++) {
%>
        <p><%= i %></p>
<%
    }
%>
  1. 定义函数:
<%
    int square(int x) {
        return x * x;
    }
%>
  1. 调用函数:
<%
    int result = square(5);
%>
4.3.2. JSP开发模型

9-V6-VRFLIXDL6-N0-2-D-BR-W.png

由上图可知,Servlet充当了控制器的角色,它首先接收浏览器发送的请求,然后根据请求信息实例化JavaBean对象,由JavaBean对象完成数据库操作并将操作结果进行封装,最后选择相应的JSP页面将响应结果显示在浏览器中。

5. JDBC和数据库连接池

JDBC是Java Database Connectivity的缩写,它是Java语言中用于连接和操作关系型数据库的标准API。JDBC提供了一组Java类和接口,用于连接和操作各种类型的关系型数据库,例如MySQL、Oracle、SQL Server等等。

通过JDBC,Java程序可以与关系型数据库进行通信,从而实现对数据库的数据读写、查询和更新等操作。JDBC提供了一组标准的API,使得Java程序可以通过一套统一的接口来访问不同类型的关系型数据库,从而提高了开发效率和程序的可移植性。

6-D5-K705-R-3-AELSKQ-KX4-P.png

JDBC的核心API包括:

  1. DriverManager:用于获取数据库连接。
  2. Connection:表示与数据库的连接。
  3. Statement:用于执行SQL语句。
  4. ResultSet:表示SQL查询结果集。
  5. PreparedStatement:支持预编译的SQL语句执行。
  6. CallableStatement:支持调用存储过程执行。

使用JDBC连接数据库通常需要进行以下步骤:

  1. 加载数据库驱动程序。
  2. 获取数据库连接。
  3. 创建执行SQL语句的Statement对象。
  4. 执行SQL语句并处理结果。
  5. 关闭数据库连接。

需要注意的是,JDBC只是一个标准API,它并不包含具体的数据库驱动程序。在使用JDBC连接数据库之前,需要先下载并安装相应的数据库驱动程序,例如MySQL的JDBC驱动程序为“mysql-connector-java”。

总之,JDBC是Java语言中用于连接和操作关系型数据库的标准API,它提供了一组Java类和接口,用于连接和操作各种类型的关系型数据库,使得Java程序可以通过一套统一的接口来访问不同类型的关系型数据库。

5.1. JDBCUtils

JDBCUtils是一个工具类,用于简化JDBC的使用,它封装了JDBC的一些常用操作,例如获取数据库连接、执行SQL语句、关闭数据库连接等。

5.1.1. JDBCUtils类 样例代码
package cn.itcast.jdbc.example.utils;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class JDBCUtils {
    // 加载驱动,并建立数据库连接
    public static Connection getConnection() throws SQLException,
            ClassNotFoundException {
        Class.forName("com.mysql.cj.jdbc.Driver");
        String url = "jdbc:mysql://localhost:3306/jdbc?serverTimezone=GMT%2B8";
        String username = "root";
        String password = "root";
        Connection conn = DriverManager.getConnection(url, username,
                password);
        return conn;
    }
    // 关闭数据库连接,释放资源
    public static void release(Statement stmt, Connection conn) {
        if (stmt != null) {
            try {
                stmt.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            stmt = null;
        }
        if (conn != null) {
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            conn = null;
        }
    }
    public static void release(ResultSet rs, Statement stmt,
                               Connection conn){
        if (rs != null) {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            rs = null;
        }
        release(stmt, conn);
    }
}

这段代码是一个JDBC的工具类,名为JDBCUtils。该类封装了JDBC的一些常用操作,包括获取数据库连接和释放资源。含以下方法::

  1. getConnection()方法:该方法用于获取数据库连接,它会加载MySQL的JDBC驱动程序,建立数据库连接,并返回一个Connection对象。
  2. release()方法:该方法用于释放资源,包括Statement对象和Connection对象。它会首先关闭Statement对象,然后关闭Connection对象。
  3. release()方法的重载:该方法还包括一个重载版本,用于释放ResultSet、Statement和Connection对象。它会先关闭ResultSet对象,然后调用上述的release()方法关闭Statement和Connection对象。
5.1.2 JDBC测试类 样例代码

以下是一个原始的JDBC测试类示例,可以用于测试JDBC连接和访问数据库:

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Date;
public class Example01 {
    public static void main(String[] args) throws SQLException {
        Statement stmt = null;
        ResultSet rs = null;
        Connection conn = null;
        try {
            // 1. 注册数据库的驱动
            Class.forName("com.mysql.cj.jdbc.Driver");
            // 2.通过DriverManager获取数据库连接
            String url = "jdbc:mysql://localhost:3306/jdbc?serverTimezone=GMT%2B8";
            String username = "root";//数据库名称
            String password = "123456";//数据库密码
            conn = DriverManager.getConnection (url, username,
                    password);
            // 3.通过Connection对象获取Statement对象
            stmt = conn.createStatement();
            // 4.使用Statement执行SQL语句。
            String sql = "select * from users";
            rs = stmt.executeQuery(sql);
            // 5. 操作ResultSet结果集
            System.out.println("id | name   | password | email  | birthday");
            while (rs.next()) {
                int id = rs.getInt("id"); // 通过列名获取指定字段的值
                String name = rs.getString("name");
                String psw = rs.getString("password");
                String email = rs.getString("email");
                Date birthday = rs.getDate("birthday");
                System.out.println(id + " | " + name + " | " + psw + " | " + email
                        + " | " + birthday);
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } finally{
            // 6.回收数据库资源
            if(rs!=null) {
                try {
                    rs.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
                rs = null;
            }
            if(stmt!=null) {
                try {
                    stmt.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
                stmt = null;
            }
            if(conn!=null) {
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
                conn = null;
            }
        }
    }
}

这个示例代码使用了MySQL数据库,需要先在本地安装MySQL数据库,并创建一个名为testdb的数据库,以及一个名为user的表。在运行这个测试类之前,需要将url、username和password变量设置为自己本地MySQL数据库的连接信息。

这个示例代码中,首先加载MySQL驱动程序,然后获取数据库连接,创建Statement对象,并执行查询操作。最后处理查询结果,并关闭ResultSet、Statement和Connection对象。

5.2. JDBC的常用API

5.2.1. Driver接口

Driver接口是所有JDBC驱动程序必须实现的接口,该接口专门提供给数据库厂商使用。需要注意的是,在编写JDBC程序时,必须要把所使用的数据库驱动程序或类库加载到项目的classpath中(这里指MySQL驱动JAR包)。

5.2.2. DriverManager接口
  1. registerDriver(Driver driver):注册JDBC驱动程序。
  2. getDriver(String url):获取与给定URL相匹配的JDBC驱动程序。
  3. getConnection(String url, String user, String password):根据给定的URL、用户名和密码,获取与数据库的连接。
  4. getConnection(String url, Properties info):根据给定的URL和属性信息,获取与数据库的连接。
  5. setLoginTimeout(int seconds):设置登录超时时间。
  6. setLogWriter(PrintWriter out):设置日志输出流。

DriverManager接口是连接数据库的入口,它负责加载和注册JDBC驱动程序,并建立与数据库的连接。在使用DriverManager获取连接时,需要指定数据库的URL、用户名和密码等信息。可以通过setLoginTimeout()方法设置登录超时时间,通过setLogWriter()方法设置日志输出流。

需要注意的是,在使用DriverManager获取连接时,需要先加载JDBC驱动程序。可以通过以下方式加载驱动程序:

Class.forName("com.mysql.cj.jdbc.Driver");

上述代码将加载MySQL JDBC驱动程序,可以根据具体的数据库类型加载相应的驱动程序。

5.2.3. Connection接口

Statement接口用于执行静态的SQL语句,并返回一个结果对象。Statement接口的对象通过Connection实例的createStatement()方法获得。利用Statement接口把静态的SQL语句发送到数据库编译执行,然后返回数据库的处理结果。Statement接口提供了执行SQL语句的3个常用方法,如下:

  1. execute(String sql): 方法用于执行各种SQL语句,包括查询语句和更新语句,返回一个boolean类型的值。如果返回值为true,表示所执行的SQL语句有查询结果,可以通过Statement的getResultSet()方法获得查询结果。
  2. executeUpdate(String sql) : 方法用于执行SQL中的insert、update和delete语句,返回一个int类型的值,表示数据库中受该SQL语句影响的记录条数。
  3. executeQuery(String sql): 方法用于执行SQL中的select语句,返回一个表示查询结果的ResultSet对象。
5.2.4. PreparedStatement接口

Statement接口封装了JDBC执行SQL语句的方法,可以完成Java程序执行SQL语句的操作。然而在实际开发过程中往往需要将程序中的变量作为SQL语句的查询条件,而使用Statement接口操作这些SQL语句会过于繁琐,并且存在安全方面的问题。针对这一问题,JDBC API提供了扩展的PreparedStatement接口。

  1. setInt(int parameterIndex, int x):将指定参数设置为给定的int值。
  2. setFloat(int parameterIndex, float x):将指定参数设置为给定的float值。
  3. setString(int parameterIndex, String x):将指定参数设置为给定的String值。
  4. setDate(int parameterIndex, Date x):将指定参数设置为给定的Date值。
  5. setCharacterStream(int parameterIndex, java.io.Reader reader, int length):将指定的输入流写入数据库的文本字段。
  6. setBinaryStream(int parameterIndex, java.io.InputStream x, int length):将二进制的输入流数据写入到二进制字段中。

需要注意的是,setDate()方法可以设置日期内容,但参数Date的类型是java.sql.Date,而不是java.util.Date。在通过setter()方法为SQL语句中的参数赋值时,可以通过参数与SQL类型相匹配的方法(例如,如果参数类型为Integer,那么应该使用setInt()方法),也可以通过setObject()方法设置多种类型的输入参数。通过setter()方法为SQL语句中的参数赋值,具体示例代码如下所示:

String sql = "INSERT INTO users(id, name, email) VALUES (?, ?, ?)";
PreparedStatement preStmt = conn.prepareStatement(sql);

preStmt.setInt(1, 1); // 设置第一个参数为整型值1
preStmt.setString(2, "zhangsan"); // 设置第二个参数为字符串值"zhangsan"
preStmt.setString(3, "zs@sina.com"); // 设置第三个参数为字符串值"zs@sina.com"

preStmt.executeUpdate(); // 执行更新操作
5.2.5. PreparedStatement接口

ResultSet接口表示一个结果集,是Java程序与数据库之间进行数据交互的重要接口之一。在执行查询操作时,如果查询语句返回了结果集,那么就可以通过ResultSet接口来获取查询结果。

ResultSet接口提供了多种方法,用于访问结果集中的数据,包括:

  1. next():将结果集中的游标向下移动一行,如果还有下一行数据,返回true,否则返回false。
  2. getInt()、getDouble()、getString()等:获取当前行指定列的数据,根据列的类型选择相应的方法。
  3. getMetaData():获取结果集的元数据,包括列名、列类型等信息。
  4. beforeFirst()、afterLast()、first()、last()、absolute()等:移动结果集中的游标到指定位置。
  5. close():关闭结果集,释放资源。

使用ResultSet接口可以方便地获取查询结果,并对结果进行处理。需要注意的是,在使用ResultSet时,需要注意资源的释放,避免出现资源泄露的情况。通常情况下,应该在使用完ResultSet后及时关闭它,并释放相关的资源。

5.2.6. ResultSet接口

ResultSet接口是Java中用于访问数据库查询结果集的核心接口之一。它提供了一系列方法,用于获取和操作查询结果集中的数据。

以下是ResultSet接口中部分常用的方法:

  1. next():将结果集中的游标向下移动一行,如果还有下一行数据,返回true,否则返回false
  2. getInt()getDouble()getString()等:获取当前行指定列的数据,根据列的类型选择相应的方法。
  3. getMetaData():获取结果集的元数据,包括列名、列类型等信息。
  4. beforeFirst()afterLast()first()last()absolute()等:移动结果集中的游标到指定位置。
  5. close():关闭结果集,释放资源。

使用ResultSet接口可以方便地获取查询结果,并对结果进行处理。需要注意的是,在使用ResultSet时,需要注意资源的释放,避免出现资源泄露的情况。通常情况下,应该在使用完ResultSet后及时关闭它,并释放相关的资源。

另外,还可以通过使用ResultSetMetaData接口获取ResultSet元数据,包括列名、列类型、列长度等信息。ResultSetMetaData接口中常用的方法包括:

  1. getColumnCount():获取结果集中的列数。
  2. getColumnName(int column):获取指定列的名称。
  3. getColumnType(int column):获取指定列的数据类型。
  4. getColumnDisplaySize(int column):获取指定列的显示长度。

通过掌握ResultSetResultSetMetaData接口的使用方法,可以更加灵活和高效地操作数据库查询结果集。

6. Java Web会话及会话技术

Java Web会话是指在Web应用程序中,为了保存用户的状态信息而建立的一种机制。它可以跨多个请求和响应之间保持用户的状态,并为用户提供连续的体验,而不需要用户在每个请求中重新验证身份或重新输入信息。会话在Web应用程序中是非常重要的,因为它可以帮助开发人员跟踪用户的活动和交互,并为他们提供更好的用户体验。

Java Web会话技术是实现会话的技术手段。主要有以下几种:

  1. Cookie:Cookie是一种小型文本文件,可以在用户计算机上存储数据。Web服务器可以通过设置Cookie来跟踪用户的活动和状态,从而实现会话。Cookie通常用于保存用户的身份验证信息、个人偏好设置等。
  2. HttpSession:HttpSession是Java Web中的一个接口,用于在Web应用程序中管理会话。在会话中,HttpSession可以通过setAttribute()和getAttribute()方法来存储和获取用户的信息。此外,HttpSession还可以设置会话超时时间和使会话无效等。
  3. URL Rewriting(URL 重写):URL重写是一种将会话ID添加到URL中的技术,以便在Web服务器和客户端之间传递会话信息。通过将会话ID添加到URL中,Web服务器可以识别用户的会话,并在多个页面之间保持用户的状态。
  4. Hidden Field(隐藏表单):隐藏表单是一种将会话ID添加到HTML表单中的技术,以便在Web服务器和客户端之间传递会话信息。通过将会话ID添加到隐藏表单中,Web服务器可以识别用户的会话,并在多个页面之间保持用户的状态。

6.1. Cookie对象

Cookie是一种小型文本文件,通常由Web服务器发送给用户的Web浏览器,并存储在用户计算机的硬盘上。Cookie可以用来存储和检索用户的信息,如登录状态、用户偏好设置、购物车内容等。Web服务器可以在HTTP响应中添加一个Set-Cookie头部,告诉浏览器保存一个Cookie,浏览器在下一次请求同一个Web服务器时,会自动发送相应的Cookie信息,从而实现用户的状态跟踪和持久化。

Cookie有以下几个特点:

  1. Cookie是一种文本文件,大小通常不超过4KB。

  2. Cookie是存储在用户计算机上的,因此它可以在用户多次访问同一个Web应用程序时保持用户的状态,并提供连续的体验。

  3. Cookie可以设置过期时间,以控制Cookie的生命周期。

  4. Cookie可以设置域名和路径限制,以控制在哪些Web页面中发送Cookie。

  5. Cookie可以加密,以保护Cookie中的敏感信息。

    HSUQNQ-1-S9-XVV-3-WQ942-CA.png

当用户首次访问服务器时,服务器可以在HTTP响应中添加一个包含Set-Cookie头字段的HTTP响应消息,告诉浏览器保存一个Cookie。该Cookie包含了一些用户的信息,例如身份验证信息、用户偏好设置等。

一旦用户的浏览器接收到服务器发送的Cookie信息,它会将该Cookie保存在浏览器的缓存中。在用户后续的请求中,浏览器会自动将存储在缓存中的Cookie信息发送给服务器,从而使服务器能够识别该请求是由哪个用户发起的,并在多个页面之间保持用户的状态。

6.1.1. cookie的构造方法

在Java中,可以使用Cookie类来构造和操作Cookie。Cookie类提供了以下构造方法:

  1. Cookie(String name, String value):构造一个具有指定名称和值的Cookie。该Cookie的其他属性(如域名、路径、过期时间等)将使用默认值。
  2. Cookie(String name, String value, String path):构造一个具有指定名称、值和路径的Cookie。该Cookie的域名和过期时间将使用默认值。
  3. Cookie(String name, String value, String path, String domain):构造一个具有指定名称、值、路径和域名的Cookie。该Cookie的过期时间将使用默认值。
  4. Cookie(String name, String value, String path, String domain, int maxAge):构造一个具有指定名称、值、路径、域名和最大存活时间的Cookie。

其中,name和value参数分别表示Cookie的名称和值。path、domain和maxAge参数分别表示Cookie的路径、域名和最大存活时间(以秒为单位)。在构造完Cookie之后,可以使用setDomain()、setPath()、setMaxAge()等方法来进一步设置Cookie的属性。

例如,以下代码创建了一个名为"myCookie",值为"123456",路径为"/",过期时间为1小时的Cookie:

Cookie cookie = new Cookie("myCookie", "123456");
cookie.setPath("/");
cookie.setMaxAge(60 * 60); // 1 hour
response.addCookie(cookie);

需要注意的是,在Java Web应用程序中,Cookie的名称不能包含空格和其他特殊字符,如";“、”,“、”="等。如果名称或值中包含这些字符,应该使用URL编码来转义它们。

6.1.2. cookie的常用方法

Cookie类中常用的方法包括:

  1. getName():获取Cookie的名称。
  2. getValue():获取Cookie的值。
  3. setValue(String value):设置Cookie的值。
  4. getPath():获取Cookie的路径。
  5. setPath(String path):设置Cookie的路径。
  6. getDomain():获取Cookie的域名。
  7. setDomain(String domain):设置Cookie的域名。
  8. getMaxAge():获取Cookie的最大存活时间(以秒为单位)。
  9. setMaxAge(int maxAge):设置Cookie的最大存活时间。
  10. isHttpOnly():检查Cookie是否为HttpOnly。
  11. setHttpOnly(boolean httpOnly):设置Cookie是否为HttpOnly。
  12. getSecure():检查Cookie是否只能通过HTTPS协议传输。
  13. setSecure(boolean secure):设置Cookie是否只能通过HTTPS协议传输。
  14. toString():将Cookie转换为字符串表示形式。

这些方法可以用来获取或设置Cookie的各种属性,例如名称、值、路径、域名、最大存活时间、HttpOnly属性和Secure属性等。需要注意的是,HttpOnly属性可以防止JavaScript代码获取Cookie的值,从而提高Cookie的安全性;Secure属性可以保护Cookie在传输过程中的安全性,但需要注意使用HTTPS协议来传输Cookie。

在Java Web应用程序中,可以使用HttpServletRequest的getCookies()方法来获取客户端发送的所有Cookie,并使用HttpServletResponse的addCookie()方法来添加新的Cookie。可以使用Cookie的setMaxAge()方法来设置Cookie的最大存活时间,以便在一定时间后自动过期并被浏览器删除。

学习任务:

在IDEA中新建Web项目chapter05并添加Servlet-api.jar包,在chapter05项目的src包中编写一个名称为LastAccessServlet的Servlet类,该类主要用于获取Cookie信息中的时间并发送给客户端。主要代码如下:

public class LastAccessServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;
    public void doGet(HttpServletRequest request,
            HttpServletResponse response)
            throws ServletException,IOException {
        //指定服务器输出内容的编码方式UTF-8,防止发生乱码
        response.setContentType("text/html;charset=utf-8");
        //获取所有cookie
        Cookie[] cookies=request.getCookies();
        //定义flag的boolean变量,用于判断cookies是否为空
        boolean flag=false;	
        //遍历cookie数组
        if(cookies.length >0&&cookies!=null){
            for(Cookie cookie:cookies) {
                //获取cookie的名称
                String name=cookie.getName();
				//判断名称是否是lastTime
                if("lastTime".equals(name)){
                    //有该cookie不是第一次访问
                    flag=true;			
                    //响应数据
                    //获取cookie的value时间
                    String value=cookie.getValue();
                    System.out.println("解码前:"+value);
                    //URL解码
                    value= URLDecoder.decode(value, "utf-8");
                    System.out.println("解码后:"+value);
                    response.getWriter().write("欢迎回来,您上次访问时间为:"+value);
                    //设置cookie的value
                    //获取当前时间的字符串,重新设置cookie的值,重新发送cookie
                    Date date=new Date();
                    SimpleDateFormat timesdf=new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
                    String str_time=timesdf.format(date);
                    System.out.println("编码前:"+str_time);
                    //URL编码
                    str_time=URLEncoder.encode(str_time, "utf-8");
					System.out.println("编码后:"+str_time);
                    cookie.setValue(str_time);
                    //设置cookie存活时间
                    cookie.setMaxAge(60*60*24*30);	//一个月
                    //加入当前cookie请求时间
                    response.addCookie(cookie);
                    break;
                }
            }
            //如果cookies中没有时间,也就是没有访问过
            if(cookies==null || cookies.length==0 || flag==false){
                //设置cookie的value
                //获取当前时间的字符串,重新设置cookie的值,重新发送cookie
                Date date=new Date();
                SimpleDateFormat sdf=new SimpleDateFormat("yyyy年MM月dd日HH:mm:ss");
                String str_date=sdf.format(date);
                System.out.println("编码前:"+str_date);
                //URL编码
                str_date= URLEncoder.encode(str_date,"utf-8");
                System.out.println("编码后:"+str_date);
                Cookie cookie=new Cookie("lastTime",str_date);
                //设置cookie存活时间
                cookie.setMaxAge(60*60*24*30);//一个月
                response.addCookie(cookie);
                response.getWriter().write("您好,欢迎您首次访问");
            }
        }
    }

6.2. Session会话对象

Session对象是在Web应用程序中用于存储和访问用户会话数据的一种机制。每个用户都可以拥有一个唯一的Session对象,该对象在用户登录到应用程序并与应用程序交互时创建。Session对象的生命周期与用户会话一样长,可以存储用户在会话期间所需的数据,这些数据可以在用户访问应用程序的不同页面之间进行共享和传递。

以下是Session对象的一些主要特点:

  1. Session对象是服务器端的机制,它在服务器端维护并存储用户的会话数据。
  2. Session对象是基于Cookie或URL重写实现的。当用户第一次访问网站时,服务器会创建一个唯一的Session ID,并将其存储在Cookie或URL参数中。在后续的请求中,服务器可以通过Session ID来识别和访问特定的Session对象。
  3. Session对象可以存储任何类型的数据,包括基本数据类型、对象、集合等。您可以使用Session对象来存储用户的登录状态、购物车信息、用户偏好设置等。
  4. Session对象的生命周期可以通过配置文件进行管理。您可以设置Session对象的超时时间、最大活动时间、会话复制等属性。
  5. Session对象可以通过JSP、Servlet、EL表达式等方式进行访问和操作。例如,您可以通过request.getSession()方法获取当前用户的Session对象,并使用setAttribute()和getAttribute()方法来存储和访问会话数据。

下面以网站购物为例,通过一张图描述Session保存用户信息的原理。

MY9-CC3-S-0-P-VF-ICT2-IF.png

BW9-IX9-RR49-I8-4-N-8-M-IW-B.png

6.2.1. HttpSession API

HttpSession是Java Servlet API中用于管理用户会话数据的接口,它提供了一组方法来访问和操作Session对象。以下是HttpSession接口中常用的方法:

  1. void setAttribute(String name, Object value): 向Session对象中存储一个属性值,其中name为属性名称,value为属性值。
  2. Object getAttribute(String name): 获取Session对象中指定属性名称的属性值。
  3. Enumeration getAttributeNames(): 获取Session对象中所有属性名称的枚举对象。
  4. void removeAttribute(String name): 从Session对象中删除指定属性名称的属性值。
  5. void invalidate(): 使Session对象无效,即删除Session对象及其所有相关的数据。
  6. boolean isNew(): 检查Session对象是否为新创建的。如果Session对象是在当前请求中创建的,则返回true;否则返回false。
  7. long getCreationTime(): 获取Session对象的创建时间,返回值为从1970年1月1日GMT开始计算的毫秒数。
  8. long getLastAccessedTime(): 获取Session对象的最后访问时间,返回值为从1970年1月1日GMT开始计算的毫秒数。
  9. int getMaxInactiveInterval(): 获取Session对象的最大不活动时间间隔,即Session对象在未被访问的情况下可以保留多长时间。返回值为秒数。
  10. void setMaxInactiveInterval(int interval): 设置Session对象的最大不活动时间间隔,即Session对象在未被访问的情况下可以保留多长时间。参数interval为秒数。

需要注意的是,HttpSession接口是在Java Servlet API中定义的,因此只能在Servlet容器中使用。在使用HttpSession接口时,您需要先从HttpServletRequest对象中获取当前用户的Session对象,例如:

HttpSession session = request.getSession();

然后,可以使用HttpSession接口中定义的方法来访问和操作Session对象。例如:

session.setAttribute("username", "Tom");
String username = (String) session.getAttribute("username");
session.removeAttribute("username");

7. Servlet高级特性

Servlet规范有三个高级特性,分别是Filter、Listener和文件的上传下载。Filter用于修改request、response对象,Listener用于监听context、session、request事件。善用Servlet规范中的这三个高级特性能够轻松地解决一些特殊问题。本章将针对过滤器Filter、监听器Listener和文件的上传下载进行详细讲解。

7.1. Filter

在Servlet高级特性中,Filter被称为过滤器,Filter基本功能就是对Servlet容器调用Servlet的过程进行拦截,它位于客户端和处理程序之间,能够对请求和响应进行检查和修改。Filter就好比现实中的污水净化设备,专门用于过滤污水杂质。

Filter在Web应用中的拦截过程如下图所示:

P-V-E-GLN-9-OREH-9-Q3-K4.png

Filter可以在Web应用中被用于拦截请求和响应,以对它们进行预处理或修改。在一个Web应用中,可以配置多个Filter,这些Filter可以按照指定的顺序依次处理请求和响应。下面是一些常见的Filter拦截方式:

7.1.1. Filter拦截所有请求

可以使用通配符“/*”来拦截所有请求,例如:

<filter-mapping>
    <filter-name>MyFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

这样配置后,所有请求都会被MyFilter拦截。

7.1.2. Filter拦截某个URL模式

可以使用URL模式来拦截特定的URL请求,例如:

<filter-mapping>
    <filter-name>MyFilter</filter-name>
    <url-pattern>/admin/*</url-pattern>
</filter-mapping>

这样配置后,所有以“/admin/”开头的请求都会被MyFilter拦截。

7.1.3. Filter拦截特定的Servlet或JSP

可以使用Servlet或JSP的名称来拦截特定的Servlet或JSP请求,例如:

<filter-mapping>
    <filter-name>MyFilter</filter-name>
    <servlet-name>MyServlet</servlet-name>
</filter-mapping>

这样配置后,只有名为MyServlet的Servlet请求会被MyFilter拦截。

在Filter中,可以使用FilterConfig对象获取到web.xml中指定的初始化参数和ServletContext对象,也可以通过FilterChain对象将请求和响应传递给下一个Filter或目标资源进行处理。下面是一个使用Filter拦截特定URL模式的示例代码:

public class MyFilter implements Filter {
    private String prefix;

    public void init(FilterConfig filterConfig) throws ServletException {
        prefix = filterConfig.getInitParameter("prefix");
    }

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 
        throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) request;
        String uri = req.getRequestURI();
        if (uri.startsWith(prefix)) {
            // 对请求进行处理
            // ...
        } else {
            chain.doFilter(request, response);
        }
    }

    public void destroy() {
        prefix = null;
    }
}

在上面的代码中,MyFilter拦截所有以指定前缀开头的请求,并对这些请求进行处理。其他请求则交由FilterChain对象处理。在web.xml文件中,可以使用以下方式指定MyFilter:

<filter>
    <filter-name>MyFilter</filter-name>
    <filter-class>com.example.MyFilter</filter-class>
    <init-param>
        <param-name>prefix</param-name>
        <param-value>/admin/</param-value>
    </init-param>
</filter>

<filter-mapping>
    <filter-name>MyFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

在上面的代码中,filter元素指定了Filter的名称和类名,并通过init-param元素指定了拦截的URL前缀。filter-mapping元素指定了Filter的映射路径,这里使用了通配符“/*”,表示对所有请求进行过滤。

7.1.4. Filter链

在一个Web应用程序中可以注册多个Filter,每个Filter都可以针对某一个URL的请求进行拦截。如果多个Filter都对同一个URL的请求进行拦截,那么这些Filter就组成一个Filter链。Filter链使用FilterChain对象表示,FilterChain对象提供了一个doFilter()方法,该方法的作用是让Filter链上的当前过滤器放行,使请求进入下一个Filter。

Filter链的拦截过程图

AR68-7-CP-2-C-KCRL-R-2-V.png

当浏览器访问Web服务器中的资源时需要经过两个过滤器Filter1Filter2,首先Filter1会对这个请求进行拦截,在Filter1过滤器中处理好请求后,通过调用Filter1的doFilter()方法将请求传递给Filter2,Filter2将用户请求处理后同样调用doFilter()方法,最终将请求发送给目标资源。当Web服务器对这个请求做出响应时,响应结果也会被过滤器拦截,拦截顺序与之前相反,最终响应结果被发送给客户端。

Servlet3.0新增了**@WebFilter注解,当使用注解配置多个Filter时,用户无法控制它们的执行顺序,Filter的执行顺序是按照Filter的类名控制的,按自然排序的规则。例如,MyFilter01会比MyFilter02**优先执行。

chain.doFilter(request, response)

chain.doFilter(request, response)是一个过滤器链的调用方法,用于将请求和响应对象传递给下一个过滤器或Servlet。该方法必须在当前过滤器的doFilter()方法中调用,以便将请求和响应对象传递给下一个过滤器或Servlet。

在过滤器中,每个过滤器都需要调用chain.doFilter(request, response)方法,以便将请求和响应对象传递给下一个过滤器或Servlet。如果当前过滤器是最后一个过滤器,那么请求和响应对象将会传递给Servlet进行处理。

在调用chain.doFilter(request, response)之前,过滤器可以对请求和响应对象进行一些处理,例如修改请求参数、添加响应头等。在调用chain.doFilter(request, response)之后,过滤器可以对响应对象进行一些处理,例如修改响应内容、添加响应头等。

需要注意的是,在调用chain.doFilter(request, response)方法之前或之后,过滤器都可以中断请求处理或响应处理,并向客户端返回自定义的响应结果。例如,在验证用户登录信息时,如果验证失败,可以直接在过滤器中返回登录页面,而不是将请求和响应对象传递给下一个过滤器或Servlet。

chain.doFilter(request, response)方法是过滤器链中的关键方法之一,它负责将请求和响应对象传递给下一个过滤器或Servlet,并在处理过程中进行必要的处理和中断。

7.2. Listener

Listener(事件监听器)是Java Web应用程序中的一种机制,用于监听特定的事件,并在事件发生时执行相应的操作。通过使用Listener,开发人员可以在Web应用程序的不同生命周期阶段或事件发生时,执行自定义的逻辑和操作,以满足特定的需求。

7.2.1. Listener的重要组成部分

9-UA-S-XOUPVJC-J-PGR-X.png

7.2.2. Listener的工作过程
  1. 注册监听器:在Java Web应用程序中,可以通过web.xml文件或注解方式注册Listener。注册完成后,Listener就可以开始监听特定类型的事件。
  2. 监听事件:当特定类型的事件发生时,Web容器会通知已经注册的Listener。例如,当ServletContext对象创建时,Web容器会通知所有已经注册的ServletContextListener。
  3. 执行逻辑:当Listener接收到事件通知后,会执行自定义的逻辑和操作,例如初始化数据库连接池、加载配置文件、记录日志等。
  4. 完成处理:Listener处理完成后,Web容器会继续执行下一步操作,例如调用Servlet或转发请求等。

需要注意的是,Listener的执行顺序是根据其在web.xml文件中注册的顺序来决定的。如果有多个Listener监听同一个事件,那么按照注册顺序依次执行。

另外,Listener可以在Web应用程序的不同生命周期阶段或事件发生时进行监听和处理。例如,ServletContextListener可以监听ServletContext对象的创建和销毁事件,HttpSessionListener可以监听HttpSession对象的创建和销毁事件,ServletRequestListener可以监听ServletRequest对象的创建和销毁事件等。通过监听这些事件,开发人员可以在不同的阶段执行自定义的逻辑和操作,从而满足特定的需求。

总之,Listener是Java Web应用程序中非常重要的一个组件,它可以帮助开发人员实现一些特定的需求和目标,提高Web应用程序的可靠性、可维护性和可扩展性。

7.2.3. Listener的API

在Java Web应用程序中,常见的Listener包括以下三种:

  1. ServletContextListener:用于监听ServletContext对象的创建和销毁事件,即Web应用程序的启动和关闭事件。
  2. HttpSessionListener:用于监听HttpSession对象的创建和销毁事件,即用户会话的开始和结束事件。
  3. ServletRequestListener:用于监听ServletRequest对象的创建和销毁事件,即HTTP请求的开始和结束事件。

除了这些常见的Listener之外,Java Web应用程序还支持其他类型的Listener,例如ServletRequestAttributeListener、HttpSessionAttributeListener、ServletContextAttributeListener等,用于监听特定对象的属性变化事件。

在使用Listener时,开发人员需要实现特定的Listener接口,并在web.xml文件中进行配置,以便在Web应用程序启动时自动注册。在Listener中,可以编写自定义的逻辑和操作,例如初始化数据库连接池、加载配置文件、记录日志等。

7.3. Servlet 3.0新特性

Servlet 3.0是Java Servlet API的最新版本,引入了一些新的特性和改进,包括:

  1. 异步支持:Servlet 3.0引入了异步Servlet的支持,可以通过异步方式处理HTTP请求和响应,从而提高应用程序的性能和吞吐量。
  2. 注解支持:Servlet 3.0引入了注解支持,可以使用注解来配置Servlet、Filter和Listener等组件,使得配置更加简洁和易于理解。
  3. Servlet容器初始化:Servlet 3.0引入了Servlet容器初始化特性,可以在应用程序启动时自动初始化Servlet容器,并执行一些必要的初始化操作,提高应用程序的启动速度和可靠性。
  4. Servlet过滤器改进:Servlet 3.0对过滤器进行了改进,可以通过注解方式配置过滤器,支持过滤器链的动态添加和移除,提高了过滤器的灵活性和可扩展性。
  5. 强制安全:Servlet 3.0引入了强制安全特性,可以通过配置来强制使用安全连接(HTTPS),从而保护Web应用程序的安全性。
  6. Servlet事件:Servlet 3.0引入了Servlet事件机制,可以监听Servlet的生命周期事件和HTTP请求事件,从而实现一些特定的需求和目标。

DD-86-BIX-3-H-5-RX62-AT.png

7.3.1. Servlet 3.0常见的注解

1. @WebServlet:用于标识一个Servlet类,可以指定Servlet的URL映射、初始化参数、加载顺序等信息。

格式:

@WebServlet(name = "servletName", urlPatterns = { "/urlPattern1", "/urlPattern2" })
public class MyServlet extends HttpServlet {
    // Servlet implementation
}

示例代码:

@WebServlet(name = "helloServlet", urlPatterns = { "/hello" })
public class HelloServlet extends HttpServlet {
 
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
 
        String name = req.getParameter("name");
        if (name == null) {
            name = "world";
        }
 
        resp.setContentType("text/plain");
        resp.getWriter().write("Hello, " + name + "!");
    }
}

2. @WebFilter:用于标识一个过滤器类,可以指定过滤器的URL映射、初始化参数、执行顺序等信息。

格式:

@WebFilter(filterName = "filterName", urlPatterns = { "/urlPattern1", "/urlPattern2" })
public class MyFilter implements Filter {
    // Filter implementation
}

示例代码:

@WebFilter(filterName = "loggingFilter", urlPatterns = { "/*" })
public class LoggingFilter implements Filter {
 
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
 
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        String requestURI = httpRequest.getRequestURI();
 
        System.out.println("Request received for " + requestURI);
 
        chain.doFilter(request, response);
    }
 
    //...省略其他方法实现
}

3.@WebListener:用于标识一个监听器类,可以指定监听器监听的事件类型。

格式:

@WebListener
public class MyListener implements ServletContextListener {
    // Listener implementation
}

示例代码:

@WebListener
public class AppContextListener implements ServletContextListener {
 
    @Override
    public void contextInitialized(ServletContextEvent sce) {
        System.out.println("Application context initialized");
    }
 
    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        System.out.println("Application context destroyed");
    }
}

4. @MultipartConfig:用于标识一个Servlet的文件上传配置,可以指定文件上传的最大大小、临时文件路径等信息。

格式:

@MultipartConfig(location = "/tmp", fileSizeThreshold = 1024 * 1024, maxFileSize = 1024 * 1024 * 10, maxRequestSize = 1024 * 1024 * 50)
public class FileUploadServlet extends HttpServlet {
    // Servlet implementation
}

示例代码:

@WebServlet(name = "fileUploadServlet", urlPatterns = { "/fileUpload" })
@MultipartConfig(location = "/tmp", fileSizeThreshold = 1024 * 1024, maxFileSize = 1024 * 1024 * 10, maxRequestSize = 1024 * 1024 * 50)
public class FileUploadServlet extends HttpServlet {
 
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
 
        Part filePart = request.getPart("file");
        String fileName = Paths.get(filePart.getSubmittedFileName()).getFileName().toString();
        InputStream fileContent = filePart.getInputStream();
 
        //...处理文件上传
    }
}

5. @ServletSecurity:用于标识一个Servlet的安全配置,可以指定Servlet的安全约束、角色授权等信息。

@WebServlet(name = "secureServlet", urlPatterns = { "/secure" })
@ServletSecurity(@HttpConstraint(rolesAllowed = { "admin" }))
public class SecureServlet extends HttpServlet {
    // Servlet implementation
}

示例代码:

@WebServlet(name = "secureServlet", urlPatterns = { "/secure" })
@ServletSecurity(@HttpConstraint(rolesAllowed = { "admin" }))
public class SecureServlet extends HttpServlet {
 
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
 
        resp.setContentType("text/plain");
        resp.getWriter().write("This is a secure page");
    }
}

6. @HandlesTypes:用于标识一个ServletContainerInitializer实现类,可以指定需要处理的类类型。

格式:

@HandlesTypes({ MyClass1.class, MyClass2.class })
public class MyServletContainerInitializer implements ServletContainerInitializer {
    // ServletContainerInitializer implementation
}

示例代码:

@HandlesTypes({ MyServlet.class, MyFilter.class })
public class MyServletContainerInitializer implements ServletContainerInitializer {
 
    @Override
    public void onStartup(Set<Class<?>> classes, ServletContext servletContext) throws ServletException {
 
        for (Class<?> clazz : classes) {
            if (clazz.isAssignableFrom(MyServlet.class)) {
                //...处理MyServlet类
            } else if (clazz.isAssignableFrom(MyFilter.class)) {
                //...处理MyFilter类
            }
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值