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

【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 {@Overridepublic 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 = "";@Overridepublic void init(ServletConfig config) throws ServletException {// 获取 ServletContext 对象 获取上下文参数charSetContent = config.getServletContext().getInitParameter("charSetContent");}@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doPost(request, response);}@Overrideprotected 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 {// 如果用户没有选择“记住密码”,则删除相关的 CookiecookieUname = 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 {@Overrideprotected 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);}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {doGet(req, resp);}
}

对应 logout.jsp

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

http://www.mrgr.cn/news/70500.html

相关文章:

  • 287. 寻找重复数(二分查找)
  • 图像处理实验四(Adaptive Filter)
  • [2024最新] java八股文实用版(附带原理)---java集合篇
  • 【C语言刷力扣】13.罗马数字转整数
  • 【月之暗面kimi-注册/登录安全分析报告】
  • ⚡️如何在 React 和 Next.js 项目里优雅的使用 Zustand
  • (三 上)VB2010 语言基础
  • 五分钟掌握vue3!!!
  • 显示器接口种类 | 附图片
  • 申报2025年安徽省16市高新技术企业认定奖励补贴政策
  • (三)【 Python最牛 -Basemap】使用Basemap进行地图可视化
  • 力扣排序506题(相对名次)
  • 如何使用 Web Scraper API 高效采集 Facebook 用户帖子信息
  • 发布rust crate和cargo工作空间
  • SD-WAN可以搭建跨国企业组网吗?
  • 如何解决企业业务流程分散的痛点
  • 深入探讨 C++ 中的 Lambda 表达式
  • CKA认证 | Day2 K8s内部监控与日志
  • Java 多态 (Polymorphism)详解
  • C++模板进阶
  • 数据重塑:长宽数据转换【基于tidyr】
  • Scala的List
  • 科普|分享10个你不知道的公司数据安全防泄密措施,让企业数据安全牢不可破!
  • AI Weekly5:过去一周重要的AI资讯汇总(1104-1110)
  • Playwright——快速入门(初章)
  • 甘肃油糕,舌尖上的滚烫美味