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

Servlet详解(Servlet源码)

Servlet

Servlet是运行在Web服务器或应用服务器上的小程序,它作为来自Web浏览器或其他HTTP客户端的请求和HTTP服务器上的数据库或应用程序之间的中间层。Servlet能够接收来自客户端的基于HTTP协议的请求,并且对请求进行响应。
Servlet是用来处理客户端请求并产生动态网页内容的Java类。
通常Servlet特指HttpServlet,用来接受浏览器的访问请求,浏览器最常用的请求为GET和POST方式,还有其它五种,而HttpServlet分别有七个方法(PUT、DELETE、HEADER、TRACE、OPTION)处理这些类型的请求,另有一个是J2EE不支持的,是CONNECT。Servlet是J2EE规范中的重要成员,是构成WEB的重要组件
Servlet是JavaEE规范中的技术之一,是Java开发中最重要的动态资源之一。

Servlet生命周期

Servlet有良好的生存期的定义,包括加载和实例化、初始化、处理请求以及服务结束。这个生存期由javax.servlet.Servlet接口的init,service和destroy方法表达。 Servlet被服务器实例化后,容器运行其init方法,请求到达时运行其service方法,service方法自动派遣运行与请求对应的doGet,doPost等,当服务器决定将实例销毁的时候调用其destroy方法。

Servlet的执行流程

客户端发起请求:客户端(如浏览器)向服务端发起HTTP请求。
服务器解析请求:Tomcat服务器通过解析请求地址(URL),找到对应的web应用,并解析出客户端想访问的web资源。
加载Servlet:如果发现Servlet是第一次访问,服务器就会加载Servlet,创建Servlet对象。
初始化:调用Servlet的init()方法,进行初始化操作。默认情况下,Servlet对象会在第一次被访问的时候初始化,对应的init()方法得到执行,并且只会执行一次。
处理请求:调用Servlet的service()方法处理客户端的请求。每当有一次来自客户端的请求,Tomcat服务器会开启一个新的线程调用service()方法。
响应请求:service()方法执行完后,服务器会响应数据给客户端浏览器。
销毁:当服务器正常关闭时,Servlet对象会被销毁,对应的destroy()方法执行,并且只会执行一次。

Servlet的创建方式

Servlet的创建主要有三种方式:
实现Servlet接口:通过实现Servlet接口,实现所有抽象方法。这种方式支持最大程度的自定义,但通常不推荐,因为需要实现的方法较多。
继承GenericServlet抽象类:GenericServlet实现了Servlet接口,但必须与协议无关。继承此类后,需要重写service()方法,其他方法可以选择重写。这种方式让开发Servlet变得简单,但和HTTP协议无关。
继承HttpServlet抽象类:HttpServlet继承自GenericServlet,并基于HTTP协议进行了封装。继承此类后,需要重写doGet()和doPost()等方法。这种方式表示请求和响应都要和HTTP相关,是最常用的方式。

Servlet的配置方式

Servlet的配置主要有两种方式:
web.xml文件配置:在web应用的web.xml文件中配置Servlet的映射关系。
注解配置:使用@WebServlet注解直接在Servlet类上进行配置,这种方式简化了配置过程,是现代开发中的主流方式。

Servlet的生命周期

Servlet的生命周期从创建开始,直到销毁结束。主要包括以下几个阶段:
加载和实例化:当Servlet容器启动时,或者在请求到达时Servlet容器首次调用Servlet的service()方法时,Servlet容器会加载并实例化Servlet。
初始化:容器调用Servlet的init()方法进行初始化。
请求处理:对于到达的客户端请求,Servlet容器会创建代表请求的HttpServletRequest对象和代表响应的HttpServletResponse对象,然后调用Servlet的service()方法。service()方法会根据请求的方式(GET、POST等)调用相应的doXXX()方法(如doGet()、doPost())。
销毁:当Servlet容器关闭或Web应用被卸载时,Servlet容器会调用Servlet的destroy()方法进行销毁。

