目录
servlet入门
01、概念
-
Servlet:server applet ,运行在服务器端的小应用程序
按照Java EE 规范定义,Servlet是运行在Servlet容器中的Java类,它能处理Web客户的HTTP请求,并产生HTTP响应。例如:当浏览器发送一个请求到服务器后,服务器会把请求交给一个特定的Servlet,该Servlet对请求进行处理后会构造一个合适的响应(通常以HTML网页形式)返回给客户。
Servlet对请求的处理和响应过程可进一步细分为如下几个步骤:
1、接收HTTP请求;
2、取得请求信息,包括请求头和请求参数数据;
3、调用其他Java类方法,完成具体的业务功能;
4、实现到其他Web组件的跳转(包括重定向或请求转发);
5、生成HTTP响应(包括HTML或非HTML响应)。
-
狭义的 Servlet 是指 Java 语言实现的一个接口,定义了java类被服务器识别的规则。广义的 Servlet 是指 任何实现了这个 Servlet 接口的类,一般情况下,人们将 Servlet 理解为后者。
Servlet 运行于支持 Java 的应用服务器中。从原理上讲,Servlet 可以响应任何类型的请求,但绝大多数情况下 Servlet 只用来扩展基于 HTTP 协议的 Web 服 务器
特点:
运行在支持 java 的应用服务器上
Servlet 的实现遵循了服务器能够识别的规则,也就是服务器会自动的根据请求调用对应的 servlet 进行请求处理。简单方便,可移植性强。
02、快速入门
-
创建 JavaEE 项目
-
定义一个类,实现Servlet接口
-
实现接口中的方法
package web.servlet; import javax.servlet.*; import java.io.IOException; public class ServletDemo1 implements Servlet { @Override public void init(ServletConfig servletConfig) throws ServletException { } @Override public ServletConfig getServletConfig() { return null; } @Override public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException { System.out.println("你好!"); } @Override public String getServletInfo() { return null; } @Override public void destroy() { } }
-
配置Servlet
WEB-INF/web.xml中配置。
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1"> <!-- 配置servlet--> <servlet> <servlet-name>demo1</servlet-name> <servlet-class>web.servlet.ServletDemo1</servlet-class> </servlet> <servlet-mapping> <servlet-name>demo1</servlet-name> <url-pattern>/demo1</url-pattern> </servlet-mapping> </web-app>
03、执行原理分析
-
当服务器接收到客户端浏览器的请求后,会解析请求URL路径,获取访问的servlet的资源路径。
-
查找web.xml文件,是否有对应的<url-pattern>标签体内容。
-
如果有,则在找到对应的<servlet-class>全类名。
-
服务器(tomcat)会将字节码文件加载进内存,并且创建其对象。
-
调用其方法。
servlet生命周期
概念
Servlet 程序本身不直接在 Java 虚拟机上运行,而是由 Servlet 容器负责管理其整个生命周期。
Servlet 生命周期是指 Servlet 实例从创建到响应客户请求,直至销毁的过程。
在 Servlet 生命周期中,会经过创建、初始化、服务可用、服务不可用、处理请求、终止服务和销毁 7种状态,
各状态之间的转换:
Servlet 的生命周期按照7种状态间的转换,可分为以下4个阶段:
1、加载和实例化
Servlet 的创建是指加载和实例化两个过程。 Servlet 容器在如下时刻加载和实例化一个Servlet:
(1) 在服务器运行中,客户机首次向Servlet发出请求时;
(2) 重新装入Servlet时(如服务器重新启动、Servlet被修改);
(3) 在为Servlet配置了自动装入选项(load-on-startup)时,服务器在启动时会自动装入此Servlet。2、初始化
Servlet实例化后,Servlet容器将调用Servlet的 init(ServletConfig config)方法来对Servlet实例进行初始化。
<--
(在这一过程中,可以读取一些固定的数据、初始化JDBC的连接以及建立与其他资源的连接等操作。)
-->
init()方法的参数ServletConfig对象由Servlet容器创建并传递给Servlet,并在初始化完成后一直在内存中存在,直到Servlet被销毁。
<--
如果初始化没有问题,Servlet在Web容器中会处于服务可用状态;
如果初始化失败,Servlet容器会从运行环境中清除掉该实例。
当Servlet运行出现异常时,Servlet容器会使该实例变为服务不可用状态。
(Web程序维护人员可以设置Servlet,使其成为服务不可用状态,或者从服务不可用状态恢复成服务可用状态。)
-->3、处理请求
服务器接收到客户端请求,会为该请求创建一个“请求”对象和一个“响应”对象并调用service()方法,service()方法再调用其他方法来处理请求。
在Servlet生命周期中,service()方法可能被多次调用。
当多个客户端同时访问某个Servlet的service()方法时,服务器会为每个请求创建一个线程,这样可以并行处理多个请求,减少请求处理的等待时间,提高服务器的响应速度。但同时也要注意对同一对象的并发访问问题。4、销毁
当Servlet容器需要终止Servlet(例如Web服务器即将被关掉或需要出让资源),它会先调用Servlet的destroy()方法使其释放正在使用的资源。
在Servlet容器调用destroy()方法之前,必须让当前正在执行service()方法的任何线程完成执行,或者超过了服务器定义的时间限制。
在destroy()方法完成后,Servlet容器必须释放Servlet实例以便被垃圾回收。
在一个请求到来时,Servlet生命周期的时序图:
时序图的处理过程如下:
(1) 客户端发送请求至Servlet容器;
(2) Servlet容器对请求信息进行解析;
(3) Servlet容器根据请求目标创建Servlet实例;
(4) Servlet容器调用Servlet实例的init()方法对其进行初始化;
(5) Servlet容器为该请求创建“请求”和“响应”对象作为参数传递给service()方法;
(6) service()方法在对请求信息进行处理后,将结果转给Servlet容器;
(7) Servlet容器将结果信息响应给客户端;
(8) 当Servlet容器需要终止Servlet时,将调用其destroy()方法使其终止服务并将其销毁。
生命周期方法代码:
package web.servlet;
import javax.servlet.*;
import java.io.IOException;
public class ServletDemo2 implements Servlet {
/**
* 初始化方法
* 在servlet被创建时执行,只执行一次
* @param servletConfig
* @throws ServletException
*/
@Override
public void init(ServletConfig servletConfig) throws ServletException {
System.out.println("初始化...");
}
@Override
public ServletConfig getServletConfig() {
return null;
}
/**
* 提供服务的方法
* 每次servlet被访问时执行,可执行多次
* @param servletRequest
* @param servletResponse
* @throws ServletException
* @throws IOException
*/
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("service方法");
}
@Override
public String getServletInfo() {
return null;
}
/**
* 销毁方法
* 在服务器正常关闭时执行,执行一次
*/
@Override
public void destroy() {
System.out.println("destroy方法");
}
}
简单小结:
Servlet中的生命周期方法:
1、被创建:执行init方法,只能被Servlet容器调用1次
-
默认情况下,第一次被访问时创建。
-
可以配置Servlet的创建时机。
在web.xml中,<servlet>标签下配置
-
第一次被访问时创建
<load-on-startup>值</load-on-startup> 值为负数
-
服务器启动时创建
<load-on-startup>值</load-on-startup> 值为0或正整数
-
-
Servlet的init方法只执行一次,说明一个Servlet在内存中只存在一个对象,Servlet是单例的
-
多个用户同时访问时,可能存在线程安全问题。
-
解决:尽量不要在Servlet中定义成员变量。即使定义了,也不要对其修改值。
-
2、提供服务:执行service方法,可被多次调用
-
每次访问Servlet时,service方法都会被调用1次
3、被销毁:执行destroy方法,只被调用1次
-
Servlet被销毁时执行。服务器关闭时,servlet被销毁。
-
只有服务器正常关闭时,才会执行destroy方法
-
destroy方法在Servlet被销毁之前执行,一般用于释放资源。
注解配置
Servlet 3.0 支持注解配置。(可以不创建web.xml)。
在类上使用 @WebServlet 注解进行配置。
@WebServlet("资源路径url")
@WebServlet注解:
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
package javax.servlet.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface WebServlet {
String name() default "";
String[] value() default {};
String[] urlPatterns() default {};
int loadOnStartup() default -1;
WebInitParam[] initParams() default {};
boolean asyncSupported() default false;
String smallIcon() default "";
String largeIcon() default "";
String description() default "";
String displayName() default "";
}
补充:
-
IDEA会为每一个tomcat部署的项目单独建立一份配置文件,
查看控制台的log : using CATALINA_BASE:" 配置文件位置 ",看到配置文件的位置。
-
WEB-INF目录下的资源不能被浏览器直接访问。
Servlet的继承体系结构
Servlet -- 接口
|
GenericServlet -- 抽象类
|
HttpServlet -- 抽象类
-
GenericServlet:将Servlet接口中其他的方法做了默认空实现,只将service()方法作为抽象方法。
-
HttpServlet:对http协议的一种封装,简化操作。(对请求方式做了判断)。
-
定义类继承HttpServlet,复写doGet/doPost方法。
-
Servlet的相关配置
urlPattern:Servlet访问路径
-
一个Servlet可以定义多个访问路径。@WebServlet({" /1","/2"})
-
路径定义规则:
-
/xxx
-
/xxx/xxx 或 /xxx/* :多层路径,目录结构。 /xxx/*形式,浏览器可以只输入 /xxx或 /xxx/。
-
/* :判断优先级比较低,输入路径是其它Servlet则访问其它Servlet。
-
*.do 这个前面不加"/"
-
好的,HTTP协议、相关核心接口的笔记写在同一专栏其他文章里。