Spring MVC学习笔记四

时间:2021-7-3 作者:qvyue

拦截器的配置和使用:

描述:

拦截器只会拦截访问控制器(handler)的方法,不会拦截静态资源(例如:html,css)和动态资源(例如:jsp),通常被用在用户登陆校验,权限验证(例如:黑白名单)、请求日志记录、方法性能检测(记录方法请求响应时间)以及共性操作(例如:要对某些请求的请求头统一加上指定字段)等功能上。

实现方式:

要使用springmvc的拦截器有两种方式,实现HandlerInterceptor或者继承HandlerInterceptor的实现类。再将自定义的拦截器路径配置到springmvc.xml中(这一步是必须的,只是自定义不告诉springmvc是不行的)。

具体实现:

一,自定义拦截器:
/**
 * xialu的自定义拦截器。
 *
 * @author xialu
 * @version 1.0
 * @date 2021/6/24 11:19 下午
 */
public class XialuHandlerInterceptor implements HandlerInterceptor {

    /**
     * 会在handler方法业务逻辑执行之前执行
     * 往往在这里完成权限校验工作
     *
     * @param request
     * @param response
     * @param handler
     * @return 返回值boolean代表是否放行,true代表放行,false代表中止
     * @throws Exception
     */
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        System.out.println("xialu:preHandle" + " hello");

        return true;
    }

    /**
     * 会在handler方法业务逻辑执行之后尚未跳转页面时执行
     *
     * @param request
     * @param response
     * @param handler
     * @param modelAndView 封装了视图和数据,此时尚未跳转页面呢,你可以在这里针对返回的数据和视图信息进行修改
     * @throws Exception
     */
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {

        String xialu = (String) modelAndView.getModel().get("xialu");
        System.out.println("xialu:postHandle " + xialu);

    }

    /**
     * 页面已经跳转渲染完毕之后执行
     *
     * @param request
     * @param response
     * @param handler
     * @param ex       可以在这里捕获异常
     * @throws Exception
     */
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
        System.out.println("xialu:afterCompletion " + "hi");
    }
}
  
二,添加配置到springmvc.xml
 
三,拦截器中三个方法的执行顺序:
Spring MVC学习笔记四

Spring MVC学习笔记四
单个拦截器执行顺序.png

上面介绍了单个拦截器时,方法的执行顺序,如果程序中存在多个拦截器,执行的顺序又是怎样呢,
再创建一个拦截器,看下结果。

public class XiamiHandlerInterceptor implements HandlerInterceptor {
    /**
     * 会在handler方法业务逻辑执行之前执行
     * 往往在这里完成权限校验工作
     *
     * @param request
     * @param response
     * @param handler
     * @return 返回值boolean代表是否放行,true代表放行,false代表中止
     * @throws Exception
     */
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        System.out.println("xiami:preHandle");

        return true;
    }

    /**
     * 会在handler方法业务逻辑执行之后尚未跳转页面时执行
     *
     * @param request
     * @param response
     * @param handler
     * @param modelAndView 封装了视图和数据,此时尚未跳转页面呢,你可以在这里针对返回的数据和视图信息进行修改
     * @throws Exception
     */
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {

        System.out.println("xiami:postHandle");

    }

    /**
     * 页面已经跳转渲染完毕之后执行
     *
     * @param request
     * @param response
     * @param handler
     * @param ex       可以在这里捕获异常
     * @throws Exception
     */
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
        System.out.println("xiami:afterCompletion");
    }

}

添加新增的拦截器到配置文件到springmvc.xml中,中配置自上往下有序,也就是xialu在xiami前面,就会先执行。

执行结果:

Spring MVC学习笔记四
执行结果

Spring MVC学习笔记四
多个拦截器的执行顺序(1).png

Spring MVC学习笔记四
多个拦截器的执行顺序(2).png

SpringMVC中的全局异常处理:

springmvc中实现全局异常处理,只要使用@ControllerAdvice和@ExceptionHandler(XialuException.class)注解就可以了。其中@ControllerAdvice用来告诉springmvc这个类被声明为全局异常拦截类,@ExceptionHandler(xxx.class)用来配置需要拦截的异常,可以定义多个

实例:
@ControllerAdvice
public class GlobalExceptionResolver {

    @ExceptionHandler(XialuException.class)
    public ModelAndView handleException(XialuException xialu, HttpServletResponse response) {
        // 实现自定义逻辑
        return null;
    }

    @ExceptionHandler(XiamiException.class)
    public ModelAndView handleException(XiamiException xiami, HttpServletResponse response) {
        // 实现自定义逻辑
        return null;
    }

    /**
     * 可以选择捕捉所有异常,再根据类型处理。
     * @param exception
     * @param response
     * @return
     */
    @ExceptionHandler(Exception.class)
    public ModelAndView handleException(Exception exception, HttpServletResponse response) {
        if (exception instanceof XialuException) {
            System.out.println("xialu hello");
        } else if (exception instanceof XiamiException) {
            System.out.println("xiami hi");
        } else {
            //......
        }
        return null;
    }
}

如果不希望全局拦截,只想异常拦截在指定的controller中生效,把下面的方法写到希望拦截的controller里面即可。

@ExceptionHandler(XialuException.class)
    public ModelAndView handleException(XialuException xialu, HttpServletResponse response) {
        // 实现自定义逻辑
        return null;
    }
声明:本文内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:qvyue@qq.com 进行举报,并提供相关证据,工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。