Servlet--快速入门及HTTP概述
Servlet概述
Servlet:server applet,是用Java编写的服务器端程序,其主要功能在于交互式的浏览和修改数据,生成动态web内容,一般来说,Servlet是指实现了这个Servlet接口的类
在Java中,Servlet是用于创建动态Web内容的服务器端组件。
Servlet运行在Java EE服务器上,可以响应客户端(通常是Web浏览器)发出的请求。
Servlet的生命周期由服务器管理,主要包括初始化、请求处理和销毁三个阶段。
Servlet是一种Java类,它实现了javax.servlet.Servlet
接口。Servlet主要用于处理HTTP请求和生成HTTP响应,可以用于创建动态网页、处理表单数据、管理会话等。
Servlet就是一个接口,定义了Java类被浏览器访问到(Tomcat识别)的规则。
将来我们自定义一个类,实现servlet接口,复写方法
Servlet工作模式
-
客户端发送请求至服务器;
-
服务器启动并调用Servlet,Servlet根据客户端请求生成响应内容并将其传给服务器;
-
服务器将响应返回客户端
快速入门
-
创建JavaEE项目,定义一个实现Servlet接口的类,实现方法,配置Servlet
代码展示:
配置servlet
<!-- 配置servlet--><servlet><servlet-name>demo</servlet-name><servlet-class>com.lyc.servlet.ServletDemo</servlet-class></servlet><servlet-mapping><servlet-name>demo</servlet-name><!-- 资源路径--><url-pattern>/demo</url-pattern> </servlet-mapping>
执行效果:
未配置静态资源,所以是空白,但未报错,说明运行成功
执行原理
原理解析:当服务器接收到客户端浏览器的请求后,会解析请求路径,获取访问的servlet的资源路径
通过Servlet_study可以找到部署在tomcat下的项目
通过资源名称(/demo),通过tomcat内部检索web配置文件(即web.xml)通过查询配置文件中是否有资源路径(url-pattern)与之匹配,如果匹配,则检索到servlet名称(servlet-name),然后通过< servlet-class >找到与之对应的全类名。
重点:tomcat将全类名对应的字节码加载进内存(Class.forName())(反射),创建实例化对象(class.newInstance()),调用方法--service()
底层原理是反射,通过servlet提供的全类名拿到servletDemo的class模板(通过Class类的方法)--Class.forName(全类名),在通过调用Class对象的newlnstance()方法,拿到类的对象,再调用类的方法
生命周期
-
加载和实例化:
-
当用户第一次向 Servlet 容器发出 HTTP 请求要求访问某个 Servlet 时,Servlet 容器会在整个容器中搜索该 Servlet 对象,如果发现这个 Servlet 对象没有被实例化,便创建这个 Servlet 对象,之后进入初始化阶段;如果找到了该 Servlet 对象的实例,则不去创建而是直接进入运行阶段。
-
-
初始化:调用
init
方法进行初始化(加载资源)。只执行一次。 -
请求处理:每次请求调用
service
方法,根据请求类型调用相应的doGet
、doPost
等方法。可以执行多次-
这是 Servlet 生命周期中最核心的阶段。在该阶段中,Servlet 容器会为当前的请求创建一个 ServletRequest 对象和一个 ServletResponse 对象(分别代表请求和响应),service() 方法从 ServletRequest 对象中获得用户的详细请求信息并可以检查 HTTP 请求类型(GET、POST、PUT、DELETE 等),并在适当的时候调用
doGet
、doPost
、doPut
,doDelete
等方法处理该请求。处理完成后通过 ServletResponse 对象生成响应结果。
-
注意:在 Servlet 对象的整个生命周期内,用户每次请求访问 Servlet 时,Servlet 容器都会调用一次 Servlet 的 service() 方法。
-
销毁:服务器关闭或Servlet被移除时调用
destroy
方法进行清理。,只执行一次。注:只有服务器正常关闭时,才会执行destroy方法。
destroy方法在Servlet被销毁之前执行,一般用于释放资源
在 Servlet 对象的整个生命周期内,destroy() 方法只会在销毁该对象被调用一次。
Servlet 对象一旦创建就会驻留在内存中一直等待客户端的访问。
直到服务器关闭或项目被移除出容器时,Servlet 对象才会被销毁。
-
代码展示:
package com.lyc.servlet;import javax.servlet.*;import java.io.IOException;public class ServletDemo2 implements Servlet {/*初始化方法* 在servlet创建时,执行,只会执行一次* */@Overridepublic void init(ServletConfig servletConfig) throws ServletException {System.out.println("init");}/*获取ServletConfig对象* ServletConfig:servlet的配置对象* 在servlet创建时,执行,只会执行一次*/@Overridepublic ServletConfig getServletConfig() {return null;}/*提供服务方法,每一次请求都会执行,执行多次* */@Overridepublic void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {System.out.println("service");}/*获取ServletInfo对象* ServletInfo:servlet的信息对象:版本,作者,描述等* 在servlet创建时,执行,只会执行一次* */@Overridepublic String getServletInfo() {return "";}/*销毁方法* 在servlet销毁时,执行,只会执行一次* */@Overridepublic void destroy() {System.out.println("destroy");}}
思考:
servlet什么时候被创建?
-
默认情况下,第一次被访问时,servlet被创建
-
可以配置servlet的创建时机
代码展示
<servlet><servlet-name>demo</servlet-name><servlet-class>com.lyc.servlet.ServletDemo</servlet-class><!-- 指定servlet的创建时机1.第一次被访问时创建<load-on-startup>值为负数</load-on-startup>2.在服务器启动时,创建<load-on-startup>值为正数</load-on-startup>--><load-on-startup>1</load-on-startup></servlet>
Servlet的init方法,只执行一次,说明Servlet在内存中只存在一个对象single(单例模式)
多个用户同时访问可能会出现线程安全问题,不能选择加锁,加锁太过于影响性能。
解决方案:
尽量不要在servlet中定义成员变量(否则就会被共享资源,造成安全问题),可以定义局部变量,即使定义了成员变量,也不要修改值
注解配置
servlet3.0以后可以使用注解配置,不需要web.xml.
创建项目,可以不创建web.xml,定义实现servlet接口的类,复写方法,在类上使用@webServlet注解(@WebServlet("资源路径")
),进行配置
代码展示:
@WebServlet("/demo")public class AnnotationServlet implements Servlet {...}
Servlet相关配置
1.url-partten:Servlet访问路径
注:一个servlet可以定义多个访问路径
@WebServlet({"/d1","/d2","/d3"})public class ServletDemo extends HttpServlet {doget();}
路径定义规则
-
/xxx
-
/xxx/xxx:多层路径,目录结构
-
*.do
代码展示:
//@WebServlet({"/d1","/d2","/d3"}) 输入/d1,/d2,/d3都可以访问//@WebServlet("/d1/d2") 输入d1/d2才可以访问//@WebServlet("/d1/*") 输入d1/任意值都可以访问//@WebServlet("/*") 输入任意值都可以访问//@WebServlet("*.do") 输入任意值.do都可以访问
拓展:IDEA与tomcat的相关配置
-
IDEA会为每一个Tomcat部署的项目单独建立一份配置文件
查询控制台的log文件:Using CATALINA_BASE: "C:\Users\20893\AppData\Local\JetBrains\IntelliJIdea2024.3\tomcat\ba95c5c2-f5e3-4c8e-a1c2-9cfce7efa4df"
从而找到conf文件夹,其中的server.xml可以更改我们的端口设置等等
工作空间项目 和tomcat部署的web项目
注意事项:
tomcat真正访问的项目是“tomcat部署的web项目”,“Tomcat部署的web项目”对应着“工作空间项目”的web目录下的所有资源
WEB-INF目录下的资源不能直接被浏览器访问
断点调试:用debug
体系结构
web相关概念回顾
-
软件架构
-
C/S:客户端/服务器端
-
B/S:浏览器端/服务器端
-
-
资源分类
-
静态资源:所有用户访问后,得到的结果一致,称为静态资源,静态资源可以直接被浏览器解析
-
如"HTML,CSS.JS"
-
-
动态资源:用户访问相同的资源,得到的结果不一致,则为动态资源,动态资源被访问后,需要先转换成静态资源,再返回给浏览器
-
如“JSP,PHP,ASP”
-
-
-
网络通信三要素
-
IP地址:电子设备(计算机)在网络中的唯一标识
-
端口:应用程序在计算机中的唯一标识
-
传输协议:规定了数据传输的规则
-
基础协议:常见的协议有TCP协议(安全协议,三次握手,四次挥手,速度稍慢),UDP协议(不安全协议,速度快),HTTP协议(超文本传输协议),ftp协议(文件上传协议),SMTP协议(发送邮件·)
-
-
体系结构
参考博客:Servlet概述:体系结构,生命周期,常用命令,注解配置_servlet体系结构-CSDN博客
Servlet由两个Java包组成:javax.servlet
和javax.servlet.http
。
在javax.servlet
包中定义了所有的Servlet类都必须实现或扩展的的通用接口和类;
在javax.servlet.http
包中定义了采用HTTP通信协议的HttpServlet类。
其中的一些比较核心的接口和类之间的关系如下,图中提到的方法是在使用该接口或类时必须要实现的:
1. Servlet 接口
Servlet
接口是所有 Servlet 类的根接口。其常用方法如下:
// 初始化 Servletpublic void init(ServletConfig config) throws ServletException;// 获取 Servlet 的配置信息public ServletConfig getServletConfig();// 处理请求public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException;// 获取 Servlet 的信息public String getServletInfo();// 销毁 Servletpublic void destroy();
2. Serializable 接口
Serializable
接口是 Java 中的标记接口,用于标识类的实例可以被序列化。实现该接口的类表示它们的实例可以被转换为字节序列,以便在网络上传输或保存到文件中。其常用方法如下:
// 序列化对象private void writeObject(ObjectOutputStream out) throws IOException;// 反序列化对象private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException;
3. ServletConfig 接口
ServletConfig
接口提供了 Servlet 配置信息的访问方法。具体来说,它允许 Servlet 访问在部署描述符中配置的初始化参数,以及获取与 ServletContext 相关联的配置信息。其常用方法如下:
// 获取 Servlet 的名称public String getServletName();// 获取初始化参数public String getInitParameter(String name);// 获取所有初始化参数的名称public Enumeration<String> getInitParameterNames();// 获取 ServletContextpublic ServletContext getServletContext();
4. GenericServlet 抽象类
GenericServlet
实现了 Servlet
接口,为 Servlet 提供了一些通用的功能,但它本身并不直接处理 HTTP 请求和响应。GenericServlet
的 service()
方法接受通用的 ServletRequest
和 ServletResponse
对象。其常用方法如下:
// 初始化 Servletpublic void init(ServletConfig config) throws ServletException;// 获取 Servlet 的配置信息public ServletConfig getServletConfig();// 获取 Servlet 的名称public String getServletName();// 处理请求public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException;// 销毁 Servletpublic void destroy();// 获取初始化参数public String getInitParameter(String name);// 获取所有初始化参数的名称public Enumeration<String> getInitParameterNames();
5. HttpServlet 抽象类
HttpServlet
继承自 GenericServlet
,专门用于处理 HTTP 请求和响应。HttpServlet
提供了对 HTTP 请求方法的更直接的支持,如 doGet()
、doPost()
等。其常用方法如下:
// 处理 HTTP GET 请求protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException;// 处理 HTTP POST 请求protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException;// 处理 HTTP PUT 请求protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException;// 处理 HTTP DELETE 请求protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException;// 处理 HTTP HEAD 请求protected void doHead(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException;// 处理 HTTP OPTIONS 请求protected void doOptions(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException;// 处理 HTTP TRACE 请求protected void doTrace(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException;// 处理 HTTP PATCH 请求protected void doPatch(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException;// 处理通用的 HTTP 请求protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException;
注意事项:
-
将servlet接口中其他的方法做了默认空实现,只将service()方法作为抽象,将来定义servlet类时,可以继承GenericServlet,实现service()方法即可
-
HttpServlet:对http协议的一种封装,简化操作
-
定义类继承HttpServlet
-
复写doGet/doPost()方法
HTTP_概述
(Hyper Text Tranfer Protocol)超文本传输协议,是一个客户端请求和响应的标准协议,这一协议详细规定了浏览器和万维网服务器之间相互通信的规则。用户输入地址和端口号之后就可以从服务器上获取需要的网页信息。
通信规则规定了客户端发送到服务器的内容格式,也规定了服务器发送给客户端的内容格式。客户端发送给服务器的格式叫做“请求协议(request)”,服务器发送给客户端的格式叫做“响应协议(response)”
传输协议:定义了客户端和服务器端通信时发送数据的格式
浏览器中的书写格式
服务器端资源需要通过浏览器进行,此时浏览器将我们给出的请求解析成满足HTTP协议的格式并发出。我们发出的请求格式需要按照浏览器规定的格式来书写,在浏览器书写格式如下
当浏览器获取到信息时,按照特定格式解析并发送即可,接受到服务器端给出的响应时,也会按照HTTP协议进行解析获取到各个数据,最后按照特定格式展示给用户。
HTTP协议特点
-
基于TCP/IP的高级协议,支持客户端/服务器模式,默认端口号为8080。
-
简单快速:客户向服务器请求服务时,只需传送请求方法和路径,请求方法常用的GET,POST。每种方法规定了客户与服务器联系的类型不同。由于HTTP协议简单,使得HTTP服务器的程序规模小,因而通信速度很快
-
灵活:HTTP允许传输任意类型的数据对象,传输的类型由Content-Type加以标记。
-
无状态的:HTTP协议是无状态协议。无状态是指协议对事务处理没有记忆能力,缺少状态意味着后续处理需要前面的信息,则必须重传,这样可能导致每次连接传送的数据量增大,且每次请求之间相互独立,不能交互数据
-
无连接:无连接是指表示每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用此方式可以节省传输时间。
注:HTTP1.1版本可支持可连续连接,通过这种连接,就有可能再建立一个TCP连接后,发送请求并得到回应,然后发送更多的请求得到更多的回应。通过把建立和释放TCP连接平摊到多个请求上,则对于每个请求而言,由于TCP造成的开销大大降低了,且可以发送流水线请求。也可以认为,一次性接连发送多个请求,有客户机确认是否关闭连接,而服务器会认为这些请求分别来自不同的客户端
一次请求流程
-
客户端(浏览器)与服务器建立连接
-
客户端(浏览器)发送请求数据给服务器。(按照HTTP格式规范)
-
服务器接收到请求数据并进行处理,然后将处理的结果相应给客户端(浏览器)
-
关闭服务器和客户端。
HTTP之URL
URL: Uniform Resource Locator 统一资源定位符
-
表示统一资源定位符,指向万维网上的“资源”的指针。用于区分、定位资源
-
一个标准的URL必须包括:protocol(方案或协议)、host(主机)、port(端口)、path(路径)、parameter( 查询参数)、anchor(锚点)
-
在www上,每一信息资源都有统一且唯一的地址
-
如:
http://www.google.com:80/index.html
,分四部分组成:协议、存放资源的主机域名、端口号、资源文件名
请求消息数据格式
-
请求行
-
请求方式 请求url 请求协议/版本
-
请求方式:
-
HTTP协议中有7种请求方式,常用的有两种
-
GET:请求参数在请求行中,在url后。请求的URL长度有限制。get请求方式相对不太安全
-
POST:请求参数在请求体中,请求的URL长度没有限制。post请求方式相对安全
-
-
-
-
请求头
-
请求头名称:请求头值(键值对)
-
常见的请求头:
-
User-Agent:浏览器告诉服务器,访问的浏览器版本信息
-
user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36 Edg/136.0.0.0
注意事项:可以在服务器端获取该请求头的信息,解决浏览器的兼容性问题
-
Referer:告诉服务器,当前请求从哪里来
-
作用:防止别人盗取链接
-
统计工作
-
-
-
请求体(正文)(POST有请求正文,GET没有)
Connection: keep-alive(可持续连接)
响应消息数据格式
在接受和解释请求信息后,服务器返回一个HTTP响应消息。HTTP响应也是有三个部分组成:
-
状态行
-
请求协议/版本 状态码(200 正常 404 未找到 500 状态错误 307/302 重定向) 状态说明
-
-
消息报头
-
响应头名称:响应头值(键值对)
-
-
消息正文
-
为静态资源代码,也就可以预览
-
消息头
HTTP 消息由客户端到服务器的请求和服务器到客户端的响应组成。
请求消息和响应消息都是由开始行(对于请求消息,开始行就是请求行,对于响应消息,开始行就是状态行),消息报头(可选),空行(只有 CRLF 的行),消息正文(可选)组成。
每一个报头域都是由“名字+":"+空格+值组成,消息报头域的名字是大小写无关的。
请求头
请求报头允许客户端向服务器端传递请求的附加信息以及客户端自身的信息。
-
Referer:该请求头指明请求从哪里来。
如果是地址栏中输入地址访问的都没有该请求头 地址栏输入地址,通过请求可以看到,此时多了一个Referer 的请求头,并且后面的值 为该请求从哪里发出。比如:百度竞价,只能从百度来的才有效果,否则不算;
通常用来做统计工作、防盗链。
响应头
响应报头允许服务器传递不能放在状态行中的附加响应信息,以及关于服务器的信息和 对 Request-URI 所标识的资源进行下一步访问的信息。
Location:Location响应报头域用于重定向,接受者到一个新的位置。
Location响应报头域,常用在更换域名的时候。
response.sendRedirect("http://www.baidu.com");
Refrach·自动跳转(单位是秒) 可以在页面通过meta标签实现,也可在后台实现
-
作用:每隔几秒种刷新页面
-
<meta http-equiv="refresh" content = "3">
-
每隔几秒种跳转页面
<meta http-equiv="refresh" content = "3; url=https://www.baidu.com">
希望对大家有所帮助!