Servlet顾名思义,服务器端应用程序,HttpServlet是用来处理基于Http的请求的服务器端程序,现在大部分请求都是基于Http的;
HttpServlet是一个继承自Servlet的抽象类HttpServlet API,继承自该类的subclass子类必须实现如下至少一个抽象方法
A subclass of HttpServlet must override at least one method, usually one of these:
doGet, if the servlet supports HTTP GET requests
doPost, for HTTP POST requests
doPut, for HTTP PUT requests
doDelete, for HTTP DELETE requests
init and destroy, to manage resources that are held for the life of the servlet
getServletInfo, which the servlet uses to provide information about itself
那HttpServlet与Servlet Container的关系如何?后者是应用服务器,用来盛放HttpServlet应用程序的,如Tomcat,那处理一个请求并返回数据的过程是怎样的呢?
1、Web客户端向Servlet容器发送请求
2、容器解析http请求并封装成HttpServletRequest对象,同时创建一个HttpServletReponse对象
3、Servlet 容器调用HttpServlet的service()方法来接受HttpServletRequest和HttpServletReponse对象,
4、HttpServlet读取HttpServletRequest对象中的请求方法,从而确定调用doGet()\doPost….方法
5、经HttpServlet的相关处理产生相应数据,调用HttpServletReponse对象的方法从而把数据封装到HttpServletReponse对象中
6、Servlet容器把HttpServlet的响应结果返回给客户
总的来说,就是Servlet Container 存放Servlet应用程序,并把request封装成HttpServletRequest和HttpServletReponse一起传递给HttpServlet做详细处理,并把返回的HttpServletReponse返回给客户端
这里有一个疑问就是HttpServlet是一个抽象类,具体项目的Servlet继承该抽象类,并重写一系列方法,那什么时候override service()方法呢?
这里有两个service()方法,
void service(ServletRequest req, ServletResponse res)————
Dispatches client requests to the protected service method.
protected void service(HttpServletRequest req, HttpServletResponse resp)---
Receives standard HTTP requests from the public service method and dispatches them to the doXXX methods defined in this class.
第一个方法接受的是ServletRequest 和ServletResponse参数,这个方法里可以判断request和reponse是否为HttpServletRequest和
HttpServletResponse类型的,不是的话则抛错,是的话则调用第二个service()方法并把参数也传给它;第二个service()主要就是接受请求并转发给具体的处理方法:doGet() or doPost or other ???
如下这个栗子(stackoverflow)
@Override
public void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException
{
HttpServletRequest request;
HttpServletResponse response;
if (!(req instanceof HttpServletRequest &&
res instanceof HttpServletResponse)) {
throw new ServletException("non-HTTP request or response");
}
request = (HttpServletRequest) req;
response = (HttpServletResponse) res;
service(request, response);
}
[...]
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException
{
String method = req.getMethod();
if (method.equals(METHOD_GET)) {
long lastModified = getLastModified(req);
if (lastModified == -1) {
// servlet doesn't support if-modified-since, no reason
// to go through further expensive logic
doGet(req, resp);
} else {
long ifModifiedSince = req.getDateHeader(HEADER_IFMODSINCE);
if (ifModifiedSince < lastModified) {
// If the servlet mod time is later, call doGet()
// Round down to the nearest second for a proper compare
// A ifModifiedSince of -1 will always be less
maybeSetLastModified(resp, lastModified);
doGet(req, resp);
} else {
resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
}
}
} else if (method.equals(METHOD_HEAD)) {
long lastModified = getLastModified(req);
maybeSetLastModified(resp, lastModified);
doHead(req, resp);
} else if (method.equals(METHOD_POST)) {
doPost(req, resp);
} else if (method.equals(METHOD_PUT)) {
doPut(req, resp);
} else if (method.equals(METHOD_DELETE)) {
doDelete(req, resp);
} else if (method.equals(METHOD_OPTIONS)) {
doOptions(req,resp);
} else if (method.equals(METHOD_TRACE)) {
doTrace(req,resp);
} else {
//
// Note that this means NO servlet supports whatever
// method was requested, anywhere on this server.
//
String errMsg = lStrings.getString("http.method_not_implemented");
Object[] errArgs = new Object[1];
errArgs[0] = method;
errMsg = MessageFormat.format(errMsg, errArgs);
resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED, errMsg);
}
}