目录
1 Servlet
Servlet包括HttpServlet,都是JavaWeb原生的Servlet接口,用于定义一套处理网络请求的规范,主要的方法有init()、destroy()、service()方法,分别是Servlet创建、销毁和具体的业务执行的操作。
实际上,Servlet并不能直接处理请求,而是由tomcat监听端口,请求过来后,根据url等信息,确定要将请求交给哪个servlet去处理;然后调用那个servlet的service()方法,service方法返回一个response对象;tomcat再把这个response返回给客户端。
2.1 Servlet工作机制
1.用户发送请求到服务器,如tomcat(Servlet容器)
2.Servlet容器加载解析Http请求
3.Servlet容器根据请求加载具体的Servlet类的实例,如果没有则init()初始化一个
4.Servlet初始化时生成servletRequest对象和servletResponse对象,request对象内存的是请求的数据
5.Servlet携带这两个对象作为参数传入service()方法中调用。
6.service()业务处理的响应结果存在response对象中
7.Servlet容器把Servlet的响应结果传给Web客户
2.2 servlet是单实例对象
Servlet一旦创建就会驻留在内存中,等待客户端的访问直至销毁。
init()只执行一次,Servlet是线程不安全的。
客户端同时并发请求时,会启动多线程执行service()。
2.3 HttpServlet
HttpServlet是Servlet的子接口,将Servlet中service()方法封装为doget()和dopost()方法,可以分别执行get和post请求。如:
public class HelloServlet extends HttpServlet {
@Override
public void init(ServletConfig config) throws ServletException {
super.init(config);
System.out.println(" HelloServlet 的init初始化方法");
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws Exception {
System.out.println(" HelloServlet 的doGet方法");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws Exception {
System.out.println(" HelloServlet 的doPost方法");
}
}
2 Tomcat
Tomcat 是 Web 应用服务器,一个 Servlet 容器,Tomcat 作为 Servlet 容器,负责处理客户端请求,把请求传给 Servlet ,并将 Servlet 的响应返回给客户端。
3 DispatcherServlet
dispatcherServlet是HttpServlet的子接口,原生的HttpServlet存在controller与servlet的高耦合,在配置文件中为每个请求地址配置一个servlet来处理请求。dispatcherServlet体现了对MVC框架和代码解耦设计理念的支持,起到了路由分发的作用,根据配置的节点有效地将请求转发到具体的控制器方法去处理。一个Servlet就能处理较多的节点发起的请求。
3.1 DispatcherServlet工作机制
1.用户的请求统一发送到前端控制器DispatcherServlet
2.DispatcherServlet 对请求URL进行解析,得到请求资源标识符(URI)
3.DispatcherServlet根据URI,调用处理器映射器HandlerMapping解析出请求对应的处理器Handler(也就是controller)
4.解析到对应的Handler后,由处理器适配器HandlerAdapter处理。
5.HandlerAdapter会根据Handler来调用真正的处理器来处理请求,并处理相应的业务逻辑。
6.处理器处理完业务后,会返回一个ModelAndView对象,Model是返回的数据对象,View是个逻辑上的视图。
7.处理器解析器ViewResolver进行视图解析,得到实际的视图View。
8.DispaterServlet把返回的Model传给View。
9.通过View返回并展示给用户。
3.2 或者一个很浅显的过程
(由于前端控制器DispatcherServlet、处理器映射器HandlerMapping、处理器适配器HandlerAdapter、处理器解析器ViewResolver这些都不需要自己开发,是框架自带的,不深究原理的话,下面的过程可能更容易理解和记忆SpringMVC中请求处理的过程)
1.浏览器发送请求,若请求地址符合前端控制器的url-pattern,该请求就会被前端控制器DispatcherServlet处理。
2.前端控制器会读取SpringMVC的核心配置文件,通过扫描组件找到控制器controller,将请求地址和控制器中@RequestMapping注解的value属性值进行匹配,若匹配成功,该注解所标识的控制器方法就是处理请求的方法。
3.处理的最终结果是返回一个ModelAndView对象,简单理解就是包含数据的视图,该视图名称会被视图解析器解析,并被Thymeleaf等这些前端框架对视图进行渲染,最终转发到视图所对应页面,显示在客户端。
3.3 处理静态资源的过程
tomcat的内部也配置了web.xml,对web工程的诸多属性做了默认的规定,我们在当前工程中进行修改时才会覆盖默认值。
这其中也配置了servlet的信息,在处理静态资源时的问题在于:当我们使用dispatcherServlet覆盖了tomcat中的defaultServlet时,由于dispatcherServlet是按照控制器请求路径去匹配请求处理方法的,这时无法访问到静态资源,而原生的servlet是可以访问静态资源的,这就需要当用dispatcherServlet无法访问到资源时,应该采用defaultServlet来访问。需要再web.xml中进行配置,用到的标签:
<mvc:default-servlet-handler/>
同时需要搭配开启注解驱动来使用,否则将会全部采用defaultServlet来执行。
3.4 处理其他请求方式
由于浏览器只支持发送get和put请求,所以servlet默认也只能处理这两种请求,如前面提到的doget()和dopost()方法,但SpringMVC提供了 HiddenHttpMethodFilter 过滤器帮助我们将 Post 请求转换为 DELETE 或 PUT 请求。当我们要发送put和delete请求请求时,可以:
1>在web.xml中注册HiddenHttpMethodFilter
<filter>
<filter-name>HiddenHttpMethodFilter</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>HiddenHttpMethodFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
2>先设置当前请求的请求方式为post
3>添加传输请求参数_method
@RequestMapping(value = "/employee/{id}", method = RequestMethod.DELETE)
public String deleteEmployee(@PathVariable("id") Integer id){
employeeDao.delete(id);
return "redirect:/employee";
}