Servlet小结
视频链接:黑马servlet视频全套视频教程,快速入门servlet原理+servlet实战
什么是Servlet?
菜鸟教程:Java Servlet
servlet: server applet
Servlet是一个运行在Web服务器(如Tomcat、Jetty)或应用服务器(如WebLogic、WildFly)中的Java类,用于扩展服务器功能,通过请求-响应模型与客户端交互(如浏览器)。
- 它实现了javax.servlet.Servlet接口或继承HttpServlet类,处理HTTP请求(GET、POST等)并生成动态响应(HTML、JSON、图片等)。
- 与JSP(JavaServer Pages)结合使用时,Servlet负责业务逻辑处理,JSP负责页面渲染。
Servlet其实就是一个接口,它定义了Java类被浏览器访问到(tomcat识别到)的规则,只要实现了这个接口的Java类就是一个Servlet
快速入门
1.创建项目
2.编写Servlet类
2.1 实现Servlet接口
public class ServletDemo1 implements Servlet
2.2 继承HttpServlet类
public class ServletDemo2 extends HttpServlet
其实这个底层也是实现Servlet接口
3.实现Servlet或重写HttpServlet里面的方法
servlet里面最重要的方法:service方法
HttpServlet里面最重要的方法: doGet doPost
public interface Servlet {// 初始化void init(ServletConfig var1) throws ServletException;// 获得配置ServletConfig getServletConfig();// 提供服务void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException;// 获得信息String getServletInfo();// 销毁前执行void destroy();
}
4.配置Servlet
4.1 基于web.xml配置
<servlet><servlet-name>servlet的名字</servlet-name><servlet-class>servlet的全类名</servlet-class>
</servlet>
<servlet-mapping><servlet-name>servlet的名字</servlet-name><url-pattern>servlet的请求路径</url-pattern>
</servlet-mapping>
eg:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd"version="5.0"><!-- 配置ServletDemo1 --><servlet><servlet-name>servlet1</servlet-name><servlet-class>com.itcast.servlet.ServletDemo1</servlet-class></servlet><servlet-mapping><servlet-name>servlet1</servlet-name><url-pattern>/servlet1</url-pattern></servlet-mapping><!-- 配置ServletDemo2 --><servlet><servlet-name>servlet2</servlet-name><servlet-class>com.itcast.servlet.ServletDemo2</servlet-class></servlet><servlet-mapping><servlet-name>servlet2</servlet-name><url-pattern>/servlet2</url-pattern></servlet-mapping></web-app>
4.2 基于@WebServlet注解配置
@WebServlet("/servlet1")
public class Servlet1 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {System.out.println("servlet1 doGet");}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {System.out.println("servlet1 doPost");}
}
@WebServlet
注解会自动把当前类注册为Servlet并且请求路径为/servlet1
相当于
<!-- 配置ServletDemo1 -->
<servlet><servlet-name>servlet1</servlet-name><servlet-class>com.itcast.servlet.ServletDemo1</servlet-class>
</servlet>
<servlet-mapping><servlet-name>servlet1</servlet-name><url-pattern>/servlet1</url-pattern>
</servlet-mapping>
执行流程
1.客户端请求
浏览器输入URL http://localhost:8080/servlet1,发送HTTP请求。
2.Tomcat接收请求
Connector组件(如 Coyote)监听端口 8080,接收请求。
解析请求:提取URL路径 /servlet1,并封装为HttpServletRequest对象。
3.URL到Servlet的映射
Tomcat在启动时已加载所有Servlet配置(包括web.xml和@WebServlet注解),建立URL到Servlet类的映射表。
匹配路径:Tomcat检查请求的URL /servlet1
是否与已注册的Servlet路径匹配。
如果匹配,找到对应的Servlet类(如 ServletDemo1)。
4.Servlet类加载与实例化(单次行为)
4.1 类加载:
Tomcat使用Web应用类加载器加载Servlet类的字节码(如 ServletDemo1.class)。
类路径通常为 WEB-INF/classes 或 WEB-INF/lib 中的JAR包。
4.2 实例化:
Tomcat通过反射机制创建Servlet类的实例(ServletDemo1 instance = new ServletDemo1())。
4.3 初始化:
调用Servlet的init()方法,完成初始化(如加载配置、数据库连接等)。
5.处理请求
调用service()方法:
Tomcat根据请求方法(如GET/POST),调用Servlet的service()方法。
service()方法会进一步分发到doGet()或doPost()等具体方法。
6.响应客户端
构建响应:Servlet通过HttpServletResponse对象生成响应内容(如HTML、JSON等)。
返回结果:Tomcat通过Connector将响应结果返回给浏览器。
Http协议
特点
- 无状态(Stateless)
定义:协议本身不保存请求与响应之间的通信状态,每次请求都是独立的。
意义:简化了服务器的实现,提高了可扩展性,但需要客户端在每次请求中携带必要的状态信息(如通过Cookie、Session等)。- 无连接(Connectionless)
定义:客户端与服务器在每次请求完成后断开连接(HTTP/1.0默认),但HTTP/1.1引入了持久连接(Keep-Alive)。
早期版本:HTTP/0.9和HTTP/1.0每次请求均建立新连接,效率低;HTTP/1.1通过持久连接复用TCP连接,减少开销。- 面向对象(Object-Oriented)
定义:通过统一资源标识符(URI)定位互联网上的资源(如HTML、图片、视频等),支持对资源的增删改查操作。
方法:GET(获取资源)、POST(提交数据)、PUT(更新资源)、DELETE(删除资源)等。- 短连接(Short-lived)
早期行为:HTTP/0.9和1.0采用短连接,请求完成后立即断开,导致频繁的TCP握手开销。
改进:HTTP/1.1引入持久连接(Keep-Alive),允许复用TCP连接,提升性能。- 可缓存(Cachable)
机制:通过Cache-Control、ETag、Last-Modified等头部字段,客户端或代理服务器可缓存响应内容,减少重复请求。
优势:降低服务器负载,加快响应速度。- 灵活扩展
头部信息:通过请求头和响应头(如Content-Type、User-Agent)传递元数据,支持功能扩展。
方法扩展:HTTP/1.1新增PUT、DELETE等方法,HTTP/2支持服务器推送(Server Push)。
请求消息
POST /login HTTP/1.1
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Accept-Encoding: gzip, deflate, br, zstd
Accept-Language: zh-CN,zh;q=0.9
Cache-Control: max-age=0
Connection: keep-alive
Content-Length: 27
Content-Type: application/x-www-form-urlencoded
Cookie: JSESSIONID=ED583FB162E9D2E951D951B649C4DEBA
Host: localhost:8080
Origin: http://localhost:8080
Referer: http://localhost:8080/
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: same-origin
Sec-Fetch-User: ?1
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36
sec-ch-ua: "Google Chrome";v="135", "Not-A.Brand";v="8", "Chromium";v="135"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"username=admin&password=123
1.请求行
POST /login HTTP/1.1
- 方法(Method):POST(向服务器提交数据,通常用于表单提交)。
- 路径(URI):
/login
(请求的目标资源路径)。 - 协议版本(Protocol):HTTP/1.1(使用的HTTP协议版本)。
2.请求头
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Accept-Encoding: gzip, deflate, br, zstd
Accept-Language: zh-CN,zh;q=0.9
Cache-Control: max-age=0
Connection: keep-alive
Content-Length: 27
Content-Type: application/x-www-form-urlencoded
Cookie: JSESSIONID=ED583FB162E9D2E951D951B649C4DEBA
Host: localhost:8080
Origin: http://localhost:8080
Referer: http://localhost:8080/
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: same-origin
Sec-Fetch-User: ?1
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36
sec-ch-ua: "Google Chrome";v="135", "Not-A.Brand";v="8", "Chromium";v="135"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
1.User-Agent: 浏览器的版本信息
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36
2.Refer: 告诉服务器,请求来源页面
Referer: http://localhost:8080/
3.Cookie:客户端携带的Cookie
Cookie: JSESSIONID=ED583FB162E9D2E951D951B649C4DEBA
4.Origin:请求的来源域
Origin: http://localhost:8080
5.Accept:浏览器可接受的响应内容
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
3.请求空行
请求头结束后必须有一个空行(即两个换行符 \r\n\r\n),表示请求头结束,请求体开始。
4.请求体
username=admin&password=123
ServletRequest 接口
public interface ServletRequest {// 获取请求中指定名称的属性值。Object getAttribute(String var1);// 返回请求中所有属性名称的枚举Enumeration<String> getAttributeNames();// 获取请求的字符编码String getCharacterEncoding();// 设置请求的字符编码(需确保编码有效,否则抛出异常)。void setCharacterEncoding(String var1) throws UnsupportedEncodingException;// 获取请求体的长度(字节),若未知返回 -1int getContentLength();// 以 long 类型返回请求体长度,避免 int 溢出long getContentLengthLong();// 获取请求体的 MIME 类型String getContentType();// 获取请求体的二进制输入流(用于读取二进制数据)。ServletInputStream getInputStream() throws IOException;// 获取指定名称的请求参数的第一个值(若参数有多个值)String getParameter(String var1);// 返回所有请求参数名称的枚举Enumeration<String> getParameterNames();// 获取指定名称的请求参数的所有值(如多选框)String[] getParameterValues(String var1);//返回所有请求参数的映射(键为参数名,值为参数值数组)Map<String, String[]> getParameterMap();// 获取请求使用的协议及版本(如 HTTP/1.1)String getProtocol();// 获取请求的协议名称(如 http、https)String getScheme();// 获取服务器的主机名(如 localhost)String getServerName();// 获取服务器的端口号(如 8080)int getServerPort();// 获取请求体的字符流(用于文本数据,如表单提交)。BufferedReader getReader() throws IOException;// 获取客户端的IP地址。String getRemoteAddr();// 获取客户端的端口号(如浏览器使用的临时端口)。String getRemoteHost();// 设置请求属性,名称为 name,值为 value。void setAttribute(String var1, Object var2);// 移除指定名称的请求属性。void removeAttribute(String var1);// 获取客户端支持的所有语言环境。Locale getLocale();// 获取客户端支持的所有语言环境。Enumeration<Locale> getLocales();// 判断请求是否通过安全通道(HTTPS)传输。boolean isSecure();// 获取用于请求转发或包含的 RequestDispatcher 对象。RequestDispatcher getRequestDispatcher(String var1);}
ServletResponse 接口
public interface ServletResponse {// 获取响应的字符编码(如 UTF-8)String getCharacterEncoding();// 获取响应的 MIME 类型(如 text/html)String getContentType();// 获取二进制输出流(用于发送二进制数据,如图片)ServletOutputStream getOutputStream() throws IOException;// 获取字符输出流(用于发送文本数据,如 HTML)PrintWriter getWriter() throws IOException;// 设置响应的字符编码(如 UTF-8)void setCharacterEncoding(String var1);// 设置响应体的长度(字节,使用 int 类型)void setContentLength(int var1);// 设置响应体的长度(字节,使用 long 类型,避免溢出)void setContentLengthLong(long var1);// 设置响应的 MIME 类型(如 text/html)void setContentType(String var1);// 设置响应缓冲区的大小(单位:字节)void setBufferSize(int var1);// 获取当前缓冲区的大小(单位:字节)int getBufferSize();// 强制刷新缓冲区,将数据立即发送到客户端void flushBuffer() throws IOException;// 重置缓冲区内容,但保留已提交的响应状态void resetBuffer();// 判断响应是否已提交(即已发送到客户端)boolean isCommitted();// 重置响应,清除缓冲区内容和状态(仅在未提交时有效)void reset();// 设置响应的区域设置(如 Locale.CHINA)void setLocale(Locale var1);// 获取当前响应的区域设置Locale getLocale();
}
HttpRequest 的核心方法
1. 请求参数获取
-
getParameter(String name)
获取指定名称的请求参数的第一个值(如表单提交或 URL 参数)。
示例:String username = request.getParameter("username");
-
getParameterValues(String name)
获取指定名称的请求参数的所有值(如多选框的多个值)。
示例:String[] hobbies = request.getParameterValues("hobby");
-
getParameterMap()
返回所有请求参数的Map
(键为参数名,值为参数值数组)。
示例:Map<String, String[]> paramMap = request.getParameterMap();
2. 请求头与元数据
-
getMethod()
获取请求方法(如GET
、POST
)。
示例:String method = request.getMethod();
-
getHeader(String name)
获取指定名称的请求头值(如User-Agent
、Content-Type
)。
示例:String userAgent = request.getHeader("User-Agent");
-
getHeaders(String name)
获取指定名称的所有请求头值(若存在多个值)。
示例:Enumeration<String> acceptTypes = request.getHeaders("Accept");
3. 请求路径与来源
-
getRequestURI()
获取请求的资源路径(不包含主机名和端口)。
示例:/api/user
(返回路径部分)。 -
getRequestURL()
获取完整的请求 URL(包含协议、主机和端口)。
示例:http://localhost:8080/api/user
。 -
getRemoteAddr()
获取客户端的 IP 地址。
示例:String clientIP = request.getRemoteAddr();
4. 会话与 Cookie
-
getSession()
获取与当前请求关联的HttpSession
对象(若不存在则新建)。
示例:HttpSession session = request.getSession();
-
getCookies()
获取客户端发送的 Cookie 集合。
示例:Cookie[] cookies = request.getCookies();
5. 其他重要方法
-
getInputStream()
获取请求体的二进制输入流(用于文件上传或二进制数据)。
示例:ServletInputStream inputStream = request.getInputStream();
-
getPart(String name)
获取上传的文件或表单字段(用于处理多部分表单数据)。
示例:Part filePart = request.getPart("file");
HttpResponse 的核心方法
1. 响应头与状态码设置
-
setStatus(int sc)
或sendError(int sc)
设置 HTTP 状态码(如200
成功、404
未找到、500
服务器错误)。
示例:response.setStatus(HttpServletResponse.SC_OK);
-
setHeader(String name, String value)
设置指定名称的响应头(如Content-Type
、Cache-Control
)。
示例:response.setHeader("Content-Type", "application/json");
2. 响应内容输出
-
getOutputStream()
获取二进制输出流(用于发送文件或二进制数据)。
示例:ServletOutputStream os = response.getOutputStream();
-
getWriter()
获取字符输出流(用于发送文本内容,如 JSON、HTML)。
示例:PrintWriter writer = response.getWriter();
3. 重定向与会话管理
-
sendRedirect(String location)
发送重定向响应(客户端会发起新请求到指定 URL)。
示例:response.sendRedirect("/login.html");
-
addCookie(Cookie cookie)
添加一个 Cookie 到响应中(用于客户端存储数据)。
示例:Cookie sessionCookie = new Cookie("session", "123456"); response.addCookie(sessionCookie);
4. 缓冲区与提交控制
-
flushBuffer()
强制刷新缓冲区,立即发送响应内容到客户端。
示例:response.flushBuffer();
-
reset()
重置响应(清除缓冲区和状态,需在响应提交前调用)。
示例:response.reset();
5. 其他重要方法
-
setContentType(String type)
设置响应的 MIME 类型(如text/html
、application/json
)。
示例:response.setContentType("application/json");
-
setCharacterEncoding(String charset)
设置响应的字符编码(如UTF-8
)。
示例:response.setCharacterEncoding("UTF-8");
关键注意事项
-
getInputStream()
和getWriter()
的冲突- 在
HttpServletRequest
中,二者不能同时使用,否则抛出IllegalStateException
。
- 在
-
响应提交后的限制
- 一旦响应提交(通过
flushBuffer()
或客户端接收),无法修改响应头或状态码。
- 一旦响应提交(通过
-
字符编码设置时机
- 应在调用
getWriter()
或getOutputStream()
之前设置字符编码。
- 应在调用
-
会话与 Cookie 的安全性
- 敏感数据(如密码)应避免通过 Cookie 传输,需使用
HttpOnly
和Secure
标志。
- 敏感数据(如密码)应避免通过 Cookie 传输,需使用
登录案例
项目结构:
index.jsp:
<%--Created by IntelliJ IDEA.User: xuanDate: 2025/4/24Time: 20:05To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>Title</title>
</head>
<body>
<form action="/login" method="post">用户名:<input type="text" name="username"><br>密码:<input type="password" name="password"><br><input type="submit" value="登录"/>
</form>
</body>
</html>
pom.xml文件:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.itcast</groupId><artifactId>login-test</artifactId><version>1.0-SNAPSHOT</version><name>login-test</name><packaging>war</packaging><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><maven.compiler.target>1.8</maven.compiler.target><maven.compiler.source>1.8</maven.compiler.source><junit.version>5.9.2</junit.version></properties><dependencies><dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>4.0.1</version><scope>provided</scope></dependency><dependency><groupId>org.junit.jupiter</groupId><artifactId>junit-jupiter-api</artifactId><version>${junit.version}</version><scope>test</scope></dependency><dependency><groupId>org.junit.jupiter</groupId><artifactId>junit-jupiter-engine</artifactId><version>${junit.version}</version><scope>test</scope></dependency><!-- Druid 连接池 --><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.2.6</version></dependency><!-- MySQL 8.0 驱动 --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.33</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-jdbc</artifactId><version>5.3.20</version></dependency><dependency><groupId>commons-beanutils</groupId><artifactId>commons-beanutils</artifactId><version>1.9.4</version></dependency></dependencies><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-war-plugin</artifactId><version>3.3.2</version></plugin></plugins></build>
</project>
1.创建数据库,创建user表
create database servlet;create table user
(id int auto_incrementprimary key,username varchar(50) not null comment '用户名',password varchar(12) not null
);
2.编写数据库配置文件
driverClassName=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/servlet
username=root
password=root
initialSize=5
maxActive=20
maxWait=60000
3.编写数据库工具类
package com.itcast.utils;import com.alibaba.druid.pool.DruidDataSourceFactory;
import javax.sql.DataSource;
import java.io.InputStream;
import java.sql.Connection;
import java.util.Properties;public class JDBCUtils {private static DataSource dataSource;static {try {Properties properties = new Properties();InputStream resource = JDBCUtils.class.getClassLoader().getResourceAsStream("druid.properties");properties.load(resource);dataSource = DruidDataSourceFactory.createDataSource(properties);} catch (Exception e) {e.printStackTrace();System.err.println("数据库加载出错");}}public static DataSource getDataSource(){return dataSource;}public Connection getConnection() throws Exception{return dataSource.getConnection();}
}
4.编写User实体类,封装用户数据
package com.itcast.dao;public class User {private String username;private String password;public User() {}public User(String username, String password) {this.username = username;this.password = password;}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}
}
5.编写LoginDao.class
package com.itcast.domain;import com.itcast.dao.User;
import com.itcast.utils.JDBCUtils;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;public class UserDao {private JdbcTemplate jdbcTemplate = new JdbcTemplate(JDBCUtils.getDataSource());/*** 登录* @param loginUser* @return*/public User login(User loginUser) {try {String sql = "select * from user where username = ? and password = ?";User user = jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper<>(User.class),loginUser.getUsername(), loginUser.getPassword());return user;} catch (DataAccessException e) {System.out.println("用户"+loginUser.getUsername()+"登录失败");return null;}}
}
6.编写servlet
LoginServlet.class:
package com.itcast.servlet;import com.itcast.dao.User;
import com.itcast.domain.UserDao;
import org.apache.commons.beanutils.BeanUtils;import javax.servlet.ServletException;
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.lang.reflect.InvocationTargetException;
import java.util.Map;@WebServlet("/login")
public class LoginServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {this.doPost(req, resp);}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {req.setCharacterEncoding("utf-8");Map<String, String[]> map = req.getParameterMap();User userDTO = new User();try {BeanUtils.populate(userDTO, map);} catch (Exception e) {e.printStackTrace();System.out.println("复制失败");}UserDao userDao = new UserDao();User user = userDao.login(userDTO);if (user == null) {// 登录失败req.setAttribute("msg", "用户名或密码错误");req.getRequestDispatcher("/fail").forward(req, resp);}else {req.getRequestDispatcher("/success").forward(req, resp);}}
}
FailServlet.class:
package com.itcast.servlet;import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;@WebServlet("/fail")
public class FailServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {this.doPost(req, resp);}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {resp.setCharacterEncoding("utf-8");resp.setContentType("text/html;charset=utf-8");resp.getWriter().write("登录失败");}
}
SuccessServlet.class:
package com.itcast.servlet;import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;@WebServlet("/success")
public class SuccessServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {this.doPost(req, resp);}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {resp.setCharacterEncoding("utf-8");resp.setContentType("text/html;charset=utf-8");String username = req.getParameter("username");resp.getWriter().write(username + "登录成功");}
}
— Xuan
相关文章:

