学习Servlet能帮助我们更好地理解MVC框架到底帮助我们做了什么,就像Hibernate和Mybatis这样的持久层框架封装了JDBC一样,Struts和SpringMVC封装了Servlet。所谓框架,就是将一些通用的功能组装在一起,留出接口以调用,省去我们每次都需要实现一遍通用功能的麻烦。那么现在,要搞懂SpringMVC的工作原理,就先要知道Servlet的工作过程。
Servlet是什么
Servlet代表Server Applet,意思是服务器端小程序。而同时你也可以抽象地理解为一些遵从Java Servlet API的Java类。狭义上,Servlet是一个接口,广义上,任何实现了Servlet接口的类都可以被称为Servlet。
HttpServlet继承GenericServlet抽象类,而GenericServlet实现Servlet接口。Servlet接口定义了五个方法,分别是:
- init(ServletConfig) : void
- getServlet() : ServletConfig
- service(ServletRequest, ServletResponse) : void
- getServletInfo() : String
- destroy() : void
Servlet可以响应任何请求,但最主要的应用还是响应HTTP请求。先看第一个简单的示例。
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class HelloServlet extends HttpServlet {
private static final long serialVersionUID = -4739360880971235479L;
public HelloServlet() {
super();
}
public void destroy() {
super.destroy(); // Just puts "destroy" string in log
// Put your code here
}
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
}
public void init() throws ServletException {
// Put your code here
}
}
这是以前写过的一个示例,我将doGet和doPost中的代码都删除了,一般都是重写这两个方法完成自己的需要。在一个Servlet中,最重要的三个方法分别是init、service和destroy。上面代码没有写出service是因为一般我们不需要重写HttpServlet中的service方法。值得一提的是,在HttpServlet中,有两个service方法:一个是public修饰的service(ServletRequest, ServletResponse),其作用是接收客户端请求,将ServletRequest和ServletResponse转换为HttpServletRequest和将HttpServletResponse,并转发给另外一个service;另一个是protected修饰的service(HttpServletRequest, HttpServletResponse),这里则是调用相应的方法去处理请求。
因为Servlet只能在Servlet容器中运行,如Tomcat,在完成了自己定义的Servlet类之后,需要将此Servlet注册到Servlet容器中。通常的做法是在项目的web.xml文件中定义,示例如下:
<servlet>
<servlet-name>HelloServlet</servlet-name>
<servlet-class>com.servlets.HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>HelloServlet</servlet-name>
<url-pattern>/HelloServlet</url-pattern>
</servlet-mapping>
当然还可以通过@webServlet注解去在Servlet类上注册Servlet,示例如下:
@WebServlet(name = "HelloServlet", urlPatterns = {"/HelloServlet"})
public class HelloServlet extends HttpServlet {...}
Servlet生命周期
Servlet从初始化到销毁包含三个核心的方法:init、service和destroy。
Servlet初始化阶段,Servlet容器会根据web.xml中的定义来初始化Servlet,
Servlet初始化之后,Servlet容器就可以调用实例中的service()方法处理相应的请求了。
在最后,Servlet容器在重新启动或者关闭时会调用destroy()方法来销毁Servlet实例,释放相应的资源。
具体的过程以后学习并记录,先记录一个请求发送到Servlet容器并处理返回的流程示意图。
- Web客户向Servlet容器发出Http请求;
- Servlet容器解析Web客户的Http请求;
- Servlet容器创建一个HttpRequest对象,在这个对象中封装Http请求信息;
- Servlet容器创建一个HttpResponse对象;
- Servlet容器调用HttpServlet的service方法,把HttpRequest和HttpResponse对象作为service方法的参数传给HttpServlet对象;
- HttpServlet调用HttpRequest的有关方法,获取HTTP请求信息;
- HttpServlet调用HttpResponse的有关方法,生成响应数据;
- Servlet容器把HttpServlet的响应结果传给Web客户。