Servlet的用途

Servlet主要用于处理客户端的请求,生成动态网页内容,并与后端的数据库或其他应用进行交互。它可以读取客户端发送的显式数据(如HTML表单数据)和隐式数据(如cookies、媒体类型等),处理这些数据,并生成响应发送给客户端。Servlet还可以与Java类库的其他部分进行交互,如通过sockets和RMI机制与applets、数据库或其他软件进行通信。

Servlet的线程安全问题

由于Servlet采用的是单例模式(即Servlet对象从始至终都只会创建一次),而一个浏览器就代表一个线程,多个浏览器就是多线程。因此,当存在成员变量时,多个线程并发访问此变量就容易出现线程安全问题。解决线程安全问题的方案包括:
改变共享属性:将成员变量变成局部变量。
改变可变属性:用final修饰成员变量,使其成为常量。
使用同步锁:虽然可以解决线程安全问题,但会降低Servlet的性能,因此通常不推荐在Servlet中使用同步锁。
实现SingleThreadModel接口:虽然可以让Servlet引擎以单线程模式调用service()方法,但这种方式并不推荐,因为它会降低Servlet的并发处理能力。
综上所述,Servlet是Java Web开发中非常重要的技术之一,它通过处理HTTP请求和响应,实现了Web应用的前后端交互。在使用Servlet时,需要注意其生命周期、配置方式、线程安全问题等方面。

Servlet 源码

Servlet 是 Java EE 中处理服务器端请求和响应的核心组件。通过 Servlet 接口、GenericServlet 类和 HttpServlet 类,我们可以实现各种功能的Servlet应用。HttpServletRequest 和 HttpServletResponse 接口提供了丰富的方法来处理HTTP请求和生成响应。理解这些类和接口的源码和工作原理,有助于开发高效的Web应用程序。
1. Servlet 接口
Servlet 接口是所有 Servlet 的父接口,定义了 Servlet 的生命周期方法:
init(ServletConfig config): 初始化 Servlet 方法。在 Servlet 被实例化后调用一次,用于进行资源初始化。
service(ServletRequest req, ServletResponse res): 处理请求和生成响应的方法。每个请求都会调用该方法。
destroy(): 销毁 Servlet 方法。在服务器卸载 Servlet 时调用,用于进行资源清理。
getServletConfig(): 返回 Servlet 的配置信息。
getServletInfo(): 返回 Servlet 的基本信息,如作者、版本等。

public interface Servlet {void init(ServletConfig config) throws ServletException;ServletConfig getServletConfig();void service(ServletRequest req, ServletResponse res) throws ServletException, IOException;String getServletInfo();void destroy();
}

2. GenericServlet 类
GenericServlet 类实现了 Servlet 接口,并简化了实现过程。开发者只需要实现 service 方法。

public abstract class GenericServlet implements Servlet, ServletConfig, Serializable {private transient ServletConfig config;public void init(ServletConfig config) throws ServletException {this.config = config;this.init();}public void init() throws ServletException {}public ServletConfig getServletConfig() {return this.config;}public abstract void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException;public String getServletInfo() {return "";}public void destroy() {}
}

3. HttpServlet 类
HttpServlet 类继承了 GenericServlet 类,专门用于处理 HTTP 请求。它定义了多个方法来处理不同的 HTTP 方法(如 GET、POST、PUT、DELETE 等)。

