以30个面试问题和案例为导向:全面解析 Java Servlet是什么?基本概念、实现原理、生命周期、类结构、请求与响应的处理机制,以及性能优化和安全性管理
Servlet 是 Java Web 开发的核心组件之一,负责处理客户端请求并生成动态响应。本文将深入探讨 Servlet 的基本概念、实现原理、生命周期、类结构、请求与响应的处理机制,以及性能优化和安全性管理,帮助开发者从多方面掌握 Servlet。
文章目录
- 1. Servlet的基本概念
- 1.1 Servlet 是什么?它的作用是什么?
- 作用:
- 案例:
- 1.2 Servlet 和 JSP 之间的区别
- 案例:
- 1.3 Servlet 和其他 Java EE 组件的关系
- 案例:
- 2. Servlet 的实现原理
- 2.1 Servlet 是如何与 HTTP 协议进行交互的?
- 案例:
- 2.2 Servlet 容器如何管理和调度 Servlet?
- 容器调度流程:
- 2.3 Servlet 容器如何处理并发请求?如何保证线程安全?
- 处理线程安全问题的方式:
- 案例:
- 3. Servlet 的生命周期
- 3.1 Servlet 的生命周期是怎样的?有哪些关键阶段?
- 3.2 `init()`、`service()` 和 `destroy()` 的作用
- 案例:
- 3.3 Servlet 的生命周期管理由谁负责?
- 3.4 如何确保资源的正确初始化和释放?
- 4. Servlet 类的结构与类型
- 4.1 Servlet 类有哪些常见的实现类?
- 4.2 `GenericServlet` 和 `HttpServlet` 的区别
- 4.3 如何自定义一个 Servlet?有哪些基本步骤?
- 案例:
- 5. Servlet 中的请求与响应
- 5.1 Servlet 如何处理 HTTP 请求?有哪些常见的请求方法?
- 案例:
- 5.2 如何在 Servlet 中获取请求参数?如何处理文件上传?
- 案例:获取表单参数
- 案例:文件上传处理
- 5.3 如何发送 HTTP 响应?如何设置响应的状态码、内容类型和输出流?
- 案例:发送 JSON 响应
- 5.4 Servlet 如何处理重定向和请求转发?它们的区别是什么?
- 区别:
- 案例:重定向
- 案例:请求转发
- 6. Servlet 的配置与部署
- 6.1 在 `web.xml` 中如何配置 Servlet?有哪些配置选项?
- 案例:`web.xml` 中的 Servlet 配置
- 6.2 什么是 Servlet 的 URL 映射?如何定义 Servlet 的访问路径?
- 案例:使用 `@WebServlet` 注解映射 URL
- 6.3 如何使用注解来配置 Servlet(如 `@WebServlet`)?
- 案例:使用 `@WebServlet` 注解配置 Servlet
- 7. Servlet 的会话管理
- 7.1 什么是 Session 和 Cookie?Servlet 如何管理它们?
- 案例:使用 Session 管理用户会话
- 7.2 如何在 Servlet 中维护用户会话?
- 案例:访问用户会话信息
- 7.3 Session 的生命周期是怎样的?如何避免 Session 丢失?
- 配置 Session 过期时间的案例:
- 8. Servlet 的性能优化
- 8.1 如何提高 Servlet 的并发处理能力?
- 案例:Servlet 异步处理
- 8.2 Servlet 的性能瓶颈有哪些?如何进行调优?
- 8.3 Servlet 中如何使用缓存来提升响应速度?
- 案例:设置页面缓存
- 9. Servlet 与安全性
- 9.1 Servlet 如何处理身份验证和授权?
- 案例:在 `web.xml` 中配置安全约束
- 9.2 Servlet 如何防御常见的 Web 安全攻击?
- 案例:使用 `PreparedStatement` 防止 SQL 注入
- 9.3 如何在 Servlet 中使用 HTTPS 和 SSL 进行安全通信?
- 配置 HTTPS 的步骤:
- 案例:强制使用 HTTPS
- 总结
- 三大域对象的比较
1. Servlet的基本概念
1.1 Servlet 是什么?它的作用是什么?
Servlet 是 Java EE 中用于生成动态 Web 内容的服务器端组件,负责接收来自客户端(通常是 Web 浏览器)的 HTTP 请求,处理后生成响应。Servlet 运行在 Servlet 容器(如 Tomcat、Jetty 等)中,它是 Java Web 应用程序的基础。
作用:
- 处理客户端请求(如表单提交、AJAX 请求)
- 与数据库或其他后端服务交互
- 根据业务逻辑生成响应,通常是 HTML 页面或 JSON 数据
案例:
假设你有一个登录页面,用户输入用户名和密码并点击登录。Servlet 可以处理这个请求,验证用户名和密码是否正确,并返回一个结果页面。如果登录成功,可能重定向到用户主页;如果失败,则返回错误消息。
@WebServlet("/login")
public class LoginServlet extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {String username = request.getParameter("username");String password = request.getParameter("password");if ("admin".equals(username) && "1234".equals(password)) {response.sendRedirect("home.jsp");} else {response.getWriter().println("Invalid login credentials");}}
}
1.2 Servlet 和 JSP 之间的区别
Servlet 和 JSP 都用于生成动态 Web 内容,但它们的角色不同:
- Servlet:偏向于逻辑处理,适合处理复杂的业务逻辑和控制流程。
- JSP:主要用于表示层,负责将 HTML 页面与 Java 代码混合,方便页面开发。
特性 | Servlet | JSP |
---|---|---|
语法 | 纯 Java 代码 | HTML 中嵌入 Java 代码 |
用途 | 控制和业务逻辑 | 页面展示 |
编译过程 | 原生 Java 类 | 被编译成 Servlet |
开发难度 | 比 JSP 难,逻辑代码较多 | 易于使用,适合前端开发人员 |
案例:
在大型应用中,你可能会使用 Servlet 处理业务逻辑,而将结果转发到 JSP 页面进行展示。例如,一个查询数据库的 Servlet 可以将查询结果传递给 JSP 页面进行渲染。
@WebServlet("/queryUser")
public class UserQueryServlet extends HttpServlet {protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {List<User> users = userService.queryAllUsers();request.setAttribute("userList", users);request.getRequestDispatcher("/userList.jsp").forward(request, response);}
}
1.3 Servlet 和其他 Java EE 组件的关系
Servlet 在 Java EE 中通常与以下组件协同工作:
- Filter:用于在请求到达 Servlet 之前或响应发出之前对请求或响应进行过滤。常用于日志、权限验证等场景。
- Listener:用于监听 Servlet 容器中的各种事件(如请求创建、Session 创建、应用上下文初始化等),常用于状态监控、资源初始化。
案例:
使用 Filter 进行权限验证。在每个请求到达特定 Servlet 之前,先检查用户是否已登录。未登录则重定向到登录页面。
@WebFilter("/protected/*")
public class AuthFilter implements Filter {public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {HttpServletRequest req = (HttpServletRequest) request;HttpSession session = req.getSession(false);if (session == null || session.getAttribute("user") == null) {((HttpServletResponse) response).sendRedirect("/login.jsp");} else {chain.doFilter(request, response);}}
}
2. Servlet 的实现原理
2.1 Servlet 是如何与 HTTP 协议进行交互的?
Servlet 基于 HTTP 协议工作,客户端通过 HTTP 请求访问服务器资源,Servlet 通过 HttpServletRequest
和 HttpServletResponse
与 HTTP 协议交互。
- HttpServletRequest:封装了来自客户端的请求信息,包括请求参数、请求头、Cookie 等。
- HttpServletResponse:用于将服务器处理结果返回给客户端,可以设置状态码、响应头、响应内容等。
案例:
一个典型的 Servlet 响应流程:客户端通过浏览器发送 GET
请求访问 /hello
,服务器通过 HttpServletResponse
返回 HTML 内容。
@WebServlet("/hello")
public class HelloServlet extends HttpServlet {protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {response.setContentType("text/html");PrintWriter out = response.getWriter();out.println("<h1>Hello, World!</h1>");}
}
2.2 Servlet 容器如何管理和调度 Servlet?
Servlet 容器(如 Tomcat)负责管理 Servlet 的生命周期,包括创建、初始化、处理请求和销毁。容器通过 URL 映射找到对应的 Servlet,创建一个线程来处理该请求,并通过线程池来管理并发请求。
容器调度流程:
- 接收请求:客户端发送 HTTP 请求到服务器。
- URL 映射:根据请求的 URL 映射到对应的 Servlet。
- 线程处理:容器为每个请求分配一个线程,调用 Servlet 的
service()
方法处理请求。 - 生成响应:Servlet 处理完后,通过
HttpServletResponse
返回响应。
2.3 Servlet 容器如何处理并发请求?如何保证线程安全?
Servlet 容器使用线程池来处理并发请求,每个请求在独立的线程中处理。Servlet 默认是多线程的,多个请求可以并发访问同一个 Servlet 实例,因此可能存在线程安全问题。
处理线程安全问题的方式:
- 局部变量:避免使用共享变量,将数据存储在局部变量中。
- 同步锁:对共享资源进行同步,但可能导致性能瓶颈。
- 无状态设计:尽量避免在 Servlet 中存储状态信息,保持无状态的设计有助于提高并发能力。
案例:
假设我们有一个计数器 Servlet,它记录访问的次数。如果不加同步,可能会出现并发问题。
@WebServlet("/counter")
public class CounterServlet extends HttpServlet {private int count = 0;protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {synchronized (this) {count++;}response.getWriter().println("Count: " + count);}
}
3. Servlet 的生命周期
3.1 Servlet 的生命周期是怎样的?有哪些关键阶段?
Servlet 的生命周期由 Servlet 容器管理,包含以下关键阶段:
- 加载和实例化:当 Servlet 第一次被请求或容器启动时,容器会加载 Servlet 类并实例化它。
- 初始化:调用
init()
方法进行初始化,通常在这个阶段分配资源,如数据库连接。 - 请求处理:每次请求都会调用
service()
方法,该方法根据请求类型(GET、POST 等)调用相应的doGet()
或doPost()
。 - 销毁:当 Servlet 容器关闭或重新加载应用时,调用
destroy()
方法释放资源。
3.2 init()
、service()
和 destroy()
的作用
init()
:Servlet 的初始化方法,通常用于资源分配或初始化参数读取。service()
:每次请求调用该方法,负责分发请求到doGet()
、doPost()
等方法。destroy()
:在 Servlet 被卸载或容器关闭时调用,用于释放资源。
案例:
@WebServlet("/example")
public class ExampleServlet extends HttpServlet {public void init() throws ServletException {// 初始化资源,如数据库连接System.out.println("Servlet is being initialized");}protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {response.getWriter().println("Servlet is handling a GET request");}public void destroy() {// 释放资源System.out.println("Servlet is being destroyed");}
}
3.3 Servlet 的生命周期管理由谁负责?
Servlet 的生命周期由 Servlet 容器(如 Tomcat、Jetty)管理,开发者只需关注如何编写 init()
、service()
和 destroy()
方法,其他生命周期管理细节由容器负责。
3.4 如何确保资源的正确初始化和释放?
为了确保资源的正确初始化和释放,应该:
- 在
init()
方法中初始化需要的资源,如数据库连接。 - 在
destroy()
方法中释放这些资源,避免资源泄漏。
4. Servlet 类的结构与类型
4.1 Servlet 类有哪些常见的实现类?
Servlet 是一个接口,常见的实现类有以下两种:
GenericServlet
:一个协议无关的基础 Servlet 类,所有具体的 Servlet 实现都可以继承自它。它实现了Servlet
接口的所有方法,并引入了service()
方法,开发者可以通过继承GenericServlet
来扩展任意协议的 Servlet。HttpServlet
:是专门用于处理 HTTP 协议请求的子类。它继承自GenericServlet
,并提供了doGet()
、doPost()
等方法来处理不同的 HTTP 请求类型。
4.2 GenericServlet
和 HttpServlet
的区别
GenericServlet
:与协议无关,适用于除 HTTP 之外的其他协议。开发者需要自行实现service()
方法。HttpServlet
:是GenericServlet
的子类,专门处理 HTTP 请求,提供了简便的方法,如doGet()
、doPost()
,让开发者可以直接处理不同的 HTTP 请求类型。
特性 | GenericServlet | HttpServlet |
---|---|---|
协议 | 通用协议 | HTTP 协议 |
方法 | 需要自己实现 service() | 提供了 doGet() 、doPost() 等 |
用途 | 适用于任意协议的 Servlet | 专门处理 HTTP 请求 |
4.3 如何自定义一个 Servlet?有哪些基本步骤?
自定义一个 Servlet 主要包括以下步骤:
- 继承
HttpServlet
类:选择继承HttpServlet
,因为大多数 Web 应用使用 HTTP 协议。 - 覆盖请求处理方法:实现
doGet()
或doPost()
方法来处理客户端请求。 - 部署到 Servlet 容器中:通过
web.xml
配置文件或使用注解配置 Servlet,并将其部署到 Servlet 容器中。
案例:
创建一个自定义的 HelloServlet
,处理 GET 请求,并返回一段简单的 HTML 代码。
@WebServlet("/hello")
public class HelloServlet extends HttpServlet {protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {response.setContentType("text/html");PrintWriter out = response.getWriter();out.println("<h1>Hello, World!</h1>");}
}
在这个案例中,HelloServlet
继承了 HttpServlet
,重写了 doGet()
方法来处理 GET 请求。
5. Servlet 中的请求与响应
5.1 Servlet 如何处理 HTTP 请求?有哪些常见的请求方法?
Servlet 使用 HttpServletRequest
对象处理 HTTP 请求,常见的请求方法包括:
- GET:用于获取资源,通常在浏览器地址栏输入 URL 或点击链接时触发。
- POST:用于提交表单数据,数据在请求体中传递。
- PUT:用于更新资源。
- DELETE:用于删除资源。
案例:
处理不同的 HTTP 请求方法,分别响应 GET 和 POST 请求。
@WebServlet("/user")
public class UserServlet extends HttpServlet {protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {response.getWriter().println("This is a GET request.");}protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {response.getWriter().println("This is a POST request.");}
}
5.2 如何在 Servlet 中获取请求参数?如何处理文件上传?
- 获取请求参数:可以通过
HttpServletRequest.getParameter()
方法获取请求中的参数,例如从表单提交的数据中获取参数。
案例:获取表单参数
@WebServlet("/login")
public class LoginServlet extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {String username = request.getParameter("username");String password = request.getParameter("password");response.getWriter().println("Username: " + username + ", Password: " + password);}
}
- 文件上传处理:Servlet 3.0 提供了文件上传的支持,可以使用
@MultipartConfig
注解和Part
对象处理文件上传。
案例:文件上传处理
@WebServlet("/upload")
@MultipartConfig
public class FileUploadServlet extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {Part filePart = request.getPart("file"); // 获取文件String fileName = filePart.getSubmittedFileName(); // 获取文件名InputStream fileContent = filePart.getInputStream(); // 获取文件内容// 保存文件或处理上传的内容response.getWriter().println("File uploaded: " + fileName);}
}
5.3 如何发送 HTTP 响应?如何设置响应的状态码、内容类型和输出流?
Servlet 可以通过 HttpServletResponse
发送响应。常见操作包括:
- 设置状态码:使用
response.setStatus()
设置状态码,如 200、404、500 等。 - 设置内容类型:使用
response.setContentType()
设置响应类型,如text/html
、application/json
。 - 使用输出流:通过
response.getWriter()
或response.getOutputStream()
返回响应数据。
案例:发送 JSON 响应
@WebServlet("/json")
public class JsonServlet extends HttpServlet {protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {response.setContentType("application/json");PrintWriter out = response.getWriter();out.println("{\"message\": \"Hello, JSON!\"}");}
}
5.4 Servlet 如何处理重定向和请求转发?它们的区别是什么?
- 重定向:使用
response.sendRedirect()
,告诉客户端发起新的请求,常用于登录后的页面跳转。 - 请求转发:使用
RequestDispatcher.forward()
,在服务器端将请求转发给另一个资源,而客户端无法察觉。
区别:
- 重定向:客户端会看到 URL 变化,发起两次请求。
- 请求转发:URL 不变,发生在服务器端,仅发起一次请求。
案例:重定向
@WebServlet("/redirect")
public class RedirectServlet extends HttpServlet {protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {response.sendRedirect("/newPage");}
}
案例:请求转发
@WebServlet("/forward")
public class ForwardServlet extends HttpServlet {protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {RequestDispatcher dispatcher = request.getRequestDispatcher("/newPage");dispatcher.forward(request, response);}
}
6. Servlet 的配置与部署
6.1 在 web.xml
中如何配置 Servlet?有哪些配置选项?
web.xml
是 Servlet 配置文件,用于定义 Servlet 的映射、初始化参数等。常见配置项包括:
<servlet>
:定义 Servlet 的名称和类。<servlet-mapping>
:定义 Servlet 的 URL 映射。<init-param>
:定义 Servlet 的初始化参数。
案例:web.xml
中的 Servlet 配置
<web-app><servlet><servlet-name>helloServlet</servlet-name><servlet-class>com.example.HelloServlet</servlet-class></servlet><servlet-mapping><servlet-name>helloServlet</servlet-name><url-pattern>/hello</url-pattern></servlet-mapping>
</web-app>
6.2 什么是 Servlet 的 URL 映射?如何定义 Servlet 的访问路径?
URL 映射是将客户端请求的 URL 路径映射到特定的 Servlet 上。通过 web.xml
中的 <url-pattern>
或 @WebServlet
注解来定义访问路径。
案例:使用 @WebServlet
注解映射 URL
@WebServlet("/hello")
public class HelloServlet extends HttpServlet {protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {response.getWriter().println("Hello, Servlet!");}
}
6.3 如何使用注解来配置 Servlet(如 @WebServlet
)?
自 Servlet 3.0 以来,可以使用注解来配置 Servlet,简化了配置过程,减少了对 web.xml
的依赖。
案例:使用 @WebServlet
注解配置 Servlet
@WebServlet(urlPatterns = {"/hello", "/greet"})
public class GreetingServlet extends HttpServlet {protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {response.getWriter().println("Greetings from Servlet!");}
}
7. Servlet 的会话管理
7.1 什么是 Session 和 Cookie?Servlet 如何管理它们?
- Session:服务器端保存的用户会话信息,它在多个请求之间保存用户状态。每个用户在访问服务器时都会有一个唯一的
Session ID
,服务器通过这个 ID 来识别不同的用户会话。 - Cookie:客户端保存的小块数据,用来存储用户的状态信息。浏览器会在之后的请求中自动带上 Cookie,帮助服务器识别用户。
Session
的Session ID
通常通过Cookie
存储在客户端。
案例:使用 Session 管理用户会话
@WebServlet("/login")
public class LoginServlet extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {String username = request.getParameter("username");HttpSession session = request.getSession(); // 获取或创建一个新的会话session.setAttribute("username", username); // 保存用户信息到会话中response.getWriter().println("User logged in: " + username);}
}
7.2 如何在 Servlet 中维护用户会话?
HttpSession
:使用HttpSession
对象管理用户会话,可以通过request.getSession()
方法获取会话对象。- 可以通过
session.setAttribute()
设置会话属性,使用session.getAttribute()
获取属性。
案例:访问用户会话信息
@WebServlet("/dashboard")
public class DashboardServlet extends HttpServlet {protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {HttpSession session = request.getSession(false); // 获取已有会话if (session != null && session.getAttribute("username") != null) {String username = (String) session.getAttribute("username");response.getWriter().println("Welcome back, " + username);} else {response.getWriter().println("No active session found. Please log in.");}}
}
7.3 Session 的生命周期是怎样的?如何避免 Session 丢失?
-
Session 的生命周期:
- Session 从创建到销毁经历以下阶段:
- 创建:用户第一次访问服务器时,服务器为该用户创建一个新的会话。
- 活跃状态:在用户交互期间,Session 处于活跃状态。
- 过期:如果用户长时间不与服务器交互,Session 会自动过期(默认 30 分钟)。
- 销毁:服务器可以在 Session 超时或通过
session.invalidate()
手动销毁 Session。
- Session 从创建到销毁经历以下阶段:
-
避免 Session 丢失的方法:
- 增加 Session 的过期时间:通过
web.xml
文件或在代码中设置。 - 使用持久化 Session 的方式(如分布式缓存)来应对多服务器集群中 Session 的丢失。
- 增加 Session 的过期时间:通过
配置 Session 过期时间的案例:
<session-config><session-timeout>60</session-timeout> <!-- 设置 Session 过期时间为 60 分钟 -->
</session-config>
8. Servlet 的性能优化
8.1 如何提高 Servlet 的并发处理能力?
Servlet 默认使用多线程处理请求,可以通过以下方式优化并发处理能力:
- 线程池:通过 Servlet 容器配置线程池,避免频繁创建和销毁线程,提高并发能力。
- 非阻塞 I/O:使用非阻塞 I/O(如
NIO
)减少 I/O 操作的等待时间,提高系统响应速度。 - 异步处理:Servlet 3.0 引入了异步处理,可以将耗时操作放到独立的线程中执行,减少主线程的阻塞。
案例:Servlet 异步处理
@WebServlet(urlPatterns = "/async", asyncSupported = true)
public class AsyncServlet extends HttpServlet {protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {AsyncContext asyncContext = request.startAsync(); // 启动异步上下文asyncContext.start(() -> {try {// 模拟耗时操作Thread.sleep(5000);PrintWriter out = asyncContext.getResponse().getWriter();out.println("Async task completed.");asyncContext.complete(); // 任务完成,关闭异步上下文} catch (Exception e) {e.printStackTrace();}});}
}
8.2 Servlet 的性能瓶颈有哪些?如何进行调优?
常见的性能瓶颈:
- I/O 操作缓慢:如数据库查询、文件读取等,可以通过使用缓存或异步 I/O 来提升性能。
- 线程管理不当:线程创建和销毁成本高,建议使用线程池管理。
- Session 管理不当:过多的 Session 或不合理的 Session 超时时间会占用大量内存,可以通过优化 Session 管理策略来减少内存开销。
8.3 Servlet 中如何使用缓存来提升响应速度?
- 页面缓存:使用
Cache-Control
或Expires
响应头来设置页面缓存。 - 数据缓存:对于频繁访问的数据,可以将其缓存到内存中,减少数据库查询次数。
案例:设置页面缓存
@WebServlet("/cachedPage")
public class CachedPageServlet extends HttpServlet {protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {response.setHeader("Cache-Control", "max-age=3600"); // 缓存页面 1 小时response.getWriter().println("This page is cached for 1 hour.");}
}
9. Servlet 与安全性
9.1 Servlet 如何处理身份验证和授权?
- 身份验证:通常通过用户登录进行身份验证,Servlet 可以使用
HttpSession
存储用户的认证状态。 - 授权:通过用户的角色和权限控制对特定资源的访问,使用
web.xml
中的<security-constraint>
标签或通过代码实现权限控制。
案例:在 web.xml
中配置安全约束
<security-constraint><web-resource-collection><web-resource-name>Protected Area</web-resource-name><url-pattern>/admin/*</url-pattern></web-resource-collection><auth-constraint><role-name>admin</role-name></auth-constraint>
</security-constraint><login-config><auth-method>BASIC</auth-method><realm-name>Admin Area</realm-name>
</login-config>
9.2 Servlet 如何防御常见的 Web 安全攻击?
- SQL 注入:通过使用预编译语句(
PreparedStatement
)来防止 SQL 注入。 - XSS(跨站脚本攻击):对用户输入进行编码,防止恶意脚本注入到 HTML 中。
- CSRF(跨站请求伪造):使用 CSRF 令牌(
CSRF Token
)进行验证,确保请求是由合法用户发起的。
案例:使用 PreparedStatement
防止 SQL 注入
String query = "SELECT * FROM users WHERE username = ? AND password = ?";
PreparedStatement stmt = connection.prepareStatement(query);
stmt.setString(1, username);
stmt.setString(2, password);
ResultSet rs = stmt.executeQuery();
9.3 如何在 Servlet 中使用 HTTPS 和 SSL 进行安全通信?
通过配置服务器支持 HTTPS,并使用 SSL 证书加密通信,确保数据传输的安全性。
配置 HTTPS 的步骤:
- 获取 SSL 证书。
- 在服务器中配置 HTTPS。
- 强制所有请求使用 HTTPS,可以通过
web.xml
中的<security-constraint>
标签进行配置。
案例:强制使用 HTTPS
<security-constraint><web-resource-collection><web-resource-name>Secure Area</web-resource-name><url-pattern>/*</url-pattern></web-resource-collection><user-data-constraint><transport-guarantee>CONFIDENTIAL</transport-guarantee></user-data-constraint>
</security-constraint>
总结
三大域对象的比较
特性 | HttpServletRequest(请求对象) | HttpSession(用户会话对象) | ServletContext(全局对象) |
---|---|---|---|
作用域 | 单次请求 | 用户会话范围 | 整个应用程序范围 |
生命周期 | 一次请求内有效 | 用户会话期间有效 | 应用启动到应用停止期间有效 |
典型用途 | 请求参数传递,转发数据 | 存储用户登录状态、购物车信息等 | 存储全局配置信息或资源 |
常用方法 | getParameter() ,setAttribute() | getAttribute() ,setAttribute() | getInitParameter() ,getRealPath() |
数据共享 | 同一次请求的各个组件共享数据 | 同一用户的多个请求间共享数据 | 应用程序的所有用户共享数据 |
通过对三大域对象的深入理解,我们能够根据不同的场景选择合适的对象来存储和共享数据,合理利用这些域对象可以有效提升 JavaWeb 应用的开发效率与性能。
Servlet 作为 Java Web 开发的核心,涵盖了请求处理、并发管理、会话维护、安全防护等多个方面。掌握 Servlet 对构建高性能、可靠的 Web 应用至关重要。
相关文章:
以30个面试问题和案例为导向:全面解析 Java Servlet是什么?基本概念、实现原理、生命周期、类结构、请求与响应的处理机制,以及性能优化和安全性管理
Servlet 是 Java Web 开发的核心组件之一,负责处理客户端请求并生成动态响应。本文将深入探讨 Servlet 的基本概念、实现原理、生命周期、类结构、请求与响应的处理机制,以及性能优化和安全性管理,帮助开发者从多方面掌握 Servlet。 文章目录…...
MFC小游戏设计
框架: 各个界面: 用户: 登录注册:账号和密码(昵称) 主菜单:各种游戏,查看自己信息(积分,装备【游戏数据】),退出 游戏界面&#…...
[漏洞挖掘与防护] 04.Windows系统安全缺陷之5次Shift漏洞启动计算机机理分析
这是作者新开的一个专栏——“漏洞挖掘与防护”,前期会复现各种经典和最新漏洞,并总结防护技巧;后期尝试从零学习漏洞挖掘技术,包括Web漏洞和二进制及IOT相关漏洞,以及Fuzzing技术。新的征程,新的开启,漫漫长征路,偏向虎山行。享受过程,感谢您的陪伴,一起加油~ 欢迎关…...

手机极简待办app哪款好用?
在快节奏的现代生活中,我们常常需要处理大量的任务和信息,这时候一款好用的极简待办软件就显得尤为重要。它们不仅能帮助我们记录和管理待办事项,还能提高我们的工作效率和生活质量。 在众多的待办软件中,敬业签是一款非常受欢迎…...

SpringBoot高级-底层原理
目录 1 SpringBoot自动化配置原理 01-SpringBoot2高级-starter依赖管理机制 02-SpringBoot2高级-自动化配置初体验 03-SpringBoot2高级-底层原理-Configuration配置注解 04-SpringBoot2高级-底层原理-Import注解使用1 05-SpringBoot2高级-底层原理-Import注解使用2 06-S…...

LabVIEW提高开发效率技巧----插入式架构
随着LabVIEW项目规模的扩大和系统复杂性的增加,传统的单一代码架构难以应对后期维护和功能扩展的需求。插入式架构(Plug-In Architecture)作为一种模块化设计方式,通过动态加载和运行子VI,使系统功能更加灵活、模块化&…...

MySQL COUNT(*)、COUNT(1)、COUNT(id)、COUNT(字段)效果及性能
文章目录 前言COUNT(exper)COUNT(*)优化COUNT(*) 与COUNT(1) COUNT(1)COUNT(id)COUNT(字段)总结参考 前言 业务开发中,我们经常要使用count做一些数据统计。今天根据MySQL5.7官方文档及丁奇老师的MySQL45讲,介绍一下COUNT(*)、COUNT(1)、COUNT(id)、COU…...
webpack4 - 动态导入文件 dynamic-import 报错的解决方法
介绍 webpack4动态导入文件报错,按照错误提示安装了插件,但未果。。 最后查到一个可行方案,记录如下。 1.通过懒加载的方式动态引入文件 const router new Router({routes: [{path: /home,name: Home,component: () >import(./views/h…...
【NodeJS】NodeJS+mongoDB在线版开发简单RestfulAPI (四):状态码的使用
本项目旨在学习如何快速使用 nodejs 开发后端api,并为以后开展其他项目的开启提供简易的后端模版。(非后端工程师) 由于文档是代码写完之后,为了记录项目中需要注意的技术点,因此文档的叙述方式并非开发顺序࿰…...

springboot061基于B2B平台的医疗病历交互系统(论文+源码)_kaic
摘 要 进入21世纪,计算机技术迅速向着网络化的、集成化方向发展。传统的单机版应用软件正在逐渐退出舞台,取而代之的是支持网络、支持多种数据信息的新一代网络版应用软件,形成了信息化的社会。信息化社会的形成和微电子技术日新月异的发展&…...

基于FFT + CNN -Transformer时域、频域特征融合的电能质量扰动识别模型
往期精彩内容: Python-电能质量扰动信号数据介绍与分类-CSDN博客 Python电能质量扰动信号分类(一)基于LSTM模型的一维信号分类-CSDN博客 Python电能质量扰动信号分类(二)基于CNN模型的一维信号分类-CSDN博客 Python电能质量扰动信号分类(三)基于Transformer的一…...

JAVA开发环境:IntelliJ IDEA、Java JDK、Maven 安装配置
一、安装IntelliJ IDEA 准备安装包 通过百度网盘分享的文件:idea2023.2U**.zip 链接:https://pan.baidu.com/s/1NB04A-jMXhZKsewYshGt-Q 提取码:oeft 安装 IntelliJ IDEA (1)、解压,安装文件如下&#…...

鸿蒙软件开发中常见的如何快速自动生成二维码?QRCode组件
QRCode 用于显示单个二维码的组件。 说明: 该组件从API Version 7开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。 二维码组件的像素点数量与内容有关,当组件尺寸过小时,可能出现无法展示内容的情况&…...

鸿蒙HarmonyOS NEXT 5.0开发(2)—— ArkUI布局组件
文章目录 布局Column:从上往下的布局Row:从左往右的布局Stack:堆叠布局Flex:自动换行或列 组件Swiper各种选择组件 华为官方教程B站视频教程 布局 主轴和交叉轴的概念: 对于Column布局而言,主轴是垂直方…...
【openGauss】OPENGAUSS/POSTGRESQL 中float类型到int类型的隐式转换
下面这条sql在oracle和POSTGRESQL/OPENGAUSS中的查询结果不一致 select cast(cast(0.5 as float) as integer);在oracle中返回1,在openGauss中返回0,咋一看好像是openGauss中使用了截断的方式,但是如果执行 select cast(cast(1.5 as float) as integ…...

Docker:安装 Syslog-ng 的技术指南
1、简述 Syslog-ng 是一种流行的日志管理工具,能够集中处理和分析日志。通过 Docker 安装 Syslog-ng 可以简化部署和管理过程。本文将介绍如何使用 Docker 安装 Syslog-ng,并提供一个 Java 示例来展示如何将日志发送到 Syslog-ng。 2、安装 2.1 创建…...

即插即用的3D神经元注意算法!
本文所涉及所有资源均在 传知代码平台 可获取。 目录 3D神经元注意力:为每一个神经元分配权重!(算法) 一、概述 二、研究背景 三、主要贡献 四、模型结构和代码 五、数据集介绍 六、性能展示 六、复现过程 七、运行过程 SimAM总结…...
FPGA 蜂鸣器 音乐播放器
点击: FPGA 蜂鸣器音乐播放器 基于FPGA的beep音乐播放器设计 FPGA(Field Programmable Gate Array)蜂鸣器音乐播放器是一个将FPGA编程用于控制蜂鸣器播放音乐的设备。下面是一个简单的实现步骤和思路: 一、硬件准备 FPGA开发板…...
前端-基础CSS总结常用
1.书写位置:title 标签下方添加 style 双标签,style 标签里面书写 CSS 代码。 <title>CSS 初体验</title> <style>/* 选择器 { } */p {/* CSS 属性 */color: red;} </style><p>体验 CSS</p> <link rel="stylesheet" href=…...

Coppelia Sim (v-REP)仿真 机器人3D相机手眼标定与实时视觉追踪 (一)
coppelia sim[V-REP]仿真实现 机器人于3D相机手眼标定与实时视觉追踪 一 标定板的制作生成标定的PDF文件PDF转为图像格式图像加载到仿真中 二 仿真场景设置加载机器人加载的控制dummy 
大数据学习栈记——Neo4j的安装与使用
本文介绍图数据库Neofj的安装与使用,操作系统:Ubuntu24.04,Neofj版本:2025.04.0。 Apt安装 Neofj可以进行官网安装:Neo4j Deployment Center - Graph Database & Analytics 我这里安装是添加软件源的方法 最新版…...

linux之kylin系统nginx的安装
一、nginx的作用 1.可做高性能的web服务器 直接处理静态资源(HTML/CSS/图片等),响应速度远超传统服务器类似apache支持高并发连接 2.反向代理服务器 隐藏后端服务器IP地址,提高安全性 3.负载均衡服务器 支持多种策略分发流量…...

PPT|230页| 制造集团企业供应链端到端的数字化解决方案:从需求到结算的全链路业务闭环构建
制造业采购供应链管理是企业运营的核心环节,供应链协同管理在供应链上下游企业之间建立紧密的合作关系,通过信息共享、资源整合、业务协同等方式,实现供应链的全面管理和优化,提高供应链的效率和透明度,降低供应链的成…...
数据链路层的主要功能是什么
数据链路层(OSI模型第2层)的核心功能是在相邻网络节点(如交换机、主机)间提供可靠的数据帧传输服务,主要职责包括: 🔑 核心功能详解: 帧封装与解封装 封装: 将网络层下发…...
数据库分批入库
今天在工作中,遇到一个问题,就是分批查询的时候,由于批次过大导致出现了一些问题,一下是问题描述和解决方案: 示例: // 假设已有数据列表 dataList 和 PreparedStatement pstmt int batchSize 1000; // …...

让AI看见世界:MCP协议与服务器的工作原理
让AI看见世界:MCP协议与服务器的工作原理 MCP(Model Context Protocol)是一种创新的通信协议,旨在让大型语言模型能够安全、高效地与外部资源进行交互。在AI技术快速发展的今天,MCP正成为连接AI与现实世界的重要桥梁。…...

Python基于历史模拟方法实现投资组合风险管理的VaR与ES模型项目实战
说明:这是一个机器学习实战项目(附带数据代码文档),如需数据代码文档可以直接到文章最后关注获取。 1.项目背景 在金融市场日益复杂和波动加剧的背景下,风险管理成为金融机构和个人投资者关注的核心议题之一。VaR&…...

Razor编程中@Html的方法使用大全
文章目录 1. 基础HTML辅助方法1.1 Html.ActionLink()1.2 Html.RouteLink()1.3 Html.Display() / Html.DisplayFor()1.4 Html.Editor() / Html.EditorFor()1.5 Html.Label() / Html.LabelFor()1.6 Html.TextBox() / Html.TextBoxFor() 2. 表单相关辅助方法2.1 Html.BeginForm() …...

沙箱虚拟化技术虚拟机容器之间的关系详解
问题 沙箱、虚拟化、容器三者分开一一介绍的话我知道他们各自都是什么东西,但是如果把三者放在一起,它们之间到底什么关系?又有什么联系呢?我不是很明白!!! 就比如说: 沙箱&#…...

网页端 js 读取发票里的二维码信息(图片和PDF格式)
起因 为了实现在报销流程中,发票不能重用的限制,发票上传后,希望能读出发票号,并记录发票号已用,下次不再可用于报销。 基于上面的需求,研究了OCR 的方式和读PDF的方式,实际是可行的ÿ…...