目录
servlet的概念:
Servlet(Server Applet)是Java Servlet的简称,称为小服务程序或服务连接器,用Java编写的服务器端程序,具有独立于平台和协议的特性,主要功能在于交互式地浏览和生成数据,生成动态Web内容。狭义的Servlet是指Java语言实现的一个接口,广义的Servlet是指任何实现了这个Servlet接口的类,一般情况下,人们将Servlet理解为后者。Servlet运行于支持Java的应用服务器中。从原理上讲,Servlet可以响应任何类型的请求,但绝大多数情况下Servlet只用来扩展基于HTTP协议的Web服务器。最早支持Servlet标准的是JavaSoft的Java Web Server,此后,一些其它的基于Java的Web服务器开始支持标准的Servlet。
servlet 是运行在 Web 服务器中的小型 Java 程序(即:服务器端的小应用程序)。servlet 通常通过 HTTP(超文本传输协议)接收和响应来自 Web 客户端的请求。servlet实例是由web服务器(tomcat)创建的,它是单例多线程的。单例是指servlet的实例只有一个,多线程是指每次客户端的请求,web服务器都会从线程池中分配一个工作线程去执行servlet的service()方法,编写servlet程序一共有三种方式。
Servlet的体系结构
Servlet -- 接口
GenericServlet -- 抽象类
HttpServlet -- 抽象类
GenericServlet:将Servlet接口中其他的方法做了默认空实现,只将service()方法作为抽象
将来定义Servlet类时,可以继承GenericServlet,实现service()方法即可
*HttpServlet:对http协议的一种封装,简化操作
1. 定义类继承HttpServlet
2. 复写doGet/doPost方法
Servlet相关配置
1. urlpartten:Servlet访问路径
1. 一个Servlet可以定义多个访问路径 : @WebServlet({"/d4","/dd4","/ddd4"})
2. 路径定义规则:
1. /xxx:路径匹配
2. /xxx/xxx:多层路径,目录结构
3. *.do:扩展名匹配
Serlet在idea配置
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
id="WebApp_ID" version="3.0">
<display-name>test</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<!-- 配置servlet -->
<servlet>
<servlet-name>ServletTest</servlet-name>
<servlet-class>com.neu.servlet.ServletTest</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ServletTest</servlet-name>
<url-pattern>/s1</url-pattern>
</servlet-mapping>
</web-app>
<servlet-name>是指servlet的名称,<servlet>标签和<servlet-mapping>标签中的<servlet-name>必须一致。<servlet-class>是当前servlet的全限定类名,<url-pattern>是映射servlet的url,例如我们要想访问这个ServletTest这个servlet,浏览器输入http://localhost:8080/test/s1即可,/一定不能省略。
private ServletConfig config;
//初始化开始的时候调用
@Override
public void init(ServletConfig servletConfig) throws ServletException {
this.config=servletConfig;
}
@Override
public ServletConfig getServletConfig() {
return config;
}
//每被访问调用
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
//根据请求方式不同,进行分别处理
HttpServletRequest request = (HttpServletRequest) servletRequest;
//1.获取请求方式
String method = request.getMethod();
//2.判断
if ("GET".equals(method)){
//成功则运行什么
}else if ("POST".equals(method)){
//失败则运行什么
}
}
@Override
public String getServletInfo() {
return null;
}
//销毁,关闭服务器调用
@Override
public void destroy() {
}
servlet的生命周期
1.执行流程:
当一个客户端请求过来的时候,tomcat服务器首先解析这个url,首先找到对应的应用app,然后根据/xxx去web.xml中根据配置信息去找对应的servlet,找到对应的servlet后去创建servlet实例,然后执行init()方法,service()方法,然后响应客户端。当应用卸载的时候,会销毁这个servlet,执行destory()方法。
2.声明周期:
实例化-----初始化-----服务-----销毁,因为servlet是单例多线程的,所以实例化,初始化和销毁只执行一次。服务方法会多次执行,每次请求过来的时候,如果servlet已经被实例化过,那么web服务器直接分配一个工作线程去处理这个请求(调用service方法执行),所以实例化和初始化只会在第一次请求过来的时候执行。如果我们在servlet类中定义成员变量,并在service()方法中使用的话,就会出现线程安全问题,因为servlet实例只有一份,多个线程共享这个实例的成员变量,如果都执行写操作,必然会导致错误的结果。所以我们不要在servlet中定义成员变量,而是在方法中定义局部变量。因为每个方法都是在虚拟机栈(或者本地方法栈)中执行,是线程独立的,所以不存在线程安全问题。下面直接看代码吧,这样对servlet的生命周期和单例理解的更加深刻些。我们还是以最原始的实现servlet接口的方式: