Servlet基础

文章目录

  • 官方文档
  • 一、Servlet 基础认知
    • 1.1 为什么需要 Servlet
      • ★☆1.1.1 对Java Web 技术体系的流程图细化
    • 1.2 什么是 Servlet——java 服务器小程序
  • 二、Servlet 开发准备
    • 2.1 Servlet 版本与规范
    • 2.2 开发环境依赖
  • 三、Servlet 开发方式
    • 3.1 方式 1:实现 Servlet 接口(手动开发,理解原理,很少使用)
      • 3.1.1 开发步骤
      • 3.1.2 代码实现(HelloServlet)
      • 3.1.3 web.xml 配置
    • 3.2 方式 2:继承 HttpServlet(实际开发主流)
      • 3.2.1 优势
      • 3.2.2 代码实现(HiServlet)
      • 3.2.3 配置方式(二选一)
        • 3.2.3.1 web.xml 配置
        • ☆★3.2.3.2 注解配置(Servlet 3.0+)
  • 四、Servlet 核心机制
    • ★☆★4.1 浏览器访问 Servlet 流程
    • ★☆★4.2 Servlet 生命周期
      • 4.2.1 1. 初始化阶段(init 方法)
      • 4.2.2 2. 处理请求阶段(service/doGet/doPost 方法)
      • 4.2.3 3. 销毁阶段(destroy 方法)
  • 五、Servlet 配置细节
    • 5.1 URL Pattern 配置规则
      • 5.1.1 优先级
      • 5.1.2 注意事项
  • 六、Servlet 核心对象
    • 6.1 ServletConfig 对象
      • 6.1.1 ServletConfig基本介绍
      • 6.1.2 作用
      • 6.1.3 代码示例
    • 6.2 ServletContext 对象
      • 6.2.1 需求引出
      • 6.2.3 ServletContext基本介绍
      • 6.2.4 ServletContext作用
      • 6.2.5 代码示例1
      • 6.2.6 示例代码2——共享数据
    • 6.3 ☆★☆HttpServletRequest 对象
      • 6.3.1 基本介绍
      • 6.3.2 常用方法
      • 6.3.3 代码示例(获取表单参数)
      • 6.3.4 注意事项
    • 6.4 请求转发
      • 6.4.1 为什么需要请求转发
      • 6.4.2 请求转发说明
        • 6.4.2.1 请求转发(Forward)代码示例
        • 6.4.2.2 请求转发注意事项和细节
      • 6.4.3 代码-获取操作系统信息
    • 6.5 HttpServletResponse 对象
      • 6.5.1 基本介绍
      • 6.5.2 常用方法
        • 6.5.2.1 中文乱码设置-两种方法
    • 6.6 请求重定向(Redirect)
      • 6.6.1 重定向代码示例——两种方式
      • 6.6.2 注意事项
      • 6.6.3 动态获取工程名
      • 6.6.4 案例 :用户登录验证
    • 6.7 转发与重定向对比
    • 九、Servlet 注意事项
  • 十、http
    • 10.1 简述
    • 10.2 响应头与请求头
    • 10.3 HTTP状态码
      • 10.3.1 常见的HTTP状态码
      • 10.3.2 HTTP状态码分类
      • 10.3.3 HTTP状态码列表:
    • 10.4 页面请求次数
      • 10.4.1 UML时序图
    • 10.5 HTTP 请求包分析
      • 10.5.1 GET请求包
      • 10.5.2 POST请求包
      • 10.5.3 GET 请求 POST 请求分别有哪些
      • 10.5.4 HTTP 请求中怎样选择 Get 和 Post 方式
        • 10.5.4.1 传输的数据大小区别
        • 10.5.4.2 什么情况下使用 post 请求
        • 10.5.4.3 什么情况下使用 get 方式呢
    • 10.6 HTTP 响应包分析
    • 10.7 MIME 类型
      • 10.7.1 常见的MIME类型
    • 10.8 常见请求方法对比

官方文档

  • 地址: https://tomcat.apache.org/tomcat-8.0-doc/servletapi/index.html

一、Servlet 基础认知

1.1 为什么需要 Servlet

  • 静态网页局限:HTML、CSS、JavaScript 只能提供固定内容,无法实现用户交互(如登录验证、数据提交存储)、动态数据展示(如购物车、用户信息展示)等功能。
  • 动态网页需求:需要一种技术能接收浏览器请求、处理业务逻辑(如与数据库交互)、动态生成响应内容,Servlet 应运而生。
  • 技术定位:Servlet 是 Java Web 开发的基石,是 SpringMVC 等框架的底层基础,可完成几乎所有网站核心功能(用户登录、数据增删改查、文件上传等)。

★☆1.1.1 对Java Web 技术体系的流程图细化

两条路
上面一条是动态网页,tomcat需要通过servlet解析,调用我们的java程序、数据库
下面一条的静态网页,静态资源直接返回(default注解,返回url匹配不到的静态资源,在tomcat/conf/web.html中)

![[sub/JAVA Web/picture/Pasted image 20251003182237.png]]

(选哪个看需要)
所以也有的结构是 B->apache(一个服务器),然后直接返回;B->nginx(充当服务器)也是直接返回去。
![[sub/JAVA Web/picture/Pasted image 20251002233501.png]]

