【Java Web】Servlet

news2024/12/29 11:12:22

文章目录

    • 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.coloradmin.cn/o/2238138.html

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

相关文章

linux命令详解,存储管理相关

存储管理 一、内存使用量&#xff0c;free free 命令是一个用于显示系统中物理内存&#xff08;RAM&#xff09;和交换空间&#xff08;swap&#xff09;使用情况的工具 free -m free -m -s 5参数 -b 功能: 以字节&#xff08;bytes&#xff09;为单位显示内存使用情况。说…

流体力学ansys Fluent二次开发scheme_eval模块剖析

在ANSYS Fluent的二次开发中&#xff0c;scheme_eval 是 Scheme 编程语言中一个非常重要的模块&#xff0c;它允许用户执行动态的 Scheme 表达式和函数&#xff0c;从而扩展 Fluent 的功能。scheme_eval 模块通常与 Fluent 的计算和自定义脚本操作紧密结合。下面我们会对这个模…

中仕公考:大四在校生考公怎么规划?

还在就读的大学生&#xff0c;大三下学期就可以备考&#xff0c;大四以应届生的身份参加考试&#xff0c;中仕不建议大家把备考战线拉得太长或者太短&#xff0c;时间太长容易疲惫&#xff0c;时间太短容易备考不到位。 考公流程&#xff1a; 查看公告职位表→网上报名一资格…

【363】基于springboot的高校竞赛管理系统

摘 要 如今社会上各行各业&#xff0c;都喜欢用自己行业的专属软件工作&#xff0c;互联网发展到这个时候&#xff0c;人们已经发现离不开了互联网。新技术的产生&#xff0c;往往能解决一些老技术的弊端问题。因为传统高校竞赛管理系统信息管理难度大&#xff0c;容错率低&am…

网站架构知识之Ansible模块(day021)

1.Ansible模块 作用:通过ansible模块实现批量管理 2.command模块与shell模块 command模块是ansible默认的模块&#xff0c;适用于执行简单的命令&#xff0c;不支持特殊符号 案列01&#xff0c;批量获取主机名 ansible all -m command -a hostname all表示对主机清单所有组…

计算机网络:网络层 —— 软件定义网络 SDN

文章目录 软件定义网络 SDN远程控制器OpenFlow协议SDN 广义转发流表简单转发负载均衡防火墙 SDN 控制器 软件定义网络 SDN 软件定义网络&#xff08;Software Defined Networking&#xff0c;SDN&#xff09;是一种新兴的网络架构&#xff0c;旨在通过网络控制与数据转发的分离…

使用 .NET Core 7 和 SignalR 构建实时聊天应用程序

动动你可爱的小手&#xff0c;请关注下本人公众号&#xff0c;继续为您提供更多原创技术文章。谢谢给为的支持 SignalR 是一个 ASP.NET 库&#xff0c;它支持实时 Web 功能&#xff0c;允许服务器立即将更新推送到客户端&#xff0c;从而提高应用程序的效率和响应能力。它通过简…

响应式网页设计--html

一&#xff0c;HTML 文档的基本结构 一个典型的 HTML 文档包含了几个主要部分&#xff0c;基本结构如下(本文以下出现的所有代码都可以套入下面示例进行测试)&#xff1a; <!DOCTYPE html> <html lang"zh"> <head><meta charset"UTF-8&q…

欢迎 Stable Diffusion 3.5 Large 加入 Diffusers

作为Stable Diffusion 3的改进版本&#xff0c;Stable Diffusion 3.5 如今已在 Hugging Face Hub 中可用&#xff0c;并可以直接使用 &#x1f9e8; Diffusers 中的代码运行。 https://hf.co/blog/sd3 本次发布包含两套模型参数: https://hf.co/collections/stabilityai/stable…

Ubuntu22.04中使用CMake配置运行boost库示例程序

Ubuntu22.04中使用CMake配置运行boost库示例程序 boost是一个比较强大的C准标准库&#xff0c;里面有很多值得学习的东西&#xff0c;比较asio网络库可以用来编写C TCP客户端或者TCP服务端接收程序。本文主要讲解如何在Ubuntu22.04中使用Cmake配置boost库&#xff0c;以及运行…

