Spring @ExceptionHandler 之 多个异常和全局处理程序

异常处理是任何Java应用程序非常重要的功能。每个良好的开源框架都允许以这样的方式编写异常处理程序,使我们可以将其与应用程序代码分开。好吧,Spring框架还允许我们使用注解Spring @ExceptionHandler来做到这一点

@ExceptionHandler 注解用于处理特定处理程序类和/或处理程序方法中的异常。

目录

1. Spring @ExceptionHandler注解
2. Spring @ExceptionHandler示例
3. Spring @ExceptionHandler-处理多个异常
4. Spring @ExceptionHandler使用@ControllerAdvice进行全局异常处理

1. Spring @ExceptionHandler注解

要处理String MVC中的异常,我们可以在控制器类中定义一个方法,并在其上使用注解@ExceptionHandler。Spring配置将检测到此注解,并将该方法注册为参数异常类及其子类的异常处理程序。

1.1。异常处理程序方法参数

使用此注解注解的处理程序方法具有非常灵活的签名。他们可以接受不同类型的参数。例如,异常参数,请求和/或响应对象,会话对象,语言环境对象和模型对象等。

1.2。异常处理程序方法的返回类型

与参数类似,返回类型可以是不同的类型。例如,ModelAndView对象,Model对象,View对象,视图名称为String等。我们可以void通过直接将响应内容写入来将该方法标记为方法是否可以处理响应本身HttpServletResponse

对于特定的HTTP错误状态,我们可以结合使用ExceptionHandler注解@ResponseStatus

1.3。异常处理程序方法示例

@ExceptionHandler(NullPointerException.class)
public ModelAndView handleException(NullPointerException ex)
{
	//Do something additional if required
	ModelAndView modelAndView = new ModelAndView();
	modelAndView.setViewName("error");
	modelAndView.addObject("message", ex.getMessage());
	return modelAndView;
}

现在,每次控制器NullPointerException在该控制器中对任何Web请求的请求处理中遇到时,控件都会自动进入此处理程序方法。

2. Spring @ExceptionHandler示例

例如,以下处理程序方法有意返回NullPointerException

@RequestMapping(value="/demo/not-exist", method = RequestMethod.GET,  headers="Accept=*/*")
public @ResponseBody ModelAndView oneFaultyMethod()
{
	if(true)
	{
		throw new NullPointerException("This error message if for demo only.");
	}
	return null;
}

如果我们部署以上应用程序并在浏览器中点击URL [ / SpringApplication / users / demo / not-exist ],它将显示第一部分中配置的“错误”页面。

< %@ taglib prefix="c" uri="http://java.sun.com/jstl/core" %>
< %@ taglib prefix="x" uri="http://java.sun.com/jstl/xml" %>
< %@ taglib prefix="fmt" uri="http://java.sun.com/jstl/fmt" %>
< %@ taglib prefix="sql" uri="http://java.sun.com/jstl/sql" %>
<html>

	<head>
		<title>This is sample error page</title>
	</head>
	<body>
		<h1>This is sample error page : <c:out value="${message}"></c:out></h1>
	</body>
<html>

下面是浏览器中的输出。

浏览器消息

3. Spring @ExceptionHandler –处理多个异常

如前所述,上述异常处理程序将处理所有异常,这些异常要么是给定类的实例,要么是参数异常的子类。但是,如果我们要为@ExceptionHandler配置不同类型的多个异常,则可以以array的形式指定所有此类异常。

@ExceptionHandler({NullPointerException.class, ArrayIndexOutOfBoundsException.class, IOException.class})
public ModelAndView handleException(NullPointerException ex)
{
	//Do something additional if required
	ModelAndView modelAndView = new ModelAndView();
	modelAndView.setViewName("error");
	modelAndView.addObject("message", ex.getMessage());
	return modelAndView;
}

4. Spring @ExceptionHandler使用@ControllerAdvice进行全局异常处理

如果我们想将异常处理逻辑集中到一个能够处理从任何处理程序类/控制器类抛出的异常的类,则可以使用@ControllerAdvice注解。

默认情况下,@ ControllerAdvice中的方法全局应用于所有Controller。我们可以创建一个类并@ControllerAdvice在上面添加注解。然后在其中@ExceptionHandler为每种类型的特定异常类添加方法。

注意,我们使用ResponseEntityExceptionHandler扩展了异常处理程序类。对于@ControllerAdvice希望@RequestMapping通过@ExceptionHandler方法在所有方法之间提供集中式异常处理的类,它是方便的基类。

@ControllerAdvice
public class CustomExceptionHandler extends ResponseEntityExceptionHandler 
{
	@ExceptionHandler(Exception.class)
	public final ResponseEntity<ErrorResponse> handleAllExceptions(Exception ex, WebRequest request) {
		List<String> details = new ArrayList<>();
		details.add(ex.getLocalizedMessage());
		ErrorResponse error = new ErrorResponse(ApplicationConstants.SERVER_ERROR, details);
		return new ResponseEntity<>(error, HttpStatus.INTERNAL_SERVER_ERROR);
	}

	@ExceptionHandler(RecordNotFoundException.class)
	public final ResponseEntity<ErrorResponse> handleUserNotFoundException(RecordNotFoundException ex,
												WebRequest request) {
		List<String> details = new ArrayList<>();
		details.add(ex.getLocalizedMessage());
		ErrorResponse error = new ErrorResponse(ApplicationConstants.RECORD_NOT_FOUND, details);
		return new ResponseEntity<>(error, HttpStatus.NOT_FOUND);
	}
}

这仅是示例。请创建您应用程序的特定异常并进行处理。

@ResponseStatus(HttpStatus.NOT_FOUND)
public class RecordNotFoundException extends RuntimeException
{
	private static final long serialVersionUID = 1L;

	public RecordNotFoundException(String exception) {
        super(exception);
    }
}
@XmlRootElement(name = "error")
public class ErrorResponse
{
    public ErrorResponse(String message, List<String> details) {
        super();
        this.message = message;
        this.details = details;
    }
 
    private String message;
    private List<String> details;

	public String getMessage() {
		return message;
	}

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

	public List<String> getDetails() {
		return details;
	}

	public void setDetails(List<String> details) {
		this.details = details;
	}
}

学习愉快!

参考文献:

ExceptionHandler Java文档
ResponseEntityExceptionHandler Java文档

saigon has written 1440 articles

Leave a Reply