Spring MVC高级技术整理
1.拦截器使用
1.1.监听器、过滤器和拦截器的对比
-
过滤器(Filter)web.xml中进行配置
对Request 请求起到过滤作用,作用在Servlet之前, /* 表示对所有资源访问进行过滤处理。 -
监听器(Listener)web.xml中进行配置
实现了ServletContextListener 接口的服务器端组件,监听器随web应用启动而启动,只初始化一次,一直运行,指导web容器销毁
作⽤⼀:做⼀些初始化⼯作,web应⽤中spring容器启动ContextLoaderListener
作⽤⼆:监听web中的特定事件,⽐如HttpSession,ServletRequest的创建和销毁;变量的创建、销毁和修改等。可以在某些动作前后增加处理,实现监控,⽐如统计在线⼈数,利⽤HttpSessionLisener等。 -
拦截器(Interceptor)Spring MVC自身的配置文件中配置
不会拦截静态资源的访问,只会拦截访问控制器方法handle,在handle执行前,执行后,页面跳转渲染完成都进行一次拦截。
1.2 Sping MVC拦截器的执行流程
1.2.1拦截器的使用
- 实现HandlerInterceptor接口
/**会在handler方法业务逻辑执行之前执行
往往在这里完成权限校验工作
@return 返回值boolean代表是否放行,true代表放行,false代表中止*/
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
/**
* 会在handler方法业务逻辑执行之后尚未跳转页面时执行
* @param modelAndView 封装了视图和数据,此时尚未跳转页面呢,你可以在这里针对返回的数据和视图信息进行修改
* @throws Exception
*/
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
/**
* 页面已经跳转渲染完毕之后执行
* @param ex 可以在这里捕获异常
* @throws Exception
*/
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
- 注册
<mvc:interceptors>
<mvc:interceptor>
<!--配置当前拦截器的url拦截规则,**代表当前目录下及其子目录下的所有url (url端口之后的所有路径)-->
<mvc:mapping path="/**"/>
<!--exclude-mapping可以在mapping的基础上排除一些url拦截-->
<mvc:exclude-mapping path="/demo/**"/>
<bean class="com.lagou.edu.interceptor.MyIntercepter01"/>
</mvc:interceptor>
</mvc:interceptors>
单个拦截器顺序:preHandle→handle→postHandle→render(DpatchServelt)→afterCompletion
1.2.2多个拦截器执行顺序
假设xml中按先后顺序配置1,2两个拦截器。
执行顺序为:
preHandle1 →preHandle2→handle→postHandle2→postHandle1→render(DpatchServelt)→afterCompletion2→afterCompletion1
像在栈一样的先进后出的顺序
2.处理multipart形式的数据
Spring MVC简易文件上传思路:
- 前端指定是post 发请求,enctype=“multipart/form-data”
- 后端handle 中用 MultipartFile 接收,另外session可以用来获取服务器上文件夹的真实路径以存储上传的文件。
public ModelAndView upload(MultipartFile uploadFile,HttpSession session)
- 文件转存直接可调用
upload.transferTo()
方法
3.异常处理器
Spring MVC 异常处理注解(方法上使用): @ExceptionHandler(要处理的异常类型)
- 单个controller类中处理该controller中所有handle的异常
@ExceptionHandler(ArithmeticException.class)
public void handleException(ArithmeticException exception,HttpServletResponse response) {
// 异常处理逻辑
try {
response.getWriter().write(exception.getMessage());
} catch (IOException e) {
e.printStackTrace();
}
}
- 对于全局异常处理可将上述代码写在全局异常处理类中,并在异常处理类上加 @ControllerAdvice注解即可,该注解会捕获所有Controller对象中的handle方法抛出的异常。
4.基于Flash属性的重定向请求数据传递
- 转发:url不会变,参数不会丢失,属于通一个请求。
- 重定向:url会变,参数丢失,属于两个请求。
如何使得重定向也能携带参数?
①拼接return "redirect:handle01?name=" + name;
但是安全性与长度有限制
②在handle方法参数中添加RedirectAttributes redirectAttributes
// addFlashAttribute方法设置了一个flash类型属性,该属性会被暂存到session中,在跳转到页面之后该属性销毁 redirectAttributes.addFlashAttribute("name",name);