当前位置: 首页 > article >正文

【Java Web】Servlet

文章目录

    • Servlet API
    • Servlet生命周期
    • Servlet配置
      • 注解
      • 配置文件
      • 全局参数
    • Servlet获得内置对象
    • 升级示例3


Servlet 是一种用于构建 Java 服务器端应用程序的技术,允许开发者创建动态的 web 内容。Servlets 在 Java 平台上运行,并由 Java Servlet API 提供支持,该 API 是 Java EE(现在称为 Jakarta EE)的一部分。Servlet 的主要功能是处理客户端请求并发送响应给客户端。

主要特点

  1. 请求和响应处理:Servlet 可以接收来自客户端(通常是浏览器)的请求,并通过 HttpServletRequest 对象获取请求信息。生成响应时,Servlet 使用 HttpServletResponse 对象,可以向客户端返回 HTML、JSON、XML 等格式的数据。
  2. 生命周期:Servlet 的生命周期由服务器控制,主要包括加载、初始化、处理请求、销毁四个阶段。初始化时,Servlet 会调用 init() 方法;处理请求时,调用 service() 方法;销毁时,调用 destroy() 方法。
  3. 多线程支持:Servlet 能够处理多个请求,通常在多线程环境下运行。每个请求会在独立的线程中处理,这样可以提高并发处理能力。
  4. 跨平台:由于基于 Java,Servlet 可以在任何支持 Java 的服务器上运行,实现了良好的跨平台能力。
  5. 集成与扩展:Servlet 可以与 JSP(JavaServer Pages)、过滤器、监听器等技术结合使用,以实现更复杂的 web 应用。

创建 Servlet 有三种常见的方式:

  • 实现 javax.servlet.Servlet 接口
  • 继承 javax.servlet.GenericServlet
  • 继承 javax.servlet.http.HttpServlet

Servlet API

javax.servlet.Servlet核心接口

  • 定义了 init(), service(), 和 destroy() 方法,这些方法分别对应于 Servlet 的初始化、服务处理和销毁阶段。
init()     // Servlet的初始化方法,仅仅会执行一次
service()  // 处理请求和生成响应
destroy()  // 在服务器停止并且程序中的 Servlet 对象不再使用的时候调用,只执行一次

javax.servlet.GenericServlet抽象类

  • 实现了 Servlet 接口,并提供了一些默认实现。提供了对 init(ServletConfig config)getServletConfig() 方法的支持。
  • 通常不直接使用,而是作为更具体的 HttpServlet 类的基础。

javax.servlet.http.HttpServlet类

  • 继承自 GenericServlet,专门为 HTTP 协议设计。提供了 doGet(), doPost(), doPut(), doDelete() 等方法来处理不同的 HTTP 请求类型。
  • 开发者通常继承这个类来创建自己的 Servlet
// 处理 GET 请求
doGet(HttpServletRequest req, HttpServletResponse res)
// 处理 POST 请求
doPost(HttpServletRequest req, HttpServletResponse res)

javax.servlet.ServletRequest接口

  • 表示客户端请求的对象,包含有关请求的信息。
  • HttpServletRequestServletRequest 的子接口,专为 HTTP 请求提供额外的方法,如获取查询参数、请求头等信息。
// 获取请求参数
getParameter(String name)
// 获取请求头信息
getHeader(String name)
// 获取请求的方法类型(GET, POST等)
getMethod()
// 获取请求的 URI
getRequestURI()

javax.servlet.ServletResponse接口

  • 表示服务器响应的对象,用于构建和发送响应到客户端。
  • HttpServletResponseServletResponse 的子接口,提供了发送状态码、设置响应头、写入响应体等与 HTTP 相关的方法。
// 设置响应内容的类型(如 text/html)
setContentType(String type)
// 获取用于发送字符数据的输出流
getWriter()
// 重定向到指定的 URL
sendRedirect(String location)

ServletConfig

  • 代表 Servlet 的配置信息。可以通过它从 web.xml 文件获取初始化参数以及 ServletContext 对象。
// 获取初始化参数
getInitParameter(String name)
// 获取 Servlet 上下文
getServletContext()

