JAVA安全—基础知识(JavaWeb的Servlet)

作者:绿洲安全 发布:2026-10-15 08:30 收录:2026-10-15 10:38 4 次阅读 约 4515 字
摘要:免责声明由于传播、利用本公众号绿洲安全所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,公
推荐理由:本文涵盖「Java」、「WEB」、「ART」等多个主题,重点关注 Java。

免责声明

图片
图片

由于传播、利用本公众号绿洲安全所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,公众号绿洲安全及作者不为此承担任何责任,一旦造成后果请自行承担!如有侵权烦请告知,我们会立即删除并致歉。谢谢

转自:https://blog.csdn.net/m0_73803300/article/details/150510975

一

Servlet 概述


Servlet(Server Applet)是运行在 Web 服务器上的 Java 程序,用于处理客户端(浏览器 )发送的 HTTP 请求,并生成 HTTP 响应。
Servlet 的特点
  • 运行在服务器端:Servlet 由 Web 服务器(如 Tomcat)加载和管理
  • 基于 HTTP 协议:专门处理 HTTP 请求和响应
  • 多线程支持:一个 Servlet 实例可以同时处理多个客户端请求(注意线程安全)
  • 组件化:遵循 Java EE 规范,可被 Web 容器管理
  • 跨平台:基于 Java 语言,一次编写,到处运行
Servlet 的作用
  • 接收客户端请求数据(表单参数、URL 参数等)
  • 处理业务逻辑(调用 Service 层、DAO 层等)
  • 与数据库交互(查询、插入、更新数据等)
  • 生成动态响应内容(HTML、JSON、XML 等)
  • 实现页面跳转和重定向