1.2 什么是 Servlet——java 服务器小程序

  1. 本质:Servlet 是运行在==服务器端的 Java 类==,是用java语言编写的
  2. 他是由服务器端(如 Tomcat)管理生命周期(创建、初始化、处理请求、销毁)的(一句话:是==Tomcat解析和执行==)
  3. 他是按照Servlet规范开发的(只有遵循这个规范,除了tomcat,像Servlet weblogic也可以执行)(像jdbc一样,本质是一套规范一个接口,只要你遵循它的规范就可以跟它对接
  4. 功能强大,可以完成几乎所有的网站功能(在以前老程员,使用Servlet开发网站) 技术栈要求高
  5. 与 Tomcat 关系Tomcat 是 Servlet 容器,负责加载、初始化 Servlet,并将 HTTP 请求转发给 Servlet 处理。

二、Servlet 开发准备

2.1 Servlet 版本与规范

  • 版本对应:Servlet 3.0 及以上支持注解配置,3.0 之前需通过 web.xml 配置
  • 查看版本:通过 javax.servlet.Servlet 接口的源码或依赖包(如 javax.servlet-api.jar)查看版本信息。

2.2 开发环境依赖

  • 核心依赖:Servlet -api.jar(Tomcat 安装目录下的 lib 文件夹中提供),需导入项目依赖。
    • Maven 项目依赖配置:
<dependency>
	<groupId>javax.servlet</groupId>
	<artifactId>javax.servlet-api</artifactId>
	<version>3.1.0</version>
	<scope>provided</scope> <!-- 服务器已提供,打包时不包含 -->
</dependency>

三、Servlet 开发方式

3.1 方式 1:实现 Servlet 接口(手动开发,理解原理,很少使用)

3.1.1 开发步骤

  1. 创建项目;添加对web框架的支持(看tomcat);添加tomcat
  2. 添加servlet-api到工程里——添加==servlet-api.jar==(在tomcat/lib下)

![[sub/JAVA Web/picture/Pasted image 在这里插入图片描述
.png]]

  1. 编写 Servlet 类:实现 javax.servlet.Servlet 接口,重写核心方法(重点是 service 方法)。
  2. 配置访问路径:通过 web.xml 配置 Servlet 的访问 URL。(要==让tomcat能找到==),记住配完重启tomcat,重新发布(redeploy(快))一下
  3. 部署测试:将项目部署到 Tomcat,通过浏览器访问。
  4. 注意出错看是不是端口被占用!!!

3.1.2 代码实现(HelloServlet)

  • 五个方法init()service()getServletConfig()getServletInfo()destroy()
package com.hspedu.servlet;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;

/**
 * 实现 Servlet 接口的 Servlet 示例
 * 功能:处理 GET/POST 请求,输出访问日志
 */
public class HelloServlet implements Servlet {

    // 初始化方法:Servlet 实例创建后调用
    //只会被调用一次
    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
        System.out.println("HelloServlet 初始化完成(init 方法调用)");
    }

    // 返回Servlet 配置信息(如初始化参数)
    @Override
    public ServletConfig getServletConfig() {
        return null; // 简化示例,实际项目可返回真实配置
    }

    /**
     * 核心方法:处理 HTTP 请求(GET/POST 等)
     * 当浏览器每次请求Servlet时,就会调用一次service
     * 当tomcat调用方法时,会把http请求的数据封装成实现 ServletRequest 接口的request对象
     * 通过 ServletRequest 对象,可以得到用户提交的数据
     * ServletResponse 对象可以用于返回数据给tomcat——>浏览器
     *
     * @param servletRequest 封装请求信息的对象
     * @param servletResponse 封装响应信息的对象
     */
    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse)
            throws ServletException, IOException {
            
        // 1. 将 ServletRequest 转为 HttpServletRequest(获取请求方法等 HTTP 特有信息)
        //HttpServletRequest为ServletRequest的子接口
        HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
        String method = httpServletRequest.getMethod(); // 获取请求方式(GET/POST)

        // 2. 根据请求方式分发处理
        if ("GET".equals(method)) {
            doGet();
        } else if ("POST".equals(method)) {
            doPost();
        }
    }
    // 处理 GET 请求
    private void doGet() {
        System.out.println("HelloServlet 处理 GET 请求");
    }
    // 处理 POST 请求
    private void doPost() {
        System.out.println("HelloServlet 处理 POST 请求");
    }

    // 获取 Servlet 信息(如作者、版本),使用少
    @Override
    public String getServletInfo() {
        return "HelloServlet v1.0";
    }

    // 销毁方法:Servlet 实例销毁前调用(如 Tomcat 关闭、项目重新部署)
    //只会调用一次
    @Override
    public void destroy() {
        System.out.println("HelloServlet 销毁(destroy 方法调用)");
    }
}

3.1.3 web.xml 配置

  • url-pattern 的作用是 “匹配请求”,而非 “自动跳转”
  • ==当浏览器明确(http)请求 /hiServlet 路径时,才会触发对应的 HiServlet。==它仅定义了 “哪些请求会被该 Servlet 处理”,但不会让 Tomcat 在访问根路径时 “自动跳转” 到这个路径
  • 没有配置 <welcome-file-list> 时,Tomcat 会默认寻找 web 目录下的默认欢迎页文件(如服务器会按默认顺序查找:index.html → index.htm → index.jsp)。如果这些文件不存在,且没有其他 Servlet 匹配根路径(url-pattern: /),则会返回 404 错误。
  • 此时,HiServleturl-pattern/hiServlet,与根路径 / 不匹配,因此不会被触发。
<?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">  
        
        <!--  
        servlet-name :自己取,唯一  
        servlet-class:servlet类的全路径,tomcat反射生成Servlet需要使用  
        servlet-mapping的servlet-name与上面保持一致  
        url-pattern:该Servlet访问的url的配置(路径);
        即http://localhost:8080/servlet(项目名)/helloServlet  
        -->    
        <servlet>  
	        <servlet-name>HelloServlet</servlet-name>  
	        <servlet-class>tt.HelloServlet</servlet-class> 
	         
	        <!-- 可选:设置 Servlet 启动时机(Tomcat 启动时加载,值越小优先级越高) -->  
			<load-on-startup>1</load-on-startup>->    
		</servlet>  
		
	    <servlet-mapping>        
		    <servlet-name>HelloServlet</servlet-name>  
	        <url-pattern>/HelloServlet</url-pattern>  
	    </servlet-mapping>    
    
	    <!--服务器不显示service方法的信息,加上这个就可以;或者将url改成“/”-->  
	    <welcome-file-list>  
	        <welcome-file>HelloServlet</welcome-file>  
	    </welcome-file-list>  
</web-app>

3.2 方式 2:继承 HttpServlet(实际开发主流)

![[sub/JAVA Web/picture/Pasted image 20251003133624.png]]
![[sub/JAVA Web/picture/Pasted image 20251003134223.png]]
![[sub/JAVA Web/picture/Pasted image 20251003153746.png]]

3.2.1 优势

  • HttpServlet 是 Servlet 接口的实现类,已封装 HTTP 请求处理逻辑(如 doGetdoPost 方法),无需重写所有接口方法,开发更==简洁==。

3.2.2 代码实现(HiServlet)

package com.hspedu.servlet;  
  
import javax.servlet.ServletException;  
import javax.servlet.annotation.WebInitParam;  
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.io.PrintWriter;  
  
/**  
 * 继承 HttpServlet 的 Servlet 示例  
 * 功能:处理 GET/POST 请求,输出对应日志  
 */  
@WebServlet(urlPatterns = "/hiServlet")  
public class HiServlet extends HttpServlet {  
  
//重写HttpServlet的doGet和doPost方法  
    /**  
     * 处理 GET 请求(如浏览器地址栏访问、表单 method="get")  
     */  
    @Override  
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)  
            throws ServletException, IOException {  
        System.out.println("HiServlet 处理 GET 请求");  
  
        // 响应浏览器:返回简单文本  
        //设置响应类型和编码  
        //text/html:基于文本的html数据(MIME类型);编码是utf-8  
        //细节:设置编码格式要在获取 流 之前!!!!!!!!!!!!!!!!!!!!  
        resp.setContentType("text/html;charset=utf-8");  
        PrintWriter writer = resp.getWriter();  
  
        //resp.setContentType("text/html;charset=utf-8");  
        writer.println("<h1>Hi Servlet!(GET 请求响应)</h1>");  
  
        //确保一下数据返回,没有也行  
        writer.flush();  
        writer.close();  //close里有flush  
    }  
  
    /**  
     * 处理 POST 请求(如表单 method="post")  
     */  
    @Override  
    protected void doPost(HttpServletRequest req, HttpServletResponse resp)  
            throws ServletException, IOException {  
        System.out.println("HiServlet 处理 POST 请求");  
        // 处理 POST 请求中文乱码  
        req.setCharacterEncoding("utf-8");  
        // 响应浏览器  
        resp.setContentType("text/html;charset=utf-8");  
        resp.getWriter().write("<h1>Hi Servlet!(POST 请求响应)</h1>");  
    }  
}
  • web下的re.html文件
