SpringMVC学习笔记(六)—— SpringMVC异常处理三种方式

版权声明:转载请注明来源 https://blog.csdn.net/qq_24598601/article/details/85018849

1. SpringMVC异常处理

  在SpringMVC框架中,异常的处理分为预期异常和运行时异常,预期异常通过需要通过捕获来获取异常信息,运行时异常就靠我们程序员进行代码规范啦。
  系统中一般有 Dao 层、Service 层、Controller 层,通过 throws exception一层一层往上抛出,最后由 DispatchServlet 中方法 doDispatch 进行捕获交由异常处理器处理。Spring MVC 异常处理详解

2. SpringMVC异常处理三种方式

  在SpringMVC中有三种处理 Controller 抛出的异常的方式。第一种是实现 HandlerExceptionResolver ;第二种是使用 @ExceptionHandler;第三种是使用 @ControllerAdvice + @ExceptionHandler。每种方法各有各的优缺点。下面我们一种一种的来说明。

2.1 实现 HandlerExceptionResolver 异常处理

  这种方式可以用来进行全局的异常控制。具体步骤是:

2.1.1 编写自定义的异常类
package com.ssm.exception;

/**
 * 描述:自定义异常类
 * @author lytao123
 *
 */
public class CustomException extends Exception {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	public CustomException(String message) {
		super(message);
		this.message = message;
	}

	// 异常信息
	private String message;

	public String getMessage() {
		return message;
	}

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

2.1.2 编写自定义的异常处理器

  这里需要实现 HandlerExceptionResolver 接口

package com.ssm.controller.exceptionresolver;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;

import com.ssm.exception.CustomException;

public class CustomExceptionResolver implements HandlerExceptionResolver {

	@Override
	public ModelAndView resolveException(HttpServletRequest request,
			HttpServletResponse response, Object handler, Exception ex) {

		ex.printStackTrace();

		CustomException customException = null;
		
		//如果抛出的是系统自定义异常则直接转换
		if(ex instanceof CustomException){
			customException = (CustomException)ex;
		}else{
			//如果抛出的不是系统自定义异常则重新构造一个未知错误异常。
			customException = new CustomException("未知错误,请与系统管理员联系!");
		}
		
		ModelAndView modelAndView = new ModelAndView();
		modelAndView.addObject("message", customException.getMessage());
		modelAndView.setViewName("error");

		return modelAndView;
	}

}

2.1.3 配置自定义的异常处理器

  在 springmvc.xml 中配置:

<!-- 全局异常处理器 -->
<bean id="handlerExceptionResolver" class="com.ssm.controller.exceptionresolver.CustomExceptionResolver"/>
	
2.1.4 测试

  在 Controller 中编写代码抛出异常:

private final static String SUCCESS = "success";  //返回结果
private final static String ERROR = "error";  //返回结果


//方式一  继承 HandlerExceptionResolver
//测试捕获全局异常
@RequestMapping(value="/testException",method=RequestMethod.GET)
public ModelAndView testException() throws Exception {
	ModelAndView modelAndView = new ModelAndView();
	
	if(!"".equals(SUCCESS)) {
		//抛出异常
		throw new CustomException("测试异常捕获方式一。");
	}
	
	modelAndView.setViewName(SUCCESS);
	
	return modelAndView;
}

  页面跳转到 error.jsp 页面,打印出 “发生错误。测试异常捕获方式一。”

2.2 使用 @ExceptionHandler 异常处理

  这种方式的异常处理因为 改注解只能注解到方法上,所以进行异常处理的方法必须与出错的方法在同一个 Controller 里面,这就造成了这种方法不好运用在全局的异常控制上,如果想实现需要每个 Controller 都写一个方法,一般用来对 Controller 的特定异常控制。

2.2.1 编写一个自定义的异常类

  代码如下:

package com.ssm.exception;
/**
* @Description 自定义异常类
* @author 欧阳
* @since 2018年12月15日 下午8:43:42
* @version V1.0
*/

public class MyException extends Exception {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	public MyException(String message) {
		super(message);
	}

}

2.2.2 编写异常处理方法及测试方法
/**
 * 方式二,@ExceptionHandler 可用来捕获单个Controller中的异常
 * @param e
 * @return
 */
//用于处理异常
@ExceptionHandler(value={MyException.class})
public /*@ResponseBody*/ String exception(Exception e) {
	System.out.println(e.getMessage());
	
	return ERROR;
//		return e.getMessage();
}

@RequestMapping("/testException2")
public ModelAndView testException2() throws Exception {
	ModelAndView modelAndView = new ModelAndView();
	
	if(!"".equals(SUCCESS)) {
		throw new MyException("测试错误,方式二");
	}
	
	modelAndView.setViewName(SUCCESS);
	return modelAndView;
}

  注意:这里被 @ExceptionHandler 注解标注的方法的参数只能是 Exception 。

  页面跳转到 error.jsp 页面,打印出 “发生错误。“

2.3 使用 @ControllerAdvice + @ExceptionHandler 异常处理

  这种方式的优点是将 Controller 层的异常和数据校验的异常进行统一处理,减少编码量,提升扩展性和可维护性。缺点是只能处理 Controller 层未捕获(往外抛)的异常,对于 Interceptor(拦截器)层的异常和Spring 框架层的异常就不能捕获到。具体使用方法如下:
  新建 GlobalExceptionHandler类,同时要保证能被扫描到并装载进 Spring 容器中,并使用注解 @ControllerAdvice 标注,在其中的方法使用注解 @ExceptionHandler 标注,如下代码所示,可定义多个方法,使用多个 @ExceptionHandler 注解不同类型的异常。

package com.ssm.controller.exceptionresolver;

import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

/**
* @Description 实现全局的 Controller 层的异常处理,要保证能被扫描到并装载进 Spring 容器中。
* @author 欧阳
* @since 2018年12月15日 下午9:00:35
* @version V1.0
*/

@ControllerAdvice
public class GlobalExceptionHandler {
	
	/**
	 * 处理所有不可知的异常
	 * @param e
	 * @return
	 */
	@ExceptionHandler(Exception.class)
    public @ResponseBody String handleException(Exception e){
		
        return "Exception! thrid";
    }
	
}

猜你喜欢

转载自blog.csdn.net/qq_24598601/article/details/85018849