public abstract class HttpServlet extends GenericServlet {protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "Method GET is not supported by this URL");}protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "Method POST is not supported by this URL");}protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "Method PUT is not supported by this URL");}protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "Method DELETE is not supported by this URL");}protected void doOptions(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {resp.setHeader("Allow", "GET, HEAD, POST, PUT, DELETE, OPTIONS");}protected void doTrace(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "Method TRACE is not supported by this URL");}protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {String method = req.getMethod();if (method.equals("GET")) {this.doGet(req, resp);} else if (method.equals("POST")) {this.doPost(req, resp);} else if (method.equals("PUT")) {this.doPut(req, resp);} else if (method.equals("DELETE")) {this.doDelete(req, resp);} else if (method.equals("OPTIONS")) {this.doOptions(req, resp);} else if (method.equals("TRACE")) {this.doTrace(req, resp);} else {resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "Method " + method + " is not supported by this URL");}}protected long getLastModified(HttpServletRequest req) {return -1L;}
}

4. HttpServletRequest 和 HttpServletResponse 接口
HttpServletRequest 和 HttpServletResponse 是两个用于处理 HTTP 请求和响应的接口。
HttpServletRequest:
获取请求参数、头信息、路径信息、会话信息等。
常用方法:getParameter(), getHeader(), getSession(), getMethod(), getRequestURI() 等。

public interface HttpServletRequest extends ServletRequest {String getAuthType();Cookie[] getCookies();long getDateHeader(String name);String getHeader(String name);Enumeration<String> getHeaders(String name);Enumeration<String> getHeaderNames();int getIntHeader(String name);String getMethod();String getPathInfo();String getPathTranslated();String getContextPath();String getQueryString();String getRemoteUser();boolean isUserInRole(String role);Principal getUserPrincipal();String getRequestedSessionId();String getRequestURI();StringBuffer getRequestURL();String getServletPath();HttpSession getSession(boolean create);HttpSession getSession();String changeSessionId();boolean isRequestedSessionIdValid();boolean isRequestedSessionIdFromCookie();boolean isRequestedSessionIdFromURL();boolean isRequestedSessionIdFromUrl();boolean authenticate(HttpServletResponse response) throws IOException, ServletException;void login(String username, String password) throws ServletException;void logout() throws ServletException;Collection<Part> getParts() throws IOException, ServletException;Part getPart(String name) throws IOException, ServletException;<T extends HttpUpgradeHandler> T upgrade(Class<T> handlerClass) throws IOException, ServletException;
}

HttpServletResponse:
设置响应状态码、头信息、内容类型,写出响应内容等。
常用方法:setStatus(), setHeader(), setContentType(), getWriter(), getOutputStream() 等。

public interface HttpServletResponse extends ServletResponse {void addCookie(Cookie cookie);boolean containsHeader(String name);String encodeURL(String url);**加粗样式**String encodeRedirectURL(String url);String encodeUrl(String url);String encodeRedirectUrl(String url);void sendError(int sc, String msg) throws IOException;void sendError(int sc) throws IOException;void sendRedirect(String location) throws IOException;void setDateHeader(String name, long date);void addDateHeader(String name, long date);void setHeader(String name, String value);void addHeader(String name, String value);void setIntHeader(String name, int value);void addIntHeader(String name, int value);void setStatus(int sc);void setStatus(int sc, String sm);int getStatus();String getHeader(String name);Collection<String> getHeaders(String name);Collection<String> getHeaderNames();void setContentType(String type);
}

5. 示例:自定义Servlet
以下是一个简单的自定义Servlet示例:

import javax.servlet.ServletException;
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;@WebServlet("/hello")
public class HelloServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {resp.setContentType("text/html");PrintWriter out = resp.getWriter();out.println("<html><body>");out.println("<h1>Hello, Servlet!</h1>");out.println("</body></html>");}
}

在这个示例中,我们创建了一个简单的Servlet,处理GET请求并返回一个HTML页面。

相关文章:

Servlet详解(Servlet源码)

Servlet Servlet是运行在Web服务器或应用服务器上的小程序&#xff0c;它作为来自Web浏览器或其他HTTP客户端的请求和HTTP服务器上的数据库或应用程序之间的中间层。Servlet能够接收来自客户端的基于HTTP协议的请求&#xff0c;并且对请求进行响应。 Servlet是用来处理客户端请…...