Servlet小结
视频链接:黑马servlet视频全套视频教程,快速入门servlet原理servlet实战 什么是Servlet? 菜鸟教程:Java Servlet servlet: server applet Servlet是一个运行在Web服务器(如Tomcat、Jetty)或应用…...

2025上海车展:光峰科技全球首发“灵境”智能车载光学系统
当AI为光赋予思想,汽车将会变成什么样?深圳光峰科技为您揭晓答案。 2025年4月23日,在刚刚开幕的“2025上海车展”上,全球领先的激光核心器件公司光峰科技举办了主题为“AI光影盛宴,智享未来出行”的媒体发布会&#x…...

BiliNote:开源的AI视频笔记生成工具,让知识提取与分享更高效——跨平台自动生成结构化笔记,实现从视频到Markdown的智能转化
引言:视频学习的痛点与BiliNote的解决方案 随着知识视频化趋势的加速,B站、YouTube等平台成为学习与信息获取的重要渠道,但手动记录笔记耗时低效、信息碎片化等问题依然突出。BiliNote的出现,通过AI驱动的自动化流程,将视频内容转化为结构清晰的Markdown笔记,支持截图插…...
docker 运行时权限和 Linux 能力了解
文档参考: https://docs.docker.com/engine/containers/run/#runtime-privilege-and-linux-capabilities https://docs.docker.com/reference/cli/docker/container/run/#privileged 本片主要了解容器在运行时如何赋予的格外的权限,默认情况下࿰…...

