(八)

异常解析器用于统一处理 servlet 中的异常;

拦截器用于统一处理业务中需要统一处理的页面(比如登录判断等), 可抽取出来统一处理.

下面举例说明一下拦截器的使用

如果不使用拦截器, 我们可能需要在多个handler中写用户是否登录的逻辑判断, 产生代码冗余, 如下例:

@RequestMapping("/inter")
@Controller
@SessionAttributes("loginID")

/**
 * 如果不使用拦截器, 可能发生这种情况: 多个handler中都要添加逻辑判断, 且这些逻辑判断可能是重复的, 造成重复代码
 * 如test1和test2中的判断用户是否登录代码
 */
public class InterBean {

    @RequestMapping("/login")
    public String login(Model model){
        //登录后留取状态标记
        model.addAttribute("loginID","613025");
        System.out.println("访问login...");
        //返回登录页面
        return "afterIndexPage";
    }

    @RequestMapping("/test1")
    public String test1(Model model){
        System.out.println("访问test1...");
        if(model.asMap().get("loginID") != null){
            System.out.println("loginID有值");
            return "afterIndexPage";
        }
        System.out.println("loginID无值");
        return "indexPage";
    }

    @RequestMapping("test2")
    public String test2(Model model){
        System.out.println("访问test2...");
        if(model.asMap().get("loginID") != null){
            System.out.println("loginID有值");
            return "afterIndexPage";
        }
        System.out.println("loginID无值");
        return "indexPage";    }
}

直接访问/inter/test1:

 先访问/inter/login 在访问 /inter/test1:

 

使用拦截器:

创建拦截器 MyInterceptor.java:(实现 HandlerInterceptor 接口并重写其三个方法)

public class MyInterceptor implements HandlerInterceptor {

    //在handler之前执行, 在这里写handler中冗余的功能
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //判断登录状态
        HttpSession session = request.getSession();
        if (session.getAttribute("loginID") != null){
            System.out.println("loginID有值");
            //return true即放行, 执行后续的handler
            return true;
        }
        //中断之前, 响应请求
        System.out.println("loginID无值");
        response.sendRedirect("/indexPage.jsp");
        return false;
    }

    //在handler之后, 响应之前执行, 一般不使用
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("post handler");
    }

    //在视图渲染完毕后执行, 如一些资源的回收操作, 一般不使用
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("after completion");
    }
}

则原来的 handler 中的登录判断逻辑都可以省略(此处把代码放到一个新的servlet: InterBeanPro中):


@RequestMapping("/interPro")
@Controller
@SessionAttributes("loginID")

public
class InterBeanPro { @RequestMapping("/login") public String login(Model model){ //登录后留取状态标记 model.addAttribute("loginID","613025"); System.out.println("访问login..."); //返回登录页面 return "afterIndexPage"; } @RequestMapping("/test1") public String test1(Model model){ System.out.println("访问test1..."); return "afterIndexPage"; } @RequestMapping("test2") public String test2(Model model){ System.out.println("访问test2..."); return "afterIndexPage"; } }

在 mvc.xml 中添加拦截器:

     ...
    <!--拦截器-->
    <mvc:interceptors>
        <mvc:interceptor>
<!--            需要添加拦截的路径-->
            <mvc:mapping path="/interPro/test1"/>
            <mvc:mapping path="/interPro/test2"/>
<!--            拦截器-->
            <bean class="com.ryan.testInterceptor.MyInterceptor"/>
        </mvc:interceptor>
    </mvc:interceptors>

</beans>

这样, 拦截器就生效了, 当有请求访问 /interPro/test1(2) 时, 请求会被 MyInterceptor.java 拦截, 并在这里进行登录判断, 若用户未登录, 则重定向到登录页面; 若用户已登录, 则正常访问:

直接访问 localhost:8080/interPro/test1, 会被拦截并跳转到登录页面:

  先访问/interPro/login 在访问 /interPro/test1:

 

补充: 添加拦截器的其他方式:

    <mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/interPro/test1"/>
            <mvc:mapping path="/interPro/test2"/>
            <mvc:mapping path="/interPro/test*"/> <!--匹配test开头的handler-->
            <mvc:mapping path="/inter/**"/> <!--匹配任意多级路径-->
            <mvc:exclude-mapping path="inter/a/**"/> <!--不拦截此路径-->
            <bean class="com.ryan.testInterceptor.MyInterceptor"/>
        </mvc:interceptor>
    </mvc:interceptors>
原文地址:https://www.cnblogs.com/Ryan368/p/14144548.html