Spring-MVC异常处理注解和拦截器

一、@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 方法 ");
    }
}

猜你喜欢

转载自blog.csdn.net/qq_42963930/article/details/102364794