图纸安全防护管理:构建企业核心竞争力的关键屏障
在当今高度竞争的商业环境中,图纸作为企业核心技术的重要载体,其安全防护管理已成为企业知识产权保护体系中的关键环节。无论是建筑行业的施工蓝图、制造业的产品设计图,还是高科技企业的研发图纸,都承载着企业的核心竞争力和商业…...
如何用WordPress AI插件自动生成SEO文章,提升网站流量?
1. 为什么你需要一个WordPress AI文章生成插件? 每天手动写文章太耗时?SEO优化总是不达标?WordPress AI插件能帮你24小时自动生成原创内容,从关键词挖掘到智能排版,全程无需人工干预。 痛点:手动写作效率低…...

借助内核逻辑锁pagecache到内存
一、背景 内存管理是一个永恒的主题,尤其在内存紧张触发内存回收的时候。系统在通过磁盘获取磁盘上的文件的内容时,若不开启O_DIRECT方式进行读写,磁盘上的任何东西都会被缓存到系统里,我们称之为page cache。可以想象࿰…...

Nacos简介—2.Nacos的原理简介
大纲 1.Nacos集群模式的数据写入存储与读取问题 2.基于Distro协议在启动后的运行规则 3.基于Distro协议在处理服务实例注册时的写路由 4.由于写路由造成的数据分片以及随机读问题 5.写路由 数据分区 读路由的CP方案分析 6.基于Distro协议的定时同步机制 7.基于Distro协…...
【信息系统项目管理师】高分论文:论人力资源管理与成本管理(医院信息系统)
更多内容请见: 备考信息系统项目管理师-专栏介绍和目录 文章目录 论文一、规划人力资源管理二、组建项目团队三、建设项目团队四、管理项目团队论文 一个完善的医院信息系统通常由上百个子系统构成,而这些系统随着医院发展需求逐步建设的,他们来源于不同厂家,基于不同的技…...
Docker Compose和 Kubernetes(k8s)区别
Docker Compose 和 Kubernetes(k8s)是两种不同层次的容器编排工具,主要区别体现在设计目标、使用场景和功能特性上。以下是它们的核心对比: 1. 设计目标 Docker Compose 单机编排:专注于在单个主机上定义和运行多容器应…...
IP查询专业版:支持IPv4/IPv6自动识别并切换解析的API接口使用指南
以下是根据您提供的网页内容编辑的符合CSDN内容发布要求的Markdown格式文本: 一、API概述 在开发过程中,我们常常需要对IP地址进行查询,以获取其详细信息,如地理位置、运营商等。万维易源的“IP查询专业版”API接口能够提供丰富…...
Spring Boot中的监视器:Actuator的原理、功能与应用
在 Spring Boot 应用中,监视器通常指 Spring Boot Actuator,一个内置的生产就绪工具,用于监控和管理运行中的应用。Actuator 提供了一系列 RESTful 端点,暴露应用的运行时信息,如健康状态、性能指标、日志配置和环境变…...
P12167 [蓝桥杯 2025 省 C/Python A] 倒水
P12167 [蓝桥杯 2025 省 C/Python A] 倒水 题目描述 小蓝有 n n n 个装了水的瓶子,从左到右摆放,第 i i i 个瓶子里装有 a i a_i ai 单位的水。为了美观,小蓝将水循环染成了 k k k 种颜色,也就是说,第 i i i …...