仓颉--接收控制台输入

package projectNameimport std.console.*main() {Console.stdOut.write("请输入信息1&#xff1a;")var c Console.stdIn.readln() // 输入&#xff1a;你好&#xff0c;请问今天星期几&#xff1f;var r c.getOrThrow()Console.stdOut.writeln("输入的信息1…...

数据库设计效率提高的5大注意事项

数据库设计效率和质量的提高对项目影响深远&#xff0c;能够显著提升数据访问速度&#xff0c;确保数据一致性和完整性&#xff0c;减少应用开发和维护成本&#xff0c;同时提升系统稳定性和用户体验。如果数据库设计不佳会导致项目性能低下&#xff0c;数据访问缓慢&#xff0…...

C语言笔试题(一)

本专栏通过整理各专业方向的面试资料并咨询业界相关人士&#xff0c;整合不同方向的面试资料&#xff0c;希望能为您的面试道路点亮一盏灯&#xff01; 1 简单题 C语言中的注释如何写&#xff1f; 答案: 单行注释使用//&#xff0c;多行注释使用/* ... */解析: 注释用于…...

轻松实现远程智能交互:OriginBot与钉钉和GPT4o的集成指南

说明 我之前实现了简单UI来跟OriginBot交互&#xff0c;可以参考这里&#xff1a;古月居 - ROS机器人知识分享社区 但是由于我不是专业的前端开发&#xff0c;写UI还是比较耗时的&#xff0c;所以最近想修改一下这部分。 还有一个原因是&#xff0c;自己开发前端&#xff0c…...

Qt题目知多少-1

1.简述Qt框架的核心组成部分及其作用。 Qt框架是一个跨平台的应用程序开发框架&#xff0c;其核心组成部分及其作用包括&#xff1a; QtCore模块&#xff1a;这是Qt的基础模块&#xff0c;提供了字符串处理(QString)、容器类(QList, QMap等)、时间日期处理、文件和目录操作、国…...

nginx的反向代理和负载均衡(seventeen day)

一、nginx的反向代理 新建一台虚拟机——static-server&#xff08;静态服务器/前端服务器&#xff09; wget https://nginx.org/download/nginx-1.26.1.tar.gz #安装nginx包 ls 安装依赖软件 yum -y install gcc gcc-c yum -y install pcre-devel yum -y install openss…...

BES编译SDK中遇到的perl问题

0 Preface/Foreword 1 问题清单 1.1 perl\r: No such file or directory 编译完成&#xff0c;通过perl&#xff0c;将elf文件转为bin文件&#xff0c;出现错误。 通过查看&#xff0c;项目源文件中&#xff0c;只有一个pl文件&#xff1a; 查看Linux distro使用的WSL版本&am…...

【康复学习--LeetCode每日一题】3111. 覆盖所有点的最少矩形数目

题目&#xff1a; 给你一个二维整数数组 point &#xff0c;其中 points[i] [xi, yi] 表示二维平面内的一个点。同时给你一个整数 w 。你需要用矩形 覆盖所有 点。 每个矩形的左下角在某个点 (x1, 0) 处&#xff0c;且右上角在某个点 (x2, y2) 处&#xff0c;其中 x1 < x…...

Django实战:开启数字化任务管理的新纪元

&#x1f680; Django实战&#xff1a;开启数字化任务管理的新纪元 &#x1f310; &#x1f4d6; 引言 在数字化转型的浪潮中&#xff0c;任务管理的智能化成为提升组织效能的关键。今天&#xff0c;我将带领大家深入了解我们最新开发的OFTS系统——一款创新的组织任务管理软…...

史上最全网络安全面试题+答案

1、什么是SQL注入攻击 前端代码未被解析被代入到数据库导致数据库报错 2、什么是XSS攻击 跨站脚本攻击 在网页中嵌入客户端恶意脚本&#xff0c;常用s语言&#xff0c;也会用其他脚本语言 属于客户端攻击&#xff0c;受害者是用户&#xff0c;网站管理员也属于用户&#xf…...

Python 爬虫入门(五):使用 lxml 解析网页

Python 爬虫入门&#xff08;五&#xff09;&#xff1a;使用 lxml 解析网页 前言1. lxml 简介1.1 什么是 lxml&#xff1f;1.2 为什么选择 lxml&#xff1f;1.3 安装 lxml 2. lxml 基础2.1 解析 HTML/XML2.2 XPath 表达式2.3 使用 XPath 提取数据 3. 深入解析3.1 处理命名空间…...

阿里云RDS到亚马逊云RDS的实时数据同步方案详解

1. 需求背景 在当今的多云环境中,企业经常需要在不同云平台之间同步数据。本文将详细介绍如何实现从阿里云RDS MySQL数据库到亚马逊云RDS MySQL数据库的实时数据同步。这种同步对于数据备份、跨区域数据访问、数据分析等场景都非常有用。 2. 方案概述 我们将使用AWS Kinesis…...

《LeetCode热题100》---<滑动窗口篇两道>

本篇博客讲解LeetCode热题100道滑动窗口篇中的两道题 第一道&#xff1a;无重复字符的最长子串 第二道&#xff1a;找到字符当中的所有字母异位词 第一道&#xff1a;无重复字符的最长子串 哈希滑动窗口 class Solution {public int lengthOfLongestSubstring(String s0) {int…...

Python学习计划——9.1多线程编程

并发编程是一种在同一时间段内运行多个任务的方法&#xff0c;可以提高程序的效率和性能。Python中的多线程编程可以使用threading模块实现。以下是多线程编程的详细讲解和可运行的Python案例。 1. 什么是多线程 多线程是一种并发编程的方式&#xff0c;它允许在同一个进程中…...

借助 NGINX 对本地的 Kubernetes 服务进行自动化的 TCP 负载均衡

原文作者&#xff1a;Chris Akker - F5 技术解决方案架构师&#xff0c;Steve Wagner - F5 NGINX 解决方案架构师 原文链接&#xff1a;借助 NGINX 对本地的 Kubernetes 服务进行自动化的 TCP 负载均衡 转载来源&#xff1a;NGINX 中文官网 NGINX 唯一中文官方社区 &#xff0c…...

基于python的大学学生影响力分析系统设计与实现

博主介绍&#xff1a; 大家好&#xff0c;本人精通Java、Python、C#、C、C编程语言&#xff0c;同时也熟练掌握微信小程序、Php和Android等技术&#xff0c;能够为大家提供全方位的技术支持和交流。 我有丰富的成品Java、Python、C#毕设项目经验&#xff0c;能够为学生提供各类…...

upload-labs靶场(1-19关)

upload-labs靶场 简介 upload-labs是一个使用php语言编写的&#xff0c;专门收集渗透测试过程中遇到的各种上传漏洞的靶场。旨在帮助大家对上传漏洞有一个全面的了解。目前一共19关&#xff0c;每一关都包含着不同上传方式。 注意&#xff1a;能运行<?php phpinfo();?&…...

Python面向对象浅析

目录 面向对象基本概念 一、类和对象 类和对象是面向对象骗程的两个核心概念。 在程序开发中&#xff0c;要设计一个类&#xff0c;通常需要满足一下三个要素: self详解&#xff1a; 对象&#xff08;Object&#xff09; 魔法方法&#xff1a; 类里的一些特殊方法 __in…...

JS基本语法

JS代码写在body结束标签的上面 如点击按钮调用方法&#xff1a; 在浏览器的控制台打印测试数据 console.log() <body><button type"button" onclick"easymethod()">点击我</button><script>//JS代码&#xff0c;写在body标签的…...

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…...

装饰模式(Decorator Pattern)重构java邮件发奖系统实战

前言 现在我们有个如下的需求&#xff0c;设计一个邮件发奖的小系统&#xff0c; 需求 1.数据验证 → 2. 敏感信息加密 → 3. 日志记录 → 4. 实际发送邮件 装饰器模式&#xff08;Decorator Pattern&#xff09;允许向一个现有的对象添加新的功能&#xff0c;同时又不改变其…...

Spring Boot面试题精选汇总

&#x1f91f;致敬读者 &#x1f7e9;感谢阅读&#x1f7e6;笑口常开&#x1f7ea;生日快乐⬛早点睡觉 &#x1f4d8;博主相关 &#x1f7e7;博主信息&#x1f7e8;博客首页&#x1f7eb;专栏推荐&#x1f7e5;活动信息 文章目录 Spring Boot面试题精选汇总⚙️ **一、核心概…...

uniapp微信小程序视频实时流+pc端预览方案

方案类型技术实现是否免费优点缺点适用场景延迟范围开发复杂度​WebSocket图片帧​定时拍照Base64传输✅ 完全免费无需服务器 纯前端实现高延迟高流量 帧率极低个人demo测试 超低频监控500ms-2s⭐⭐​RTMP推流​TRTC/即构SDK推流❌ 付费方案 &#xff08;部分有免费额度&#x…...

OpenLayers 分屏对比(地图联动)

注&#xff1a;当前使用的是 ol 5.3.0 版本&#xff0c;天地图使用的key请到天地图官网申请&#xff0c;并替换为自己的key 地图分屏对比在WebGIS开发中是很常见的功能&#xff0c;和卷帘图层不一样的是&#xff0c;分屏对比是在各个地图中添加相同或者不同的图层进行对比查看。…...

AspectJ 在 Android 中的完整使用指南

一、环境配置&#xff08;Gradle 7.0 适配&#xff09; 1. 项目级 build.gradle // 注意&#xff1a;沪江插件已停更&#xff0c;推荐官方兼容方案 buildscript {dependencies {classpath org.aspectj:aspectjtools:1.9.9.1 // AspectJ 工具} } 2. 模块级 build.gradle plu…...

AI病理诊断七剑下天山,医疗未来触手可及

一、病理诊断困局&#xff1a;刀尖上的医学艺术 1.1 金标准背后的隐痛 病理诊断被誉为"诊断的诊断"&#xff0c;医生需通过显微镜观察组织切片&#xff0c;在细胞迷宫中捕捉癌变信号。某省病理质控报告显示&#xff0c;基层医院误诊率达12%-15%&#xff0c;专家会诊…...

GitHub 趋势日报 (2025年06月06日)

&#x1f4ca; 由 TrendForge 系统生成 | &#x1f310; https://trendforge.devlive.org/ &#x1f310; 本日报中的项目描述已自动翻译为中文 &#x1f4c8; 今日获星趋势图 今日获星趋势图 590 cognee 551 onlook 399 project-based-learning 348 build-your-own-x 320 ne…...

Java求职者面试指南:Spring、Spring Boot、Spring MVC与MyBatis技术解析

Java求职者面试指南&#xff1a;Spring、Spring Boot、Spring MVC与MyBatis技术解析 一、第一轮基础概念问题 1. Spring框架的核心容器是什么&#xff1f;它的作用是什么&#xff1f; Spring框架的核心容器是IoC&#xff08;控制反转&#xff09;容器。它的主要作用是管理对…...

快速排序算法改进:随机快排-荷兰国旗划分详解

随机快速排序-荷兰国旗划分算法详解 一、基础知识回顾1.1 快速排序简介1.2 荷兰国旗问题 二、随机快排 - 荷兰国旗划分原理2.1 随机化枢轴选择2.2 荷兰国旗划分过程2.3 结合随机快排与荷兰国旗划分 三、代码实现3.1 Python实现3.2 Java实现3.3 C实现 四、性能分析4.1 时间复杂度…...