Java Web 7-10

Java Web 7-10

  • [7. 开发第一个 Servlet](#7. 开发第一个 Servlet)
    • [7.1 创建项目的标准目录](#7.1 创建项目的标准目录)
    • [7.2 编写 Servlet](#7.2 编写 Servlet)
    • [7.3 编译 Servlet](#7.3 编译 Servlet)
    • [编译后拷贝到 classes 目录](#编译后拷贝到 classes 目录)
    • [7.4 编写 web.xml 配置](#7.4 编写 web.xml 配置)
    • [7.5 部署项目到 Tomcat](#7.5 部署项目到 Tomcat)
    • [启动 Tomcat 打开浏览器访问](#启动 Tomcat 打开浏览器访问)
    • [7.6 使用超链接发送请求](#7.6 使用超链接发送请求)
    • [7.7 响应一段中文到浏览器](#7.7 响应一段中文到浏览器)
  • [8. Servlet 连接数据库](#8. Servlet 连接数据库)
    • [8.1 添加 mysql 驱动](#8.1 添加 mysql 驱动)
    • [8.2 编写 DeptListServlet](#8.2 编写 DeptListServlet)
    • [8.3 编写 web.xml](#8.3 编写 web.xml)
    • [8.4 提供超链接](#8.4 提供超链接)
    • [8.5 部署测试](#8.5 部署测试)
  • [9. IDEA 开发 Servlet](#9. IDEA 开发 Servlet)
    • [9.1 创建空项目](#9.1 创建空项目)
    • [9.2 创建普通 java 模块](#9.2 创建普通 java 模块)
    • [9.3 创建 web 目录作为 webapproot](#9.3 创建 web 目录作为 webapproot)
    • [9.4 添加 web 支持](#9.4 添加 web 支持)
    • [9.5 添加 Artifact(构件)](#9.5 添加 Artifact(构件))
    • [将 servlet-api.jar 添加到 classpath 中](#将 servlet-api.jar 添加到 classpath 中)
    • [9.6 添加数据库驱动](#9.6 添加数据库驱动)
    • [9.7 编写 Servlet 和 web.xml](#9.7 编写 Servlet 和 web.xml)
    • [9.8 IDEA 配置 Tomcat](#9.8 IDEA 配置 Tomcat)
    • [9.9 部署构件到 Tomcat](#9.9 部署构件到 Tomcat)
    • [9.10 启动 Tomcat 测试](#9.10 启动 Tomcat 测试)
  • [10. HTTP协议](#10. HTTP协议)
    • [10.1 什么是HTTP协议](#10.1 什么是HTTP协议)
    • [10.2 HTTP请求报文详解](#10.2 HTTP请求报文详解)
    • [10.3 HTTP响应报文详解](#10.3 HTTP响应报文详解)
    • [10.4 GET与POST的区别及选择](#10.4 GET与POST的区别及选择)
      • [10.4.1 区别](#10.4.1 区别)
      • [10.4.2 如何选择](#10.4.2 如何选择)
      • [10.4.3 怎么发送 POST 请求](#10.4.3 怎么发送 POST 请求)
    • [10.5 URL编码](#10.5 URL编码)
      • [10.5.1 URL编码的作用](#10.5.1 URL编码的作用)
      • [10.5.2 前端系统中什么情况下需要手动编码](#10.5.2 前端系统中什么情况下需要手动编码)
      • [10.5.3 后端系统中什么情况下需要手动编码](#10.5.3 后端系统中什么情况下需要手动编码)

7. 开发第一个 Servlet

7.1 创建项目的标准目录

在任意位置创建一个目录 web01,作为项目的根目录。然后在该目录下按照以下目录结构创建:

plain 复制代码
web01
    |-------WEB-INF
               |-------classes

7.2 编写 Servlet

在任意位置创建 HelloServlet.java。

任何 Servlet都必须实现 jakarta.servlet.Servlet接口,该接口中有哪些方法呢?参考帮助文档:

编写 HelloServlet实现该接口中所有方法:

java 复制代码
package com.jkweilai.servlet;

import jakarta.servlet.Servlet;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
import jakarta.servlet.ServletConfig;
import java.io.PrintWriter;
import java.io.IOException;
// HelloServlet对象的创建以及这个对象上方法的调用,都是Tomcat服务器负责的。
// 程序员只提供实现类和实现方法。程序员不能自己new HelloServlet(),也不能自己手动调用方法。
public class HelloServlet implements Servlet{

	public void init(ServletConfig config) throws ServletException{}
	// 这个回调函数是Servlet的核心方法。
	// 每一次请求,这个方法都会被调用。
	public void service(ServletRequest request,ServletResponse response)
		throws ServletException, IOException{
		// 向控制台打印
		System.out.println("Hello Servlet!");
		// 向浏览器上响应HTML
		PrintWriter out = response.getWriter();
		out.print("<h1>Hello Servlet!</h1>");
	}

	public void destroy(){}

	public String getServletInfo(){
		return "";
	}

	public ServletConfig getServletConfig(){
		return null;
	}

}

7.3 编译 Servlet

配置环境变量 CLASSPATH:

思考,为什么要配置 CLASSPATH 环境变量,另外环境变量中为什么要添加一个 .

编译:

以上编译命令表示:编译当前目录下的 HelloServlet.java文件,将编译之后的程序放到当前目录下。

编译之后生成了:

编译后拷贝到 classes 目录

将以上编译之后的结果拷贝到 WEB-INF/classes目录下:

7.4 编写 web.xml 配置

Tomcat 服务器 webapps 目录下自带了几个项目,这些项目当中都有 web.xml,可以从这里拷贝样例文件。

在 web01\WEB-INF\目录下新建 web.xml文件,进行以下的配置:

xml 复制代码
<?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_6_0.xsd"
  version="6.0"
  metadata-complete="true">

  <servlet>
  	<servlet-name>firstServlet</servlet-name>
  	<servlet-class>com.jkweilai.servlet.HelloServlet</servlet-class>
  </servlet>
  <servlet-mapping>
  	<servlet-name>firstServlet</servlet-name>
  	<url-pattern>/hello</url-pattern>
  </servlet-mapping>
  
</web-app>

需要引起注意:

**metadata-complete="true"**:容器忽略所有注解,只使用 web.xml 配置

<font style="color:rgb(15, 17, 21);">metadata-complete="false"</font>(默认值):容器会扫描注解

7.5 部署项目到 Tomcat

将 web01目录拷贝到 CATALINA_HOME/webapps目录下,如下:

启动 Tomcat 打开浏览器访问

浏览器上的结果:

控制台的结果:

7.6 使用超链接发送请求

在上面测试时,浏览器地址栏上直接输入的地址是:http://localhost:8080/web01/hello,也可以采用用户点击超链接的方式发送请求。在 web01目录下新建 index.html。然后编写如下代码:

html 复制代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>首页</title>
</head>
<body>
  <a href="http://localhost:8080/web01/hello">hello1</a>
  <!--http://ip:port 可以省略。前端编写的路径目前都以 / 开头,并且一定要添加项目名。-->
  <a href="/web01/hello">hello1</a>
</body>
</html>

将 index.html文件部署到 Tomcat 服务器的 web01项目下:

再次启动服务器测试

启动 Tomcat 服务器,然后打开浏览器在地址栏上输入:http://localhost:8080/web01/index.html

点击以上两个超链接发送请求,结果都是:

将 index.html 放到 WEB-INF 目录下测试

启动服务器,打开浏览器,输入地址:http://localhost:8080/web01/WEB-INF/index.html,如下:

通过测试得知,放在 WEB-INF 目录下的资源是受保护的。

7.7 响应一段中文到浏览器

修改 HelloServlet.java中的代码,响应一段中文到浏览器。修改代码之后,保存,然后重新编译,将新生成的代码重新拷贝到 Tomcat 服务器的 web01/WEB-INF/classes目录下,最后启动 Tomcat 服务器,打开浏览器访问。

java 复制代码
public void service(ServletRequest request,ServletResponse response)
    throws ServletException, IOException{
    // 向控制台打印
    System.out.println("Hello Servlet!");
    // 向浏览器上响应HTML
    PrintWriter out = response.getWriter();
    out.print("<h1>Hello Servlet!</h1>");
    out.print("<h1>你好,服务器端的小程序!</h1>");
}

运行效果:

发现响应中文的时候出现了乱码问题,编写以下代码来解决响应时的中文乱码问题:

java 复制代码
public void service(ServletRequest request,ServletResponse response)
    throws ServletException, IOException{
    // 向控制台打印
    System.out.println("Hello Servlet!");
    
    // 向浏览器上响应HTML
    response.setContentType("text/html"); // 设置响应的内容类型,这个对解决响应时的中文乱码问题没有作用。
    response.setCharacterEncoding("UTF-8"); // 设置响应时采用的字符编码方式。这个是解决响应时中文乱码问题的关键。
    
    PrintWriter out = response.getWriter();
    out.print("<h1>Hello Servlet!</h1>");
    out.print("<h1>你好,服务器端的小程序!</h1>");
}

重新编译、重新部署、重启服务器访问:

中文乱码问题就解决了。另外,以上解决中文乱码的两行代码:

java 复制代码
response.setContentType("text/html");
response.setCharacterEncoding("UTF-8");

可以合并为一行:

java 复制代码
response.setContentType("text/html;charset=UTF-8");

**注意:这行代码必须出现在 ****PrintWriter out = response.getWriter();**之前才能解决乱码问题。

**<font style="color:#DF2A3F;">response.setCharacterEncoding("UTF-8");</font>**和 HTML 中的 **<font style="color:#DF2A3F;"><meta charset="UTF-8"></font>**有什么区别?

  • 前者:设置Servlet输出流的字符编码方式,影响**<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">PrintWriter</font>**如何将Java字符串转换为字节序列,是服务器端的行为,发生在内容发送到客户端之前,会自动设置**<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">Content-Type</font>**响应头的charset部分,例如:**<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">Content-Type: text/html;charset=UTF-8</font>**这是最根本的编码设置,决定了数据在传输时的实际编码。
  • 后者:是HTML文档内部的编码声明,浏览器在解析HTML时会参考这个提示,当HTTP响应头没有指定charset时,浏览器会查找meta标签,如果HTTP头已指定charset,meta标签通常会被忽略。

8. Servlet 连接数据库

继续在 web01项目中实现连接数据库的效果。实现功能:以列表形式显示部门名称。

8.1 添加 mysql 驱动

在 WEB-INF目录下新建 lib目录,将 mysql.jar驱动放到 lib目录中。

8.2 编写 DeptListServlet

java 复制代码
package com.jkweilai.servlet;

import jakarta.servlet.Servlet;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
import jakarta.servlet.ServletConfig;
import java.io.PrintWriter;
import java.io.IOException;
import java.sql.*;

public class DeptListServlet implements Servlet{

	public void init(ServletConfig config) throws ServletException{}

	public void service(ServletRequest request,ServletResponse response)
		throws ServletException, IOException{
		response.setContentType("text/html;charset=UTF-8");
		PrintWriter out = response.getWriter();

		Connection conn = null;
		PreparedStatement ps = null;
		ResultSet rs = null;
		try{
			// 1.注册驱动
			Class.forName("com.mysql.cj.jdbc.Driver");
			// 2.获取连接
			String url = "jdbc:mysql://localhost:3306/servlet";
			String user = "root";
			String password = "123456";
			conn = DriverManager.getConnection(url, user, password);
			// 3.获取预编译的数据库操作对象
			String sql = "select dname from dept";
			ps = conn.prepareStatement(sql);
			// 4.执行SQL
			rs = ps.executeQuery();
			// 5.处理查询结果集
			while(rs.next()){
				String dname = rs.getString("dname");
				out.print(dname);
				out.print("<br>");
			}
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			// 6.释放资源
			if(rs != null){
				try{
					rs.close();
				}catch(Exception e){
					e.printStackTrace();
				}
			}
			if(ps != null){
				try{
					ps.close();
				}catch(Exception e){
					e.printStackTrace();
				}
			}
			if(conn != null){
				try{
					conn.close();
				}catch(Exception e){
					e.printStackTrace();
				}
			}
		}
	}

	public void destroy(){}

	public String getServletInfo(){
		return "";
	}

	public ServletConfig getServletConfig(){
		return null;
	}

}

编译后,将编译后的字节码拷贝到 WEB-INF/classes目录下,这里不再赘述。

8.3 编写 web.xml

xml 复制代码
<servlet>
  <servlet-name>dListServlet</servlet-name>
  <servlet-class>com.jkweilai.servlet.DeptListServlet</servlet-class>
</servlet>
<servlet-mapping>
  <servlet-name>dListServlet</servlet-name>
  <url-pattern>/list</url-pattern>
</servlet-mapping>

8.4 提供超链接

在 index.html文件中添加超链接:

html 复制代码
<!--对于前端请求路径目前以 / 开始,带项目名。web.xml文件中的路径不带项目名。-->
<a href="/web01/list">部门列表</a>

8.5 部署测试

将项目部署到 Tomcat 的 webapps 目录下,启动 Tomcat 服务器,打开浏览器输入地址:http://localhost:8080/web01/index.html

点击部门列表超链接发送请求:

9. IDEA 开发 Servlet

9.1 创建空项目

设置空项目的 JDK 版本:

9.2 创建普通 java 模块

9.3 创建 web 目录作为 webapproot

9.4 添加 web 支持

添加 web.xml文件时,选择 6.0版本。

9.5 添加 Artifact(构件)

Artifact 是构件的意思,通常指代** 可部署的输出文件**。

将 servlet-api.jar 添加到 classpath 中

注意,这个 jar 包只是起到一个编译阶段的作用(只是让我们在 IDEA 中编写的 Servlet 程序能够正常编译),因此这个 jar 包不需要放到 WEB-INF/lib目录中。因为 WEB-INF/lib目录下的 jar 包是在运行阶段起作用的,Tomcat 服务器运行时 servlet-api.jar 已经在 CATALINA_HOME/lib目录下了。

在 web01模块下随意创建一个目录,例如 lib,然后将 servlet-api.jar拷贝到该目录下,然后 右键-->Add as Library...

9.6 添加数据库驱动

在 WEB-INF目录下新建 lib目录,将 mysql 驱动 jar 包拷贝到该目录下:

这个 jar 包是在运行阶段起作用的,编译阶段不需要。

9.7 编写 Servlet 和 web.xml

使用之前的 DeptListServlet程序即可。

xml 复制代码
<?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_6_0.xsd"
         version="6.0">
    <servlet>
        <servlet-name>listServlet</servlet-name>
        <servlet-class>com.jkweilai.servlet.DeptListServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>listServlet</servlet-name>
        <url-pattern>/list</url-pattern>
    </servlet-mapping>
</web-app>

9.8 IDEA 配置 Tomcat

9.9 部署构件到 Tomcat

**上图当中的 ****On 'Update' action**是指定什么的?

  • 它是用来:当你手动触发"更新"操作时,IDEA 应该对正在运行的 Tomcat 应用执行什么动作。
  • 怎么手动触发"更新"操作?当我们修改了项目代码之后,需要更新应用,代码才能生效,通过 <font style="color:rgb(15, 17, 21);">ctrl + F10</font>可以手动触发应用更新。或者点击下图面板上的刷新按钮,也能够触发应用更新
  • 执行的动作包括:

Update resources表示仅更新静态资源。

Update classes and resources表示既更新静态资源又更新字节码。

Redeploy表示整个 web 项目重新部署。

Restart server表示重启 web 服务器。

**上图当中的 ****On frame deactivation**是指定什么的?

  • 当你把 IDEA 窗口切换到其他应用程序(即 IDEA 失去焦点)时,IDEA 自动执行什么操作。
  • 一般建议设置为 <font style="color:rgb(15, 17, 21);">Do nothing</font>,除非你电脑的配置很好。

9.10 启动 Tomcat 测试

启动成功,但控制台有中文乱码,这是因为当前版本的 IDEA 控制台的默认字符编码方式为 UTF-8(看下图可以查看控制台的字符编码方式) ,需要将 CATALINA_HOME/conf/logging.properties文件中之前的修改的 GBK,再次改回 UTF-8即可:

打开浏览器访问:http://localhost:8080/web01/list

10. HTTP协议

10.1 什么是HTTP协议

HTTP(HyperText Transfer Protocol,超文本传输协议) 是一种用于分布式、协作式超媒体信息系统的应用层协议。它是万维网(WWW)数据通信的基础,基于客户端-服务器模型,通过请求-响应模式工作。

核心特点:

  • 无状态:默认不保留之前的请求/响应信息(可通过Cookie/Session实现状态管理)。
  • 基于TCP/IP:默认端口80(HTTPS为443)。
  • 灵活可扩展:支持自定义头部、多种数据格式(JSON、XML等)。

HTTP 协议版本:

  • HTTP/1.0:短连接。每次浏览器向服务器发起一个请求,都会建立一个全新的 TCP 连接。
  • HTTP/1.1:持久连接。浏览器和服务器建立一次 TCP 连接后,可以在这个连接上连续进行多次请求和响应。

HTTP1.1 连接是可复用的:

  • 对同一域名的请求,可以复用同一个连接
  • 例如有这样一个网页:在 HTTP/1.1 时代,浏览器通常为每个域名开启 6 个左右的并行连接,以下页面在加载的时候就会有连接复用的情况。(底层弄了个 TCP 连接池,连接池最高支持 6 个 TCP 连接并发,下面这个 HTML 页面需要 9 个 TCP 连接,1 个加载 HTML,8 个加载图片。因此有连接复用的情况)
html 复制代码
<body>
  <img src="http://localhost:8080/app/1.jpg">
  <img src="http://localhost:8080/app/2.jpg">
  <img src="http://localhost:8080/app/3.jpg">
  <img src="http://localhost:8080/app/4.jpg">
  <img src="http://localhost:8080/app/5.jpg">
  <img src="http://localhost:8080/app/6.jpg">
  <img src="http://localhost:8080/app/7.jpg">
  <img src="http://localhost:8080/app/8.jpg">
</body>

HTTP/1.1 是有状态的吗?

  • 无状态。尽管从 1.0 的短连接升级成了 1.1 的持久连接,但 HTTP 协议仍然是无状态的。无状态主要体现在:默认不保留之前的请求/响应信息。

10.2 HTTP请求报文详解

HTTP请求报文由以下部分组成:

http 复制代码
GET /index.html?name=value&name=value HTTP/1.1          # 请求行(方法 + URI + 协议版本)
Host: www.example.com             # 请求头部(键值对)
User-Agent: Mozilla/5.0          
Accept: text/html,application/xhtml+xml
Accept-Language: en-US           
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded
Cookie: sessionId=abc123; userId=admin
                                  # 空行(分隔头部和体)
name=John&age=30                  # 请求体(GET通常无体,POST/PUT等有)

关键字段说明:

  • 请求行 :
    • 方法:GET(获取资源)、POST(提交数据)、PUT(更新)、DELETE(删除)等。
    • URI :请求的资源路径(如/index.html)。
    • 协议版本:HTTP/1.1 或 HTTP/2。
  • 请求头部 :
    • Host:目标服务器域名(必填)。
    • User-Agent:客户端标识(如浏览器类型)。
    • Content-Type:请求体的数据类型(application/x-www-form-urlencoded表示普通表单提交,application/json表示以 JSON 格式提交数据)。
    • Cookie:客户端携带的会话信息。
  • 请求体:仅POST/PUT等方法携带数据(如表单、JSON)。

10.3 HTTP响应报文详解

HTTP响应报文结构:

http 复制代码
HTTP/1.1 200 OK                  # 状态行(协议版本 + 状态码 + 描述)
Server: nginx/1.18.0             # 响应头部
Date: Mon, 01 Jun 2025 12:00:00 GMT
Content-Type: text/html; charset=UTF-8          
Content-Length: 1234             
Connection: keep-alive          
Set-Cookie: session_id=abc123; HttpOnly; SameSite=Strict
                                 # 空行
<!DOCTYPE html>                  # 响应体(实际数据)
<html>...</html>

关键字段说明:

  • 状态行 :
    • 状态码 :
      • **<font style="color:#DF2A3F;">200 OK</font>**:成功。
      • **<font style="color:#DF2A3F;">404 Not Found</font>**:资源不存在。
      • **<font style="color:#DF2A3F;">405</font>**:请求方式和服务器端的处理方式不一致。(例如:前端请求方式为 POST,服务器端处理方式是 GET,则发生 405 错误。)
      • **<font style="color:#DF2A3F;">500 Internal Server Error</font>**:服务器错误。
  • 响应头部 :
    • Content-Type:响应体类型(如text/html、application/json)。
    • Content-Length:响应体大小(字节)。
    • Set-Cookie:服务器设置的会话标识。【HttpOnly设置在浏览器不能使用 document.cookie 读取,防止 XSS 攻击。 SameSite=Lax允许部分安全的跨站请求(如导航链接),SameSite=Strict最严格,完全禁止在跨站请求中发送Cookie】
  • 响应体:返回的实际数据(HTML、JSON等)。

10.4 GET与POST的区别及选择

10.4.1 区别

特性 GET请求 POST请求
数据位置 URL查询参数(如?name=John) 请求体中(不可见)
数据长度限制 受URL长度限制(约2048字符) 无限制(服务器可配置)
安全性 参数暴露在URL,不适合敏感数据 相对更安全(HTTPS下加密)
幂等性 幂等(多次请求结果相同) 非幂等(可能修改数据)
缓存 可被缓存 默认不缓存
浏览器历史记录 保留参数 不保留

**幂等性 **就是:同一个操作,你执行1次和执行N次,结果都一样。

**幂等 **操作:你按电梯的"关门"按钮,按1次和疯狂按10次,效果都一样------门只会关一次。

非幂等操作:你喝奶茶,每点一次"加珍珠"按钮,杯子里就多一份珍珠(点10次就爆炸了)。

提示:GET 和 POST 请求提交数据时的格式都是 **<font style="color:#DF2A3F;">name=value&name=value&name=value...</font>**。只是提交数据的位置不同,GET 在请求行上提交数据。POST 在请求体中提交数据。

10.4.2 如何选择

  • 用GET :
    • 获取数据(如搜索、页面加载)。
    • 参数简单且非敏感(如分页?page=2)。
  • 用POST :
    • 提交敏感数据(如登录表单、支付信息)。
    • 上传文件或大量数据(如JSON body)。
    • 修改服务器状态(如创建/更新资源)。

10.4.3 怎么发送 POST 请求

到目前为止,浏览器向服务器发送请求时,我们所掌握的所有的方式包括:

  1. 用户在浏览器地址栏上直接输入 URL
  2. 用户点击超链接
  3. 使用 window.location.href 或 document.location.href
  4. 使用 window.open
  5. 用户提交 form 表单
  6. 使用 img的 src属性也可以发送请求:GET 请求

以上所有的方式中,只有当使用 form表单提交数据,并且 form标签的 method属性设置为 post时,才是 POST请求,其它都是 GET 请求。

10.5 URL编码

URL编码(也称为百分号编码)是HTTP协议和Web开发中一个非常重要的概念。

B/S 系统通信标准中规定 :URL 字符串中只允许出现 ASCII 字符集之内的字符。非 ASCII 字符(如:中文)在传输中都可能被错误的解析。

不过大家不需要担心,大部分的请求发送都已经自动对 URL 进行了编码,只有少数情况需要手动编码。

只要有 URL,就一定涉及到 URL 的编码和解码,前端系统需要,后端系统也需要。

10.5.1 URL编码的作用

URL编码主要用于:

  1. 解决特殊字符问题:URL中某些字符有特殊含义(如?、&、/等),当这些字符需要作为普通字符使用时必须编码
  2. 支持非ASCII字符:URL只能使用ASCII字符集,非ASCII字符(如中文)必须编码,防止数据在传输过程中被错误解析

10.5.2 前端系统中什么情况下需要手动编码

浏览器只在"用户交互触发的导航"(如地址栏输入、点击链接、表单提交)时自动编码;

在"JavaScript 程序化地拼接和操作 URL"时,不会自动编码,需要开发者手动 encodeURIComponent。

以下情况都会自动编码:

以下情况需要手动编码:

  • AJAX 请求中,手动拼接 URL 参数时
  • 使用 window.location.href 进行页面跳转时
  • history.pushState 或 replaceState 改变 URL 时

前端系统对 URL 进行编码解码的 API 是: **encodeURIComponent() / decodeURIComponent()**

10.5.3 后端系统中什么情况下需要手动编码

后端系统中,以下三种情况都需要手动编码 ,其他情况都不需要。

第一种情况:重定向时的 URL 参数需要手动编码。

java 复制代码
String redirectUrl = "/search?q=" + URLEncoder.encode(userInput, "UTF-8");
response.sendRedirect(redirectUrl);

第二种情况:Cookie 的值需要手动编码。【其实这个和 URL 就没什么关系了,属于 HTTP 协议的一部分】

第三种情况:自定义响应头的值需要手动编码。【其实这个和 URL 也没什么关系了,属于 HTTP 协议的一部分】

后端系统手动编码/解码的 API 如下:

java 复制代码
String original = "搜索 关键词&特殊字符";
String encoded = URLEncoder.encode(original, "UTF-8");
// 手动编码
// %E6%90%9C%E7%B4%A2+%E5%85%B3%E9%94%AE%E8%AF%8D%26%E7%89%B9%E6%AE%8A%E5%AD%97%E7%AC%A6
System.out.println(encoded);

// 手动解码
// 搜索 关键词&特殊字符
String decoded = URLDecoder.decode(encoded, "UTF-8");
System.out.println(decoded);
相关推荐
蜗牛互联网3 小时前
GPT-6 与 Intelligent UI:从回答到可审计操作的产品迁移
java·人工智能·后端
SL_staff3 小时前
运维救火实录:钉钉考勤API变更引发工资计算异常,我们用JVS-Logic可视化逻辑引擎实现分钟级热修复
java·mysql·全栈
SunnyDays10113 小时前
Java 查找并高亮 Word 文字:精确查找及正则表达式模糊查找
java·查找文字·word 文档·高亮文字·正则匹配查找·模糊查找
geats人山人海4 小时前
java 4继承
java·开发语言
众链网络4 小时前
Agent 的成本大头不在“写“,在“判断“:拆解专用决策模型的三层架构
java·开发语言·人工智能·微服务
周小董4 小时前
[1371]jdk管理工具
java·开发语言
青春逝如流水4 小时前
Java 中线程的创建方式:从基础到现代
java·开发语言·多线程·ai文章
Peregrine95 小时前
C++ - > 类和对象
java·c++·算法
2501_933923255 小时前
SpringCloud组件:Eureka服务注册与发现
java·开发语言·后端·spring cloud·eureka