spring异常处理

简介: 还是上次数据不能为空的问题,写到了C层测试。先写一行测试代码,先期待一个200,但是我们是知道的,因为没有学科类别,这肯定会抛出异常,我们就是想看看Spring捕获这个异常之后给出的反馈是什么状态码。

还是上次数据不能为空的问题,写到了C层测试。

先写一行测试代码,先期待一个200,但是我们是知道的,因为没有学科类别,这肯定会抛出异常,我们就是想看看Spring捕获这个异常之后给出的反馈是什么状态码。

@Test
public void saveTest() throws Exception {
    logger.debug("基础测试数据准备");
    MeasurementUnitCategory measurementUnitCategory = new MeasurementUnitCategory();
    String json = JSON.toJSONString(measurementUnitCategory);

    this.mockMvc.perform(post(baseUrl)
                        .header(xAuthKey, xAuthToken)
                        .contentType(MediaType.APPLICATION_JSON_UTF8)
                        .content(json))
                .andExpect(status().isOk());
}

测试一下,果然,控制台报错。

但是看一下报错信息,发现并不是我们期待的一个错误的状态码,而是200。同时下面还有异常抛出。

这说明Spring为我们抛出了这个DataIntegrityViolationException异常,但是却没有帮我们处理,这就需要我们手动处理然后返回给前台状态码。

MockHttpServletResponse:
           Status = 200
    Error message = null
          Headers = {X-Content-Type-Options=[nosniff], X-XSS-Protection=[1; mode=block], Cache-Control=[no-cache, no-store, max-age=0, must-revalidate], Pragma=[no-cache], Expires=[0], X-Application-Context=[application:-1], Content-Type=[application/json;charset=UTF-8], x-auth-token=[1b2b8d9f-3457-4277-879e-2ada48e3599e]}
     Content type = application/json;charset=UTF-8
             Body = {"id":8,"name":"","username":"usersdfdfwef23dfvdfwewef","mobile":"","pinyin":null,"createTime":1528338758059,"updateTime":1528338758059,"status":0,"department":{"id":1,"name":"内蒙古自治区管理部门","code":"","postalCode":"","address":"","legalName":"","legalPhone":"","registrantName":"","registrantPhone":"","registrantTel":null,"registrantMail":"","phone":"","pinyin":"neimengguzishiquguanglibumeng","registerDate":null,"createTime":1528338752423,"updateTime":1528338752423,"status":null,"createUser":null,"departmentType":{"id":1,"name":"管理部门","pinyin":"guanlibumen","createTime":1528338751963,"updateTime":1528338751963,"createUser":null},"district":{"id":1,"districtType":{"id":1,"name":"省","pinyin":"sheng"},"name":"内蒙古自治区","createUser":null,"pinyin":"neimengguzizhiqu","createTime":null,"updateTime":null},"checkAbility":false,"outOfRange":null,"standard":false},"roles":[],"createUser":null,"updateUser":null}
    Forwarded URL = null
   Redirected URL = null
          Cookies = []

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint [null]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement
Caused by: org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint [null]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement
Caused by: org.hibernate.exception.ConstraintViolationException: could not execute statement
Caused by: org.h2.jdbc.JdbcSQLException: NULL not allowed for column "DISCIPLINE_ID"; SQL statement:
insert into measurement_unit_category (id, discipline_id, is_asc) values (null, ?, ?) [23502-194]

理论上我们所有的异常都是由M层抛出,直接捕获或全局异常处理,是不会将异常抛给控制器的。

所以,我们需要全局异常处理,M层抛出异常,直接处理,返回xx状态码,而不将异常抛给控制器。

/**
 * 手动捕获数据冲突异常,经测试,该异常系由Spring抛出,但未捕获
 * @return HttpStatus.CONFLICT
 * 冲突错误,409
 * 参考:
 * https://stackoverflow.com/questions/37248719/couldnt-catch-dataintegrityviolationexception-with-spring-data-rest
 */
@ExceptionHandler(value = DataIntegrityViolationException.class)
public ResponseEntity<JsonErrorResult> dataIntegrityViolationException(HttpServletRequest httpServletRequest, Exception exception) {
    logger.error("---数据不合法:---Host {} invokes url {} ERROR: {}", httpServletRequest.getRemoteHost(), httpServletRequest.getRequestURL(), exception.getMessage());
    return new ResponseEntity<>(new JsonErrorResult(httpServletRequest, exception), HttpStatus.CONFLICT);
}

我这里对状态码也不是很熟悉,去StackOverflow上看到一个老哥是和我遇到了一样的问题,他解决的方案是捕获异常返回409(冲突),参考原文

异常捕获后,修改测试,期待状态码为409Conflict

@Test
public void saveTest() throws Exception {
    logger.debug("基础测试数据准备");
    MeasurementUnitCategory measurementUnitCategory = new MeasurementUnitCategory();
    String json = JSON.toJSONString(measurementUnitCategory);

    logger.debug("无学科的计量单位类别保存,期待409,冲突状态码");
    this.mockMvc.perform(post(baseUrl)
                        .header(xAuthKey, xAuthToken)
                        .contentType(MediaType.APPLICATION_JSON_UTF8)
                        .content(json))
                .andExpect(status().isConflict());
}

重新运行单元测试,通过。

clipboard.png

