Servlet如何处理请求
servlet是如何处理传来的不同的请求的呢?
我们首先要对servlet的生命周期有一个了解!
servlet生命周期
新建一个web项目,new一个servlet,这里叫做TestServlet.
在TestServlet中重写构造方法,init,service,doGet,doPost,destory等方法.
package com.jd.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class TestServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public TestServlet() {
System.out.println("构造方法");
}
@Override
public void init() throws ServletException {
System.out.println("init");
}
@Override
protected void service(HttpServletRequest arg0, HttpServletResponse arg1) throws ServletException, IOException {
System.out.println("service");
super.service(arg0, arg1);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("doGet");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("doPost");
}
@Override
public void destroy() {
System.out.println("destory");
}
}
运行tomcat,观察控制台输出,发现在服务器完成运行前控制台都没有任何输出,也就是说,服务器运行,TestServlet并没有创建对象
而当访问这个servlet时控制台才会输出(下图)。
即在请求这个TestServlet时,创建对象,初始化,并立即执行方法处理请求。
我们多次访问TestServlet,控制台只会输出service和doGet,说明此servlet只会创建一次对象,之后再次接收到请求的时候只是这一个对象在执行方法。
那么,如何在服务器运行的时候就直接创建对象而不是等到请求的时候再创建呢?
在web.xml文件中这个TestServlet所在的< servlet >标签中加上一行代码:
<load-on-startup>1</load-on-startup>
这个数字1也可以是别的数字,不用深究。这行代码的作用就是在服务器运行的时候就创建此servlet对象
再次运行tomcat,果然这次控制台输出了代码,说明创建了对象。
总结serrvlet的生命周期:
1.创建对象
默认情况servlet不会随着服务器的启动而创建对象,第一次向此请求时候创建,之后请求不再创建对象,不管在哪个浏览器上发送请求。
如果在web.xml文件中配置了< load-on-startup>1< /load-on-startup>,会随着服务器的启动而创建对象。
2.初始化(init)
在构造方法中会调用init方法,由于对象只创建一次,则在创建对象时执行构造函数,只会进行一次初始化,init只会执行一次。
3.处理请求
所有请求到达servlet后先执行service方法,在方法中根据请求方式决定执行doGet还是doPost方法。
4.销毁(destory)
重新发布项目,正常关闭tomcat时,会执行此方法,如果非正常关闭,相当于程序中断,不会执行方法。
那么服务器如何知道把某个请求交给哪个servlet来处理呢?
web.xml匹配
当我们向服务器发送一个请求时:http://127.0.0.1:8080/servlet_re1/TestServlet
服务器会先截掉前面项目名,只剩下后面的请求:/TestServlet
接着在web.xml文件中的标签< url-pattern>< /url-pattern>内找到一个与上面请求匹配的字符串,记录上一行的< servlet-name>< /servlet-name>标签内的字符串。
接着在各个< servlet>< /servlet>标签中的< servlet-name>< /servlet-name>内找到一个与上面记录下来的字符串相同的字符串,执行下一行地址所对应的servlet,至此匹配完毕。
如果没有发送任何请求怎么办?
当我们只向服务器发送项目名:http://127.0.0.1:8080/servlet_re1
怎么来处理它呢?
首先在web.xml中我们会发现这段代码:
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
联想到我们的网页主页一般都是index.html,是不是非常熟悉呢,当我们访问这个网页名称,后面没有跟任何请求时,服务器将会按照上面顺序,如何有相匹配的请求,就会请求那个servlet,返回请求的页面,这也是我们大多数网页的主页都是index.html的原因。
WebContent匹配
如果发送的请求在web.xml文件中找不到一个匹配的怎么办?
这时候服务器将会把请求与自己的静态资源匹配:
若请求为:http://127.0.0.1:8080/servlet_re1/index.jsp
截取后为:/index.jsp,在web.xml中找不到匹配的,将会与项目中的WebContent中的文件进行匹配,匹配了根目录下的index.jsp,显示此文件中的内容。
SpringMVC匹配
如果我们使用的是Spring框架,那么又是如何进行匹配的呢?
首先看一下spring在web.xml中的配置(spring配置文件为application.xml)
<servlet>
<servlet-name>DispatcherServlet</servlet-name> <!-- 代码3 -->
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name> <!-- 代码4 -->
<param-value>classpath:application.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup> <!-- 代码1 -->
</servlet>
<servlet-mapping>
<servlet-name>DispatcherServlet</servlet-name> <!-- 代码2 -->
<url-pattern>/</url-pattern>
</servlet-mapping>
代码1:在服务器运行的时候就创建对象。
代码2:接收所有请求,并记录servlet-name标签中的字符串
代码3:在这里匹配到标签中字符串于刚才保存的字符串相同,运行下一行的类文件
代码4:在代码3运行的servlet中加载spring配置文件
也就是说,所有请求都将使这个DispatcherServlet执行
那么它是如何匹配不同的请求的呢?
这是一个Controller注解类,当容器spring扫描类并创建对象时,会将带有@RequestMapping注解的方法中的注解值添加到一个map集合中。
当请求传来的时候,与map集合中的字符串匹配,若匹配到,执行对应的方法处理请求。
如何map集合中没有与请求匹配的字符串呢?
如果没有相匹配的,我们可以在spring配置文件application.xml中添加这两行代码:
<mvc:default-servlet-handler/>
<mvc:annotation-driven></mvc:annotation-driven>
作用就是,当没有与请求相匹配的字符串时,使用服务器默认的servlet响应,按照地址匹配,也就是上面提到的 WebContent匹配。
上一篇: Servlet之处理请求(七)
推荐阅读
-
Servlet获取AJAX POST请求中参数以form data和request payload形式传输的方法
-
如何优雅的处理Spring Boot异常信息详解
-
SpringBoot+SpringSecurity处理Ajax登录请求问题(推荐)
-
iOS开发中不合法的网络请求地址如何解决
-
iOS在页面销毁时如何优雅的cancel网络请求详解
-
Node.js如何响应Ajax的POST请求并且保存为JSON文件详解
-
深入剖析JSP和Servlet对中文的处理
-
实例讲解如何在PHP的Yii框架中进行错误和异常处理
-
解读PHP的Yii框架中请求与响应的处理流程
-
实例讲解Python中SocketServer模块处理网络请求的用法