SpringMVC 学习笔记心得(八)自定义异常处理器&&自定义拦截器

异常流程处理过程,出现异常之后都会默认向上抛出异常直到有人处理,如果整个过程中一直没有人去处理,那么将会将异常抛给浏览器(也就是用户),这样对用户的体验是非常不友好的,所以我们应该要手动去处理这些异常,以展示友好界面


1)、自定义异常处理器

1).自定义异常SysException类
public class SysException extends Exception {
    private String msg;

    public SysException(String msg) {
        this.msg = msg;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }
}
2).实现HandlerExceptionResolver
public class SysExceptionResolver implements HandlerExceptionResolver {

    @Override
    public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) {
        //controller 抛出的异常对象Exception ex
            SysException sys = null;
        if(e instanceof SysException){
            sys = (SysException) e;
        }else{
        //如果没有就抛出异常
            sys = new SysException("服务器异常");
        }
		//创建modelAndView对象
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.addObject("msg",sys.getMsg());
        //选择异常跳转视图
        modelAndView.setViewName("error");
        return modelAndView;
    }
}

3)、配置异常处理器
 <bean id="sysExceptionResolver" class="cn.itcast.exception.SysExceptionResolver"/>

2)、拦截器(Interceptor)

1).拦截器和过滤器的区别?
  1. 过滤器是Servlet规范的一部分,任何框架都可以使用过滤器技术
  2. 拦截器是SpringMVC框架独有的
  3. 过滤器配置了/*,可以拦截任何资源。
  4. 拦截器只会对控制器中的方法进行拦截
2).自定义拦截器步骤

1.实现HandlerInterceptor接口,重写public boolean preHandle()方法

public class MyInteceptorHandler implements HandlerInterceptor {
	//最先被执行,在controller之前
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("拦截器开始执行咯。。");
        return true;
    }
//在controller执行之后再执行
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("posthandle...");
        //这里实现页面转发,跳到index.jsp页面中
        request.getRequestDispatcher("/index.jsp").forward(request,re	sponse);
        System.out.println("拦截器执行完咯。。");

    }
//在之后执行的方法
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("拦截器执行完之后咯。。");
    }
}

2.配置springmvc配置文件注册拦截器作用范围

  <mvc:interceptors>
        <mvc:interceptor>
            <!-- 设置哪些路径被拦截 -->
            <mvc:mapping path="/hello"/>
            <!-- 设置哪些路径不被拦截 -->
            <mvc:exclude-mapping path="/"/>
            <bean id="myInteceptorHandler" class="cn.itcast.controller.MyInteceptorHandler"/>
        </mvc:interceptor>
    </mvc:interceptors>

3.controller跳转到success.jsp界面

@RequestMapping("/hello")
    public String hello(){
        System.out.println("hello方法。。。");
        return "success";
    }

注意:小编在index.jsp和success.jsp中都输出了一句话以证明拦截器的执行流程

3).拦截器执行过程

在这里插入图片描述
控制台打印,首先走的是preHandle方法,其次就是controller,然后走的postHandle方法,再走的controller的视图解析器,最后走的afterHandle方法

在这里插入图片描述
注意:最后显示的视图是index.jsp视图,原因是 如果postHandler中指定了跳转的页面,那么controller方法跳转的页面将不会显示,所以最终显示的是index.jsp界面
在这里插入图片描述

4).单个拦截器使用总结
  1. preHandle方法是controller方法执行前拦截的方法
    1. 可以使用request或者response跳转到指定的页面
    2. return true放行,执行下一个拦截器,如果没有拦截器,执行controller中的方法。
    3. return false不放行,不会执行controller中的方法。
  2. postHandle是controller方法执行后执行的方法,在JSP视图执行前。
    1. 可以使用request或者response跳转到指定的页面
    2. 如果指定了跳转的页面,那么controller方法跳转的页面将不会显示。
  3. postHandle方法是在JSP执行后执行
    1. request或者response不能再跳转页面了

3)、多个拦截器定义的使用

1).执行顺序?

a).多个拦截器全部都放行的执行顺序:
在这里插入图片描述

拦截器111开始执行咯。。
拦截器2开始执行咯。。
hello方法。。。
拦截器执2行完咯。。
拦截器执2行完之后咯。。
拦截器111执行完之后咯。。

b).多个拦截器后者不放行的执行顺序:

在这里插入图片描述

控制台打印:
拦截器111开始执行咯。。
拦截器2开始执行咯。。
拦截器111执行完之后咯。。

这里小编对没有页面显示也还有些疑问,显示的是空白页面,在不断的学习和探索之后再进行回更,多拦截器执行原理!

猜你喜欢

转载自blog.csdn.net/weixin_43409994/article/details/106409005