SpringMVC 从入门到精通系列 07 —— 拦截器与异常处理


一、拦截器

1.1 概述

  1. SpringMVC框架中的拦截器用于对处理器进行 预处理后处理 的技术。
  2. 可以定义拦截器链,连接器链就是将拦截器按着一定的顺序结成一条链,在访问被拦截的方法时,拦截器链中的拦截器会按着定义的顺序执行。
  3. 拦截器和过滤器的功能比较类似,有如下区别:
    1. 过滤器是Servlet规范的一部分,任何框架都可以使用过滤器技术。
    2. 拦截器是 SpringMVC 框架独有的。
    3. 过滤器配置了 /*,可以拦截任何资源。
    4. 拦截器只会对控制器中的方法进行拦截。
  4. 拦截器也是AOP思想的一种实现方式
  5. 想要自定义拦截器,需要实现 HandlerInterceptor 接口。

1.2 自定义拦截器步骤

  1. 创建类,实现 HandlerInterceptor 接口,重写需要的方法。
    return true 放行,执行下一个拦截器。如果没有,执行 controller 中的方法
    return false 不放行。

    public class MyInterceptor implements HandlerInterceptor {
        /**
         * 预处理,在controller方法执行前
         */
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            System.out.println("MyInterceptor执行了。。");
            //成功放行
            return true;
            //不放行
            //request.getRequestDispatcher("/WEB-INF/pages/error.jsp").forward(request, response);
           	//return false;
        }
    }
    
  2. 在 springmvc.xml 中配置拦截器类。

    <!--配置拦截器-->
    <mvc:interceptors>
        <!--配置第一个拦截器-->
        <mvc:interceptor>
            <!--要拦截的方法-->
            <mvc:mapping path="/user/*"/>
            <!--不要拦截的方法-->
            <!--<mvc:exclude-mapping path=""/>-->
            <!--配置拦截器对象-->
            <bean class="com.itheima.interceptor.MyInterceptor"></bean>
        </mvc:interceptor>
    </mvc:interceptors>
    

    注:拦截的方法和不拦截的方法配置选择其一。


演示如下:

工程目录:
在这里插入图片描述

Controller:

@Controller
@RequestMapping(path = "/user")
public class  UserController {

    @RequestMapping(path = "/testInterceptor")
    public String testInterceptor(){
        System.out.println("testInterceptor方法执行了");

        return "success";
    }
}

演示页面:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
	<h3>拦截器</h3>
	<a href="user/testInterceptor">拦截器</a>
</body>
</html>

成功页面:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
	<h3>执行成功</h3>
</body>
</html>

演示效果:
在这里插入图片描述
在这里插入图片描述


1.3 HandlerInterceptor接口中的方法

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

代码演示:

public class MyInterceptor implements HandlerInterceptor {

    /**
     * 预处理,在controller方法执行前
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("MyInterceptor执行了。。。前");
        return true;
    }

    /**
     * 后处理方法,controller方法执行后,success.jsp执行之前
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("MyInterceptor执行了。。。后");
    }

    /**
     * success.jsp执行后,该方法会执行
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("MyInterceptor执行了。。。最后");
    }
}

成功页面输出信息:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>

<h3>执行成功</h3>
<%System.out.println("success.jsp");%>
</body>
</html>

演示结果:
在这里插入图片描述


1.4 配置多个拦截器

<!--配置拦截器-->
<mvc:interceptors>
    <!--配置第一个拦截器-->
    <mvc:interceptor>
        <!--要拦截的方法-->
        <mvc:mapping path="/user/*"/>
        <!--不要拦截的方法-->
        <!--<mvc:exclude-mapping path=""/>-->
        <!--配置拦截器对象-->
        <bean class="com.itheima.interceptor.MyInterceptor"></bean>
    </mvc:interceptor>

    <!--配置第二个拦截器-->
    <mvc:interceptor>
        <!--要拦截的方法-->
        <mvc:mapping path="/user/*"/>
        <!--不要拦截的方法-->
        <!--<mvc:exclude-mapping path=""/>-->
        <!--配置拦截器对象-->
        <bean class="com.itheima.interceptor.MyInterceptor2"></bean>
    </mvc:interceptor>
</mvc:interceptors>

拦截顺序是 根据配置里面的拦截顺序进行拦截,放行也是从最深处向外放行,具体图示如下:

在这里插入图片描述

演示效果如下:
在这里插入图片描述


二、异常处理

2.1 异常处理思路

Controller调用service,service调用dao,异常都是向上抛出的,最终有 DispatcherServlet 找异常处理器进行异常的处理。

在这里插入图片描述


2.2 异常处理实现

① 编写自定义异常类(做提示信息的)
② 编写异常处理器
③ 配置异常处理器(跳转到提示页面)

项目目录:

在这里插入图片描述

编写自定义异常类

public class SysException extends Exception{
    // 存储提示信息的
    private String message;
    
    public SysException(String message) {
        this.message = message;
    }
    public String getMessage() {
        return message;
    }
    public void setMessage(String message) {
        this.message = message;
    }
}

自定义异常处理器

public class SysExceptionResolver implements HandlerExceptionResolver{
    /**
     * 处理异常业务逻辑
     */
    public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
        // 获取到异常对象
        SysException e = null;
        if(ex instanceof SysException){
            e = (SysException)ex;
        }else{
            e = new SysException("系统正在维护....");
        }
        // 创建ModelAndView对象
        ModelAndView mv = new ModelAndView();
        mv.addObject("errorMsg",e.getMessage());
        // 跳转到的视图
        mv.setViewName("error");
        return mv;
    }
}

配置异常处理器

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

error.jsp:

<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    ${errorMsg}
</body>
</html>

controller:

@Controller
@RequestMapping("/user")
public class UserController {
    @RequestMapping("/testException")
    public String testException() throws SysException{
        System.out.println("testException执行了...");
        try {
            // 模拟异常
            int a = 10/0;
        } catch (Exception e) {
            // 打印异常信息
            e.printStackTrace();
            // 抛出自定义异常信息
            throw new SysException("查询所有用户出现错误了...");
        }
        return "success";
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Xiu Yan

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值