Web服务器处理Servlet处理请求过程
Web服务器如何确定哪个Servlet处理请求
1、各种容器与服务器的区别与联系
1.1 容器与服务器的联系
1.2 各种容器的区别/联系
1.3 各种服务器的区别/联系
2、web服务器处理Servlet请求
2.1 处理Servlet请求图解
2.2 处理Servlet请求代码运行过程
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<display-name>dubhe</display-name>
<welcome-file-list>
<welcome-file>login.jsp</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>UserInfoLoginServlet</servlet-name><!--step3 -->
<servlet-class>com.jd.userinfo.UserInfoLoginServlet</servlet-class><!--step4-->
<!--
<load-on-startup>1</load-on-startup>,
web项目发布时就创建Servlet实例
-->
</servlet>
<servlet-mapping>
<servlet-name>UserInfoLoginServlet</servlet-name><!--step2-->
<url-pattern>/UserInfoLoginServlet</url-pattern><!--step1-->
</servlet-mapping>
</web-app>
代码执行步骤:
step1:根据客户端发过来的请求,Servlet容器判断是否创建并加载Servlet实例。如果是客户端第一次给服务器发送该Servlet请求时,Servlet容器会加载并创建Servlet实例 ,(注意:默认情况下不是Tomcat服务器或服务器上的Web应用启动的时候加载并实例化Servlet),之后会调用一次init()方法对Servlet实例初始化 。当客户端(可以是非第一次请求的客户端)再次向服务器发送该Servlet请求时,服务器会从内存 。中查找该Servlet实例,并用找到的Servlet实例处理用户请求。
step2:根据URL得到servlet的name;
step3:找到代码中的中与name 相同的那个 标签;
step4:最后根据这行代码找到客户端对应的Servlet
<servlet-class>com.jd.userinfo.UserInfoLoginServlet</servlet-class>
step5执行Servlet中的代码
- Servlet容器首先会针对该请求创建ServletRequest和ServletResponse对象;
- 调用Servlet的service()方法并把这两个参数传递给service()方法处理客户端请求;
- Servlet实例通过ServletRequest对象获得客户端的请求;
- 通过调用ServletResponse对象的方法进行响应,通过web服务器向客户端返回静态页面;
- 请求处理完毕,ServletRequest和ServletResponse对象被销毁(销毁的方式:服务器关闭或重新发布项目,都由Servlet容器完成)
如何确定请求的方式是Get还是POST?
不管客户端发送请求的方式是Get还是POST,这个请求都由 service方法来处理。在service方法的处理过程中,会根据客户端发送请求的方式不同,调用 doGet和doPost方法分别进行处理,通过HttpServlet类中的service方法可以了解这一调用过程,如下代码:
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) {
doGet(req, resp);
} else {
long ifModifiedSince = req.getDateHeader(HEADER_IFMODSINCE);
if (ifModifiedSince < lastModified) {
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 {
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);
}
}
【参考资料】
[服务器,容器的区别] https://blog.csdn.net/tjiyu/article/details/53148174