Salmon的全栈知识 Salmon的全栈知识
首页
  • JavaSE
  • JavaWeb
  • Spring生态
  • JUC
  • JVM
  • Netty
  • Java各版本特性
  • 23种设计模式
  • Maven
  • Java常用框架
  • Dubbo
  • OpenFeign
  • Nacos
  • Zookeeper
  • Sentinel
  • Seata
  • SpringCloud Gateway
  • Apollo
  • Eureka
  • Go基础
  • Gin
  • SQL数据库

    • MySQL
    • Oracle
  • NoSQL数据库

    • Redis
    • MongoDB
    • ElasticSearch
  • 消息中间件

    • RabbitMQ
    • RocketMQ
    • Kafka
    • ActiveMQ
    • MQTT
    • NATS
  • 网关中间件

    • Nginx
  • Linux
  • Docker
  • Git
  • K8s
  • Solidity
  • Java
  • 计算机网络
  • 操作系统
GitHub (opens new window)
首页
  • JavaSE
  • JavaWeb
  • Spring生态
  • JUC
  • JVM
  • Netty
  • Java各版本特性
  • 23种设计模式
  • Maven
  • Java常用框架
  • Dubbo
  • OpenFeign
  • Nacos
  • Zookeeper
  • Sentinel
  • Seata
  • SpringCloud Gateway
  • Apollo
  • Eureka
  • Go基础
  • Gin
  • SQL数据库

    • MySQL
    • Oracle
  • NoSQL数据库

    • Redis
    • MongoDB
    • ElasticSearch
  • 消息中间件

    • RabbitMQ
    • RocketMQ
    • Kafka
    • ActiveMQ
    • MQTT
    • NATS
  • 网关中间件

    • Nginx
  • Linux
  • Docker
  • Git
  • K8s
  • Solidity
  • Java
  • 计算机网络
  • 操作系统
GitHub (opens new window)
npm

(进入注册为作者充电)

  • JUnit单元测试
  • JDBC
  • JDBC连接池&JDBCTemplate
  • XML
  • Tomcat&Servlet
  • Servlet&HTTP&Request
    • Servlet
      • 1. 概念
      • 2. 步骤
      • 3. 执行原理
      • 4. 生命周期
      • 5. Servlet 3.0 注解配置
      • 6. Servlet 的体系结构
      • 7. Servlet 相关配置
    • HTTP 协议
      • 概念
      • 请求消息数据格式
    • Request
      • 1. request 和 response 对象原理
      • 2. request 对象继承结构
      • 3. request 功能
      • 获取请求消息数据
      • 获取请求参数通用方法
      • 请求转发
      • request 域对象(共享数据)
      • 获取 ServletContext
    • 案例:用户登录
      • 需求
      • 数据库建表语句
      • 实体类 User
      • JDBC 工具类 JDBCUtils
      • DAO 类:UserDao
      • LoginServlet
      • 成功与失败页面 Servlet
      • login.html 表单提交路径
      • BeanUtils 工具类
  • Response
  • Cookie&Session
  • EL&JSTL
  • Filter&Listener
  • 《JavaWeb》笔记
Salmon
2025-07-21
目录

Servlet&HTTP&Request

# Servlet

# 1. 概念

Servlet 是运行在服务器端的小程序(Java 编写),主要用于接收客户端的请求、处理请求并返回响应,是 Java Web 的核心技术之一。它运行在 Web 容器(如 Tomcat)中。

# 2. 步骤

  1. 创建一个类实现 javax.servlet.Servlet 接口(或继承 HttpServlet)。
  2. 重写核心方法(如 doGet、doPost)。
  3. 在 web.xml 中配置 Servlet,或使用注解 @WebServlet。
  4. 部署到 Servlet 容器中(如 Tomcat)。
  5. 浏览器访问对应的 URL,触发 Servlet 处理请求。

# 3. 执行原理

简要流程如下:

  1. 启动时加载 Servlet(可通过配置或注解控制是否懒加载)。

  2. 当客户端发送请求:

    • Web 容器接收到请求。
    • 容器根据 URL 映射找到对应的 Servlet。
    • 若是第一次访问,容器先创建 Servlet 实例并调用 init() 方法进行初始化。
    • 接着调用 service() 方法处理请求。
      • 对于 HttpServlet,会进一步分发到 doGet() 或 doPost()。
    • 最终生成响应,返回客户端。

# 4. 生命周期