高效档案管理案例介绍:文档内容批量结构化解决方案解析

一、项目背景介绍 档案文件中包含的内容丰富且形式多样&#xff0c;通常不仅包括文本&#xff0c;还可能包含表格、图片、标题、段落、注释等多种内容元素。传统的档案管理往往依赖人工对文档内容进行归档、分类和标注&#xff0c;这种方式耗时费力&#xff0c;且在管理庞大数…

如何在vscode中安装git详细新手教程

一、安装git后点击vscode中的设置 今天教大家如何在VScode中编写代码后提交到git仓库&#xff0c;如果我们不想切换到git的命令行窗口&#xff0c;可以在VScode中配置git&#xff0c;然后就可以很方便快捷的把代码提交到仓库中。 二、在输入框中输入 git.path &#xff0c;再点…

负梯度方法与Newton型方法-数值最优化方法-课程学习笔记-4

今天我们继续来学习数值最优化方法的第三章内容的后续知识 Newton方法 Newton方法是Newton方法的基础, 本节主要讨论的是基本Newton方法, 阻尼Newton方法以及修正Newton方法的构造和特性, 这类方法适合解决中小型最优化问题 基本Newton方法 对于 f ( x ) f(x) f(x)如果有连续…

element-plus的Tree 树形控件添加图标

该文章为本菜鸡学习记录&#xff0c;如有错误还请大佬指教 本人刚开始接触vue框架&#xff0c;在使用element-plus组件想实现树形控件&#xff0c;发现官网的组件示例没有图标区分显示 实现效果 代码 <temple 部分 <el-tree :data"data" node-click"hand…

Visual Studio Code从安装到正常使用

Visual Studio Code的汉化 下载的Visual Studio Code的话可以去应用商店也可以去官网下载。 Visual Studio Code只是一个编译器&#xff0c;不具备编译器功能。因此需要下载一个编译器MinGW MinGW的安装 官网链接MinGW官网链接 一步到位的链接 添加环境变量 进入cmd界面…

netty之关闭连接源码分析

写在前面 本文看下netty关闭channel相关源码。 1&#xff1a;前置准备 为了测试&#xff0c;我们需要使用netty源码中examples模块的echoserver和echoclient&#xff0c;但是echoclient因为会不断的发送消息&#xff0c;并不会断开连接&#xff0c;所以&#xff0c;我们需要…

Linux(CentOS)yum update -y 事故

CentOS版本&#xff1a;CentOS 7 事情经过&#xff1a; 1、安装好CentOS 7&#xff0c;系统自带JDK8&#xff0c;版本为&#xff1a;1.8.0_181 2、安装好JDK17&#xff0c;版本为&#xff1a;17.0.13 3、为了安装MySQL执行了 yum update -y&#xff08;这个时候不知道该命令的…

基于SpringBoot的“在线考试系统”的设计与实现(源码+数据库+文档+PPT)

基于SpringBoot的“在线考试系统”的设计与实现&#xff08;源码数据库文档PPT) 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;SpringBoot 工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系统展示 系统总体结构图 系统登录界面图 用户注册界面图 管…

Ubuntu 的 ROS 操作系统安装与测试

引言 机器人操作系统&#xff08;ROS, Robot Operating System&#xff09;是一个用于开发机器人应用的开源框架&#xff0c;它提供了一系列功能丰富的库和工具&#xff0c;能够帮助开发者构建和控制机器人。 当前&#xff0c;ROS1的最新版本为Noetic Ninjemys&#xff0c;专为…

学习threejs,将多个网格合并成一个网格

&#x1f468;‍⚕️ 主页&#xff1a; gis分享者 &#x1f468;‍⚕️ 感谢各位大佬 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍⚕️ 收录于专栏&#xff1a;threejs gis工程师 文章目录 一、&#x1f340;前言1.1 ☘️THREE.Geometry 几何体1.2 …