Servlet生命周期

生命周期谁来做何时做
实例化Servlet 容器当Servlet容器启动或者容器检测到客户端请求时
初始化Servlet 容器实例化后,容器调用Servlet的init()初始化对象
处理请求Servlet 容器得到客户端请求并做出处理时
销毁Servlet 容器当程序中的Servlet对象不再使用的时候,或者Web服务器停止运行的时候

在这里插入图片描述

执行顺序

  • MyServlet():构造方法 实例化
  • init():初始化方法
  • service():req.getMethod() 判断请求类型是 get || post
  • 加载 get || post
  • destroy():销毁方法

Servlet配置

注解

@WebServlet 注解用于将一个 Servlet 类与一个或多个 URL 模式进行映射,并且可以配置一些初始化参数。

// 单个 URL 映射
@WebServlet("/user/login")
// 多个 URL 映射
@WebServlet({"/user/login", "/user/signin"})
// 高级设置 设置 Servlet 名称和启动加载顺序
@WebServlet(name = "loginServlet", value = "/user/login", loadOnStartup = 1)
  • name 属性指定了 Servlet 的名称,可以用于在 web.xml 中引用。
  • value 属性指定了 Servlet 的 URL 映射。
  • loadOnStartup 属性指定了 Servlet 的启动加载顺序。值为 1 表示在应用启动时立即加载该 Servlet。值越大,加载顺序越靠后。

还可以使用 @WebInitParam 注解来设置初始化参数

@WebServlet(name = "loginServlet", 
            value = "/user/login", 
            loadOnStartup = 1,
            initParams = {
                @WebInitParam(name = "maxAge", value = "3600"),
                @WebInitParam(name = "allowedMethods", value = "GET,POST")
            })

配置文件

web.xml文件中配置 Servlet 元素及其初始化参数

1. 配置 Servlet 元素

web.xml中定义 Servlet 本身。通过<servlet>标签及其子标签来完成。

<servlet>
    <!-- Servlet的名称,可自定义,用于在web.xml内部标识该Servlet -->
    <servlet-name>indexServlet</servlet-name>
    <!-- Servlet的完整类名,包括包名 -->
    <servlet-class>com.example.IndexServlet</servlet-class>
</servlet>

2. 配置 Servlet 映射

配置完 Servlet 后将其与特定的 URL 模式进行映射,以便当客户端请求特定的 URL 时,Web 容器能知道应该调用哪个 Servlet 来处理请求。通过<servlet-mapping>标签来完成。

<servlet-mapping>
    <!-- 这里的servlet-name要和前面定义Servlet时设置的名称一致 -->
    <servlet-name>indexServlet</servlet-name>
    <!-- 定义该Servlet处理的URL模式,可以是精确匹配的具体URL,也可以是通配符模式 -->
    <url-pattern>/user/index</url-pattern>
</servlet-mapping>

3. 配置 Servlet 初始化参数

为 Servlet 配置初始化参数。在<servlet>标签内添加<init-param>子标签来实现。

<servlet>
    <servlet-name>indexServlet</servlet-name>
    <servlet-class>com.example.IndexServlet</servlet-class>

    <!-- 开始配置初始化参数 -->
    <init-param>
        <!-- 参数名称,可自定义 -->
        <param-name>charSetContent</param-name>
        <!-- 参数值,根据实际需求设置 -->
        <param-value>utf-8</param-value>
    </init-param>
    <init-param>
        <param-name>anotherParamKey</param-name>
        <param-value>anotherParamValue</param-value>
    </init-param>
    <!-- 结束配置初始化参数 -->
    
    <!-- 指定 Servlet 的加载顺序 越小越靠前 -->
    <load-on-startup>1</load-on-startup>
</servlet>

4. 获取初始化参数

假设上述配置的MyServletClass继承自HttpServlet(通常处理 HTTP 请求的 Servlet 会这么做),在MyServletClassinit()方法中可以这样获取初始化参数