目录
相关文章
|
12天前
|
Java 关系型数据库 数据库连接
SpringBoot项目使用yml文件链接数据库异常
【10月更文挑战第3天】Spring Boot项目中数据库连接问题可能源于配置错误或依赖缺失。YAML配置文件的格式不正确,如缩进错误,会导致解析失败;而数据库驱动不匹配、连接字符串或认证信息错误同样引发连接异常。解决方法包括检查并修正YAML格式,确认配置属性无误,以及添加正确的数据库驱动依赖。利用日志记录和异常信息分析可辅助问题排查。
36 10
|
10天前
|
Java 关系型数据库 MySQL
SpringBoot项目使用yml文件链接数据库异常
【10月更文挑战第4天】本文分析了Spring Boot应用在连接数据库时可能遇到的问题及其解决方案。主要从四个方面探讨:配置文件格式错误、依赖缺失或版本不兼容、数据库服务问题、配置属性未正确注入。针对这些问题,提供了详细的检查方法和调试技巧,如检查YAML格式、验证依赖版本、确认数据库服务状态及用户权限,并通过日志和断点调试定位问题。
|
2月前
|
前端开发 小程序 Java
【规范】SpringBoot接口返回结果及异常统一处理,这样封装才优雅
本文详细介绍了如何在SpringBoot项目中统一处理接口返回结果及全局异常。首先,通过封装`ResponseResult`类,实现了接口返回结果的规范化,包括状态码、状态信息、返回信息和数据等字段,提供了多种成功和失败的返回方法。其次,利用`@RestControllerAdvice`和`@ExceptionHandler`注解配置全局异常处理,捕获并友好地处理各种异常信息。
352 0
【规范】SpringBoot接口返回结果及异常统一处理,这样封装才优雅
|
2月前
|
Java Spring UED
Spring框架的异常处理秘籍:打造不败之身的应用!
【8月更文挑战第31天】在软件开发中,异常处理对应用的稳定性和健壮性至关重要。Spring框架提供了一套完善的异常处理机制,包括使用`@ExceptionHandler`注解和配置`@ControllerAdvice`。本文将详细介绍这两种方式,并通过示例代码展示其具体应用。`@ExceptionHandler`可用于控制器类中的方法,处理特定异常;而`@ControllerAdvice`则允许定义全局异常处理器,捕获多个控制器中的异常。
41 0
|
2月前
|
Java API 开发者
【开发者福音】Spring Boot 异常处理:优雅应对错误,提升应用健壮性,让调试不再是噩梦!
【8月更文挑战第29天】本文通过对比传统错误处理方式与Spring Boot推荐的最佳实践,展示了如何在Spring Boot应用中实现统一且优雅的异常处理。传统方法需在每个可能出错的地方显式处理异常,导致代码冗余且不一致。而Spring Boot的全局异常处理机制则能集中处理所有异常,简化代码并确保错误响应格式统一,提高应用程序的健壮性和可维护性。文中提供了具体的示例代码以帮助读者更好地理解和应用这一机制。
78 0
|
2月前
|
消息中间件 Java 开发工具
【Azure 事件中心】Spring Cloud Stream Event Hubs Binder 发送Event Hub消息遇见 Spec. Rule 1.3 - onSubscribe, onNext, onError and onComplete signaled to a Subscriber MUST be signaled serially 异常
【Azure 事件中心】Spring Cloud Stream Event Hubs Binder 发送Event Hub消息遇见 Spec. Rule 1.3 - onSubscribe, onNext, onError and onComplete signaled to a Subscriber MUST be signaled serially 异常
|
2月前
|
Java Spring
【Azure 事件中心】Spring Boot 集成 Event Hub(azure-spring-cloud-stream-binder-eventhubs)指定Partition Key有异常消息
【Azure 事件中心】Spring Boot 集成 Event Hub(azure-spring-cloud-stream-binder-eventhubs)指定Partition Key有异常消息
|
2月前
|
Java Spring
【Azure 服务总线】Spring Cloud 的应用 使用Service Bus 引起 org.springframework.beans.BeanInstantiationException 异常,无法启动
【Azure 服务总线】Spring Cloud 的应用 使用Service Bus 引起 org.springframework.beans.BeanInstantiationException 异常,无法启动
|
2月前
|
NoSQL Java Redis
【Azure Spring Cloud】Java Spring Cloud 应用部署到Azure上后,发现大量的 java.lang.NullPointerException: null at io.lettuce.core.protocol.CommandHandler.writeSingleCommand(CommandHandler.java:426) at ... 异常
【Azure Spring Cloud】Java Spring Cloud 应用部署到Azure上后,发现大量的 java.lang.NullPointerException: null at io.lettuce.core.protocol.CommandHandler.writeSingleCommand(CommandHandler.java:426) at ... 异常
|
2月前
|
Dubbo Java Nacos
【实战攻略】破解Dubbo+Nacos+Spring Boot 3 Native打包后运行异常的终极秘籍——从零开始彻底攻克那些让你头疼不已的技术难题!
【8月更文挑战第15天】Nacos作为微服务注册与配置中心受到欢迎,但使用Dubbo+Nacos+Spring Boot 3进行GraalVM native打包后常遇运行异常。本文剖析此问题及其解决策略:确认GraalVM版本兼容性;配置反射列表以支持必要类和方法;采用静态代理替代动态代理;检查并调整配置文件;禁用不支持的功能;利用日志和GraalVM诊断工具定位问题;根据诊断结果调整GraalVM配置。通过系统排查方法,能有效解决此类问题,确保服务稳定运行。
76 0