<!DOCTYPE html>  
<html lang="en">  
<head>  
    <meta charset="UTF-8">  
    <title>tt</title>  
</head>  
<body>  
  
<form action="http://localhost:8080/servlet/hiServlet" method="get">  
    u : <input type="text" name = "username"/><br>  
    <input type="submit" value="注册"/>  
</form>  
</body>  
</html>

3.2.3 配置方式(二选一)

3.2.3.1 web.xml 配置

[[#★☆★4.1 浏览器访问 Servlet 流程]]

<servlet>
    <servlet-name>HiServlet</servlet-name>
    <servlet-class>tt.HiServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>HiServlet</servlet-name>
    <url-pattern>/hiServlet</url-pattern> <!-- 访问路径:/hiServlet -->
</servlet-mapping>
<welcome-file-list>  
    <welcome-file>re.html</welcome-file>  
</welcome-file-list>
☆★3.2.3.2 注解配置(Servlet 3.0+)

[[#★☆★4.1 浏览器访问 Servlet 流程]]
直接在类上添加 @WebServlet 注解,无需 web.xml
一个Servlet支持配置多个urlPattern
![[sub/JAVA Web/picture/Pasted image 在这里插入图片描述
.png]]
![[sub/JAVA Web/picture/Pasted image 在这里插入图片描述
.png]]

package com.hspedu.servlet;

import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

// 注解配置:urlPatterns 指定访问路径(支持多个路径)
@WebServlet(urlPatterns = {"/hiServlet", "/hi"},   
        initParams = {@WebInitParam(name = "tt", value = "18"), @WebInitParam(name = "dd", value = "20")})
        
public class HiServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        resp.setContentType("text/html;charset=utf-8");
        resp.getWriter().write("<h1>通过注解配置访问 HiServlet</h1>");
    }
}

四、Servlet 核心机制

★☆★4.1 浏览器访问 Servlet 流程

  1. 浏览器输入 URL(如 http://localhost:8080/MyWeb/helloServlet),发送 HTTP 请求。
  2. Tomcat 解析 URL:
    • localhost:8080:定位服务器和端口。
    • MyWeb:找到部署的 Web 项目。
    • helloServlet:通过 web.xml 或注解找到对应的 Servlet 类(如 HelloServlet)。
  3. 注解方式:通过扫描整个包,找到某个类是被@WebServlet修饰(得到类的全路径),就说明是Servlet类,读取该urlPatterns;跟.xml流程一样;如果没有在map中找到这个实例,可以用获得的全类名使用反射实例化,然后初始化,实例放到hashMap中
  4. Tomcat 创建 HttpServletRequest(封装请求信息)和 HttpServletResponse(封装响应信息)对象。
  5. Tomcat 调用 Servlet 的 service 方法(或 doGet/doPost),传入上述两个对象。
  6. Servlet 处理业务逻辑,通过 HttpServletResponse 生成响应内容。
  7. Tomcat 将响应内容转为 HTTP 响应,返回给浏览器。
    ![[sub/JAVA Web/picture/Pasted image 20251003112029.png]]

★☆★4.2 Servlet 生命周期

Servlet 生命周期由 Tomcat 管理,分为 3 个核心阶段:
![[sub/JAVA Web/picture/Pasted image 在这里插入图片描述
.png]]

4.2.1 1. 初始化阶段(init 方法)

Servlet 容器(比如: Tomcat)加载 Servlet,加载完成后,Servlet 容器会创建一个 Servlet 实例调用 init()方法init()方法只会调用一次,Servlet 容器在下面的情况==装载 Servlet(不等于实例化)==

  1. 情况1:Servlet 容器(比如Tomcat)启动时自动装载不等于实例化)某些 servlet对象。实现这个需要web.xml 文件中添加==<load-on-startup>1</load-on-startup>== 1 表示装载的顺序
  2. 情况2:在 Servlet 容器启动后,浏览器首次向 Servlet 发送请求
  3. 情况3:Servlet 重新装载时浏览器再向 Servlet 发送请求的第 1 次(比如 tomcat 进行 redeployredeploy 会销毁所有的 Servlet 实例】),

4.2.2 2. 处理请求阶段(service/doGet/doPost 方法)

  1. 收到一个 http 请求,服务器(tomcat)就会==产生一个新的线程==去处理(线程)
  2. 创建一个用于封装 HTTP 请求消息的 ServletRequest 对象和一个代表 HTTP 响应消息的ServletResponse 对象
  1. ServletRequest只是接口而已,真正的运行类型有服务器(tomcat)规定
  2. 通过ServletRequest形参里的方法,反过来得到(tomcat封装的)浏览器的信息
  3. 为什么需要tomcat中间过渡一下:http的数据封装好作为对象给你还不好,get,set一下。浏览器与servlet直接传输的信息很大
  1. 调用 Servlet 的 service()方法并将请求和响应对象作为参数传递进去

service 方法会根据请求方式(GET/POST)自动调用 doGetdoPost

  1. 线程安全Servlet 是单例(一个类只有一个实例),共享属性需注意线程安全(如避免使用成员变量存储请求相关数据)。

4.2.3 3. 销毁阶段(destroy 方法)

  • web 应用被终止,或者Servlet 容器终止运行,或者Servlet 类重新装载时,(tomcat)会调用 destroy()方法

比如重启 tomcat ,或者 redeploy web 应用

  • 特点:只调用一次,用于释放资源(如关闭数据库连接、销毁线程池)。

五、Servlet 配置细节

5.1 URL Pattern 配置规则

urlPattern 用于指定 Servlet 的访问路径,支持以下 4 种匹配规则:

规则类型配置示例说明
精确匹配/helloServlet只能匹配 http://localhost:8080/项目名/helloServlet
目录匹配/user/*匹配 /user 下的所有路径(如 /user/login/user/info/11
扩展名匹配*.action匹配所有以 .action 结尾的路径(如 /login.action/user.action
任意匹配//*/ 覆盖 Tomcat 默认 Servlet(处理静态资源);
/* 匹配所有路径
(避免,会匹配所有请求)

5.1.1 优先级

精确匹配 > 目录匹配 > 扩展名匹配 > 任意匹配

5.1.2 注意事项

  • 扩展名匹配不能带 /(如 /*.action 错误,应为 *.action)。
  • / 会拦截静态资源(如 HTML、CSS、图片),需避免(可通过配置 Tomcat 默认 Servlet 解决)。

当 Servelt 配置了 /*·会覆盖tomcat的DefaultServlet注解,这个注解会将.xml文件里url匹配不到的静态文件返回;被拦截了很可怕,无法正常返回
![[sub/JAVA Web/picture/Pasted image 在这里插入图片描述
.png]]

六、Servlet 核心对象

6.1 ServletConfig 对象

6.1.1 ServletConfig基本介绍

  1. ServletConfig 类是为 Servlet 程序的配置信息 的类
  2. Servlet 程序和 ServletConfig 对象都是由 Tomcat 负责创建
  3. Servlet 程序==默认是第 1 次访问的时候创建==,ServletConfig 在 Servlet 程序创建时就创建一个对应的 ServletConfig 对象

6.1.2 作用

  • 获取 Servlet 的初始化参数init-param(如 db.username)。
  • 获取 Servlet 名称(getServletName())。
  • 获取 ServletContext 对象(全局上下文,比较大的容器),可以跟其他servlet共享数据。

6.1.3 代码示例

需求:
![[sub/JAVA Web/picture/Pasted image 在这里插入图片描述
.png]]
有一个小坑

  • GenericServlet 为我们DBServlet的父类
  • DBServlet对象初始化时, tomcat会同时创建一个 ServletConfig对象——init()方法
  • 如果DBServlet重写方法init(),没有调用 super.init(config),即就是调用父类 GenericServletinit()方法,那定义的private transient ServletConfig config就没有赋值(为null),getServletConfig()就会报错
  • 因此如果你重写init()方法,记住如果你想在其它方法通过 getServletConfig() 方法获取ServletConfig 则一定要记住 调用 super.init(config);
    ![[sub/JAVA Web/picture/Pasted image 在这里插入图片描述
    .png]]
    ![[sub/JAVA Web/picture/Pasted image 在这里插入图片描述
    .png]]
package com.hspedu.servlet;

import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
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.Serializable;
import java.util.concurrent.ConcurrentHashMap;

public class DBServlet extends HttpServlet {
    /**
     * @param config
     * @throws ServletException
     */
    @Override
    public void init(ServletConfig config) throws ServletException {
        //ConcurrentHashMap, 是一个线程安全的容器.
        System.out.println("init" + config);
        super.init(config);
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        //在DBServlet 执行 doGet()/doPost() 时,可以获取到web.xml配置的用户名和密码
        //DBServlet的父类GenericServlet有getServletConfig()
        /**
         * 1. getServletConfig() 方法是 GenericServlet的
         * 2. 返回的 servletConfig对象是 GenericServlet的private transient ServletConfig config;
         * 3. 当一个属性被 transient 修饰,表示该属性不会被串行化(有些重要信息,不希望保存到文件)
         */
        ServletConfig servletConfig = getServletConfig();
        System.out.println("doPost=" + servletConfig);
        String username = servletConfig.getInitParameter("username");
        String pwd = servletConfig.getInitParameter("pwd");
        System.out.println("初始化参数username= " + username);
        System.out.println("初始化参数pwd= " + pwd);

    }

	//等于post请求和get公用方法
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }
}

