一、什么是Servlet
1、什么是Servlet?
维基百科上有写:Java Servlet 是Java编写的服务器端程序,其主要功能在于交互式地浏览和修改数据,生成动态Web内容。Servlet是是不能够独立运行的,Servlet运行在Web容器里面。(什么是Web容器?Web容器是一个特殊的JVM,它负责维护Servlet的生命周期及为每个请求生成线程)
2、Servlet有什么用?
Servlet承担的功能可以理解为三点:1)接收客户端的请求;2)自己处理或者调用逻辑层的API处理请求;3)处理结果返回应答给客户端。
3、请求/应答模式(最常用的是基于HTTP 协议传输)
注意几点:
1)大多数的传输是基于HTTP协议的;
2)一次HTTP调用是指一个请求和应答来回;
3)HTTP协议是面向连接的;(即,经过一次调用后会断开(节省资源,但延长时间),现在也有长连接(能缩短响应时间))
4)HTTP协议是无状态的。(即,服务器答应后不再保留客户端信息)
二、Servlet主要API
ServletAPI主要在javax.servlet包里面:
关于Servlet的的主要API,这里主要是思考一下它的设计思路,以下是三个问题:1)三个接口的来源;2)什么时候使用抽象类;3)为什么抽象类分为了两层?下面逐一分析:
1、三个接口的来源:Servlet接口,原理上只要实现了这一个接口就可以建立一个Servlet类,但是这样的话里面有一些方法就要自己去实现了;ServletRequest接口,用来接受请求内容;ServletResponse接口,用来返回应答给客户端。
2、什么时候使用抽象类:抽象类和接口的区别在于抽象类可以定义实现一些方法的同时又可以对其子类进行约束。也就是在上图中的抽象方法可以实现接口的部分方法,对于不能实现的又可以以抽象方法的形式对其子类进行约束,让其子类实现其还没有实现的方法。
3、为什么抽象类分开为两层:便于扩展,因为这里的设计思路是先建立一个原型的抽象Servlet类,原型Serrvlet之后可以依据不同的通讯协议再建立一个基于某一个协议的Servlet抽象类,例如这里的是Http协议的Servlet抽象类,如果以后有扩展可以继承原型抽象类建立另一个协议的Servlet抽象类。
三、搭建ServletDemo
(一)、web应用的基本结构:
—WEB-INF
— —web.xml(部署描述文件,项目必备,web服务器对项目解析时首先读取该文件)
— —classes(用来存放程序的字节码文件)
— —lib(用于存放程序执行需要的jar包)
(二)、Servlet
1、DemoServlet.java
1 package com.kwan.web.servlet; 2 3 import java.io.IOException; 4 import java.io.PrintWriter; 5 6 import javax.servlet.ServletException; 7 import javax.servlet.http.HttpServlet; 8 import javax.servlet.http.HttpServletRequest; 9 import javax.servlet.http.HttpServletResponse; 10 11 public class DemoServlet extends HttpServlet { 12 13 private int initCounter = 0; 14 private int doCounter = 0; 15 private int serviceCounter = 0; 16 private int destroyCounter = 0; 17 private String str = ""; 18 19 @Override 20 protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 21 doPost(req, resp); 22 } 23 24 @Override 25 protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 26 System.out.println("-----doGet or doPost-----"); 27 doCounter++; 28 PrintWriter pw = resp.getWriter(); 29 str += "Thank you! " + doCounter + "\n"; 30 pw.write(str); 31 pw.close(); 32 } 33 34 @Override 35 protected void service(HttpServletRequest arg0, HttpServletResponse arg1) throws ServletException, IOException { 36 System.out.println("-----service-----"); 37 serviceCounter++; 38 super.service(arg0, arg1); 39 } 40 41 @Override 42 public void destroy() { 43 System.out.println("-----destroy-----"); 44 destroyCounter++; 45 System.out.println("-----end-----"); 46 System.out.println("initCounter="+initCounter); 47 System.out.println("serviceCounter="+serviceCounter); 48 System.out.println("doCounter="+doCounter); 49 System.out.println("destroyCounter="+destroyCounter); 50 } 51 52 @Override 53 public void init() throws ServletException { 54 System.out.println("-----init-----"); 55 initCounter++; 56 } 57 58 }
2、web.xml
1 <?xml version="1.0" encoding="ISO-8859-1"?> 2 3 <web-app xmlns="http://java.sun.com/xml/ns/javaee" 4 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 5 xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 6 http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" 7 version="3.0" 8 metadata-complete="true"> 9 10 <servlet> 11 <servlet-name>DemoServlet</servlet-name> 12 <servlet-class>com.kwan.web.servlet.DemoServlet</servlet-class> 13 </servlet> 14 15 <servlet-mapping> 16 <servlet-name>DemoServlet</servlet-name> 17 <url-pattern>/demo</url-pattern> 18 </servlet-mapping> 19 20 </web-app>
3、index.html
1 <html> 2 <body> 3 <form method="post" action="/DemoServlet/demo"> 4 <input type="submit"></input> 5 </form> 6 <body> 7 </html>
四、Servlet的生命周期
上面的小例子运行后,点击五次submit之后再退出会看到下面的显示结果:
这里只是说明Servlet生命周期中的三个回调方法:init、destroy、service,这三个方法是由web容器调用,而非servlet类调用,而且init和destroy方法只会调用一次。
Servlet的生命周期是这样的:
1)web容器加载servlet类,在接收请求时检查实例池是否存在servlet类,若不存在则实例化并调用init方法初始花servlet实例;
2)web容器接受请求时,调用service方法,在service方法里面可以调用各种方法来处理这些请求;
3)当servlet实例要销毁前,web容器会调用destroy方法,这个方法可以用来在实例销毁前做一些保留信息的工作。
五、参考资料
2、Java私塾