一、拦截器
DispatcherServlet收到请求之后,如果有拦截器,会先调用 拦截器,然后再调用Controller。
注:过滤器属于servlet规范,而拦截器属于spring框架。
配置拦截器的步骤如下:
1、写一个java类,实现HandlerInterceptor接口
2、在接口方法里面,实现拦截处理逻辑。
package interceptors;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 实现HandlerInterceptor接口
* step1. 写一个java类,实现HandlerInterceptor接口。
* step2. 在接口方法里面,实现拦截处理逻辑。
* step3. 配置拦截器。
*/
public class SomeInterceptor implements HandlerInterceptor {
/**
* DispatcherServlet收到请求后会先调用preHandle()方法,
* 如果该方法的返回值为true,表示请求继续向后调用(如调用下一个拦截器或处理器)。
* 如果返回值为false,表示请求中断(如登录检查失败),则不会继续调用其他的拦截器或处理器,
* 此时我们需要通过response来产生响应。
* 第三个参数为响应的处理器的Method方法对象。
*/
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
System.out.println("preHandle()");
return true;
}
/**
* postHandle方法只会在当前这个拦截器的preHandle方法成功完成且返回值为true的时候才会执行。
* 处理器(Controller)的方法已经执行完毕,正准备将处理结果(ModelAndView)返回给DispatcherServlet
* 之前执行postHandle方法。可以在该方法里面修改Controller返回的处理结果。
*/
public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
System.out.println("postHandle()");
}
/**
* 最后执行的方法
* afterCompletion方法只会在当前这个拦截器的preHandle方法成功完成且返回值为true的时候,且postHandle方法执行完之后才会执行。
* 即:该方法将在整个请求完成之后,也就是DispatcherServlet渲染了视图执行。
* exception:是处理器所抛出的异常,可以写一个拦截器,用来处理这些异常。
*/
public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception exception) throws Exception {
System.out.println("afterCompletion()");
}
}
3、配置拦截器
<mvc:interceptors>
<!--可配置多个自定义的拦截器,如果有多个拦截器,则会按照配置的先后顺序来执行。-->
<mvc:interceptor>
<!--1.拦截的请求:
path属性: /*表示所有请求,如果访问路径是分层的,如:/demo/hello2.do则path属性的值应为/**
/demo/* 表示/demo下的所有请求-->
<mvc:mapping path="/**"/>
<!--2.排除的请求-->
<!--<mvc:exclude-mapping path=""/> -->
<!--3.实现了HandlerInterceptor接口的类-->
<bean class="interceptors.SomeInterceptor"></bean>
</mvc:interceptor>
</mvc:interceptors>
二、异常处理
注:即将异常抛给spring框架,让spring框架来处理。 默认情况下,spring框架会将异常直接抛给最终的用户。
准备一个Controller如下:
@RequestMapping("/hello.do")
public String hello(){
System.out.println("hello()");
//方式一:配置简单异常处理器
Integer.parseInt("100a");//运行时异常,这里把异常抛给了前端控制器。
return "hello";
}
1、方式一:配置简单异常处理器。
使用Spring MVC提供的简单异常处理器SimpleMappingExceptionResolver,SimpleMappingExceptionResolver使用时,只需要在Spring的XML配置文件中定义下就可以了,定义示例如下:
step1.在spring配置文件当中,配置简单异常处理器。
<!--5.配置简单异常处理器-->
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<property name="exceptionMappings">
<props>
<!--key:异常的类型,这里的error是视图名。出异常时会转发到这个视图。-->
<prop key="java.lang.NumberFormatException">error1</prop>
<prop key="java.lang.StringIndexOutOfBoundsException">error2</prop>
</props>
</property>
</bean>
step2.添加相应的异常处理页面。 注:简单异常处理器,不能够对异常做复杂的处理。
<%@ page contentType="text/html;charset=UTF-8" language="java" isErrorPage="true" %>
<html>
<head>
<title>错误页面</title>
</head>
<body>
<h1 style="color: red;">错误:${requestScope.errorMsg}</h1>
<h1 style="color: red;">错误:${pageContext.exception}</h1>
</body>
</html>
2、方式二:使用 @ExceptionHandler注解实现异常处理
@ExceptionHandler注解实现异常处理, 使用方法如下。首先编写一个BaseController类,定义如下:
public class BaseController {
@ExceptionHandler
public String execute(HttpServletRequest request, Exception ex){
request. setAttribute("ex", ex);
//可根据异常类型不同返回不同视图名
return "error";
}
}
然后其他的Controller继承BaseController类即可。适合局部处理有"处理过程”的异常。
step1. 在处理器当中添加一个异常处理方法。该方法 前面需要添加@ExceptionHandler注解。在异常处理方法里面,依据异常类型做不同的处理
step2. 添加异常处理页面。
//ex是处理器其它方法所抛出的异常。
@ExceptionHandler
public String exHandle(Exception ex, HttpServletRequest request){
System.out.println("exHandle()");
//依据异常类型的不同,分别做相应的处理。
if (ex instanceof NumberFormatException){
request.setAttribute("errorMsg","亲,请输入正确的数字!");
return "error";
}else if (ex instanceof StringIndexOutOfBoundsException){
request.setAttribute("errorMsg","字符串下标越界!");
return "error";
}
//其他异常
return "system_error";
}