.xml
![[sub/JAVA Web/picture/Pasted image 在这里插入图片描述
.png]]

6.2 ServletContext 对象

6.2.1 需求引出

问题:

  • 如果我们希望统计某个 web 应用的所有 Servlet 被访问的次数,怎么办?
    方案:
  • ![[sub/JAVA Web/picture/Pasted image 20251003234555.png]]
  • ![[sub/JAVA Web/picture/Pasted image 20251003234604.png]]

6.2.3 ServletContext基本介绍

  1. ServletContext 是一个接口,它表示 Servlet 上下文对象
  2. 一个 web 工程,==只有一个 ServletContext 对象实例==
  3. ServletContext 对象 是在 web 工程启动的时候创建(tomcat创建),在 web 工程停止的时销毁
  4. ServletContext 对象可以通过 ServletConfig.getServletContext() 方法获得对 ServletContext对象的引用,也可以通过this.getServletContext()来获得其对象的引用。

![[sub/JAVA Web/picture/Pasted image 在这里插入图片描述
.png]]

  1. 由于一个 WEB 应用中的所有 Servlet 共享同一个 ServletContext 对象,因此 Servlet 对象之间可以通过 ServletContext 对象来实现多个 Servlet 间通讯ServletContext 对象通常也被称之为==域对象==。【示意图】
  2. 线程安全问题,会有一个[[sub/JAVA Web/后续引用|ConcurrentMap]]

