SpringMVC 温习笔记(四)springMVC框架之SpringMVC拦截器和异常处理机制
拦截器的概念
Spring MVC的拦截器类似于Servlet中的Filter,一般用于处理器进行预处理和后处理。
将拦截器按一定的顺序联结成一条链,这条链称为拦截器链(Interceptor Chain)。在访问被拦截的方法或字段时,拦截器链中的拦截器就会按其之前定义的顺序被调用。拦截器也是AOP思想的具体实现。
拦截器和过滤器的区别
从以下两个方面进行区分。
使用范围
filter是servlet规范中的一部分,任何javaWeb工程中都可使用。
intercepter是SpringMVC框架自己的,只有使用了SpringMVC框架的工程才能使用。
拦截范围
filter在url-pattern中配置后对应拦截的方法或者资源都会被拦截。
**intercept只会拦截访问的控制方法,**如果访问的资源是jsp、html、css、image或者js等静态资源时,则不会进行拦截。
拦截器中方法
方法名 | 说明 |
---|---|
preHandle() | 方法将在请求处理之前进行调用,该方法的返回值是布尔值Boolean类型的,当它返回为false 时,表示请求结束,后续的Interceptor 和Controller 都不会再执行;当返回值为true 时就会继续调用下一个Interceptor 的preHandle 方法 |
postHandle() | 该方法是在当前请求进行处理之后被调用,前提是preHandle 方法的返回值为true 时才能被调用,且它会在DispatcherServlet 进行视图返回渲染之前被调用,所以我们可以在这个方法中对Controller 处理之后的ModelAndView 对象进行操作 |
afterCompletion() | 该方法将在整个请求结束之后,也就是在DispatcherServlet 渲染了对应的视图之后执行,前提是preHandle 方法的返回值为true 时才能被调用 |
案例
单拦截器案例
资源类
@Controller
public class TargetController {
@RequestMapping("/target")
public ModelAndView show(){
System.out.println("目标资源执行......");
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("name","feitian");
modelAndView.setViewName("index");
return modelAndView;
}
}
编写拦截器
public class Interceptor01Demo implements HandlerInterceptor {
//在目标方法执行之情
public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
Object handler) throws Exception {
System.out.println("preHandle01........");
String param = request.getParameter("param");
if("yes".equals(param)){
return true;
}else {
request.getRequestDispatcher("/error.jsp").forward(request,response);
return false;
}
//return true; //返回ture表示放行,返回false 表示不放行。
}
//目标方法执行完毕,返回视图之情
public void postHandle(HttpServletRequest request, HttpServletResponse response,
Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("postHandle01........");
}
//整个请求流程基本完毕后执行
public void afterCompletion(HttpServletRequest request, HttpServletResponse response,
Object handler, Exception ex) throws Exception {
System.out.println("afterCompletion01........");
}
}
springMVC配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!--1、mvc注解驱动-->
<mvc:annotation-driven/>
<!--2、配置视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/"/>
<property name="suffix" value=".jsp"/>
</bean>
<!--3、静态资源权限开放-->
<mvc:default-servlet-handler/>
<!--4、组件扫描 扫描Controller-->
<context:component-scan base-package="com.feitian.controller"/>
<!--配置拦截器-->
<mvc:interceptors>
<mvc:interceptor>
<!--对哪些资源执行拦截操作-->
<mvc:mapping path="/**"/>
<bean class="com.feitian.intercept.Interceptor01Demo"/>
</mvc:interceptor>
</mvc:interceptors>
</beans>
拦截器运行正常,当请求参数正确就直接返回,当不正确时跳转error界面。
当请求参数错误时,拦截器返回false的执行效果。
拦截器链案例
资源类跟上面保持一致
拦截器一
public class Interceptor01Demo implements HandlerInterceptor {
//在目标方法执行之情
public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
Object handler) throws Exception {
System.out.println("preHandle01........");
return true; //返回ture表示放行,返回false 表示不放行。
}
//目标方法执行完毕,返回视图之情
public void postHandle(HttpServletRequest request, HttpServletResponse response,
Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("postHandle01........");
}
//整个请求流程基本完毕后执行
public void afterCompletion(HttpServletRequest request, HttpServletResponse response,
Object handler, Exception ex) throws Exception {
System.out.println("afterCompletion01........");
}
}
拦截器二
public class Interceptor02Demo implements HandlerInterceptor {
//在目标方法执行之情
public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
Object handler) throws Exception {
System.out.println("preHandle02........");
String param = request.getParameter("param");
/*if("yes".equals(param)){
return true;
}else {
request.getRequestDispatcher("/error.jsp").forward(request,response);
return false;
}*/
return true; //返回ture表示放行,返回false 表示不放行。
}
//目标方法执行完毕,返回视图之情
public void postHandle(HttpServletRequest request, HttpServletResponse response,
Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("postHandle02........");
}
//整个请求流程基本完毕后执行
public void afterCompletion(HttpServletRequest request, HttpServletResponse response,
Object handler, Exception ex) throws Exception {
System.out.println("afterCompletion02........");
}
}
springMVC配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!--1、mvc注解驱动-->
<mvc:annotation-driven/>
<!--2、配置视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/"/>
<property name="suffix" value=".jsp"/>
</bean>
<!--3、静态资源权限开放-->
<mvc:default-servlet-handler/>
<!--4、组件扫描 扫描Controller-->
<context:component-scan base-package="com.feitian.controller"/>
<!--配置拦截器-->
<mvc:interceptors>
<mvc:interceptor>
<!--对哪些资源执行拦截操作-->
<mvc:mapping path="/**"/>
<bean class="com.feitian.intercept.Interceptor01Demo"/>
</mvc:interceptor>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean class="com.feitian.intercept.Interceptor02Demo"/>
</mvc:interceptor>
</mvc:interceptors>
</beans>
执行效果
此处值得说明的一点是拦截器的执行顺序其实是与springMVC.xml文件中拦截器配置顺序有关系,有兴趣的同学可以自己尝试配置一下。
异常处理机制
系统中异常包括两类:预期异常和运行时异常RuntimeException,前者通过捕获异常从而获取异常信息,后者主要通过规范代码开发、测试等手段减少运行时异常的发生。
系统的Dao、Service、Controller出现都通过throws Exception向上抛出,最后由SpringMVC前端控制器交由异常处理器进行异常处理,如下图:
异常的两种处理方式
使用springMVC提供的简单的异常处理器SimpleMappingExceptionResolver
使用Spring的异常处理接口HandlerExceptionResolver,自己定义异常处理器。
SimpleMappingExceptionResolver
springMVC已经定义好了该类的转换器,在使用时可以根据项目情况进行相应异常与视图的映射配置。
<!--配置异常处理器-->
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<property name="defaultErrorView" value="error"/>
<property name="exceptionMappings">
<map>
<entry key="java.lang.ClassCastException" value="error1"/>
<entry key="com.itheima.exception.MyException" value="error2"/>
</map>
</property>
</bean>
上述中如果系统出现异常,首先回去匹配map中的异常,如果匹配不到则直接跳转到defaultErrorView中所对应的error视图。
HandlerExceptionResolver
自定义异常类型
public class MyExceptionResolver implements HandlerExceptionResolver {
/*
参数Exception:异常对象
返回值ModelAndView:跳转到错误视图信息
*/
public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) {
ModelAndView modelAndView = new ModelAndView();
if(e instanceof MyException){
modelAndView.addObject("info","自定义异常");
}else if(e instanceof ClassCastException){
modelAndView.addObject("info","类转换异常");
}
modelAndView.setViewName("error");
return modelAndView;
}
}
springMVC文件中需要配置MyExceptionResolver 的bean。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
">
<!--1、mvc注解驱动-->
<mvc:annotation-driven/>
<!--2、配置视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/"/>
<property name="suffix" value=".jsp"/>
</bean>
<!--3、静态资源权限开放-->
<mvc:default-servlet-handler/>
<!--4、组件扫描 扫描Controller-->
<context:component-scan base-package="com.feitian.controller"/>
<!--自定义异常处理器-->
<bean class="com.feitian.resolver.MyExceptionResolver"/>
</beans>
在service类
public class DemoServiceImpl implements DemoService {
......
public void show4() {
System.out.println("空指针异常.....");
String str = null;
str.length();
}
public void show5() throws MyException {
System.out.println("自定义异常....");
throw new MyException();
}
......
}
web层
@Controller
public class DemoController {
@Autowired
private DemoService demoService;
@RequestMapping(value = "/show")
public String show() throws FileNotFoundException, MyException {
System.out.println("show running......");
demoService.show5();
return "index";
}
}
web项目中普通异常处理方式是有即向上抛即可,最后通过自定义异常或者springMVC自己的处理异常机制来处理异常。
本文地址:https://blog.csdn.net/xueshanfeitian/article/details/113939506