Spring---处理异常

目录

 

1. 简介

2. Spring自身异常自动映射为指定HTTP状态码

3. 使用@ResponseStatus将自定义异常映射为指定HTTP状态码

4. 基于控制器处理异常:@ExceptionHandler

5. 全局异常处理:@ControllerAdvice———推荐


参考:Spring MVC异常统一处理的三种方式

1. 简介

在具体的SSM项目开发中,由于Controller层为处于请求处理的最顶层,再往上就是框架代码的。因此,肯定需要在Controller捕获所有异常,并且做适当处理,返回给前端一个友好的错误码

Spring提供了多种方式将异常转换为响应:

  • 特定的Spring异常将会自动映射为指定的HTTP状态码
  • 自定义异常上可以添加@ResponseStatus注解,从而将其映射为某一个HTTP状态码
  • 方法上可以添加@ExceptionHandler注解,使其用来处理异常

2. Spring自身异常自动映射为指定HTTP状态码

 在默认情况下,Spring会将自身的一些异常自动转换为合适的状态码,从而反馈给客户端。实际上,如果没有出现任何映射的异常,响应都会带有500状态码。映射表如下:

 

3. 使用@ResponseStatus将自定义异常映射为指定HTTP状态码

通过使用@ResponseStatus注解将自定义的异常映射为指定的HTTP状态码

/**
 * value 要匹配的异常状态码
 * reson 提示的异常原因
 */
@ResponseStatus(value = HttpStatus.NOT_FOUND,reason = "Own Exception")
public class OwnException extends RuntimeException {
}

4. 基于控制器处理异常:@ExceptionHandler

方法上添加@ExceptionHander(xxxx异常.class),该方法会处理指定的异常。

该注解有一个不好的地方就是:进行异常处理的方法必须与出错的方法在同一个Controller里面。不能全局控制异常。每个类都要写一遍

@Controller      
public class GlobalController {               
   /**    
     * 用于处理异常的    
     * @return    
     */      
    @ExceptionHandler({MyException.class})       
    public String exception(MyException e) {       
        System.out.println(e.getMessage());       
        e.printStackTrace();       
        return "exception";       
    }       

    @RequestMapping("test")       
    public void test() {       
        throw new MyException("出错了!");       
    }                    
}

5. 全局异常处理:@ControllerAdvice———推荐

控制器通知:是任意使用@ControllerAdvice注解修饰的类。这个类中包含了一个或多个如下类型的方法:

  • @ExceptionHandler注解的方法
  • @InitBinder注解标注的方法
  • @ModelAttribute标注的方法

控制器通知中上述的方法都会运用到应用程序中所有带有@RequestMapping注解的方法或类上。达到全局异常的处理。

@ControllerAdvice
@ResponseBody
public class WebExceptionHandle {
    private static Logger logger = LoggerFactory.getLogger(WebExceptionHandle.class);
    /**
     * 400 - Bad Request
     */
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(HttpMessageNotReadableException.class)
    public ServiceResponse handleHttpMessageNotReadableException(HttpMessageNotReadableException e) {
        logger.error("参数解析失败", e);
        return ServiceResponseHandle.failed("could_not_read_json");
    }
    
    /**
     * 405 - Method Not Allowed
     */
    @ResponseStatus(HttpStatus.METHOD_NOT_ALLOWED)
    @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
    public ServiceResponse handleHttpRequestMethodNotSupportedException(HttpRequestMethodNotSupportedException e) {
        logger.error("不支持当前请求方法", e);
        return ServiceResponseHandle.failed("request_method_not_supported");
    }

    /**
     * 415 - Unsupported Media Type
     */
    @ResponseStatus(HttpStatus.UNSUPPORTED_MEDIA_TYPE)
    @ExceptionHandler(HttpMediaTypeNotSupportedException.class)
    public ServiceResponse handleHttpMediaTypeNotSupportedException(Exception e) {
        logger.error("不支持当前媒体类型", e);
        return ServiceResponseHandle.failed("content_type_not_supported");
    }

    /**
     * 500 - Internal Server Error
     */
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    @ExceptionHandler(Exception.class)
    public ServiceResponse handleException(Exception e) {
        if (e instanceof BusinessException){
            return ServiceResponseHandle.failed("BUSINESS_ERROR", e.getMessage());
        }
        
        logger.error("服务运行异常", e);
        e.printStackTrace();
        return ServiceResponseHandle.failed("server_error");
    }
}

如果 @ExceptionHandler 注解中未声明要处理的异常类型,则默认为参数列表中的异常类型。所以还可以写成这样:

@ControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler()
    @ResponseBody
    String handleException(Exception e){
        return "Exception Deal! " + e.getMessage();
    }
}

猜你喜欢

转载自blog.csdn.net/zhangpower1993/article/details/88912182