6.2.4 ServletContext作用

  1. 获取 web.xml 中配置的上下文参数 context-param这个信息和整个 web 应用相关,而不是属于某个 Servlet)
  2. 获取当前的工程路径,格式:/工程路径 (比如 /servlet
  3. 获 取 工 程 部 署 后 在 服 务 器 硬 盘 上 的 绝 对 路 径( out目录下的,比 如:D:\servlet\out\artifacts\servlet_war_exploded)
  4. 像 Map 一样存取数据, 多个 Servlet 共享数据

6.2.5 代码示例1

  • 实现它的作用
package tt;  
  
import javax.servlet.ServletContext;  
import javax.servlet.ServletException;  
import javax.servlet.http.HttpServlet;  
import javax.servlet.http.HttpServletRequest;  
import javax.servlet.http.HttpServletResponse;  
import java.io.IOException;  
  
public class ServletContext_ extends HttpServlet {  
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {  
        //获取web.xml的context-parameter  
  
        //1.获取到ServletContext对象  
        ServletContext servletContext = getServletContext();  
        //2. 获取website  
        String website = servletContext.getInitParameter("website");  
        String company = servletContext.getInitParameter("company");  
        //3. 获取项目的工程路径  
        String contextPath = servletContext.getContextPath();  
        //4. 获取项目发布会,正真的的工作路径(out目录  
        // "/"表示我们的项目(发布后)的 根路径  
        String realPath = servletContext.getRealPath("/");  
        System.out.println("项目路径= " + contextPath);// /servlet  
        System.out.println("website= " + website);  //website= http://www.tt.net  
        System.out.println("company= " + company);  //tt�Ĺ�˾
          
        //D:\sofeware\IDEA\a_project\servlet\out\artifacts\servlet_Web_exploded\  
        System.out.println("项目发布后的绝对路径= " + realPath);  
  
    }  
  
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {  
        doPost(request, response);  
    }  
}

配置文件

  <servlet>  
        <servlet-name>ServletContext_</servlet-name>  
        <servlet-class>tt.HelloServlet</servlet-class>  
    </servlet>    
    <servlet-mapping>        
	    <servlet-name>ServletContext_</servlet-name>  
        <url-pattern>/ServletContext_</url-pattern>  
    </servlet-mapping>
    
    <!--    网站信息-->  
    <context-param>  
        <param-name>website</param-name>  
        <param-value>http://www.tt.net</param-value>  
    </context-param>    
    <context-param>        
	    <param-name>company</param-name>  
        <param-value>tt的公司</param-value>  
    </context-param>

6.2.6 示例代码2——共享数据

  • 建两个servlet
  • 封装信息
package tt;  
  
import javax.servlet.ServletContext;  
  
public class webUtils {  
    public static Integer visitweb_count(ServletContext servletContext){  
        //从servletContext获取 visit_count 属性 k-v        Object webCount = servletContext.getAttribute("web_count");  
  
        //判断visit_count是否为null  
        if(webCount == null){  
            servletContext.setAttribute("web_count",1);  
            webCount = 1;  
        }else {  
            //取出visit_count属性的值+1  
            webCount = Integer.parseInt(webCount + "") + 1;  
            //放回到servletContext  
            servletContext.setAttribute("web_count",webCount);  
        }  
        return Integer.parseInt(webCount + "");  
    }  
  
}

两个servlet调用,输出

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {  
    //下面两句可以合并  
    //Integer integer1 = webUtils.visitweb_count(getServletContext());    
ServletContext servletContext1 = getServletContext();  
    Integer integer = webUtils.visitweb_count(servletContext1);  
  
    System.out.println(servletContext1.getClass());  
    //class org.apache.catalina.core.ApplicationContextFacade//tomcat设定的运行对象  
  
    //输出    
	//注意编码  
    response.setContentType("text/html;charset = utf-8");  
    PrintWriter writer = response.getWriter();  
    writer.println("刷新次数:" + integer);  
    writer.flush();  
    writer.close();  
  
}

6.3 ☆★☆HttpServletRequest 对象

![[sub/JAVA Web/picture/Pasted image 20251004014025.png]]

6.3.1 基本介绍

  1. HttpServletRequest 对象代表==客户端的请求==
  2. 当客户端/浏览器通过 HTTP 协议访问服务器时,HTTP 请求头中的所有信息都封装在这个对象中
  3. 通过这个对象的方法,可以获得客户端这些信息。
  4. 作用:封装 HTTP 请求信息(如请求参数、请求头、请求方式),提供方法获取这些信息。

6.3.2 常用方法

方法说明
String getRequestURI()获取请求资源路径(如 /MyWeb/helloServlet
String getRequestURL()获取完整请求 URL(如 http://localhost:8080/MyWeb/helloServlet
getRemoteHost()获取客户端的 主机
getRemoteAddr()获取客户端的 ip地址(网关ip,不一定是真实的ip)
getHeader()
getHeader(字段)
获取请求头的信息
getHeader(host)->localhost:8080)
String getMethod()获取请求方式(GET/POST)
String getParameter(String name)获取单个请求参数(如表单输入框的值)
String[] getParameterValues(String name)获取多个请求参数(如复选框,多个值)
返回的时数组
Parameter:参数
setAttribute(key, value)设置域数据
attribute:属性
getAttribute(key)获取域数据
void setCharacterEncoding(String charset)设置 POST 请求中文编码(如 utf-8
RequestDispatcher getRequestDispatcher(String path)获取请求转发对象
String path:/xxx,要转发的一个servlet的url

6.3.3 代码示例(获取表单参数)

package tt;  
  
import javax.servlet.ServletContext;  
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;  
  
public class ServletContext_ extends HttpServlet {  
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {  
    
    //!!!!!!!!!先设定编码,再获取
        request.setCharacterEncoding("UTF-8");  
        //用户名
        String username = request.getParameter("username");  
        System.out.println(username); //tt  
        
        //没有设定的为null
        String username1 = request.getParameter("username1");  
        System.out.println(username1); //没有的为null  
  
        System.out.println(Arrays.toString(request.getParameterValues("sport"))); //[lq, sq]  
        System.out.println(Arrays.toString(request.getParameterValues("gender")));  //[female]  
  
    }  
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {  
        doPost(request, response);  
    }  
}
  • 表单
<!DOCTYPE html>  
<html lang="en">  
<head>  
    <meta charset="UTF-8">  
    <title>表单格式化</title>  
</head>  
<body>  
<form action="http://localhost:8080/servlet/ServletContext_" method="post">  
    <h1 align="center">用户注册信息</h1>  
    <table align="center">  
        <tr>            <td>用户名称:</td>  
            <td><input type="text" name="username"></td>  
        </tr>        <tr>            <td>用户密码:</td>  
            <td><input type="password" name="pwd1"></td>  
        </tr>        <tr>            <td>确认密码:</td>  
            <td><input type="password" name="pwd2"></td>  
        </tr>        <tr>            <td>选择你喜欢的运动项目:</td>  
            <td>                <input type="checkbox" name="sport" value="lq">篮球  
                <input type="checkbox" name="sport" value="zq" checked>足球  
                <input type="checkbox" name="sport" value="sq" checked>手球  
            </td>  
        </tr>        <tr>            <td>请选择性别:</td>  
            <td>                <input type="radio" name="gender" value="male"><input type="radio" name="gender" value="female"></td>  
        </tr>        <tr>            <td>请选择城市:</td>  
            <td>                <select name="city">  
                    <option>--选择--</option>  
                    <option value="cd">成都</option>  
                    <option value="bj">北京</option>  
                    <option value="sh">上海</option>  
                </select>            </td>        </tr>        <tr>            <td>自我介绍:</td>  
            <td><textarea rows="6" cols="20" name="intro"></textarea></td>  
        </tr>        <tr>            <td>选择你的头像:</td>  
            <td><input type="file" name="myfile"></td>  
        </tr>        <tr>            <td><input type="submit" value="提交"/></td>  
            <td><input type="reset" value="重置"/></td>  
        </tr>    </table></form>  
</body>  
</html>

6.3.4 注意事项

  1. . 获取doPost参数中文乱码方案 , 注意setCharacterEncoding("utf-8") 要 写 在request.getParameter()前。
request.setCharacterEncoding("utf-8")

可恶idea,中文乱码搞好久(看其他的解决办法会有JDK版本问题,以后注意!!!!)
[[sub/JAVA Web/web问题#2. 控制台中文输出乱码|控制台中文输出乱码]]

  1. 如果通过 PrintWriter writer, 有返回数据给浏览器,建议将获取参数代码写在writer.print() 之前,否则可能获取不到参数值(doPost)

,被我遇到了!!!!!!!!
代码逻辑顺序:处理请求(例如编码格式)-> 业务逻辑(获取数据)-> 响应输出
[[sub/JAVA Web/web问题#. 1请求体冲突问题|请求体冲突问题]]

  1. 处理 http 响应数据中文乱码问题

设置文件格式和编码

response.setContentType("text/html;charset = utf-8");
  1. 次理解 Http 协议响应 Content-Type

表示返回的资源类型,浏览器要安装指定格式解析
[[#10.7 MIME 类型]]

//之前
response.setContentType("text/html;charset = utf-8");

//改成
response.setContentType("application/x-tar;charset = utf-8");  //

结果:

![[sub/JAVA Web/picture/Pasted image 在这里插入图片描述
.png]]

6.4 请求转发

6.4.1 为什么需要请求转发

  • 一个大的业务分配给多个Servlet处理不同的业务
    ![[sub/JAVA Web/picture/Pasted image 20251004133824.png]]

6.4.2 请求转发说明

  1. 实现请求转发:请求转发指一个 web 资源收到客户端请求后,通知==服务器去调用另外一个 web 资源进行处理==
  2. HttpServletRequest 对象(也叫 Request 对象)提供了一个Request方法,该方法返回一个Request 对象,调用这个对象的 forward方法可以实现请求转发

Dispatcher 调度员

  1. HttpServletRequest 对象同时也是一个域对象,开发人员通过 Request 对象在实现转发时,把数据通过 Request 对象带给其它 web 资源处理

![[sub/JAVA Web/picture/Pasted image 20251004144743.png]]

6.4.2.1 请求转发(Forward)代码示例

要求:如果是 tom,提示为管理员,;其它是普通用户.

  • 步骤
  1. 确保环境,配置正确,打通线路
  2. 编写ServletA
  3. ServletB
  • 注意:
  1. 转发是不可能到外网上的
// ServletA:转发到 ServletB
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

	//获取用户名
	String username = request.getParameter("username");

	// 1. 判断是否是管理员tom,存储数据到 request 域(转发后可获取)
	if ("tom".equals(username)) {
		//分配
		request.setAttribute("role", "管理员");
	} 
	else {
		request.setAttribute("role", "普通用户");
	}

    // 2. 获取请求转发对象,指定目标路径
    // “/”:解析为 http//localhost:8080/项目名
    //所以它的转发是不可能到外网上的
    RequestDispatcher dispatcher = request.getRequestDispatcher("/servletB");

    // 3. 执行转发
    //表示把当前 servlet 的 request 对象和response 对象,传递给下一个 servlet 使用
    dispatcher.forward(request, response);
}

// ServletB:获取转发数据
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {

	String username = request.getParameter("username");
    // 获取 request 域中的数据
    String role = (String) request.getAttribute("role");

	//输出
    response.setContentType("text/html;charset=utf-8");
    response.getWriter().write("用户名是:" + username + "角色是:" + role);
    writer.flush();
    writer.close();
}
6.4.2.2 请求转发注意事项和细节
  1. 服务器内部跳转,浏览器地址栏不变(地址会保留在第 1 个 servlet 的 url)
  2. 在同一次 HTTP 请求中,进行多次转发,仍然是一次 HTTP 请求
  3. 在同一次 HTTP 请求中,进行多次转发,多个 Servlet 可以共享 request 域/对象的数据(因为始终是同一个 request 对象)
  4. 可以转发到 WEB-INF 目录下(后面做项目使用)
  5. 不能跳转到当前web项目外的资源(如 http://www.baidu.com)。
  6. 因为浏览器地址栏会停止在第一个 servlet ,如果你刷新页面,会再次发出请求(并且会带数据)

所以在支付页面情况下,不要使用请求转发,否则会造成重复支付——使用重定向/使用==数据库==验证

6.4.3 代码-获取操作系统信息

    request.setCharacterEncoding("utf-8");  
	String userAgent = request.getHeader("User-Agent");  
	System.out.println(userAgent);
	//Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0  

	//正则表达式,    .*:任意字符  
//  String Agent0 = "\\((.*)\\)";  //贪婪匹配 //从第一个左括号到最后一个右括号  
	String Agent = "\\((.*?)\\)"; //尽可能少的匹配  
	System.out.println(Agent);  
	Pattern compile = Pattern.compile(Agent);  
	Matcher matcher = compile.matcher(userAgent);  
	matcher.find();//只有一组就不用循环去查找  
	String group = matcher.group(0);   
	System.out.println(group);  [//完整括弧(Windows NT 10.0; Win64; x64)]
	String group1 = matcher.group(1);
	
	System.out.println(group1);  //括弧内容Windows NT 10.0; Win64; x64
	String[] s = group1.split(";"); 
	
	System.out.println(s[0]);  //Windows NT 10.0  
	System.out.println(s[1]);  // Win64  


	response.setContentType("text/html;Charset = utf-8");  
	PrintWriter writer = response.getWriter();  
	writer.println("操作系统版本为:" + s[0]);  
	writer.print("是:" + s[1] + "位");  
	writer.flush();  
	writer.close();

6.5 HttpServletResponse 对象

6.5.1 基本介绍

  1. 每次 HTTP 请求,Tomcat 会创建一个 HttpServletResponse 对象传递给 Servlet 程序去使用。
  2. HttpServletRequest 表示请求过来的信息,HttpServletResponse 表示所有响应的信息,如果需要设置返回给客户端的信息,通过 HttpServletResponse 对象来进行设置即可

6.5.2 常用方法

方法说明
void setContentType(String type)设置响应类型和编码(如 text/html;charset=utf-8
setHeader(String s)设置响应头的内容
PrintWriter getWriter()获取字符输出流(用于返回文本、HTML 内容)
ServletOutputStream getOutputStream()获取字节输出流(用于返回图片、文件下载)
void sendRedirect(String location)实现请求重定向(浏览器地址栏变化,两次请求)
void setStatus(int sc)设置响应状态码(如 302 重定向、404 未找到)

![[sub/JAVA Web/picture/Pasted image 20251004185309.png]]

6.5.2.1 中文乱码设置-两种方法
//只是设置 服务器字符集为utf-8
resp.setCharacterEncoding("UTF-8")

//第一:通过设置响应头
response.setHeader("Content-Type","text/html;charset = utf-8");

//第二:常用,其实跟第一效果一样
response.setContentType("text/html;charset = utf-8");

6.6 请求重定向(Redirect)

  • 请求重定向指:一个 web 资源收到客户端请求后,通知客户端去访问另外一个 web资源,这称之为请求重定向[[#10.3.1 常见的HTTP状态码|302状态码]]
    ![[sub/JAVA Web/picture/Pasted image 20251004190719.png]]

6.6.1 重定向代码示例——两种方式


@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
//业务完成,发给浏览器重定向

    // 方式 1:通过状态码和响应头实现
    resp.setStatus(302); // 重定向状态码
    resp.setHeader("Location", "/MyWeb/servletB"); // 目标路径

    // 方式 2:简化方法(推荐)!!!!!!!!!!!!!跟上面效果一样
    //  格式:/项目/url     解析成http://localhost:8080/MyWeb/servletB
    //如果没有 /项目 会被解析成 //localhost:8080/servletB  ———> 404
    //sendRedirect 本质会返回 302状态码 和Location:/MyWeb/servletB
    resp.sendRedirect("/MyWeb/servletB");  // /MyWeb写成自动获取的方法比较灵活

    // 跳转到外部资源(如百度)
    // resp.sendRedirect("http://www.baidu.com");
}

6.6.2 注意事项

  1. 最佳应用场景:网站迁移,比如原域名是www.hsp.com迁移到 www.hsp.cn ,但是百度抓取的还是原来网址.
  2. 浏览器地址会发生变化,本质是两次 http 请求.
  3. 不能共享 Request 域中的数据,本质是两次 http 请求,会生成两个 HttpServletRequest对象
  4. 不能重定向/WEB-INF 下的资源
  5. 可以重定向到 Web 工程以外的资源, 比如 到 www.baidu.com
  6. 重定向有两种方式, 推荐resp.sendRedirect()

6.6.3 动态获取工程名

——[[#6.2.4 ServletContext作用]]

String contextPath = getServletContext().getContextPath();  
System.out.println(contextPath);  // /servlet

6.6.4 案例 :用户登录验证

需求

  • 表单提交用户名和密码。
  • 验证通过(假设用户名 hspedu、密码 123456),跳转到成功页面;否则返回登录页并提示错误。
    登录页面(login.html)
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>用户登录</title>
</head>
<body>
    <h1>用户登录</h1>
    <!-- 表单提交到 LoginServlet -->
    <form action="/MyWeb/loginServlet" method="post">
        用户名:<input type="text" name="username"><br><br>
        密码:<input type="password" name="password"><br><br>
        <input type="submit" value="登录">
    </form>
</body>
</html>

登录 Servlet(LoginServlet)

package com.hspedu.servlet;

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("/loginServlet")
public class LoginServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        // 1. 处理中文乱码
        req.setCharacterEncoding("utf-8");

        // 2. 获取表单参数
        String username = req.getParameter("username");
        String password = req.getParameter("password");

        // 3. 验证逻辑
        if ("hspedu".equals(username) && "123456".equals(password)) {
            // 登录成功:重定向到成功页面(避免表单重复提交)
            resp.sendRedirect("/MyWeb/loginSuccess.html");
        } else {
            // 登录失败:重定向回登录页,并携带错误信息(通过 URL 参数)
            resp.sendRedirect("/MyWeb/login.html?msg=用户名或密码错误");
        }
    }
}

成功页面(loginSuccess.html)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>登录成功</title>
</head>
<body>
    <h1>恭喜您,登录成功!</h1>
</body>
</html>

6.7 转发与重定向对比

对比维度请求转发(Forward)请求重定向(Redirect)
地址栏不变变为目标路径
请求次数1 次2 次
request 共享
跳转范围仅项目内项目内 / 外均可
代码实现req.getRequestDispatcher().forward()resp.sendRedirect()
定向/WEB-INF 下的资源可以不能

九、Servlet 注意事项

  1. 线程安全:Servlet 是单例,避免使用成员变量存储请求相关数据(如 private String username),可使用局部变量或 request/session 域对象。
  2. 中文乱码
    • POST 请求:req.setCharacterEncoding("utf-8")(需在获取参数前调用)。
    • 响应:resp.setContentType("text/html;charset=utf-8")
  3. 资源释放:在 destroy 方法中释放资源(如数据库连接、线程池),避免内存泄漏。
  4. 路径问题
    • 相对路径:以当前浏览器地址栏路径为基准(如 ./login.html)。
    • 绝对路径:以项目上下文路径为基准(如 /MyWeb/login.html),可通过 request.getContextPath() 获取上下文路径。
  5. 部署问题:确保 Servlet 类的全类名与配置(web.xml 或注解)一致,避免 ClassNotFoundException。

十、http

10.1 简述

HTTP(Hypertext Transfer Protocol,超文本传输协议)是一种用于在万维网(WWW)上传输数据的应用层协议,是互联网的基础协议之一。它定义了客户端(如浏览器)与服务器之间如何通信,以及数据如何被格式化、传输和处理。

  • HTTP/1.0:每次请求需建立新的 TCP 连接,效率较低。

  • HTTP/1.1:支持长连接(Connection: keep-alive),多个请求可复用一个 TCP 连接,性能提升。

  • HTTP/2:引入二进制分帧、多路复用等特性,大幅提升并发性能,支持服务器主动推送数据。

  • HTTP/3:基于 QUIC 协议(而非 TCP),进一步优化传输速度和稳定性,减少延迟。

  • 基于==** TCP 协议**默认使用端口 80==,HTTPS 为 443

10.2 响应头与请求头

响应:响应头和响应体
![[sub/JAVA Web/picture/HTTP常见请求和响应头-说明.pdf]]

10.3 HTTP状态码

  • 当浏览者访问一个网页时,浏览者的浏览器会向网页所在服务器发出请求。当浏览器接收并显示网页前,此网页所在的服务器会返回一个包含HTTP状态码的信息头(server header)用以响应浏览器的请求。
  • HTTP状态码的英文为HTTP Status Code
    ![[sub/JAVA Web/picture/Pasted image 20251003195939.png]]

10.3.1 常见的HTTP状态码

  • 200 - 请求成功
  • 301 - 资源(网页等)被永久转移到其它URL
  • 302 -资源暂时转移,客户端应继续使用原有URI(重定向,第一个资源不干,返回给你一个url,你去对应的url再次发出请求)

![[sub/JAVA Web/picture/Pasted image 在这里插入图片描述
.png]]

  • 304:Not Modified([[#10.6 HTTP 响应包分析|响应头的Last-Modified相关]])
  • 404 - 请求的资源(网页等)不存在
  • 500 - 内部服务器错误

10.3.2 HTTP状态码分类

HTTP状态码由三个十进制数字组成,第一个十进制数字定义了==状态码的类型==,后两个数字没有分类的作用。HTTP状态码共分为5种类型:

HTTP状态码分类
分类分类描述
1**信息,服务器收到请求,需要请求者继续执行操作
2**成功,操作被成功接收并处理
3**重定向,需要进一步的操作以完成请求
4**客户端错误,请求包含语法错误或无法完成请求
5**服务器错误,服务器在处理请求的过程中发生了错误

10.3.3 HTTP状态码列表:

HTTP状态码列表
状态码状态码英文名称中文描述
100Continue继续。客户端应继续其请求
101Switching Protocols切换协议。服务器根据客户端的请求切换协议。只能切换到更高级的协议,例如,切换到HTTP的新版本协议
200OK请求成功。一般用于GET与POST请求
201Created已创建。成功请求并创建了新的资源
202Accepted已接受。已经接受请求,但未处理完成
203Non-Authoritative Information非授权信息。请求成功。但返回的meta信息不在原始的服务器,而是一个副本
204No Content无内容。服务器成功处理,但未返回内容。在未更新网页的情况下,可确保浏览器继续显示当前文档
205Reset Content重置内容。服务器处理成功,用户终端(例如:浏览器)应重置文档视图。可通过此返回码清除浏览器的表单域
206Partial Content部分内容。服务器成功处理了部分GET请求
300Multiple Choices多种选择。请求的资源可包括多个位置,相应可返回一个资源特征与地址的列表用于用户终端(例如:浏览器)选择
301Moved Permanently永久移动。请求的资源已被永久的移动到新URI,返回信息会包括新的URI,浏览器会自动定向到新URI。今后任何新的请求都应使用新的URI代替
302Found临时移动。与301类似。但资源只是临时被移动。客户端应继续使用原有URI.(重定向,发出了两次请求)
303See Other查看其它地址。与301类似。使用GET和POST请求查看
304Not Modified未修改。所请求的资源未修改,服务器返回此状态码时,不会返回任何资源。客户端通常会缓存访问过的资源,通过提供一个头信息指出客户端希望只返回在指定日期之后修改的资源
305Use Proxy使用代理。所请求的资源必须通过代理访问
306Unused已经被废弃的HTTP状态码
307Temporary Redirect临时重定向。与302类似。使用GET请求重定向
400Bad Request客户端请求的语法错误,服务器无法理解
401Unauthorized请求要求用户的身份认证
402Payment Required保留,将来使用
403Forbidden服务器理解请求客户端的请求,但是拒绝执行此请求
404Not Found服务器无法根据客户端的请求找到资源(网页)。通过此代码,网站设计人员可设置"您所请求的资源无法找到"的个性页面
405Method Not Allowed客户端请求中的方法被禁止
406Not Acceptable服务器无法根据客户端请求的内容特性完成请求
407Proxy Authentication Required请求要求代理的身份认证,与401类似,但请求者应当使用代理进行授权
408Request Time-out服务器等待客户端发送的请求时间过长,超时
409Conflict服务器完成客户端的PUT请求是可能返回此代码,服务器处理请求时发生了冲突
410Gone客户端请求的资源已经不存在。410不同于404,如果资源以前有现在被永久删除了可使用410代码,网站设计人员可通过301代码指定资源的新位置
411Length Required服务器无法处理客户端发送的不带Content-Length的请求信息
412Precondition Failed客户端请求信息的先决条件错误
413Request Entity Too Large由于请求的实体过大,服务器无法处理,因此拒绝请求。为防止客户端的连续请求,服务器可能会关闭连接。如果只是服务器暂时无法处理,则会包含一个Retry-After的响应信息
414Request-URI Too Large请求的URI过长(URI通常为网址),服务器无法处理
415Unsupported Media Type服务器无法处理请求附带的媒体格式
416Requested range not satisfiable客户端请求的范围无效
417Expectation Failed服务器无法满足Expect的请求头信息
500Internal Server Error服务器内部错误,无法完成请求
501Not Implemented服务器不支持请求的功能,无法完成请求
502Bad Gateway充当网关或代理的服务器,从远端服务器接收到了一个无效的请求
503Service Unavailable由于超载或系统维护,服务器暂时的无法处理客户端的请求。延时的长度可包含在服务器的Retry-After头信息中
504Gateway Time-out充当网关或代理的服务器,未及时从远端服务器获取请求
505HTTP Version not supported服务器不支持请求的HTTP协议的版本,无法完成处理

10.4 页面请求次数

一个index.html文件,有两张.img和文本,问浏览器向服务端请求几次?

三次。
第一次发送请求index.html文件
返回发现有其他资源(img),再次发送请求(两张两次)
所有如果有.js/.css请求更多

10.4.1 UML时序图

![[sub/JAVA Web/picture/Pasted image 在这里插入图片描述
.png]]

10.5 HTTP 请求包分析

10.5.1 GET请求包

补充细节

  • User-Agent:tomcat会根据不同浏览器返回不同的响应格式,所有有些浏览器和服务器的版本会不匹配
  • Accept:接受的不同格式顺序也有用,会根据从头到尾的方案解析
  • Accept-Encoding:可以接受的压缩算法
  • Referer:防盗链,有些主机只接受自己发出的请求,根据解析前面的ip和port判定
  • Cookie:客户端存储的 Cookie 数据(用于会话保持,如登录状态)
    ![[sub/JAVA Web/picture/Pasted image 在这里插入图片描述
    .png]]

10.5.2 POST请求包

补充细节

  • content-type:xxx->表示告诉服务器我们的表单数据是经过url编码->网络传输一种通用的编码格式(不同
  • host:目标主机
  • Origin:我是哪个主机(不同
    ![[sub/JAVA Web/picture/Pasted image 在这里插入图片描述
    .png]]

10.5.3 GET 请求 POST 请求分别有哪些

● GET 请求有哪些

  1. form 标签 method=get (指定]
  2. 2.a 标签
  3. link 标签引入 css (以get方式来获取资源]
  4. Script 标签引入 js 文件 (以get方式来获取资源]
  5. img 标签引入图片 (以get请求来获取图片]
  6. iframe 引入 html 页面
  7. 在浏览器地址栏中输入地址后敲回车(用的比较多]
    ● POST 请求有哪些
  8. form 标签 method=post

10.5.4 HTTP 请求中怎样选择 Get 和 Post 方式

  • 业务本身就会自动区别,比如你要显示图片,引入 css/js 这个天然的就是 get 请求,比如你登录,发帖,上传文件, 你就会使用 post(感情的自然流露)
  • get 方式的安全性较 Post 方式要差些。包括机密信息的话。建议用 Post 数据提交方式;
  • 在做数据查询时,建议用 Get 方式;而在做数据加入、改动或删除时,建议用 Post方式
10.5.4.1 传输的数据大小区别
  1. get 传送的数据量较小不大于 2KB(不同浏览器不一样)。
  2. post 传送的数据量较大。一般默认不受限制
10.5.4.2 什么情况下使用 post 请求
  1. post 请求是会在浏览器上隐藏參数部分的,在安全要求的部分都会使用到 POST 请求。如用户登录。数据增上改
  2. 在向 server 传递数据较大的时候。使用 POST,get 是有限制的, 比如发帖, 上传文件
10.5.4.3 什么情况下使用 get 方式呢
  1. 前台页面展示,比如分页内容等,可以保留传递参数, 可用来非常好的分享和传播,POST 中链接地址是不变化的

10.6 HTTP 响应包分析

  • Last-Modified缓存优化。服务器会对比请求的资源最后一次修改的时间。如果没有修改就不会返回,浏览器是直接显示缓存里的资源
  1. 前提:浏览器支持缓存,如果浏览器禁用缓存, 这个 Last-Modified:信息就没有使用,每次都返回资源
  2. 对一些大的资源是很好的优化;所以有时候第一次会慢后面就快
  3. 所以修改html页面时不用redeploy的原因,刷新一下就好。资源已经缓存在浏览器里
  4. ——与状态码304相关[[#10.3.1 常见的HTTP状态码|304状态码]]
  • 响应头和响应体之间有==空行==
  • 响应行的描述:ok、not found
    ![[sub/JAVA Web/picture/Pasted image 在这里插入图片描述
    .png]]

10.7 MIME 类型

  1. MIME 是 HTTP 协议中数据类型。 MIME 的英文全称是"Multipurpose Internet MailExtensions" 多功能 Internet 邮件扩充服务。MIME 类型的格式是==“大类型/小类型”==,并与某一种文件的扩展名相对应
  2. 请求头的Accept,响应头的Content-Type(与响应体类型对应)。

10.7.1 常见的MIME类型

![[sub/JAVA Web/picture/Pasted image 在这里插入图片描述
.png]]

10.8 常见请求方法对比

方法作用数据位置安全性数据长度限制
GET获取资源(如页面、图片)URL 末尾(Query 参数)通常 2KB(浏览器限制)
POST提交数据(如表单、文件)请求体(Body)较高理论无限制(服务器可配置)
PUT全量更新资源请求体无限制
DELETE删除资源URL 或请求体无限制
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值