Spring学习_day6

Spring MVC拦截器

在Spring MVC中,拦截器Interceptor和过滤器的Filter的作用是一样的,都是对某些资源的拦截。并且如果有多个拦截器对同一个资源进行拦截的时候,那么这时候就形成了拦截器链,此时是根据在spring-mvc.xml中配置拦截器的顺序,按照顺序执行preHandle方法,然后当目标资源执行完毕之后,就根据配置的顺序,倒序执行postHandle操作,当postHandle操作执行完毕之后,在根据配置的顺序,倒叙执行afterCompletion操作

而Spring MVC拦截器和Filter的区别是:
在这里插入图片描述
所以执行拦截器的相关操作主要有3个步骤:

  • 自定义拦截器XXInterceptor,使得这个类实现了HandlerInterceptor,然后重写它的方法preHandle,postHandle,afterCompletion,其中主要是重写preHandle方法

  • spring-mvc.xml中配置拦截器,对应的格式为:

    <mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="xxx"/> <!--对path中的资源进行拦截,其中如果它的值为/**时,表示对所有的资源进行拦截-->
            <mvc:exclude-mapping path="zzz"> <!--对path中的资源不进行拦截-->
            <bean class="yyyy"></bean> <!--class是对应的拦截器-->
        </mvc:interceptor>
        <mvc:interceptor>
          ......
        </mvc:interceptor>
    </mvc:interceptors>
    
  • 进行相应的测试

所以Interceptors自定义类对应的代码为:

public class MyInterceptor implements HandlerInterceptor {
    /*
    在对应的方法执行之前,进行拦截。如果返回值为true,那么表示
    放行,这时候就可以执行下面postHandle,afterCompletion方法
    否则,如果返回的是false,那么表示进行拦截,不可以执行对应的
    方法,从而下面2个方法也不会执行。
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("preHandle is running......");
        String param = request.getParameter("param");
        if("yes".equals(param)){
            //如果param不为null,并且值为yes,那么就放行
            return true;
        }
        //如果没有传递参数param,或者它的值不为yes,那么不会放行
        return false;
    }

    //在对应的方法执行完毕之后,但是还没有开始渲染视图之前执行的
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle is running......");
    }

    //当所有的操作完成之后,也即视图已经渲染完成了,才执行这个方法
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("afterCompletion is running.....");
    }
}

public class MyInterceptor2 implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("MyInterceptor2 preHandle is running.........");
        return true;//放行
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("MyInterceptor2 postHandle is running........");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("MyInterceptor2 afterCompletion is running........");
    }
}

对应的spring-mvc.xml文件中配置拦截器的代码为:

<mvc:interceptors>
    <mvc:interceptor>
        <mvc:mapping path="/interceptorController/**"/>
        <bean class="day6.demo.interceptors.MyInterceptor"></bean>
    </mvc:interceptor>
    <mvc:interceptor>
        <mvc:mapping path="/**"></mvc:mapping> <!--拦截所有的资源-->
        <bean class="day6.demo.interceptors.MyInterceptor2"></bean>
    </mvc:interceptor>
</mvc:interceptors>

对应的测试类:

@Controller
@RequestMapping("/interceptorController")
public class InterceptorController {
    @RequestMapping("/test")
    public ModelAndView test(ModelAndView modelAndView){
        System.out.println("InterceptorController is running....");
        modelAndView.addObject("name","大大怪");
        modelAndView.setViewName("/index.jsp");
        return modelAndView;
    }
}

所以,如果输入的是localhost:8080/interceptorController/test?param=yes的时候,2个拦截器都进行拦截同一个资源,这时候preHandle操作时根据sprng-mvc中配置的顺序来执行的是,当所有的拦截器的preHandle方法都执行之后,才可以放行去执行目标资源,当目标资源执行完毕之后,先去执行postHandle操作,但是这时候是根据拦截器配置的顺序的倒序执行的,当所有的拦截器都执行了postHandle方法之后,再根据拦截器配置的顺序的倒序执行afterCompletion方法。所以多个拦截器对同一资源进行拦截的时候,执行顺序也是如此。所以对应的结果如下所示:
在这里插入图片描述

Spring MVC中请求映射发生404错误

当Spring MVC请求映射发生404错误的时候,情况可能有很多种:

  • controller中没有使用注解@Controller,将这个xxxController添加到Spring MVC容器中;
  • 虽然已经使用了注解@Controller,但是spring-mvc.xml中没有配置<context:component-scan base-package="xxx"/>来扫描controller层的组件;
  • 有可能请求的资源路径错误了;
  • 可能web.xml中配置错误

但是如果上面的配置都没有错误的情况下,那么我们需要看一下spring-mvc.xml中是否已经添加了<mvc:annotation-driven/>,如果没有,那么尝试将这一句添加到spring-mvc.xml中,再次请求的时候,发现能够正常映射了(我的情况就是这个,😭😭😭)

但是为什么加上这个之后,就可以映射了呢?

原来,<mvc:annotation-driver/>是Spring MVC用来提供Controller请求转发,json自动转换,配置内部资源解析器等功能的类,会默认帮我们注册处理请求,参数和返回值的类

参考资料:springmvc 中 注解驱动:<mvc:annotation-driven>的作用和使用

Spring MVC的异常处理

利用Spring MVC中,我们可以在service.dao层通过throws来声明可能出现的异常,如果抛出了异常,那么将会有controller来通过try-catch来处理。但是我们可以利用Spring MVC来处理异常,所以并不需要我们在controller层中来try-catch异常。所以对应的异常处理步骤如下所示:
在这里插入图片描述
所以我们在利用Spring MVC来处理异常的时候,需要配置异常处理器HandlerExceptionResolver.而配置异常处理器可以有2种方式:

  1. 直接在spring-mvc.xml中配置Spring MVC中的SimpleMappingExceptionResolver(简单映射异常解析器),对应的代码为:

    <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
            <!--defaultErrorView的值表示发生错误时,默认跳转的页面是error.jsp-->
            <property name="defaultErrorView" value="error.jsp"></property>
            <property name="exceptionMappings">
                <!--当发生的异常和下面的异常匹配的时候,那么就会跳转到value对应的界面,否则
                如果不匹配时候,就会跳转到默认界面-->
                <map>
                    <entry key="java.lang.ArithmeticException" value="error2.jsp"></entry>
                    <entry key="java.lang.NumberFormatException" value="error1.jsp"></entry>
                    <entry key="java.lang.NullPointerException" value="error3.jsp"></entry>
                </map>
            </property>
        </bean>
    
  2. 自定义一个类,使得这个类实现了Spring MVC中的HandlerExceptionResolver接口,并且实现它的resolveException方法,在这个方法中,根据对应的异常,从而做出相应的处理,然后将返回一个ModleAndView对象。之后再spring mvc中将这个自定义类添加到Spring MVC容器中,对应的代码为:

    自定义类MyExceptionResolver代码:

    public class MyHandlerExceptionResolver implements HandlerExceptionResolver {
        @Override
        public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) {
            ModelAndView modelAndView = new ModelAndView();
            if(e instanceof NumberFormatException){
                //如果发生的是NumberFormatException异常,那么跳转到error1.jsp页面
                modelAndView.setViewName("error1.jsp");
            }else if(e instanceof NullPointerException){
                 //如果发生的是NullPointerException异常,那么跳转到error3.jsp页面
                modelAndView.setViewName("error3.jsp");
            }else if(e instanceof ArithmeticException){
                //如果发生的是ArithmeticException异常,那么跳转到error2.jsp页面
                modelAndView.setViewName("error2.jsp");
            }else{
                //默认跳转到error.jsp页面
                modelAndView.setViewName("error.jsp");
            }
            return modelAndView;
        }
    }
    
    

    在spring-mvc.xml中配置自定义类

    <bean class="day7.demo.exceptions.MyHandlerException"></bean>
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值