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.pswp.cn/bicheng/78887.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/78887.shtml
英文地址,請注明出處:http://en.pswp.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…