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协议

特点

  1. 无状态(Stateless)
    定义:协议本身不保存请求与响应之间的通信状态,每次请求都是独立的。
    意义:简化了服务器的实现,提高了可扩展性,但需要客户端在每次请求中携带必要的状态信息(如通过Cookie、Session等)。
  2. 无连接(Connectionless)
    定义:客户端与服务器在每次请求完成后断开连接(HTTP/1.0默认),但HTTP/1.1引入了持久连接(Keep-Alive)。
    早期版本:HTTP/0.9和HTTP/1.0每次请求均建立新连接,效率低;HTTP/1.1通过持久连接复用TCP连接,减少开销。
  3. 面向对象(Object-Oriented)
    定义:通过统一资源标识符(URI)定位互联网上的资源(如HTML、图片、视频等),支持对资源的增删改查操作。
    方法:GET(获取资源)、POST(提交数据)、PUT(更新资源)、DELETE(删除资源)等。
  4. 短连接(Short-lived)
    早期行为:HTTP/0.9和1.0采用短连接,请求完成后立即断开,导致频繁的TCP握手开销。
    改进:HTTP/1.1引入持久连接(Keep-Alive),允许复用TCP连接,提升性能。
  5. 可缓存(Cachable)
    机制:通过Cache-Control、ETag、Last-Modified等头部字段,客户端或代理服务器可缓存响应内容,减少重复请求。
    优势:降低服务器负载,加快响应速度。
  6. 灵活扩展
    头部信息:通过请求头和响应头(如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()
    获取请求方法(如 GETPOST)。
    示例String method = request.getMethod();

  • getHeader(String name)
    获取指定名称的请求头值(如 User-AgentContent-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-TypeCache-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/htmlapplication/json)。
    示例response.setContentType("application/json");

  • setCharacterEncoding(String charset)
    设置响应的字符编码(如 UTF-8)。
    示例response.setCharacterEncoding("UTF-8");


关键注意事项

  1. getInputStream()getWriter() 的冲突

    • HttpServletRequest 中,二者不能同时使用,否则抛出 IllegalStateException
  2. 响应提交后的限制

    • 一旦响应提交(通过 flushBuffer() 或客户端接收),无法修改响应头或状态码。
  3. 字符编码设置时机

    • 应在调用 getWriter()getOutputStream() 之前设置字符编码。
  4. 会话与 Cookie 的安全性

    • 敏感数据(如密码)应避免通过 Cookie 传输,需使用 HttpOnlySecure 标志。

登录案例

项目结构:

在这里插入图片描述

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/78887.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数据库进阶之MySQL 程序

1.目标 1> 了解mysqlId服务端程序 2> 掌握mysql客户端程序的使用 3> 了解工具包中的其他程序 2. MySQL程序简介 本章介绍 MySQL 命令⾏程序以及在运⾏这些程序时指定选项的⼀般语法(如:mysql -uroot -p)。 对常⽤程序进⾏详细的讲解(实用工具的使用方法)&#xf…

VS2022 设置 Qt Project Settings方法

本文解决的问题&#xff1a;创建完成后&#xff0c;如需要用到Sql或者Socket等技术&#xff0c;需要设置Qt Project Settings&#xff1b; 1、打开VS2022编译器&#xff0c;创建QT项目工程 2、创建完成后&#xff0c;点击 解决方案 →右键属性 3、选择 Qt Project Settings →…

React:封装一个评论回复组件

分析 用户想要一个能够显示评论列表&#xff0c;并且允许用户进行回复的组件。可能还需要支持多级回复&#xff0c;也就是对回复进行再回复。然后&#xff0c;我要考虑组件的结构和功能。 首先&#xff0c;数据结构方面&#xff0c;评论应该包含id、内容、作者、时间&#xf…

wx读书某sign算法详解

未加固 版本&#xff1a;9.2.3 前置知识&#xff1a; (v41 & 0xFFFFFFFFFFFFFFFELL) 是一种高效的奇偶检查方法&#xff0c;用于判断数值 v41 是否为奇数。 std::sort<std::lessstd::string,std::string &,std::string>(a1, v6, s); 排序算法 # 完全等价的字…

Django的异步任务队列管理_Celery

1 基本原理 Celery 是一个异步任务队列&#xff0c;能够将耗时操作&#xff08;如发邮件、处理图片、网络爬虫等&#xff09;从 Django 主线程中分离出来&#xff0c;由后台的 worker 处理&#xff0c;避免阻塞请求。Celery 作为独立运行的后台进程&#xff08;Worker&#xf…

【计算机网络】Linux网络的几个常用命令

&#x1f4da; 博主的专栏 &#x1f427; Linux | &#x1f5a5;️ C | &#x1f4ca; 数据结构 | &#x1f4a1;C 算法 | &#x1f152; C 语言 | &#x1f310; 计算机网络 相关文章&#xff1a;计算机网络专栏 目录 ping&#xff08;检测网络连通性&#xff09;…

全开源、私有化部署!轻量级用户行为分析系统-ClkLog

ClkLog是一款支持私有化部署的全开源埋点数据采集与分析系统&#xff0c;兼容Web、App、小程序多端埋点&#xff0c;快速洞察用户访问路径、行为轨迹&#xff0c;并生成多维用户画像。助力中小团队搭建轻量灵活的用户行为分析平台。 为什么需要一款私有化的埋点分析系统&#x…

golang定时器的精度

以 go1.23.3 linux/amd64 为例。 定时器示例代码&#xff1a; package mainimport ("context""fmt""time" )var ctx context.Contextfunc main() {timeout : 600 * time.Secondctx, _ context.WithTimeout(context.Background(), timeout)dea…

svn 远程服务搜索功能

svn服务器没有远程搜索功能&#xff0c;靠人工检索耗时耗力&#xff0c;当服务器文件过多时&#xff0c;全部checkout到本地检索&#xff0c;耗时太久。 1. TortoiseSVN 安装注意事项 下载官网地址&#xff1a;https://tortoisesvn.en.softonic.com/download 安装时选中 co…

uniapp-商城-39-shop 购物车 选好了 进行订单确认4 配送方式2 地址页面

上面讲基本的样式和地址信息&#xff0c;但是如果没有地址就需要添加地址&#xff0c;如果有不同的地址就要选地址。 来看看处理方式&#xff0c; 1、回顾 在delivery-layout中 methods:{goAddress(){uni.navigateTo({url:"/pagesub/pageshop/address/addrlist"})…

Linux命令-iostat

iostat 命令介绍 iostat 是一个用于监控 Linux 系统输入/输出设备加载情况的工具。它可以显示 CPU 的使用情况以及设备和分区的输入/输出统计信息&#xff0c;对于诊断系统性能瓶颈&#xff08;如磁盘或网络活动缓慢&#xff09;特别有用。 语法&#xff1a; iostat [options…

vue2关于Node.js17及以上报digital envelope错误的解决办法

文章目录 简介错误原因解决方案设置环境变量修改package.json安装旧版本Node.js更新依赖项更改加密设置 简介 digital envelope routines::unsupported错误‌通常发生在Node.js版本升级到17或更高版本后&#xff0c;因为这些版本开始使用OpenSSL 3.0&#xff0c;它对算法和密钥…

LLM - Large Language Model

回顾2024&#xff1a;与LLM又相伴一年的经历与思考 - 知乎万字长文入门大语言模型&#xff08;LLM&#xff09; - 知乎“大模型本质就是两个文件&#xff01;”特斯拉前AI总监爆火LLM科普&#xff0c;时长1小时&#xff0c;面向普通大众 - 知乎大模型本质及趋势剖析&#xff0c…

Linux 内核网络协议栈中的关键数据结构:inet_skb_parm 与 ip_options

在 Linux 内核的网络协议栈中,数据包的高效处理依赖于一系列精心设计的数据结构。这些结构体不仅需要存储网络数据的元信息,还需支持复杂的协议逻辑(如路由、分片、安全策略等)。本文聚焦两个核心结构体 struct inet_skb_parm 和 struct ip_options,解析它们的设计原理、功…

如何修复卡在恢复模式下的 iPhone:简短指南

Apple 建议使用恢复模式作为最后的手段&#xff0c;以便在 iPhone 启动循环或显示 Apple 标志时恢复 iPhone。这是解决持续问题的简单方法&#xff0c;但您很少使用。但是&#xff0c;当您的 iPhone 卡住恢复模式本身时&#xff0c;您会怎么做&#xff1f;虽然 iPhone 卡在这种…

10前端项目----商品详情页/滚轮行为

商品详情页面 商品详情组件发送请求获取相应商品详情信息组件展示数据 优化一下路由配置代码滚轮自动置顶 商品详情组件 路由配置 点击商品进行跳转—将Detail组件变成路由组件 从商品到详情&#xff0c;肯定需要传参(产品ID)告诉Detail是哪个商品&#xff0c;需要展示哪个商品…

DIFY 又跟新了,来到 1.3.0 版本,看正文

欢迎来到 1.3.0 版本&#xff01;添加了各种巧妙的功能、修复了错误&#xff0c;并带来了一些新功能&#xff1a; 一、核心亮点&#xff1a; 结构化输出 1、LLM 节点新增JSON Schema编辑器&#xff0c;确保大语言模型能够返回符合预设格式的JSON数据。这一功能有助于提升数据…

git检查提交分支和package.json的version版本是否一致

这里写自定义目录标题 一、核心实现步骤‌1.安装必要依赖‌2.初始化 Husky‌3.创建校验脚本‌4.配置 lint-staged‌5.更新 Husky 钩子‌ 三、工作流程说明‌四、注意事项‌ 以下是基于 Git Hooks 的完整解决方案&#xff0c;通过 husky 和自定义脚本实现分支名与版本号一致性校…

react-navigation-draw抽屉导航

心得写在前面分享给大家&#xff1a; 我的实现方法&#xff0c;并没有完全安装官网来做&#xff0c;而是进行了简化&#xff0c;效果是一样的。没有按照官网说的修改metro.config.js文件&#xff0c;同时也没有 react-native-gesture-handler 的安装后&#xff0c;我们需要有条…

【计算机视觉】CV实战项目-高分辨率遥感图像语义分割:High-Resolution-Remote-Sensing-Semantic-Segmentation

高分辨率遥感图像语义分割技术解析与实战指南 项目背景与意义核心技术解析1. **膨胀预测&#xff08;Dilated Prediction&#xff09;**2. **后处理优化**3. **半监督学习&#xff1a;伪标签&#xff08;Pseudo Labeling&#xff09;**4. **可视化与监控** 实战指南&#xff1a…