public class IndexServlet extends HttpServlet {
    @Override
    public void init(ServletConfig config) throws ServletException {
        super.init(config);
        // 获取名为charSetContent的初始化参数值
        String initParam = config.getInitParameter("charSetContent");
        System.out.println("charSetContent的值为: " + initParam);

        // 获取名为anotherParamKey的初始化参数值
        String anotherParamKeyValue = config.getInitParameter("anotherParamKey");
        System.out.println("anotherParamKey的值为: " + anotherParamKeyValue);
    }
}

在浏览器 URL 地址栏输入 http://localhost:8888/user/index(具体端口号看自己 Tomcat 设置)

在这里插入图片描述

全局参数

<context-param> 元素定义上下文参数,这些参数在整个 Web 应用程序中都可用。

可以在 Servlet 中通过 ServletContext 对象来访问全局参数。

<!-- 定义上下文参数 -->
<context-param>
    <param-name>charSetContent</param-name>
    <param-value>utf-8</param-value>
</context-param>
<!-- 配置 Servlet -->
<servlet>
	...
</servlet>
<!-- 映射 Servlet 到 URL -->
<servlet-mapping>
	...
</servlet-mapping>
@Override
public void init(ServletConfig config) throws ServletException {
    // super.init(config);
    // 获取 ServletContext 对象
    ServletContext context = config.getServletContext();
    // 获取上下文参数
    String charSetContent = context.getInitParameter("charSetContent");
    System.out.println("Character Set Content: " + charSetContent);
}

Servlet获得内置对象

1、获取 PageContext 对象

JspFactory jspFactory = JspFactory.getDefaultFactory();
PageContext pageContext = jspFactory.getPageContext(this, request, response, null, true, 8192, true);

// 使用 PageContext 对象
pageContext.getOut().print("<h1 style='color:red'>这是doGET</h1>");

// 释放 PageContext 对象
pageContext.forward("/index.jsp"); // 或者 pageContext.include("/index.jsp");
pageContext.release();

2、获取 out 对象

response.setContentType("text/html;charset=UTF-8");

PrintWriter out = response.getWriter();
out.print("<h1 style='color:red'>这是doGET</h1>");

3、获取 session 对象

HttpSession session = request.getSession();
session.setAttribute("username", "liming");
response.getWriter().println("Session ID: " + session.getId());

4、获取 application 对象

ServletContext context = this.getServletContext();
context.setAttribute("appAttribute", "Application Value");
response.getWriter().println("Application Context: " + context.getRealPath("/"));

升级示例3

doxxx.jsp 中的逻辑处理步骤移动到 Servlet 中处理。

首先,在 web.xml 文件中设置全局参数

<!-- 定义上下文参数 -->
<context-param>
    <param-name>charSetContent</param-name>
    <param-value>utf-8</param-value>
</context-param>

在 Servlet 中获取并使用 charSetContent 参数

@WebServlet("/user/login")
public class UserLoginServlet extends HttpServlet {
    String charSetContent = "";
    @Override
    public void init(ServletConfig config) throws ServletException {
        // 获取 ServletContext 对象 获取上下文参数
        charSetContent = config.getServletContext().getInitParameter("charSetContent");
    }
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding(charSetContent);
        HttpSession session = request.getSession();
        // 接收参数
        String uname = request.getParameter("uname");
        String upwd = request.getParameter("upwd");
        boolean jzpwd = "on".equals(request.getParameter("jzpwd"));
        // 调用 Java 方法 登录
        SmbmsUserDao smbmsUserDao = new SmbmsUserDaoImpl();
        SmbmsUser smbmsUser =  smbmsUserDao.login(uname,upwd);

