一、拦截器

        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提供的简单异常处理器SimpleMappingExceptionResolverSimpleMappingExceptionResolver使用时,只需要在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";
}