SpringMVC是基于MVC的轻量级Web框架,使用DispatcherServlet作为前端控制器,且内部提供了处理器映射器、处理器适配器、视图解析器等组
件。
SpringMVC依赖:(包含Spring依赖)
1 | <dependency> |
Spring整合SpringMVC的配置:
- 创建SpringMVC容器,并配置扫描的包(主要为controller层)
- web.xml配置DispatcherServlet,并指定
SpringMVC容器,进行初始化 - web.xml
配置DispatcherServlet请求拦截路径 - 创建Spring容器,并配置扫描的包(主要为业务层service层)
- web.xml配置ContextLoaderListener,用于
加载Spring容器
web.xml:
1 | <servlet> |
SpringMVC关键组件:
- 处理器映射器:HandlerMapping,匹配映射路径对应的Handler,返回可执行的处理器链对象HandlerExecutionChain对象(常用:RequestMappingHandlerMapping)
- 处理器适配器:HandlerAdapter 匹配HandlerExecutionChain对应的适配器进行处理器调用,返回视图模型对象 (常用:RequestMappingHandlerAdapter)
- 视图解析器:ViewResolver 对视图模型对象进行解析(常用:InternalResourceViewResolver)
SpringMVC前端控制器DispatcherServlet初始化主要做了两件事:获得了一个 SpringMVC 的 ApplicationContext容器;注册了 SpringMVC的 九大组件。
SpringMVC组件注册规则:如果在SpringMVC容器中没有找到对应的组件,则到Spring容器中查找,如果都没配置,则加载默认组件配置(在DispatcherServlet.properties 文件中,该文件存在与spring-webmvc-5.3.7.jar包下的 org\springframework\web\servlet\DispatcherServlet.properties)
前端控制器DispatcherServlet执行流程:
- 客户端发送请求,DispatcherServlet拦截到请求
- DispatcherServlet根据请求信息匹配对应的处理器映射器(HandlerMapping),HandlerMapping匹配对应Handler(执行的目标方法)
- HandlerMapping返回HandlerExecutionChain(包含一个Handler处理器对象,多个HandlerInterceptor拦截器对象)到DispatcherServlet
- DispatcherServlet执行对应拦截器方法和调用HandlerAdapter执行对应目标方法,HandlerAdapter返回结果数据到DispatcherServlet
- DispatcherServlet调用ViewResolver解析视图
- DispatcherServlet根据返回结果给客户端响应
请求静态资源:
- 静态资源请求失效的原因:当DispatcherServlet的映射路径配置为 / 的时候,那么就覆盖的Tomcat容器默认的缺省
Servlet(DefaultServlet具备二次去匹配静态资源的功能) - 解决无静态资源处理器问题:在spring-mvc.xml中配置< mvc:default-servlet-handler/>,该方式是注册了一个DefaultServletHttpRequestHandler 处理器,静态资源的访问都由该处理器去处理(该方式过程会注入SimpleUrlHandlerMapping到SpringMVC容器,导致不会加载默认HandlerMapping组件配置,导致SpringMVC容器没有RequestMappingHandlerMapping,访问Controller会出错)
- 解决无处理器映射器问题:在spring-mvc.xml中配置注解驱动 < mvc:annotation-driven /> 标签,该标签会自动注册RequestMappingHandlerMapping(处理器映射器)、RequestMappingHandlerAdapter(处理器设配器)、ExceptionHandlerExceptionResolver(异常解析器)、Json消息转换器等功能Bean
文件上传依赖:
1 | <dependency> |
1 | <!--配置文件上传解析器--> |
SpringMVC拦截器:
Filter 和 Interceptor 对比:Filter,Javaweb原生技术,可以对所有请求都过滤,包括任何Servlet、Jsp、其他资源等,Servlet执行前;Interceptor,SpringMVC框架技术,只对进入了SpringMVC管辖范围的才拦截,主要拦截Controller请求,Servlet执行后。
拦截器实现:
- 编写拦截器类实现HandlerInterceptor接口,重写preHandle、postHandle、afterCompletion方法
- 注册拦截器
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16public class MyInterceptor01 implements HandlerInterceptor {
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("Controller方法执行之前...");
return true;//放行
}
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("Controller方法执行之后...");
}
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("渲染视图结束,整个流程完毕...");
}
}xml方式注册拦截器:SpringMVC容器注册
1
2
3
4
5
6
7
8
9<!--配置拦截器-->
<mvc:interceptors>
<mvc:interceptor>
<!--配置对哪些资源进行拦截操作-->
<mvc:mapping path="/*"/>
<bean class="com.zzr.interceptor.MyInterceptor01"></bean>
</mvc:interceptor>
</mvc:interceptors>注解方式注册拦截器:
- 创建类
实现WebMvcConfigurer接口,实现addInterceptors(注册拦截器)和configureDefaultServletHandling(处理静态资源)方法 - SpringMVC配置类
加@EnableWebMvc注解1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class MyWebMvcConfigurer implements WebMvcConfigurer {
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
//开启DefaultServlet,可以处理静态资源了
configurer.enable();
}
public void addInterceptors(InterceptorRegistry registry) {
//创建拦截器对象,进行注册
//Interceptor的执行顺序也取决于添加顺序
registry.addInterceptor(new MyInterceptor01()).addPathPatterns("/*");
}
}
多个拦截器方法执行顺序:只要有一个拦截器不放行,则postHandle()都不会执行。如果都放行,preHandle()按配置顺序执行,postHandle()、afterCompletion()按配置顺序倒序执行。
拦截器执行原理:DispatcherServlet根据返回的HandlerExecutionChain执行对应拦截器方法和调用HandlerAdapter执行对应目标方法
SpringMVC常用注解:
1 | 设置控制器类 |
SpringMVC异常处理
- 流程:一路向上抛,都抛给前端控制器 DispatcherServlet ,DispatcherServlet 在调用异常处理器ExceptionResolver进行处理
- 注解方式实现异常处理:使用@ControllerAdvice/@RestControllerAdvice(交互json格式) + @ExceptionHandler 来处理
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class GlobalExceptionHandler {
public ResultInfo runtimeHandleException(RuntimeException e){
//模拟一个ResultInfo
ResultInfo resultInfo = new ResultInfo(0,"RuntimeException",null);
return resultInfo;
}
public ResultInfo ioHandleException(IOException e){
//模拟一个ResultInfo
ResultInfo resultInfo = new ResultInfo(0,"IOException",null);
return resultInfo;
}
}
SpringMVC全注解开发:
- spring-mvc.xml替换:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//相当于<context:component-scan base-package="com.zzr.controller"/>
public class SpringMVCConfig {
//文件上传Bean
public CommonsMultipartResolver multipartResolver(){
CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver();
multipartResolver.setDefaultEncoding("UTF-8");
multipartResolver.setMaxUploadSize(3145728);
multipartResolver.setMaxUploadSizePerFile(1048576);
multipartResolver.setMaxInMemorySize(1048576);
return multipartResolver;
}
} - web.xml替换:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19public class ServletConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
//加载Spring容器
protected Class<?>[] getRootConfigClasses() {
return new Class[]{SpringConfig.class};
}
//加载SpringMVC容器
protected Class<?>[] getServletConfigClasses() {
return new Class[]{SpringMVCConfig.class};
}
//DispatcherServlet拦截路径
protected String[] getServletMappings() {
return new String[]{"/"};
}
}
- 本文作者: zzr
- 本文链接: http://zzruei.github.io/2023/12ae0f95e0.html
- 版权声明: 本博客所有文章除特别声明外,均采用 Apache License 2.0 许可协议。转载请注明出处!
