一个http请求过来之后,tomcat的核心组件之一connector会接受这个请求,并从输入流InputStream中获取参数的信息,接受页面上的request,response对象,并封装成httprequest和httpresponse对象,然后会产生一个线程来处理这个请求并把产生的 Request 和 Response 对象传给处理这个请求的线程,处理这个请求的线程就是tomcat的另一核心组件 Container 要做的事了。
container接到这个请求后,会依次创建并链式调用engine--host--context--wrapper,其中wrapper是servlet在tomcat中封装形式,这样一次 Request 请求达到最终的 Wrapper 容器,我们现正知道了请求是如何达到正确的 Wrapper 容器,但是请求到达最终的 Servlet 还要完成一些步骤,必须要执行 Filter 链,以及要通知你在 web.xml 中定义的 listener,并根据http中的请求,从mapper(tomcat启动时会从配置文件中读取所有的servlet的配置信息)中找到对应的servlet,之后就加载实例化这个servlet并将其初始化,代码如下:
从上面的代码可以看出实例化一个servlet之后会调用servlet的service方法,下面再看看在service方法中做了什么处理(假定我们自己写的servlet继承自httpServlet)
这段代码很明确的告诉我们,在servlet的service方法中会根据你页面上写的mothod方法去调用相应的doGet(.,.),doPost(.,.)等方法,也就是我们自己在servlet中自己写的业务逻辑。
container接到这个请求后,会依次创建并链式调用engine--host--context--wrapper,其中wrapper是servlet在tomcat中封装形式,这样一次 Request 请求达到最终的 Wrapper 容器,我们现正知道了请求是如何达到正确的 Wrapper 容器,但是请求到达最终的 Servlet 还要完成一些步骤,必须要执行 Filter 链,以及要通知你在 web.xml 中定义的 listener,并根据http中的请求,从mapper(tomcat启动时会从配置文件中读取所有的servlet的配置信息)中找到对应的servlet,之后就加载实例化这个servlet并将其初始化,代码如下:
public synchronized Servlet loadServlet() throws ServletException {
………
Servlet servlet;
try {
………
ClassLoader classLoader = loader.getClassLoader();
………
Class classClass = null;
………
servlet = (Servlet) classClass.newInstance();
if ((servlet instanceof ContainerServlet) &&
(isContainerProvidedServlet(actualClass) ||
((Context)getParent()).getPrivileged() )) {
((ContainerServlet) servlet).setWrapper(this);
}
classLoadTime=(int) (System.currentTimeMillis() -t1);
try {
instanceSupport.fireInstanceEvent(InstanceEvent.BEFORE_INIT_EVENT,servlet);
if( System.getSecurityManager() != null) {
Class[] classType = new Class[]{ServletConfig.class};
Object[] args = new Object[]{((ServletConfig)facade)};
SecurityUtil.doAsPrivilege("init",servlet,classType,args);
} else {
servlet.init(facade);
}
if ((loadOnStartup >= 0) && (jspFile != null)) {
………
if( System.getSecurityManager() != null) {
Class[] classType = new Class[]{ServletRequest.class,
ServletResponse.class};
Object[] args = new Object[]{req, res};
SecurityUtil.doAsPrivilege("service",servlet,classType,args);
} else {
servlet.service(req, res);
}
}
instanceSupport.fireInstanceEvent(InstanceEvent.AFTER_INIT_EVENT,servlet);
………
return servlet;
}
从上面的代码可以看出实例化一个servlet之后会调用servlet的service方法,下面再看看在service方法中做了什么处理(假定我们自己写的servlet继承自httpServlet)
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 / 1000 * 1000)) {
// 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);
}
}
这段代码很明确的告诉我们,在servlet的service方法中会根据你页面上写的mothod方法去调用相应的doGet(.,.),doPost(.,.)等方法,也就是我们自己在servlet中自己写的业务逻辑。