
🌈 个人主页: Hygge_Code
🔥 热门专栏:从0开始学习Java | Linux学习| 计算机网络
💫 个人格言: "既然选择了远方,便不顾风雨兼程"

文章目录
- 深入理解Servlet与MVC
-
- JSP内置对象回顾🥝
-
- [1. request对象](#1. request对象)
- [2. response对象](#2. response对象)
- [3. session对象](#3. session对象)
- [4. application对象](#4. application对象)
- [5. Cookie的操作方式](#5. Cookie的操作方式)
- [6. GET请求与POST请求的区别](#6. GET请求与POST请求的区别)
- 一、Servlet------Web应用的请求处理核心🥝
-
- [1. Servlet的核心概念](#1. Servlet的核心概念)
- [2. Servlet的体系结构](#2. Servlet的体系结构)
-
- [2.1 Servlet接口的核心方法](#2.1 Servlet接口的核心方法)
- [2.2 ServletConfig接口的核心方法](#2.2 ServletConfig接口的核心方法)
- [3. Servlet案例:登录功能实现](#3. Servlet案例:登录功能实现)
-
- [3.1 编写LoginServlet类(实现Servlet接口)](#3.1 编写LoginServlet类(实现Servlet接口))
- [3.2 配置web.xml文件](#3.2 配置web.xml文件)
-
- 🐦🔥web.xml配置详解🐦🔥
- [1. `<servlet>` 标签:注册 Servlet 实例](#1.
<servlet>标签:注册 Servlet 实例) - [2. `<servlet-mapping>` 标签:映射请求地址](#2.
<servlet-mapping>标签:映射请求地址)
- [3.3 编写登录页面(index.jsp)](#3.3 编写登录页面(index.jsp))
- [3.4 测试结果与生命周期验证](#3.4 测试结果与生命周期验证)
- [4. Servlet的生命周期详解](#4. Servlet的生命周期详解)
- [5. JSP的本质](#5. JSP的本质)
- 二、请求处理与响应机制
-
- [1. 请求与响应的体系结构](#1. 请求与响应的体系结构)
- [2. ServletRequest接口常用方法](#2. ServletRequest接口常用方法)
-
- [2.1 ServletRequest接口用法示例](#2.1 ServletRequest接口用法示例)
- [2.2 GET与POST请求的参数获取差异](#2.2 GET与POST请求的参数获取差异)
- [3. ServletResponse接口常用方法](#3. ServletResponse接口常用方法)
-
- [3.1 ServletResponse接口用法示例](#3.1 ServletResponse接口用法示例)
- [4. HttpServletRequest接口常用方法](#4. HttpServletRequest接口常用方法)
- [5. HttpServletResponse接口常用方法](#5. HttpServletResponse接口常用方法)
- [6. HttpServlet的核心方法](#6. HttpServlet的核心方法)
-
- [6.1 实战:注册功能实现(继承HttpServlet)](#6.1 实战:注册功能实现(继承HttpServlet))
- [6.2 编写注册页面(register.jsp)](#6.2 编写注册页面(register.jsp))
- [6.3 配置web.xml(添加注册Servlet映射)](#6.3 配置web.xml(添加注册Servlet映射))
- [7. ServletContext接口常用方法](#7. ServletContext接口常用方法)
-
- [7.1 配置上下文初始化参数(web.xml)](#7.1 配置上下文初始化参数(web.xml))
- [7.2 读取上下文参数(修改RegisterServlet)](#7.2 读取上下文参数(修改RegisterServlet))
- [8. Servlet交互流程简单图示](#8. Servlet交互流程简单图示)
- 三、MVC设计模式------Web应用的架构核心
-
- [1. MVC的核心概念](#1. MVC的核心概念)
- [2. MVC模式的核心优点](#2. MVC模式的核心优点)
- [3. JSP中的MVC实现](#3. JSP中的MVC实现)
-
- [3.1 应用:用户信息展示功能(MVC完整实现)](#3.1 应用:用户信息展示功能(MVC完整实现))
-
- [(1)编写Model(User类,Java Bean)](#(1)编写Model(User类,Java Bean))
- (2)编写Controller(UserInfoServlet,Servlet)
- (3)编写View(user.jsp,视图页面)
- (4)配置web.xml(注册UserInfoServlet)
深入理解Servlet与MVC
在Java Web开发体系中,Servlet、MVC设计模式和Filter是构建高性能、易维护Web应用的三大核心支柱。它们分别承担着请求处理、架构设计和请求过滤的关键职责,共同构成了Java Web应用的基础骨架。
JSP内置对象回顾🥝
1. request对象
request对象专门用于接收客户端发送的请求信息,核心方法及作用如下:
- 获取单个参数值:
String parameterValue = request.getParameter("参数名称"); - 获取多个参数值(如复选框):
String[] parameterValues = request.getParameterValues("参数名称"); - 获取所有参数名与值的映射:
Map<String,String[]> paramMap = request.getParameterMap();(注:原文档中getPrameterMap为拼写错误,正确方法名应为getParameterMap) - 获取当前请求的URL(包含上下文路径):
String uri = request.getRequestURI(); - 获取当前会话:
HttpSession session = request.getSession(); - 获取请求转发对象:
RequestDispatcher dispatcher = request.getRequestDispatcher("转发的页面");
2. response对象
response对象用于向客户端返回处理结果,核心方法及作用如下:
- 重定向到新资源:
response.sendRedirect("新的页面");(重定向会发起新的HTTP请求,URL地址会变更) - 设置响应状态码:
response.setStatus(200);(200表示成功,404表示资源未找到,500表示服务器内部错误等) - 获取响应输出流(用于打印字符串):
PrintWriter writer = response.getWriter();
3. session对象
session的设计初衷是跟踪当前登录用户的操作状态,其工作原理如下:
- 用户首次请求时,未携带sessionID,服务器会创建一个唯一的session对象并分配sessionID
- 服务器将sessionID通过Cookie写入客户端,后续用户所有请求都会携带该sessionID
- 服务器通过sessionID识别用户身份,session中存储的均为用户私有数据
- session默认超时时间可通过配置设置,超时后服务器会销毁该session对象
4. application对象
application对象的数据类型为ServletContext,代表Servlet运行的上下文环境,核心特性如下:
- 上下文环境包含Servlet运行的所有环境配置,是应用级别的全局对象
- 存储在application中的数据对整个Web应用生效,所有用户可共享
- 常用于存储全局配置信息(如数据库连接参数、系统常量等)
5. Cookie的操作方式
Cookie用于在客户端存储少量数据,其操作遵循"请求获取、响应添加"的原则:
- 添加Cookie(响应阶段):通过response对象完成,
response.addCookie(cookie); - 获取Cookie(请求阶段):通过request对象完成,
Cookie[] cookies = request.getCookies();(返回Cookie数组,需遍历获取目标Cookie)
6. GET请求与POST请求的区别
| 请求方式 | 参数存储位置 | 安全性 | 参数长度限制 | 适用场景 |
|---|---|---|---|---|
| GET | URL地址栏 | 较低(参数暴露) | 有(由服务器/浏览器限制) | 数据查询、页面跳转(无敏感信息) |
| POST | 请求体中 | 较高(参数隐藏) | 无 | 数据提交、登录注册(含敏感信息) |
一、Servlet------Web应用的请求处理核心🥝
1. Servlet的核心概念
Servlet是运行在服务器端的Java程序,能够接收客户端的HTTP请求,执行相应的业务逻辑,并向客户端返回处理结果。
2. Servlet的体系结构

2.1 Servlet接口的核心方法
Servlet接口定义了Servlet的生命周期方法,由Servlet容器(如Tomcat)负责调用:
- 初始化方法:
public void init(ServletConfig config) throws ServletException;------Servlet实例创建后调用,用于完成初始化(如读取配置参数) - 获取配置信息:
public ServletConfig getServletConfig();------返回当前Servlet的配置对象 - 请求处理方法:
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException;------接收并处理客户端请求,是核心业务方法 - 获取Servlet信息:
public String getServletInfo();------返回Servlet的相关信息(如作者、版本、版权) - 销毁方法:
public void destroy();------Servlet容器关闭时调用,用于释放资源(如关闭数据库连接)
2.2 ServletConfig接口的核心方法
ServletConfig接口用于获取Servlet的初始化配置信息,核心方法如下:
- 获取Servlet实例名称:
public String getServletName();------返回web.xml中配置的<servlet-name>值 - 获取Servlet上下文:
public ServletContext getServletContext();------返回当前Web应用的ServletContext对象 - 获取指定名称的初始化参数:
public String getInitParameter(String name);------返回web.xml中配置的指定名称的初始化参数值 - 获取所有初始化参数名称:
public Enumeration<String> getInitParameterNames();------返回所有初始化参数名称的枚举集合
3. Servlet案例:登录功能实现
3.1 编写LoginServlet类(实现Servlet接口)
java
package com.cyx.jsp.servlet;
import javax.servlet.*;
import java.io.IOException;
import java.util.Enumeration;
public class LoginServlet implements Servlet {
private ServletConfig servletConfig;
@Override
public void init(ServletConfig config) throws ServletException {
// 初始化ServletConfig对象
this.servletConfig = config;
// 获取Servlet实例名称并打印
String servletName = config.getServletName();
System.out.println("Servlet 实例的名称:" + servletName);
// 获取所有初始化参数并打印
Enumeration<String> initParameterNames = config.getInitParameterNames();
while (initParameterNames.hasMoreElements()) {
String initParameterName = initParameterNames.nextElement();
String initParameterValue = config.getInitParameter(initParameterName);
System.out.println("Servlet 初始化参数 " + initParameterName + ":" + initParameterValue);
}
}
@Override
public ServletConfig getServletConfig() {
// 返回ServletConfig对象
return servletConfig;
}
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
// 处理客户端登录请求
System.out.println("Servlet 处理请求");
}
@Override
public String getServletInfo() {
// 返回Servlet相关信息
return "Login Servlet";
}
@Override
public void destroy() {
// 销毁Servlet时执行
System.out.println("Servlet 销毁");
}
}
3.2 配置web.xml文件
web.xml是Servlet的核心配置文件,用于注册Servlet实例并配置请求映射:
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">
<display-name>ServletApp</display-name>
<!--Servlet 实例配置-->
<servlet>
<!-- Servlet 实例的名称(需与servlet-mapping中名称一致)-->
<servlet-name>loginServlet</servlet-name>
<!-- Servlet 的全类名(包名+类名)-->
<servlet-class>com.cyx.jsp.servlet.LoginServlet</servlet-class>
<!-- 初始化参数配置 -->
<init-param>
<param-name>characterEncoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</servlet>
<!--Servlet 实例与请求地址的映射配置-->
<servlet-mapping>
<servlet-name>loginServlet</servlet-name>
<!-- 匹配的请求地址(客户端通过该地址访问Servlet)-->
<url-pattern>/login</url-pattern>
</servlet-mapping>
<!--session 超时配置(单位:分钟)-->
<session-config>
<session-timeout>30</session-timeout>
</session-config>
</web-app>
🐦🔥web.xml配置详解🐦🔥
上面这段配置是 Servlet 在 web.xml 中的核心注册与映射配置,用于告诉服务器"哪个 Servlet 处理哪个请求地址"。下面逐一解释各部分含义及命名规则:
1. <servlet> 标签:注册 Servlet 实例
作用:向服务器声明一个 Servlet 实例,指定其名称、对应的 Java 类,以及初始化参数。
| 子标签 | 含义 | 能否随意起名? |
|---|---|---|
<servlet-name> |
给当前 Servlet 起一个唯一标识名称 (如 loginServlet),需与下面 <servlet-mapping> 中的名称一致,否则无法映射。 |
可以自定义,但必须唯一 (同一 web.xml 中不能有重复的 <servlet-name>),建议见名知意(如处理登录的叫 loginServlet)。 |
<servlet-class> |
指定 Servlet 对应的全类名 (包名 + 类名,如 com.cyx.jsp.servlet.LoginServlet),服务器通过这个路径找到对应的 Java 类并加载。 |
不能随意起名!必须与实际 Java 类的包名和类名完全一致(包括大小写),否则服务器会报"类找不到"错误。 |
<init-param> |
配置当前 Servlet 的初始化参数 (可选),如编码格式、配置项等,Servlet 可通过 ServletConfig 获取这些参数。 |
<param-name> 可自定义(如 characterEncoding),<param-value> 按需求设置(如 UTF-8),但参数名建议与业务相关。 |
2. <servlet-mapping> 标签:映射请求地址
作用:将上面注册的 Servlet 与客户端的请求地址绑定,告诉服务器"当收到某个请求时,交给哪个 Servlet 处理"。
| 子标签 | 含义 | 能否随意起名? |
|---|---|---|
<servlet-name> |
关联的 Servlet 名称,必须与 <servlet> 中定义的 <servlet-name> 完全一致,否则映射失败。 |
不能随意改,必须和对应 <servlet> 的名称保持一致。 |
<url-pattern> |
指定客户端访问该 Servlet 的请求路径 (如 /login),客户端通过 http://服务器地址:端口/上下文路径/url-pattern 访问(例如 http://localhost:8080/myapp/login)。 |
可以自定义,但有规则: - 必须以 / 开头(如 /login、/user/add); - 支持通配符(如 /* 匹配所有请求,/user/* 匹配 /user 下的所有请求); - 建议与业务相关(如登录用 /login,注册用 /register)。 |
3.3 编写登录页面(index.jsp)
jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE HTML>
<html>
<head>
<title>登录页面</title>
</head>
<body>
<!-- 表单提交地址为/login,请求方式为POST -->
<form action="login" method="post">
<div>
<input type="text" name="username" placeholder="请输入用户名">
</div>
<div>
<input type="password" name="password" placeholder="请输入密码">
</div>
<div>
<input type="submit" value="登录">
</div>
</form>
</body>
</html>
3.4 测试结果与生命周期验证
启动Tomcat服务器,访问index.jsp并提交登录请求,观察控制台输出:
- 首次访问时,控制台打印:

- 多次提交请求时,仅打印
Servlet 处理请求(说明Servlet实例为单例,仅初始化一次)

- 关闭Tomcat服务器时,控制台打印
Servlet 销毁(说明Servlet与容器共存亡)

4. Servlet的生命周期详解
通过上述测试,可明确Servlet的完整生命周期由以下四个阶段组成,全程由Servlet容器管理:
- 实例化:客户端首次发送请求时,Servlet容器创建Servlet实例(单例模式,整个应用仅一个实例)
- 初始化 :实例创建后,容器立即调用
init()方法,完成初始化操作(仅执行一次) - 请求处理 :每次客户端发送请求,容器调用
service()方法处理请求(可执行多次) - 销毁 :Servlet容器关闭或应用卸载时,容器调用
destroy()方法释放资源(仅执行一次)[跟随容器共存亡]
5. JSP的本质
JSP(Java Server Pages)是简化的Servlet,其本质是Servlet,工作原理如下:
- 客户端请求JSP页面时,Servlet容器(如Tomcat)会将JSP文件编译为Java类(.java文件)
- 编译后的Java类继承自
org.apache.jasper.runtime.HttpJspBase(该类继承自HttpServlet) - 最终编译为.class文件并加载运行,处理请求并返回响应结果
JSP与Servlet的核心区别:
- JSP侧重页面内容展示,允许在HTML中嵌入Java代码,适合构建视图层
- Servlet侧重业务逻辑处理,通过Java代码动态生成HTML,适合构建控制层
二、请求处理与响应机制
1. 请求与响应的体系结构

2. ServletRequest接口常用方法
ServletRequest接口定义了通用的请求处理方法,核心方法如下:
- 操作请求属性(用于请求转发时的数据传递):
- 获取属性值:
Object getAttribute(String attributeName); - 设置属性值:
void setAttribute(String attributeName, Object attributeValue);(注:原文档中attributeVaue为拼写错误,正确参数名为attributeValue) - 移除属性:
void removeAttribute(String attributeName); - 获取所有属性名:
Enumeration<String> getAttributeNames();
- 获取属性值:
- 操作请求参数:
- 获取单个参数值:
String getParameter(String parameterName); - 获取多个参数值:
String[] getParameterValues(String parameterName); - 获取所有参数名:
Enumeration<String> getParameterNames(); - 获取参数映射:
Map<String, String[]> getParameterMap();
- 获取单个参数值:
- 字符编码处理:
- 获取字符编码:
String getCharacterEncoding(); - 设置字符编码:
void setCharacterEncoding(String charset) throws UnsupportedEncodingException;(需在读取参数前设置,否则无效)
- 获取字符编码:
- 流操作(读取请求体数据):
- 获取字符流:
BufferedReader getReader() throws IOException;(仅能读取请求体数据,与字节流互斥) - 获取字节流:
ServletInputStream getInputStream() throws IOException;(仅能读取请求体数据,与字符流互斥)
- 获取字符流:
- 其他核心方法:
- 获取Servlet上下文:
ServletContext getServletContext(); - 获取请求转发对象:
RequestDispatcher getRequestDispatcher(String path);
- 获取Servlet上下文:
2.1 ServletRequest接口用法示例
java
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("请求的字符集编码需要在读取请求信息之前进行设置,否则设置的字符集编码格式将不生效");
// 获取并打印默认字符编码
System.out.println("请求字符集编码:" + servletRequest.getCharacterEncoding());
// 设置字符编码为UTF-8
servletRequest.setCharacterEncoding("UTF-8");
System.out.println("请求字符集编码:" + servletRequest.getCharacterEncoding());
// 通过字符流读取请求体数据(POST请求适用)
BufferedReader reader = servletRequest.getReader();
System.out.println("开始读取请求参数信息");
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
System.out.println("请求参数信息读取完毕");
System.out.println("================");
// 获取请求中的属性数据
System.out.println("开始获取请求中存储的数据");
Enumeration<String> attributeNames = servletRequest.getAttributeNames();
while (attributeNames.hasMoreElements()) {
String attributeName = attributeNames.nextElement();
Object attributeValue = servletRequest.getAttribute(attributeName);
System.out.println(attributeName + " => " + attributeValue);
}
System.out.println("请求中存储的数据获取完毕");
System.out.println("================");
// 方式一:通过Enumeration获取请求参数
System.out.println("方式一:开始获取请求参数信息");
Enumeration<String> parameterNames = servletRequest.getParameterNames();
while (parameterNames.hasMoreElements()) {
String parameterName = parameterNames.nextElement();
String parameterValue = servletRequest.getParameter(parameterName);
System.out.println(parameterName + " => " + parameterValue);
}
System.out.println("方式一:请求参数信息获取完毕");
System.out.println("================");
// 方式二:通过Map获取请求参数
System.out.println("方式二:开始获取请求参数信息");
Map<String, String[]> parameterMap = servletRequest.getParameterMap();
parameterMap.forEach((k, values) -> System.out.println(k + " => " + Arrays.toString(values)));
System.out.println("方式二:请求参数信息获取完毕");
System.out.println("请求所使用的上下文路径:" + servletRequest.getServletContext().getContextPath());
}
-
POST请求测试

-
GET请求测试

-
结论
使用GET方式发送的请求,只能通过getParameter 方法获取;使用POST方式发送的请求,只能使用流来获取。这是因为使用GET方式发送的请求,参数在URL地址中,解析这些参数的时候将其存放在一个Map集合中,因此可以直接获取。而POS方式发送的请求,参数在请求体中,这部分内容只能通过流来读取,然后再进行处理。
2.2 GET与POST请求的参数获取差异
通过测试可得出以下结论:
- **GET请求:**参数存储在URL地址栏中,Servlet容器会自动解析参数并存储在Map集合中,可通过
getParameter()、getParameterValues()等方法直接获取 - **POST请求:**参数存储在请求体中,需通过
getReader()或getInputStream()读取请求体数据,手动解析参数
3. ServletResponse接口常用方法
ServletResponse接口定义了通用的响应处理方法,核心方法如下:
- 字符编码与内容类型处理:
- 获取字符编码:
String getCharacterEncoding(); - 设置字符编码:
void setCharacterEncoding(String charset); - 获取内容类型:
String getContentType(); - 设置内容类型:
void setContentType(String contentType);(如text/html;charset=utf-8,同时指定内容类型和字符编码)
- 获取字符编码:
- 流操作(向客户端输出数据):
- 获取字节流(用于下载文件):
ServletOutputStream getOutputStream() throws IOException; - 获取字符流(用于输出HTML、字符串等):
PrintWriter getWriter() throws IOException;
- 获取字节流(用于下载文件):
3.1 ServletResponse接口用法示例
在Servlet的service方法中追加响应处理代码:
java
// 响应字符编码处理
System.out.println("响应的字符集编码:" + servletResponse.getCharacterEncoding());
servletResponse.setCharacterEncoding("UTF-8");
System.out.println("响应的字符集编码:" + servletResponse.getCharacterEncoding());
// 响应内容类型处理
System.out.println("响应的内容类型:" + servletResponse.getContentType());
servletResponse.setContentType("text/html;charset=utf-8");
System.out.println("响应的内容类型:" + servletResponse.getContentType());
// 通过PrintWriter向客户端输出内容
PrintWriter writer = servletResponse.getWriter();
writer.print("登录请求已处理");
writer.flush(); // 刷新流,确保数据发送
writer.close(); // 关闭流
测试结果:

4. HttpServletRequest接口常用方法
HttpServletRequest接口针对HTTP协议扩展了请求处理方法,核心方法如下:
- Cookie操作:
Cookie[] getCookies();(获取客户端发送的所有Cookie) - 请求头操作:
- 获取指定请求头:
String getHeader(String headerName); - 获取所有请求头名称:
Enumeration<String> getHeaderNames();
- 获取指定请求头:
- 请求信息获取:
- 获取请求方式:
String getMethod();(返回GET、POST、PUT、DELETE等) - 获取上下文路径:
String getContextPath();(返回Web应用的根路径) - 获取会话:
HttpSession getSession();(获取或创建Session) - 获取请求地址:
String getRequestURI();(返回包含上下文路径的请求地址)
- 获取请求方式:
5. HttpServletResponse接口常用方法
HttpServletResponse接口针对HTTP协议扩展了响应处理方法,核心方法如下:
- Cookie操作:
void addCookie(Cookie cookie);(向客户端添加Cookie) - 错误响应:
- 发送错误状态码和信息:
void sendError(int status, String errorMsg) throws IOException; - 发送错误状态码:
void sendError(int status) throws IOException;
- 发送错误状态码和信息:
- 重定向:
void sendRedirect(String redirectURL) throws IOException;(重定向到指定URL) - 响应头操作:
- 设置响应头:
void setHeader(String headerName, String headerValue); - 添加响应头:
void addHeader(String headerName, String headerValue);(与setHeader的区别:addHeader可添加多个同名头,setHeader会覆盖同名头)
- 设置响应头:
- 设置响应状态码:
void setStatus(int status);
6. HttpServlet的核心方法
HttpServlet是HTTP协议专用的Servlet抽象类,重写了service方法,核心逻辑如下:
- 重写
service(ServletRequest req, ServletResponse res):将请求和响应对象强转为HttpServletRequest和HttpServletResponse,调用重载的service(HttpServletRequest req, HttpServletResponse res)方法 - 重载
service(HttpServletRequest req, HttpServletResponse res):根据请求方式(GET、POST、PUT、DELETE等),调用对应的doXxx方法(如doGet、doPost) - 常用
doXxx方法:doGet(HttpServletRequest req, HttpServletResponse res):处理GET请求doPost(HttpServletRequest req, HttpServletResponse res):处理POST请求doPut(HttpServletRequest req, HttpServletResponse res):处理PUT请求doDelete(HttpServletRequest req, HttpServletResponse res):处理DELETE请求
6.1 实战:注册功能实现(继承HttpServlet)
java
package com.cyx.jsp.servlet;
import javax.servlet.ServletException;
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.Enumeration;
import java.util.Map;
public class RegisterServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 获取请求头信息
System.out.println("开始获取请求头信息");
Enumeration<String> headerNames = req.getHeaderNames();
while (headerNames.hasMoreElements()) {
String headerName = headerNames.nextElement();
String headerValue = req.getHeader(headerName);
System.out.println(headerName + " => " + headerValue);
}
System.out.println("请求头信息获取完毕");
// 获取请求基本信息
System.out.println("请求方式:" + req.getMethod());
System.out.println("请求地址:" + req.getRequestURI());
System.out.println("请求的上下文路径:" + req.getContextPath());
System.out.println("==================");
// 获取请求参数
System.out.println("开始读取请求参数");
Map<String, String[]> parameterMap = req.getParameterMap();
parameterMap.forEach((k, values) -> System.out.println(k + " => " + Arrays.toString(values)));
System.out.println("请求参数读取完毕");
System.out.println();
// 构建响应
System.out.println("响应开始");
resp.setContentType("text/html;charset=utf-8");
PrintWriter writer = resp.getWriter();
writer.print("注册请求已经处理");
writer.flush();
writer.close();
}
}
6.2 编写注册页面(register.jsp)
jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE HTML>
<html>
<head>
<title>注册页面</title>
</head>
<body>
<form action="createUser" method="post">
<div>
<input type="text" name="username" placeholder="请输入用户名">
</div>
<div>
<input type="password" name="password" placeholder="请输入密码">
</div>
<div>
<input type="submit" value="注册">
</div>
</form>
</body>
</html>
6.3 配置web.xml(添加注册Servlet映射)
xml
<servlet>
<servlet-name>registerServlet</servlet-name>
<servlet-class>com.cyx.jsp.servlet.RegisterServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>registerServlet</servlet-name>
<url-pattern>/createUser</url-pattern>
</servlet-mapping>
注册后,控制台的运行结果如下:

7. ServletContext接口常用方法
ServletContext(上下文对象)是应用级别的全局对象,核心方法如下:
- 获取上下文路径:
String getContextPath();(返回Web应用的根路径) - 获取资源绝对路径:
String getRealPath(String path);(根据相对路径获取服务器上的绝对路径) - 操作上下文初始化参数(在web.xml中配置的全局参数):
- 获取指定参数值:
String getInitParameter(String parameterName); - 获取所有参数名:
Enumeration<String> getInitParameterNames();
- 获取指定参数值:
- 操作上下文属性(全局共享数据):
- 获取属性值:
Object getAttribute(String attributeName); - 设置属性值:
void setAttribute(String attributeName, Object attributeValue); - 移除属性:
void removeAttribute(String attributeName); - 获取所有属性名:
Enumeration<String> getAttributeNames();
- 获取属性值:
7.1 配置上下文初始化参数(web.xml)
xml
<context-param>
<param-name>characterEncoding</param-name>
<param-value>UTF-8</param-value> <!-- 原文档中"UFT-8"为拼写错误,正确编码为"UTF-8" -->
</context-param>
7.2 读取上下文参数(修改RegisterServlet)
java
@Override
public void init(ServletConfig config) throws ServletException {
super.init(config); // 继承HttpServlet时需调用父类init方法
System.out.println("开始读取上下文参数信息");
ServletContext servletContext = config.getServletContext();
Enumeration<String> initParameterNames = servletContext.getInitParameterNames();
while (initParameterNames.hasMoreElements()) {
String initParameterName = initParameterNames.nextElement();
String initParameterValue = servletContext.getInitParameter(initParameterName);
System.out.println(initParameterName + " => " + initParameterValue);
}
}
8. Servlet交互流程简单图示

三、MVC设计模式------Web应用的架构核心
1. MVC的核心概念
**MVC(Model-View-Controller)**是一种经典的软件架构模式,将应用程序分为三个核心组件,实现职责分离:
- Model(模型):持有应用程序的所有数据、状态和业务逻辑,独立于视图和控制器。模型负责数据的存储、验证和处理,是应用程序的核心。
- View(视图):用于呈现模型中的数据,提供用户交互界面。视图仅负责数据展示,不包含业务逻辑,可根据模型数据动态更新。
- Controller(控制器):位于视图和模型之间,负责接收用户输入,解析输入并调用模型处理数据,最后将处理结果传递给视图展示。

2. MVC模式的核心优点
- 解耦性强:模型与视图分离,修改视图不会影响模型,修改模型也不会影响视图,提高了代码的可维护性。
- 复用性高:一个模型可对应多个视图(如同一组数据可通过列表、图表等多种形式展示),模型可独立移植到其他平台。
- 开发效率高:开发人员可分工协作,前端开发者专注于视图设计,后端开发者专注于模型和业务逻辑开发。
- 扩展性好:新增功能时,可单独扩展模型、视图或控制器,无需修改其他组件。
3. JSP中的MVC实现
在JSP Web应用中,MVC的三个组件对应如下:
- Controller(控制器):Servlet------接收请求、调用模型处理数据、转发请求到视图
- View(视图):JSP页面------展示模型数据,提供用户交互界面
- Model(模型):Java Bean------封装数据和业务逻辑,如User类、Product类等
3.1 应用:用户信息展示功能(MVC完整实现)
(1)编写Model(User类,Java Bean)
java
package com.cyx.jsp.pojo;
public class User {
private String username;
private String name;
private String sex;
private int age;
// getter方法
public String getUsername() {
return username;
}
public String getName() {
return name;
}
public String getSex() {
return sex;
}
public int getAge() {
return age;
}
// setter方法
public void setUsername(String username) {
this.username = username;
}
public void setName(String name) {
this.name = name;
}
public void setSex(String sex) {
this.sex = sex;
}
public void setAge(int age) {
this.age = age;
}
// toString方法(原文档中缺少右大括号,已补充)
@Override
public String toString() {
return "User{" +
"username='" + username + '\'' +
", name='" + name + '\'' +
", sex='" + sex + '\'' +
", age=" + age +
'}';
}
}
(2)编写Controller(UserInfoServlet,Servlet)
java
package com.cyx.jsp.servlet;
import com.cyx.jsp.pojo.User;
import javax.servlet.ServletException;
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 UserInfoServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 1. 模拟业务逻辑处理(如从数据库查询用户信息)
User user = new User();
user.setUsername("admin");
user.setName("管理员");
user.setSex("男");
user.setAge(20);
// 2. 设置响应格式和编码
resp.setContentType("text/html;charset=utf-8");
resp.setCharacterEncoding("UTF-8");
// 3. 将模型数据传递给视图(此处直接输出,实际开发中可通过请求转发传递给JSP)
PrintWriter writer = resp.getWriter();
writer.print("用户信息:" + user.toString());
writer.flush();
writer.close();
}
}
(3)编写View(user.jsp,视图页面)
jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>显示用户信息</title>
</head>
<body>
<!-- 点击链接发送GET请求到UserInfoServlet -->
<a href="showUserInfo">显示用户信息</a>
</body>
</html>
(4)配置web.xml(注册UserInfoServlet)
xml
<servlet>
<servlet-name>userInfoServlet</servlet-name>
<servlet-class>com.servlet.UserInfoServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>userInfoServlet</servlet-name>
<url-pattern>/showUserInfo</url-pattern>
</servlet-mapping>
启动服务器,访问user.jsp,测试结果如下:

如果我的内容对你有帮助,请 点赞 , 评论 , 收藏 。创作不易,大家的支持就是我坚持下去的动力!