Servlet 的完整生命周期包括以下三个阶段:

  1. 初始化(init)
    • 容器创建 Servlet 实例后,调用 init() 方法,仅调用一次。
    • 可做资源初始化等操作。
  2. 服务(service)
    • 每次请求都会调用一次 service() 方法。
    • HttpServlet 会根据请求类型调用 doGet()、doPost() 等。
  3. 销毁(destroy)
    • 当容器关闭或 Servlet 被卸载时调用 destroy() 方法,只调用一次。
    • 用于资源释放,如关闭数据库连接、线程池等。

# 5. Servlet 3.0 注解配置

使用 @WebServlet 注解可以代替 web.xml 配置。

import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet(name = "HelloServlet", urlPatterns = "/hello")
public class HelloServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
        resp.setContentType("text/html;charset=UTF-8");
        try (PrintWriter out = resp.getWriter()) {
            out.println("\<h1\>Hello Servlet\</h1\>");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

# 6. Servlet 的体系结构

Servlet 接口和相关类的继承结构如下:

javax.servlet.Servlet (接口)
  ├── javax.servlet.GenericServlet (抽象类)
  │     └── javax.servlet.http.HttpServlet (抽象类)
  │           └── 自定义 Servlet(通常继承 HttpServlet)
  • 说明:
    • Servlet(接口):定义了所有 Servlet 必须实现的方法,包括 init()、service()、destroy()、getServletConfig()、getServletInfo()。
    • GenericServlet(抽象类):简化了开发,只需实现 service() 方法,适用于协议无关的 Servlet。
    • HttpServlet(抽象类):是最常用的 Servlet 基类,已经实现了 service() 方法并根据请求类型调用 doGet()、doPost() 等。

开发时我们一般直接继承 HttpServlet,重写 doGet() 或 doPost() 方法即可。

# 7. Servlet 相关配置

  • urlPattern:Servlet 访问路径
    • 一个 Servlet 可以定义多个访问路径:
@WebServlet({"/d4","/dd4","/ddd4"})
  • 路径定义规则:
    1. /xxx:路径匹配
    2. /xxx/xxx:多层路径,目录结构
    3. *.do:扩展名匹配

# HTTP 协议

# 概念

HTTP(Hyper Text Transfer Protocol 超文本传输协议)

  • 定义了客户端与服务器通信时的数据格式
  • 特点:
    1. 基于 TCP/IP 的高级协议
    2. 默认端口号:80
    3. 基于请求/响应模型:一次请求对应一次响应
    4. 无状态:每次请求之间相互独立,不能交互数据
  • 历史版本:
    • 1.0:每次请求响应都会建立新的连接
    • 1.1:复用连接

# 请求消息数据格式

  1. 请求行
GET /login.html HTTP/1.1
  • 请求方式:
    • HTTP 协议有 7 种请求方式,常用:GET 和 POST
      • GET:
        1. 参数在请求行 url 后
        2. URL 长度有限制
        3. 安全性较低
      • POST:
        1. 参数在请求体中
        2. URL 长度无限制
        3. 安全性较高
  1. 请求头
请求头名称: 请求头值
  • 常见请求头:
    • User-Agent:浏览器告诉服务器当前的浏览器版本信息
    • Referer:请求来源地址(如:http://localhost/login.html (opens new window))
      • 作用:
        1. 防盗链
        2. 统计来源
  1. 请求空行
  • 分割请求头和请求体
  1. 请求体(POST 数据)
username=zhangsan

完整请求样例如下:

POST /login.html HTTP/1.1
Host: localhost
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:60.0) Gecko/20100101 Firefox/60.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8
Accept-Encoding: gzip, deflate
Referer: http://localhost/login.html
Connection: keep-alive
Upgrade-Insecure-Requests: 1

username=zhangsan

# Request

# 1. request 和 response 对象原理

  • 由服务器创建,开发者使用
  • request 获取请求数据,response 设置响应数据

# 2. request 对象继承结构

ServletRequest         -- 接口
    └── HttpServletRequest -- 接口
        └── RequestFacade   -- 实现类(Tomcat)

# 3. request 功能

# 获取请求消息数据

  • 请求行:
String getMethod();         // GET
String getContextPath();    // /day14
String getServletPath();    // /demo1
String getQueryString();    // name=zhangsan
String getRequestURI();     // /day14/demo1
StringBuffer getRequestURL(); // http://localhost/day14/demo1
String getProtocol();       // HTTP/1.1
String getRemoteAddr();     // 客户端 IP 地址
  • 请求头:
String getHeader(String name);
Enumeration<String> getHeaderNames();
  • 请求体(POST):
BufferedReader getReader();         // 字符输入流
ServletInputStream getInputStream();// 字节输入流

# 获取请求参数通用方法

适用于 GET 和 POST:

String getParameter(String name);
String[] getParameterValues(String name);
Enumeration<String> getParameterNames();
Map<String,String[]> getParameterMap();
  • POST 中文乱码解决:
request.setCharacterEncoding("utf-8");

# 请求转发

  • 步骤:
RequestDispatcher rd = request.getRequestDispatcher("/xxx");
rd.forward(request, response);
  • 特点:

    1. 地址栏不变
    2. 只能转发服务器内部资源
    3. 属于一次请求

# request 域对象(共享数据)

request.setAttribute("name", obj);
Object obj = request.getAttribute("name");
request.removeAttribute("name");

# 获取 ServletContext

ServletContext context = request.getServletContext();

# 案例:用户登录

# 需求

  1. 编写 login.html 页面,包含 username 和 password 输入框
  2. 使用 Druid 连接池,操作 day14 数据库中的 user 表
  3. 使用 JdbcTemplate 封装 JDBC
  4. 登录成功跳转到 SuccessServlet,展示欢迎信息
  5. 登录失败跳转到 FailServlet,提示错误信息

# 数据库建表语句

CREATE DATABASE day14;
USE day14;
CREATE TABLE USER (
  id INT PRIMARY KEY AUTO_INCREMENT,
  username VARCHAR(32) UNIQUE NOT NULL,
  PASSWORD VARCHAR(32) NOT NULL
);

# 实体类 User

public class User {
    private int id;
    private String username;
    private String password;

    // Getters / Setters / toString()
}

# JDBC 工具类 JDBCUtils

public class JDBCUtils {
    private static DataSource ds;

    static {
        try {
            Properties pro = new Properties();
            InputStream is = JDBCUtils.class.getClassLoader()
                .getResourceAsStream("druid.properties");
            pro.load(is);
            ds = DruidDataSourceFactory.createDataSource(pro);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static DataSource getDataSource() {
        return ds;
    }

    public static Connection getConnection() throws SQLException {
        return ds.getConnection();
    }
}

# DAO 类:UserDao

public class UserDao {
    private JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource());

    public User login(User loginUser) {
        try {
            String sql = "select * from user where username = ? and password = ?";
            return template.queryForObject(sql,
                new BeanPropertyRowMapper<>(User.class),
                loginUser.getUsername(), loginUser.getPassword());
        } catch (DataAccessException e) {
            e.printStackTrace();
            return null;
        }
    }
}

# LoginServlet

@WebServlet("/loginServlet")
public class LoginServlet extends HttpServlet {
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
        throws ServletException, IOException {

        req.setCharacterEncoding("utf-8");
        String username = req.getParameter("username");
        String password = req.getParameter("password");

        User loginUser = new User();
        loginUser.setUsername(username);
        loginUser.setPassword(password);

        UserDao dao = new UserDao();
        User user = dao.login(loginUser);

        if (user == null) {
            req.getRequestDispatcher("/failServlet").forward(req, resp);
        } else {
            req.setAttribute("user", user);
            req.getRequestDispatcher("/successServlet").forward(req, resp);
        }
    }

    protected void doPost(HttpServletRequest req, HttpServletResponse resp)
        throws ServletException, IOException {
        this.doGet(req, resp);
    }
}

# 成功与失败页面 Servlet

SuccessServlet

@WebServlet("/successServlet")
public class SuccessServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {

        User user = (User) request.getAttribute("user");
        if (user != null) {
            response.setContentType("text/html;charset=utf-8");
            response.getWriter().write("登录成功!" + user.getUsername() + ",欢迎您");
        }
    }
}

FailServlet

@WebServlet("/failServlet")
public class FailServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {

        response.setContentType("text/html;charset=utf-8");
        response.getWriter().write("登录失败,用户名或密码错误");
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
        this.doPost(request, response);
    }
}

# login.html 表单提交路径

  • 表单 action:
action="${pageContext.request.contextPath}/loginServlet"

# BeanUtils 工具类

用于简化 JavaBean 数据封装

  • JavaBean 要求:
    1. public 修饰类
    2. 空参构造器
    3. 成员变量为 private
    4. 提供 getter / setter
  • 方法:
BeanUtils.setProperty(obj, "name", value);
BeanUtils.getProperty(obj, "name");
BeanUtils.populate(obj, map); // map 的键值封装进 JavaBean
上次更新: 2025/07/23, 01:37:33
Tomcat&Servlet
Response

← Tomcat&Servlet Response→

Theme by Vdoing | Copyright © 2022-2025 Salmon's Blog
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式