一、@ExceptionHandler
介绍这个注解之前先谈另外一个注解、@ControllerAdvice
被这个注解所修饰的类称为处理器增强器。是给控制器对象增强功能的。使用@ControllerAdvice 修饰的类中可以使用@ExceptionHandler。
package com.bjpowernode.handle;
import com.bjpowernode.expe.AgeException;
import com.bjpowernode.expe.NameException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.servlet.ModelAndView;
/**
* 2019/09/02
* MyExceptionResolver实现HandlerExceptionResolver,
* 所以MyExceptionResolver是异常处理器, 能够处理异常。
*/
@ControllerAdvice
public class MyExceptionResolver {
//@ExceptionHandle 的属性value 异常类的class文件
@ExceptionHandler(value = NameException.class)
public ModelAndView doNameException(Exception ex){
ModelAndView mv = new ModelAndView();
mv.addObject("tips", "@ControllerAdvice使用注解处理NameException");
mv.addObject("ex", ex);
mv.setViewName("NameError");
return mv;
}
@ExceptionHandler(value = AgeException.class)
public ModelAndView doAgeException(Exception ex){
ModelAndView mv = new ModelAndView();
mv.addObject("tips", "@ControllerAdvice使用注解处理AgeException");
mv.addObject("ex", ex);
mv.setViewName("AgeError");
return mv;
}
//处理其他异常
@ExceptionHandler
public ModelAndView DefaultException(Exception ex){
ModelAndView mv = new ModelAndView();
mv.addObject("tips", "@ControllerAdvice使用注解处理DefaultException");
mv.addObject("ex", ex);
mv.setViewName("defaultError");
return mv;
}
}
// 其中@ExceptionHandler注解的value 属性值如果没有指定。表示如果抛出的异常在其他注解都不能处理的情况下,该异常将有该注解所修饰的方法来处理
使用ControllerAdvice注解也是需要指定所在的包结构和声明注解驱动
<!--指定文件扫描器-->
<context:component-scan base-package="com.bjpowernode.handle"></context:component-scan>
<!--声明注解驱动-->
<aop:annotation-driven></aop:annotation-driven>
二、拦截器
SpringMVC的Interceptor拦截器可以拦截指定的用户所发起的请求。
自定义拦截器。其实就是一个普通类实现了HandlerInterceptor 接口。实现该接口会重写该接口中的三个方法。
preHandle
该方法在用户请求处理前执行。可以对用户的请求进行预处理。常用户登陆验证、权限验证。身份检验。
postHandle
该方法在处理器方法处理完请求之后执行,注意此时的处理完但是处理器(中央适配器)并没有调用我们的dispatcherServlet视图解析器将页面进行渲染。即没有进行数据填充。返回的依然是ModelAndView 因此此时我们依然可以修改ModelAndView。并且可以请求转发或者重定向到其它页面
afterCompletion
该方法在处理器完全处理完用户的请求,页面也进行渲染完成。此时我能的中央调度器调用视图对象对试图对象进行解析。将响应结果响应给浏览器。此时对 ModelAndView 再操作也对响应无济于事。 这个方法的主要作用是用于==清理资源==的,当然这个方法也只能在当前这个Interceptor的preHandle方法的返回值为true时才会执行。
下面用一段代码简单说一下拦截器的用法
package com.bjpowernode.handle;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;
/**
* 2019/09/03
*/
public class Myinterceptor implements HandlerInterceptor {
/**
*preHandel 表示拦截器执行的方法 handle 表示
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("执行拦截器的prehandle 方法 ");
String uname = "";
Object attr = request.getSession().getAttribute("username");
if(attr != null){
uname = (String) attr;
}
if(!"zs".equals(uname)){
//不是zs 就不能正常访问
request.getRequestDispatcher("/result.jsp").forward(request, response);
return false;
}
return true;
}
//modelAndView 表示控制器的返回结果
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView mv) throws Exception {
System.out.println("执行拦截器的 postHandle 方法 ");
//postHandle 可以修改 modelAndview 结果
if(mv !=null){
//修改数据
mv.addObject("myDate", new Date());
//修改视图
mv.setViewName("other");
}
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response,
Object handler,
Exception ex) throws Exception {
System.out.println("执行拦截器的afterCompletion 方法 ");
}
}