Servlet是运行在web服务器端的java程序,可以生成动态的web页面,属于客户与服务器响应的中间层。实际上jsp的底层就是servle。学习它有助于了解底层的细节,毕竟servlet是一个java类。常见的servlet的写法有两种,一种就是extends HttpServlet;另一种是覆盖原有的service方法。在servlet中默认情况下,无论你是get还是post 提交过来 都会经过service()方法来处理,然后转向到doGet或是doPost方法,
原代码:
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException
{
String method = req.getMethod();
if(method.equals("GET"))
{
long lastModified = getLastModified(req);
if(lastModified == -1L)
{
doGet(req, resp);
} else
{
long ifModifiedSince = req.getDateHeader("If-Modified-Since");
if(ifModifiedSince < (lastModified / 1000L) * 1000L)
{
maybeSetLastModified(resp, lastModified);
doGet(req, resp);
} else
{
resp.setStatus(304);
}
}
} else
if(method.equals("HEAD"))
{
long lastModified = getLastModified(req);
maybeSetLastModified(resp, lastModified);
doHead(req, resp);
} else
if(method.equals("POST"))
doPost(req, resp);
else
if(method.equals("PUT"))
doPut(req, resp);
else
if(method.equals("DELETE"))
doDelete(req, resp);
else
if(method.equals("OPTIONS"))
doOptions(req, resp);
else
if(method.equals("TRACE"))
{
doTrace(req, resp);
} else
{
String errMsg = lStrings.getString("http.method_not_implemented");
Object errArgs[] = new Object[1];
errArgs[0] = method;
errMsg = MessageFormat.format(errMsg, errArgs);
resp.sendError(501, errMsg);
}
}
由源代码可以看出service只是用来转向,但如果servlet类中覆盖了service方法,比如:
public class HelloServlet extends HttpServlet{
public void service(HttpServletRequest request,HttpServletResponse response)
throws ServletException,IOException{
//设置一个消息头,告诉客户端(即浏览器)服务器
//返回的数据类型。
response.setContentType("text/html");
//通过response获得输出流。
PrintWriter out = response.getWriter();
out.println(
"<div style='color:red;font-size:30px;'>" +
"Hello World</div>");
out.close();
}
}
这时service用来做业务处理,不论客户端是用pos还是get来请求此servlet都会执行service方法也只能执行servlet方法,不会去执行doPost或是doGet方法。
那么一次http请求,servlet内部是怎么处理并执行的呢?看下面这张图:
画的很抽象是吧,凑合看吧!不过挺有手感的。这就是servlet执行的全过程。
事实上,客户端对servlet发送一个请求,服务器就会开启一个线程,该线程会调用service方法,service方法会根据就收到的客户端的请求类型来决定是调用doGet还是doPost。
servlet的生命周期如下图:
这张看着还舒服点,当客户端向web服务器发送第一次servlet请求时,web服务器会实例化一个servlet,并调用init()方法;如果web服务器已经存在一个servlet实例,将直接调用次实例;然后调用service()方法,service()方法将根据客户端的请求方式来决定调用对应的doXXX方法;当servlet从web武器中消亡时,web服务器会调用servlet的destroy()方法。
待续...