SpringMVC学习记录-05

一、异常处理

1.异常处理思路

在这里插入图片描述

2.具体步骤

2.1.自定义异常类

public class SysException extends Exception {

    //异常提示信息
    private String message;

    @Override
    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public SysException(String message) {
        this.message = message;
    }
}

2.2.编写异常处理器

@Controller
public class SysExceptionResolver implements HandlerExceptionResolver {
    @Override
    public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception ex) {
        SysException e = null;
        //判断异常类型是否是自定义类型
        if(ex instanceof SysException){
            //如果抛出的是系统自定义异常则直接转换
            e = (SysException) ex;
        }else{
            //如果抛出的不是系统自定义异常则重新构造一个系统错误异常。
            e = new SysException("执行失败,请联系管理员");
        }

        ModelAndView mv = new ModelAndView();
        //存入错误提示信息
        mv.addObject("errormsg",e.getMessage());
        //跳转到jsp界面
        mv.setViewName("error");
        return mv;
    }
}

2.3.模拟异常

	<a href="/testException">异常模拟</a>

-------------------------------------------------

	@RequestMapping("/testException")
    public String testException(){
        int i = 10/0; //模拟异常
        return "success";
    }

2.4.error.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <h3>错误提示界面</h3>
    ${errormsg}
</body>
</html>

注意 isELIgnored="false"

二、拦截器

1.拦截器的作用

Spring MVC 的处理器拦截器类似于 Servlet 开发中的过滤器 Filter,用于对处理器进行预处理和后处理。 用户可以自己定义一些拦截器来实现特定的功能。

谈到拦截器,还要向大家提一个词——拦截器链(Interceptor Chain)。拦截器链就是将拦截器按一定的顺序联结成一条链。在访问被拦截的方法或字段时,拦截器链中的拦截器就会按其之前定义的顺序被调用。

它和过滤器是有几分相似,但是也有区别,他们的区别如下:

  • 过滤器是 servlet 规范中的一部分,任何 java web 工程都可以使用。 拦截器是 SpringMVC 框架自己的,只有使用了 SpringMVC 框架的工程才能用。
  • 过滤器在 url-pattern 中配置了 /* 之后,可以对所有要访问的资源拦截。 拦截器它是只会拦截访问的控制器方法,如果访问的是 jsp,html, css, image 或者 js 是不会进行拦 截的。

拦截器也是 AOP 思想的具体应用。 我们要想自定义拦截器, 要求必须实现:HandlerInterceptor 接口

2.拦截器的工作原理

在这里插入图片描述

3.自定义拦截器的步骤

3.1.写一个类继承HandlerInterceptor接口

public class HandlerInterceptorDemo1 implements HandlerInterceptor { 
 	
 	/**
 	* 控制器之前执行
 	*/
 	@Override  
 	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)    throws Exception {   
 		System.out.println("preHandle 拦截器拦截了");   
 		return true;  //如果程序员决定不需要再调用其他的组件去处理请求,则返回 false。 
 	} 
 	
 	/*
 	* 控制器之后执行
 	* 拦截器链内所有 preHandle 返回 true 才会调用 
 	*/
 	@Override  
 	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, 
 ModelAndView modelAndView) throws Exception {   
 		System.out.println("postHandle 方法执行了");  
 	} 
 	
 	/**
 	* 最后执行,只有 preHandle 返回 true 才调用 
 	* 可以在该方法中进行一些资源清理的操作。 
 	*/
 	@Override  
 	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)    throws Exception {   
 		System.out.println("afterCompletion 方法执行了");  
 	} 
} 

3.2.配置拦截器

<!-- 配置拦截器 --> 
<mvc:interceptors>  
	<mvc:interceptor>   
		<mvc:mapping path="/user/*"/> <!--指定需要进行拦截的url /**/表示拦截所有-->
		<mvc:exclude-mapping path=""/> <!--指定不进行拦截的url-->
  		<bean id="handlerInterceptorDemo1"     class="com.itheima.web.interceptor.HandlerInterceptorDemo1"></bean>  		
  	</mvc:interceptor> 
</mvc:interceptors> 

3.3.运行结果

在这里插入图片描述

4.多个拦截器的执行顺序

按照配置的顺序来执行

<!-- 配置拦截器 --> 
<mvc:interceptors>  
	<mvc:interceptor>   
		<mvc:mapping path="/user/*"/> <!--指定需要进行拦截的url /**/表示拦截所有-->
		<mvc:exclude-mapping path=""/> <!--指定不进行拦截的url-->
  		<bean id="handlerInterceptorDemo1"     class="com.itheima.web.interceptor.HandlerInterceptorDemo1"></bean>  		
  	</mvc:interceptor> 

	<mvc:interceptor>   
		<mvc:mapping path="/**"/> 
  		<bean id="handlerInterceptorDemo2"     class="com.itheima.web.interceptor.HandlerInterceptorDemo2"></bean>  		
  	</mvc:interceptor> 
</mvc:interceptors> 
  • preHandle :按拦截器定义顺序调用
  • postHandle :按拦截器定义逆序调用
  • afterCompletion:按拦截器定义逆序调用
  • 在这里插入图片描述
    在这里插入图片描述

5.拦截器方法细节

  • preHandler :只要配置了都会调用 。如果程序员决定该拦截器对请求进行拦截处理后还要调用其他的拦截器,或者是业务处理器去进行处理,则返回 true。 如果程序员决定不需要再调用其他的组件去处理请求,则返回 false。

  • postHandle :在拦截器链内所有拦截器的 preHandle 返回 true 才调用

  • afterCompletion:自己的拦截器 preHandle 返回 true 调用

思考: 如果有多个拦截器,这时拦截器 1 的 preHandle 方法返回 true,但是拦截器 2 的 preHandle 方法返 回 false,而此时拦截器 1 的 afterCompletion 方法是否执行?

答案: 拦截器 1 的 afterCompletion 执行,拦截器2的 afterCompletion 不执行, 两个拦截器的 postHandle 都不执行

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值