Servlet 工作原理
Servlet 的工作流程涉及三个核心角色:客户端(浏览器)、Web 服务器(如 Tomcat) 和Servlet 程序。
1.客户端发送请求:浏览器向 Web 服务器发送 HTTP 请求(如访问http://localhost:8080/myapp/user)
2.Web 服务器接收请求:
    1.服务器解析请求 URL,确定要访问的 Web 应用(myapp)
    2.根据 URL 路径(/user)查找对应的 Servlet
3.Servlet 处理请求:
    1.Web 服务器创建HttpServletRequest和HttpServletResponse对象
    2.调用 Servlet 的相应方法(如doGet()、doPost())处理请求
   3.Servlet 通过HttpServletRequest获取请求数据,处理后通过HttpServletResponse生成响应
4.Web 服务器返回响应:
    1.服务器将 Servlet 生成的响应转换为 HTTP 响应
    2.将响应发送回客户端浏览器
5.浏览器显示结果:浏览器解析并显示响应内容
Servlet 生命周期:Servlet 从创建到销毁的整个过程,由 Web 容器(如 Tomcat )管理。

二

Servlet 的生命周期


Servlet 的生命周期包含四个阶段,由 Web 容器调用相应方法完成:
1.加载和实例化:
    1.Web 容器启动时或第一次请求 Servlet 时,加载 Servlet 类
    2.创建 Servlet 实例(默认单例,一个 Servlet 类只有一个实例)
2.初始化:
    1.调用init(ServletConfig config)方法
    2.用于初始化资源(如数据库连接、配置参数)
    3.只执行一次
3.处理请求:
    1.每次收到请求时,Web 容器创建新的线程
    2.调用service(ServletRequest req, ServletResponse res)方法
    3.service()方法根据请求类型(GET/POST 等)调用对应的doGet()、doPost()等方法
    4.可被多次调用
4.销毁:
    1.Web 容器关闭时或 Servlet 被移除时调用destroy()方法
    2.用于释放资源(如关闭数据库连接)
    3.只执行一次
生命周期示例
import javax.servlet.*;import javax.servlet.annotation.WebServlet;import java.io.IOException;
@WebServlet("/lifeCycle")public class LifeCycleServlet implements Servlet {    private ServletConfig config;
    // 1. 构造方法(实例化阶段)    public LifeCycleServlet() {        System.out.println("1. 构造方法被调用(实例化Servlet)");    }
    // 2. 初始化方法    @Override    public void init(ServletConfig config) throws ServletException {        this.config = config;        System.out.println("2. init()方法被调用(初始化Servlet)");        // 可以获取初始化参数        String param = config.getInitParameter("initParam");        if (param != null) {            System.out.println("初始化参数:" + param);        }    }
    // 3. 处理请求的核心方法    @Override    public void service(ServletRequest req, ServletResponse res)             throws ServletException, IOException {        System.out.println("3. service()方法被调用(处理请求)");        res.getWriter().write("Servlet Life Cycle Demo");    }
    // 4. 销毁方法    @Override    public void destroy() {        System.out.println("4. destroy()方法被调用(销毁Servlet)");        // 释放资源操作    }
    @Override    public ServletConfig getServletConfig() {        return config;    }
    @Override    public String getServletInfo() {        return "Life Cycle Servlet Demo";    }}
启动和访问后的输出:
1. 构造方法被调用(实例化Servlet)2. init()方法被调用(初始化Servlet)3. service()方法被调用(处理请求)  // 第一次访问时3. service()方法被调用(处理请求)  // 第二次访问时...
关闭服务器时输出:
4. destroy()方法被调用(销毁Servlet)

三

编写 Servlet 的两种方式


在实际开发中,我们通常不直接实现Servlet接口,而是继承其实现类:

方式 1:继承 GenericServlet 类

GenericServlet是Servlet接口的通用实现类,简化了 Servlet 的编写:

import javax.servlet.GenericServlet;import javax.servlet.ServletException;import javax.servlet.annotation.WebServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;import java.io.PrintWriter;
@WebServlet("/genericServletDemo")public class MyGenericServlet extends GenericServlet {
    @Override    public void service(ServletRequest req, ServletResponse res)             throws ServletException, IOException {        // 设置响应内容类型        res.setContentType("text/html;charset=UTF-8");        PrintWriter out = res.getWriter();
        // 输出HTML内容        out.println("<html>");        out.println("<head><title>GenericServlet示例</title></head>");        out.println("<body>");        out.println("<h1>这是一个GenericServlet示例</h1>");        out.println("请求方法:" + ((HttpServletRequest) req).getMethod());        out.println("</body>");        out.println("</html>");    }}

GenericServlet的优势:

  •    实现了Servlet和ServletConfig接口

  •    提供了getServletContext()、getInitParameter()等便捷方法

  •    无需重写所有Servlet接口方法,只需实现service()

方式 2:继承 HttpServlet 类(推荐)

HttpServlet是GenericServlet的子类,专门用于处理 HTTP 请求,是最常用的方式:

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;
@WebServlet("/httpServletDemo")public class MyHttpServlet extends HttpServlet {
    // 处理GET请求    @Override    protected void doGet(HttpServletRequest req, HttpServletResponse res)             throws IOException {        res.setContentType("text/html;charset=UTF-8");        PrintWriter out = res.getWriter();
        out.println("<h1>处理GET请求</h1>");        out.println("用户名:" + req.getParameter("username")); // 获取URL参数    }
    // 处理POST请求    @Override    protected void doPost(HttpServletRequest req, HttpServletResponse res)             throws IOException {        // 设置请求编码(处理中文参数)        req.setCharacterEncoding("UTF-8");        res.setContentType("text/html;charset=UTF-8");
        PrintWriter out = res.getWriter();        out.println("<h1>处理POST请求</h1>");        out.println("用户名:" + req.getParameter("username")); // 获取表单参数    }}

HttpServlet的工作流程:

   1.重写service()方法,将ServletRequest和ServletResponse转换为HttpServletRequest和HttpServletResponse

   2.根据 HTTP 请求方法(GET、POST、PUT、DELETE 等)调用对应的doXxx()方法

   3.开发者只需重写需要处理的doXxx()方法(通常是doGet()和doPost())


四

Servlet 配置方式


Servlet 有两种配置方式:注解配置(Servlet 3.0 + 推荐)和XML 配置(传统方式)。

1. 注解配置(@WebServlet)

@WebServlet注解用于配置 Servlet,常用属性:

属性
说明
name
Servlet 名称(可选)
value/urlPatterns
映射的 URL 路径(必需,如"/user"、"/*")
loadOnStartup
启动时加载顺序(正数,数字越小越先加载)
initParams
初始化参数(@WebInitParam数组)
asyncSupported
是否支持异步处理(默认 false)

示例:

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;
@WebServlet(    name = "ConfigServlet",    urlPatterns = {"/config", "/configServlet"}, // 多个URL映射    loadOnStartup = 2, // 服务器启动时加载    initParams = { // 初始化参数        @WebInitParam(name = "version", value = "1.0"),        @WebInitParam(name = "author", value = "JavaWeb")    })public class ConfigServlet extends HttpServlet {
    @Override    protected void doGet(HttpServletRequest req, HttpServletResponse res)             throws IOException {        res.setContentType("text/html;charset=UTF-8");        PrintWriter out = res.getWriter();
        out.println("<h1>Servlet配置示例</h1>");        out.println("Servlet名称:" + getServletName() + "<br>");
        // 获取初始化参数        out.println("版本:" + getInitParameter("version") + "<br>");        out.println("作者:" + getInitParameter("author") + "<br>");
        // 获取所有初始化参数名称        out.println("<h3>所有初始化参数:</h3>");        getInitParameterNames().asIterator().forEachRemaining(name -> {            out.println(name + ":" + getInitParameter((String) name) + "<br>");        });    }}

2. XML 配置(web.xml)

传统的 Servlet 配置方式,在WEB-INF/web.xml文件中配置:

<?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/javaee                              http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"         version="4.0">
    <!-- 配置Servlet -->    <servlet>        <servlet-name>XmlConfigServlet</servlet-name>        <servlet-class>com.example.XmlConfigServlet</servlet-class>
        <!-- 初始化参数 -->        <init-param>            <param-name>encoding</param-name>            <param-value>UTF-8</param-value>        </init-param>
        <!-- 启动时加载(可选) -->        <load-on-startup>3</load-on-startup>    </servlet>
    <!-- 配置Servlet映射 -->    <servlet-mapping>        <servlet-name>XmlConfigServlet</servlet-name>        <url-pattern>/xmlConfig</url-pattern>    </servlet-mapping>
    <!-- 可以配置多个映射 -->    <servlet-mapping>        <servlet-name>XmlConfigServlet</servlet-name>        <url-pattern>/xmlConfigServlet</url-pattern>    </servlet-mapping></web-app>

对应的 Servlet 类:

package com.example;
import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;import java.io.PrintWriter;
public class XmlConfigServlet extends HttpServlet {    @Override    protected void doGet(HttpServletRequest req, HttpServletResponse res)             throws IOException {        res.setContentType("text/html;charset=UTF-8");        PrintWriter out = res.getWriter();
        out.println("<h1>XML配置的Servlet</h1>");        out.println("编码:" + getInitParameter("encoding"));    }}

五

Servlet 核心对象:Request 与 Response


HttpServletRequest和HttpServletResponse是 Servlet 处理请求和响应的核心对象。

1. HttpServletRequest(请求对象)

封装了客户端发送的 HTTP 请求信息,常用方法:

方法说明
String getParameter(String name)获取请求参数(表单或 URL 参数)
String[] getParameterValues(String name)获取多值参数(如复选框)
Map<String, String[]> getParameterMap()获取所有参数的 Map 集合
String getMethod()获取 HTTP 请求方法(GET/POST 等)
String getRequestURI()获取请求 URI(如 /myapp/user)
String getContextPath()获取 Web 应用上下文路径(如 /myapp)
String getRemoteAddr()获取客户端 IP 地址
void setCharacterEncoding(String env)设置请求体编码(处理 POST 中文)
HttpSession getSession()获取会话对象
void setAttribute(String name, Object o)设置请求域属性
Object getAttribute(String name)获取请求域属性

示例:处理表单提交

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.Arrays;import java.util.Map;
@WebServlet("/formHandler")public class FormHandlerServlet extends HttpServlet {    @Override    protected void doPost(HttpServletRequest req, HttpServletResponse res)             throws IOException {        // 处理POST中文参数        req.setCharacterEncoding("UTF-8");        res.setContentType("text/html;charset=UTF-8");        PrintWriter out = res.getWriter();
        out.println("<h1>表单处理结果</h1>");
        // 获取单个参数        String username = req.getParameter("username");        String password = req.getParameter("password");        out.println("用户名:" + username + "<br>");        out.println("密码:" + password + "<br>");
        // 获取多值参数(复选框)        String[] hobbies = req.getParameterValues("hobby");        if (hobbies != null) {            out.println("爱好:" + Arrays.toString(hobbies) + "<br>");        }
        // 获取所有参数        out.println("<h3>所有参数:</h3>");        Map<String, String[]> paramMap = req.getParameterMap();        for (Map.Entry<String, String[]> entry : paramMap.entrySet()) {            out.println(entry.getKey() + ":" + Arrays.toString(entry.getValue()) + "<br>");        }
        // 获取请求信息        out.println("<h3>请求信息:</h3>");        out.println("请求方法:" + req.getMethod() + "<br>");        out.println("请求URI:" + req.getRequestURI() + "<br>");        out.println("客户端IP:" + req.getRemoteAddr() + "<br>");    }
    // 支持GET请求访问    @Override    protected void doGet(HttpServletRequest req, HttpServletResponse res)             throws IOException {        res.sendRedirect("form.html"); // 重定向到表单页面    }}

对应的表单页面(form.html):

<!DOCTYPE html><html><head>    <meta charset="UTF-8">    <title>用户表单</title></head><body>    <form action="/myapp/formHandler" method="post">        <div>            用户名:<input type="text" name="username">        </div>        <div>            密码:<input type="password" name="password">        </div>        <div>            爱好:            <input type="checkbox" name="hobby" value="reading">阅读            <input type="checkbox" name="hobby" value="sports">运动            <input type="checkbox" name="hobby" value="music">音乐        </div>        <div>            <input type="submit" value="提交">        </div>    </form></body></html>

2. HttpServletResponse(响应对象)

用于向客户端发送响应,常用方法:

方法说明
PrintWriter getWriter()获取字符输出流(输出文本)
ServletOutputStream getOutputStream()获取字节输出流(输出二进制数据)
void setContentType(String type)设置响应内容类型(如 text/html;charset=UTF-8)
void setCharacterEncoding(String charset)设置响应字符编码
void sendRedirect(String location)重定向到新 URL(客户端跳转)
void setStatus(int sc)设置 HTTP 响应状态码
void addHeader(String name, String value)添加响应头

示例:生成动态响应

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.Date;
@WebServlet("/responseDemo")public class ResponseDemoServlet extends HttpServlet {    @Override    protected void doGet(HttpServletRequest req, HttpServletResponse res)             throws IOException {        // 1. 输出HTML响应        res.setContentType("text/html;charset=UTF-8");        PrintWriter out = res.getWriter();
        out.println("<!DOCTYPE html>");        out.println("<html>");        out.println("<head>");        out.println("<title>响应示例</title>");        out.println("</head>");        out.println("<body>");        out.println("<h1>动态生成的HTML页面</h1>");        out.println("<p>当前时间:" + new Date() + "</p>");        out.println("<p>客户端IP:" + req.getRemoteAddr() + "</p>");        out.println("</body>");        out.println("</html>");
        // 2. 重定向示例(注释上面代码,测试重定向)        // res.sendRedirect("https://www.example.com");
        // 3. 设置响应状态码示例        // res.setStatus(404); // 未找到        // res.setStatus(500); // 服务器错误    }}

六

请求与转发


在 Web 开发中,经常需要将请求从一个 Servlet 转发到另一个 Servlet 或页面,有两种实现方式:

1. 请求转发(Forward)

服务器端跳转:由 Web 服务器内部将请求转发给其他资源,客户端浏览器地址栏不变。

// Servlet1:处理部分逻辑后转发到Servlet2@WebServlet("/servlet1")public class Servlet1 extends HttpServlet {    @Override    protected void doGet(HttpServletRequest req, HttpServletResponse res)             throws ServletException, IOException {        System.out.println("Servlet1处理请求");
        // 设置请求域属性(可在转发目标中获取)        req.setAttribute("message", "来自Servlet1的消息");
        // 获取请求调度器,转发到/servlet2        RequestDispatcher dispatcher = req.getRequestDispatcher("/servlet2");        dispatcher.forward(req, res); // 执行转发    }}
// Servlet2:接收转发的请求@WebServlet("/servlet2")public class Servlet2 extends HttpServlet {    @Override    protected void doGet(HttpServletRequest req, HttpServletResponse res)             throws IOException {        res.setContentType("text/html;charset=UTF-8");        PrintWriter out = res.getWriter();
        out.println("<h1>Servlet2处理结果</h1>");        // 获取Servlet1设置的属性        String message = (String) req.getAttribute("message");        out.println("接收到的消息:" + message);    }}

请求转发的特点:

    客户端只发送一次请求

    浏览器地址栏 URL 不变

    共享同一个HttpServletRequest对象(可通过setAttribute()传递数据)

    只能转发到当前 Web 应用内部的资源

2. 重定向(Redirect)

客户端跳转:服务器向客户端发送一个 302 响应和新的 URL,客户端自动向新 URL 发送请求,地址栏会改变。

@WebServlet("/redirect1")public class RedirectServlet1 extends HttpServlet {    @Override    protected void doGet(HttpServletRequest req, HttpServletResponse res)             throws IOException {        System.out.println("RedirectServlet1处理请求");
        // 设置请求域属性(重定向中无法传递)        req.setAttribute("message", "这个消息不会被收到");
        // 重定向到/redirect2        // 方式1:使用sendRedirect()        res.sendRedirect("/myapp/redirect2");
        // 方式2:手动设置状态码和响应头(等价于方式1)        // res.setStatus(302);        // res.setHeader("Location", "/myapp/redirect2");    }}
@WebServlet("/redirect2")public class RedirectServlet2 extends HttpServlet {    @Override    protected void doGet(HttpServletRequest req, HttpServletResponse res)             throws IOException {        res.setContentType("text/html;charset=UTF-8");        PrintWriter out = res.getWriter();
        out.println("<h1>RedirectServlet2处理结果</h1>");        // 尝试获取RedirectServlet1设置的属性(结果为null)        String message = (String) req.getAttribute("message");        out.println("接收到的消息:" + message); // null    }}

重定向的特点:

  • 客户端发送两次请求
  • 浏览器地址栏 URL 改变
  • 不共享HttpServletRequest对象(无法通过setAttribute()传递数据)
  • 可以重定向到其他 Web 应用甚至其他网站的资源

请求转发与重定向的对比

特性请求转发(Forward)重定向(Redirect)
跳转方式服务器端跳转客户端跳转
浏览器地址不变改变
请求次数1 次2 次
数据共享共享 Request 对象不共享
跳转范围仅限当前 Web 应用任意 URL
适用场景同一应用内页面跳转,需传递数据不同应用间跳转,或避免表单重复提交

ServletContext 对象

ServletContext(Servlet 上下文)代表整个 Web 应用,是所有 Servlet 共享的全局对象。

ServletContext 的作用

    存储全局配置信息

    在不同 Servlet 之间共享数据

    获取 Web 应用的资源文件

    获取 Web 应用的初始化参数

ServletContext 示例

import javax.servlet.ServletContext;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;
@WebServlet("/servletContextDemo")public class ServletContextDemoServlet extends HttpServlet {    @Override    protected void doGet(HttpServletRequest req, HttpServletResponse res)             throws IOException {        res.setContentType("text/html;charset=UTF-8");        PrintWriter out = res.getWriter();
        // 获取ServletContext对象        ServletContext context = getServletContext();
        // 1. 获取Web应用初始化参数(在web.xml中配置)        out.println("<h3>Web应用初始化参数:</h3>");        String appName = context.getInitParameter("appName");        String appVersion = context.getInitParameter("appVersion");        out.println("应用名称:" + appName + "<br>");        out.println("应用版本:" + appVersion + "<br>");
        // 2. 存储和获取全局共享数据        context.setAttribute("onlineUsers", 100); // 设置全局属性        int onlineUsers = (Integer) context.getAttribute("onlineUsers"); // 获取全局属性        out.println("<h3>全局共享数据:</h3>");        out.println("在线用户数:" + onlineUsers + "<br>");
        // 3. 获取Web应用资源        out.println("<h3>Web应用资源:</h3>");
        // 获取资源在服务器上的真实路径        String realPath = context.getRealPath("/WEB-INF/config.properties");        out.println("config.properties真实路径:" + realPath + "<br>");
        // 读取资源文件内容        InputStream is = context.getResourceAsStream("/WEB-INF/config.properties");        Properties props = new Properties();        props.load(is);        out.println("数据库URL:" + props.getProperty("db.url") + "<br>");
        // 4. 获取Web应用信息        out.println("<h3>Web应用信息:</h3>");        out.println("上下文路径:" + context.getContextPath() + "<br>");        out.println("服务器信息:" + context.getServerInfo() + "<br>");    }}

对应的 web.xml 配置:

<!-- Web应用初始化参数 --><context-param>    <param-name>appName</param-name>    <param-value>MyJavaWebApp</param-value></context-param><context-param>    <param-name>appVersion</param-name>    <param-value>1.0.0</param-value></context-param>

七

线程安全问题


Servlet 默认是单例的(一个 Servlet 类只有一个实例),多线程并发访问时可能出现线程安全问题。

线程安全问题示例

@WebServlet("/unsafeServlet")public class UnsafeServlet extends HttpServlet {    // 实例变量(多线程共享)    private int count = 0;
    @Override    protected void doGet(HttpServletRequest req, HttpServletResponse res)             throws IOException {        res.setContentType("text/html;charset=UTF-8");        PrintWriter out = res.getWriter();
        // 自增操作(非原子操作,存在线程安全问题)        count++;
        // 模拟耗时操作        try {            Thread.sleep(100);        } catch (InterruptedException e) {            e.printStackTrace();        }
        out.println("访问次数:" + count);    }}

问题:当多个线程同时访问时,count++操作可能导致计数错误(因为count++实际包含读取、加 1、写入三个步骤)。

解决线程安全问题的方法

  1. 避免使用实例变量:尽量使用局部变量(每个线程有独立的局部变量)

  2. 使用同步代码块:对共享资源的操作进行同步

@WebServlet("/safeServlet")public class SafeServlet extends HttpServlet {    private int count = 0;
    @Override    protected void doGet(HttpServletRequest req, HttpServletResponse res)             throws IOException {        res.setContentType("text/html;charset=UTF-8");        PrintWriter out = res.getWriter();
        // 同步代码块(使用当前Servlet实例作为锁)        synchronized (this) {            count++;
            try {                Thread.sleep(100);            } catch (InterruptedException e) {                e.printStackTrace();            }
            out.println("访问次数:" + count);        }    }}

1.实现 SingleThreadModel 接口(不推荐):

    1.让 Servlet 每次处理请求时创建新实例(破坏单例)

    2.已被 Servlet 规范标记为过时(deprecated)

最佳实践:

    尽量避免在 Servlet 中使用实例变量

    必须使用共享变量时,通过synchronized保证线程安全

    考虑使用线程安全的集合(如ConcurrentHashMap)


八

知识点回顾


1.Servlet 基础:运行在服务器端的 Java 程序,处理 HTTP 请求和响应

2.生命周期:实例化→初始化(init())→处理请求(service())→销毁(destroy())

3.编写方式:继承HttpServlet(推荐),重写doGet()、doPost()等方法

4.配置方式:@WebServlet注解(Servlet 3.0+)或web.xml

5.核心对象:

    1.HttpServletRequest:获取请求信息、参数

    2.HttpServletResponse:生成响应、页面跳转

    3.ServletContext:全局上下文,共享数据

6.页面跳转:请求转发(服务器端)和重定向(客户端)

7.线程安全:Servlet 默认单例,需注意多线程并发问题


转载声明:本文转载自原发布平台 (作者:绿洲安全), 原文标题《JAVA安全—基础知识(JavaWeb的Servlet)》, 查看原文。 版权归原作者及原发布平台所有,本站仅作收录与展示,未对正文内容作实质性修改; 若涉及侵权请联系本站处理。