狭义的Servlet是指Java语言中的一个接口,广义的Servlet是指任何实现了这个Servlet接口的类,一般情况下,人们将Servlet理解为后者。
Servlet
事实上,Servlet就是一个Java中的接口,里面有5个方法:
// 负责Servlet初始化工作,容器在创建好Servlet对象之后,就会调用此方法,该方法接收一个ServletConfig类型的参数,Servlet容器通过这个参数,向Servlet传递初始化配置信息
void init(ServletConfig config)
// 返回容器调用init(ServletConfig config)方法时,传递给Servlet的ServletConfig对象
ServletConfig getServlet(getServletConfig)
// 返回一个字符串,其中包含关于Servlet的信息,比如,作者、版本和版权等信息
String getServletInfo()
// 负责响应用户的请求,当容器接收到客户端访问Servlet对象的请求时,就会调用此方法,容器会构造一个标识客户端请求信息的ServletRequest对象,与一个用于响应客户端的ServletResponse对象,作为参数传递给service()方法,在service()方法中,可以通过ServletRequest对象得到客户端的相关信息和请求信息,在对请求进行处理之后,调用ServletResponse对象的方法设置响应信息
void service(ServletRequest request,ServletResponse response)
// 赋值释放Servlet对象占用的资源,当Servlet对象被销毁时,容器会调用此方法
void destroy()
那 Servlet是干嘛的?很简单,接口的作用是什么?规范呗!
Servlet接口定义的是一套处理网络请求的规范,所有实现Servlet的类,都需要实现这个接口的五个方法,其中最主要的是两个生命周期方法 init()和destroy(),还有一个处理请求的service(),也就是说,所有实现servlet接口的类,或者说,所有想要处理网络请求的类,都需要回答这三个问题:
- 你初始化时要做什么
- 你销毁时要做什么
- 你接受到请求时要做什么
既然,Servlet是一个规范,那实现了 Servlet 的类,就能处理请求了吗?
答案是,不能。
你可以随便谷歌一个Servlet的hello world教程,里面都会让你写一个Servlet,相信我,你从来不会在Servlet中写什么监听8080端口的代码,Servlet不会直接和客户端打交道!
那请求怎么来到Servlet呢?答案是Servlet容器(Servlet Container),比如我们最常用的Apache Tomcat。
同样,你可以随便谷歌一个Servlet的hello world教程,里面肯定会让你把Servlet部署到一个容器中,不然你的Servlet压根不会起作用。
Tomcat才是与客户端直接打交道的家伙,他监听了端口,请求过来后,根据url等信息,确定要将请求交给哪个Servlet去处理,然后调用那个Servlet的service方法,service方法返回一个response对象,Tomcat再把这个response返回给客户端。
等Spring家族出现后,Servlet开始退居幕后,取而代之的是方便的SpringMVC。SpringMVC的核心组件DispatcherServlet其实本质就是一个Servlet。但它已经自立门户,在原来HttpServlet的基础上,又封装了一条逻辑。
Web container(Servlet container)
As we see here, the user/client can only request static webpage from the server. This is not good enough, if the user wants to read the web page based on his input. The basic idea of Servlet container is using Java to dynamically generate the web page on the server side. So servlet container is essentially a part of a web server that interacts with the servlets.
在JSP技术推出后,管理和运行Servlet和JSP的容器也称为Web container(Web容器)。
First Servlet
// importing the javax.servlet package
// importing java.io package for PrintWriter
import javax.servlet.*;
import java.io.*;
// now creating a servlet by implementing Servlet interface
public class LifeCycleServlet implements Servlet {
ServletConfig config = null;
// init method
public void init(ServletConfig sc)
{
config = sc;
System.out.println("in init");
}
// service method
public void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException
{
res.setContenttype("text/html");
PrintWriter pw = res.getWriter();
pw.println("<h2>hello from life cycle servlet</h2>");
System.out.println("in service");
}
// destroy method
public void destroy()
{
System.out.println("in destroy");
}
public String getServletInfo()
{
return "LifeCycleServlet";
}
public ServletConfig getServletConfig()
{
return config; // getServletConfig
}
}
JSP
由于Servlet并不擅长往浏览器输出HTML页面,所以出现了JSP。
JSP将Java代码和特定变动内容嵌入到静态的页面中,实现以静态页面为模板,动态生成其中的部分内容。JSP引入了被称为“JSP动作”的XML标签,用来调用内建功能。
与 JSP 的关系
Java服务器页面(JSP)是HttpServlet的扩展。由于HttpServlet大多是用来响应HTTP请求,并返回Web页面(例如HTML、XML),所以不可避免地,在编写servlet时会涉及大量的HTML内容,这给servlet的书写效率和可读性带来很大障碍,JSP便是在这个基础上产生的。其功能是使用HTML的书写格式,在适当的地方加入Java代码片段,将程序员从复杂的HTML中解放出来,更专注于servlet本身的内容。
Reference
- https://en.wikipedia.org/wiki/Java_servlet
- https://en.wikipedia.org/wiki/JSP
- https://docs.oracle.com/cd/E14571_01/web.1111/e13712/basics.htm#WBAPP130
- https://www.geeksforgeeks.org/starting-first-servlet-application/
- https://dzone.com/articles/what-servlet-container
- servlet的本质是什么,它是如何工作的? - https://www.zhihu.com/question/21416727
- https://blog.csdn.net/weixin_43869318/article/details/94054315
- https://www.zhihu.com/question/19998865/answer/29395327
- https://confluence.shopee.io/display/LABS/1.1+Life+cycle+of+a+page+load