Java Web入门之 Servlet
在学习java web 的时候,我最开始接触的servlet,那时候做一个页面上扫雷的游戏,页面是jsp写的,那会也不知道servlet是干嘛用的,只是知道是用来处理请求用的,还要把编写好的servlet配置在web.xml里。把每个请求都按照servlet的格式来写,回想起来也是醉了,废话少说,看看servlet源码。
一、Servlet相关依赖及实现
servle接口如下:
public interface Servlet {
void init(ServletConfig var1) throws ServletException;
ServletConfig getServletConfig();
void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException;
String getServletInfo();
void destroy();
}
相关依赖图如下:
查看源码得知,servlet中service的实现不是在GenericServlet中,而是在它的子类,代码如下:
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String method = req.getMethod();
long lastModified;
if (method.equals("GET")) {
lastModified = this.getLastModified(req);
if (lastModified == -1L) {
this.doGet(req, resp);
} else {
long ifModifiedSince;
try {
ifModifiedSince = req.getDateHeader("If-Modified-Since");
} catch (IllegalArgumentException var9) {
ifModifiedSince = -1L;
}
if (ifModifiedSince < lastModified / 1000L * 1000L) {
this.maybeSetLastModified(resp, lastModified);
this.doGet(req, resp);
} else {
resp.setStatus(304);
}
}
} else if (method.equals("HEAD")) {
lastModified = this.getLastModified(req);
this.maybeSetLastModified(resp, lastModified);
this.doHead(req, resp);
} else if (method.equals("POST")) {
this.doPost(req, resp);
} else if (method.equals("PUT")) {
this.doPut(req, resp);
} else if (method.equals("DELETE")) {
this.doDelete(req, resp);
} else if (method.equals("OPTIONS")) {
this.doOptions(req, resp);
} else if (method.equals("TRACE")) {
this.doTrace(req, resp);
} else {
String errMsg = lStrings.getString("http.method_not_implemented");
Object[] errArgs = new Object[]{method};
errMsg = MessageFormat.format(errMsg, errArgs);
resp.sendError(501, errMsg);
}
}
我们一般重写doGet()和doPost(),基本上就能满足我们的需求。
二、Servlet 执行过程
servlet的执行要依赖servlet容器,例如Tomcat 、WebLogic等。执行过程如下图:
简单说明:
1.浏览器发送请求到服务器。
2.服务器收到请求,根据请求路径判断为Servlet请求,此时容器将产生两个对象:请求对象(HttpServletRequest)和响应对象(HttpServletResponce)。
3.容器根据路径匹配到对应的Servlet,且创建一个线程。
4.将刚才创建的请求对象和响应对象传递给线程。
5.调用Servlet的service()方法。
6.service()方法根据请求类型调用doGet()或doPost()方法。
7.处理完逻辑后,将结果返回给容器逻辑组件,继而返回到用户的浏览器。
8.线程被销毁或被放在线程池中。
注意:
1.每个servlet原则上只有一个是实例,每一个servlet请求对应一个线程。
2.多个线程访问同一个Servlet会造成线程不安全。
3.每个线程处理完之后,就被销毁或放在线程池中等待回收。
三、Servlet 生命周期
Servlet生命周期可以定义为创建直到消亡的过程。
1)容器先加载Servlet类。
2)容器实例化Servlet,调用无参构造器。
3)执行init()方法,只执行一次。
4)调用service()方法,处理客户请求,间接调用doPost()或doGet()。
5)执行destroy(),销毁线程。