        // 判断登录是否成功
        if (smbmsUser != null) {
            // session 存储登录信息
            session.setAttribute("smbmsUser",smbmsUser);
            Cookie cookieUname = null;
            Cookie cookieUpwd = null;
            Cookie cookieJzpwd = null;
            // 如果用户选择了“记住密码”,则将保存到 Cookie 中
            if (jzpwd) {
                cookieUname = new Cookie("uname", URLEncoder.encode(uname, "UTF-8"));
                cookieUpwd = new Cookie("upwd", upwd);
                cookieJzpwd = new Cookie("jzpwd", "on");
                // 设置 Cookie 的有效期为 2 小时
                setCookie(response,cookieUname,60 * 60 * 2);
                setCookie(response,cookieUpwd,60 * 60 * 2);
                setCookie(response,cookieJzpwd,60 * 60 * 2);
            } else {
                // 如果用户没有选择“记住密码”,则删除相关的 Cookie
                cookieUname = new Cookie("uname", "");
                cookieUpwd = new Cookie("upwd", "");
                cookieJzpwd = new Cookie("jzpwd", "");
                setCookie(response,cookieUname,0);
                setCookie(response,cookieUpwd,0);
                setCookie(response,cookieJzpwd,0);
            }
            // 转发
            request.getRequestDispatcher("/index").forward(request,response);
            // 重定向
            // response.sendRedirect("/doindex.jsp");
        } else {
            // 登录失败则重定向回登录界面
            response.sendRedirect("/login.jsp");
        }
    }
    private void setCookie(HttpServletResponse response,Cookie cookie, int maxAge) {
        // 设置 Cookie 的有效期
        cookie.setMaxAge(maxAge);
        // 设置 Cookie 的路径为根路径
        cookie.setPath("/");
        // 将 Cookie 添加到响应中
        response.addCookie(cookie);
    }
}

对应 doindex.jsp

@WebServlet("/index")
public class IndexServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 调用 Java 方法 获取供应商列表信息
        SmbmsProviderDao smbmsProviderDao = new SmbmsProviderDaoImpl();
        List<SmbmsProvider> providerList = smbmsProviderDao.findAll();
        // setAttribute 存储供应商信息
        request.setAttribute("providerList",providerList);
        // 转发
        request.getRequestDispatcher("/index.jsp").forward(request,response);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

对应 logout.jsp

@WebServlet("/user/logout")
public class UserLogoutServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        HttpSession session = request.getSession();
        // 清除所有 session
        session.invalidate();
        // 重定向回首页
        response.sendRedirect("/login.jsp");
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

http://www.kler.cn/a/395577.html

相关文章:

  • <AI 学习> 下载 Stable Diffusions via Windows OS
  • 基于ssh得网上预约挂号系统的设计与实现
  • 深入探索 TypeScript:从基础到高级特性
  • ubuntu22.04 安装FFmpeg,并进行视频的转化格式和裁剪
  • 进入未来城:第五周游戏指南
  • C/C++语言基础--C++模板与元编程系列六,C++元编程相关库的讲解与使用
  • IntelliJ IDEA新建项目或导入未识别为maven解决
  • 视频流媒体播放器EasyPlayer.js RTSP播放器视频颜色变灰色/渲染发绿的原因分析
  • Spring Boot编程训练系统:开发与管理
  • C语言之MakeFile
  • SQL,力扣题目1126,查询活跃业务
  • 响应“一机两用”政策 落实政务外网安全
  • 【系统架构设计师】真题论文: 论企业集成平台的架构设计(包括解题思路和素材)
  • uniapp小程序分享使用canvas自定义绘制 vue3
  • 【开源免费】基于SpringBoot+Vue.JS高校学科竞赛平台(JAVA毕业设计)
  • 【MYSQL】数据库三大范式是什么?【最简单理解】
  • 多端校园圈子论坛小程序,多个学校同时代理,校园小程序分展示后台管理源码
  • ‌MySQL 5.7和8.0版本在多个方面存在显著区别,主要包括性能优化、新特性引入以及安全性提升
  • 2:Vue.js 父子组件通信:让你的组件“说话”
  • git命令提交项目
  • 适用比亚迪汽车生产线的RFID高频读写器
  • 为什么 Vue3 封装 Table 组件丢失 expose 方法呢?
  • 鸿蒙学习-PersistentStorage持久化存储
  • 【递归回溯与搜索算法篇】算法的镜花水月:在无尽的自我倒影中,递归步步生花
  • 深入浅出:Java 中的经典排序算法详解与实现
  • 1、C语言学习专栏介绍