TCP协议理解
文章目录 TCP协议理解理论基础TCP首部结构图示字段逐项解析 TCP是面向连接(Connection-Oriented)面向连接的核心表现TCP 面向连接的核心特性TCP 与UDP对比 TCP是一个可靠的(reliable)序号与确认机制(Sequencing & Acknowledgment…...

用 LangChain 手搓 RAG 系统:从原理到实战
一、RAG 系统简介 在当今信息爆炸的时代,如何高效地从海量数据中获取有价值的信息并生成准确、自然的回答,成为了人工智能领域的重要课题。检索增强生成(Retrieval-Augmented Generation,RAG)系统应运而生,…...

联合体和枚举类型
1.联合体类型 1.1:联合体类型变量的创建 与结构体类型一样,联合体类型 (关键字:union) 也是由⼀个或者多个成员变量构成,这些成员变量既可以是不同的类型,也可以是相同的类型。但是编译器只为最⼤的成员变量分配⾜够的内存空间。联合体的特…...
一种企业信息查询系统设计和实现:xujian.tech/cs
一种企业信息查询系统设计和实现:xujian.tech/cs 背景与定位 企业在对外合作、风控审查或市场调研时,常需快速获取公开的工商信息。本文介绍一个企业信息搜索引擎,面向普通用户与开发者,帮助快速定位企业名称、统一社会信用代码…...

C语言指针5
1.void*概述 void称为无类型,void*称为无类型指针,void不可以单独定义变量,却可以定义无类型的指针,而且所定义的指针称为泛型指针,所谓泛型指针,其含义是void*类型的指针可以接收一切类型变量的地址 struc…...
[4A/OP]
2.2 安装程序 2.2.1 解压缩.tar.gz文件 调用UNIX命令tar会在当前目录下创建4A/OP子例程主目录4AOP-1.5/,包括所有必要的子目录。只需键入以下命令即可解压缩和“untar”4AOP-1.5.tar.gz: tar -xzvf 4AOP-1.5.tar.gz4AOP-1.5/目录现在应该已经创建&…...
来云台跑腿配送平台:用户体验至上的服务理念
来云台跑腿配送平台始终秉持用户体验至上的服务理念,从下单到收货的每一个环节,都致力于为用户提供优质、便捷的服务。 简洁的下单流程是良好体验的开端。用户通过 APP 或小程序,只需几步操作就能完成下单。清晰的服务分类、自动定位功能和…...
本地部署 Dify + Ollama 到 D盘,并挂载本地大模型 的完整教程,结合 Docker 运行环境
一、环境准备 1. 软件与硬件要求 • 操作系统:Windows 10/11 专业版(需开启 Hyper-V) • 硬件配置: • CPU ≥ 4核(推荐 Intel i5 及以上) • 内存 ≥ 16GB(大模型运行需预留 8GB 以上&#…...

文档构建:Sphinx全面使用指南 — 强化篇
文档构建:Sphinx全面使用指南 — 强化篇 Sphinx 是一款强大的文档生成工具,使用 reStructuredText 作为标记语言,通过扩展兼容 Markdown,支持 HTML、PDF、EPUB 等多种输出格式。它具备自动索引、代码高亮、跨语言支持等功能&#…...

深度理解C语言函数之strlen()的模拟实现
文章目录 前言一、strlen的模拟实现二、模拟实现代码及思路2.1 计数法2.2 指针相减法三、递归计数法 总结 前言 我写这篇文章的目的主要是帮助理解C语言中重要函数的用法,后面也会总结C相关的函数的模拟实现,这里的算法不一定是最好的,因为只…...

0基础 | Proteus仿真 | 51单片机 | 继电器
继电器---RELAY 本次选择一款5v一路继电器进行讲解 信号输入 IN1输入高电平,三极管导通,LED1点亮,电磁铁12接通吸引3向下与4接通,J1A的12接通 IN1输入低电平,则J1A的23接通 产品引脚定义及功能 序号 引脚符号 引脚…...

Python解析地址中省市区街道
Python解析地址中省市区街道 1、效果 输入:海珠区沙园街道西基村 输出: 2、导入库 pip install jionlp3、示例代码 import jionlp as jiotext 海珠区沙园街道西基村 res jio.parse_location(text, town_villageTrue) print(res)...

在vscode终端中运行npm命令报错
解决方案 这个错误信息表明,你的系统(可能是 Windows)阻止了 PowerShell 执行脚本,这是由于 PowerShell 的执行策略导致的。PowerShell 的执行策略控制着在系统上运行哪些 PowerShell 脚本。默认情况下,Windows 可能…...

提升变电站运维效率:安科瑞无线测温系统创新应用
一、引言 变电站作为电力系统的关键枢纽,承担着变换电压、分配电能以及控制电力流向等重要任务。在变电站的运行过程中,电气设备的接点温度监测至关重要。过热问题可能由多种因素引发,如电阻过大、接头质量欠佳、衔接不紧密、物理老化等&…...

vue3 使用 vite 管理多个项目,实现各子项目独立运行,独立打包
场景: 之前写过一篇 vite vue2 的配置,但是现在项目使用 vue3 较多,再更新一下 vue脚手架初始化之后的项目,每个项目都是独立的,导致项目多了之后,node依赖包过多,占用内存较多。想实现的效果…...

WebRTC服务器Coturn服务器用户管理和安全性
1、概述 Coturn服务器对用户管理和安全方面也做了很多的措施,以下会介绍到用户方面的设置 1.1、相关术语 1.1.1 realm 在 coturn 服务器中,域(realm)是一种逻辑上的分组概念,用于对不同的用户群体、应用或者服务进行区…...

如何使用极狐GitLab 的外部状态检查功能?
极狐GitLab 是 GitLab 在中国的发行版,关于中文参考文档和资料有: 极狐GitLab 中文文档极狐GitLab 中文论坛极狐GitLab 官网 外部状态检查 (ULTIMATE ALL) pending 状态引入于极狐GitLab 16.5 pending 状态检查的超时时间为两分钟引入于极狐GitLab 16…...