【问题标题】:@ControllerAdvice handle the exception but not customize response@ControllerAdvice 处理异常但不自定义响应
【发布时间】:2019-06-23 00:16:48
【问题描述】:

这是我的异常处理程序

@ControllerAdvice(basePackageClasses = [SignUpController::class])
class ControllerAdvice: ResponseEntityExceptionHandler() {

    @ExceptionHandler(Exception::class)
    @ResponseBody
    fun handleControllerException(request: HttpServletRequest, ex: Throwable): ResponseEntity<*> {
        val status = HttpStatus.CONFLICT
        return ResponseEntity<Any>(ApiError(status.value(), ex.message), status)
    }
}

还有我的自定义类

data class ApiError(val status: Int, val message: String?)

处理程序正常工作,但抛出错误,如下所示

{
    "timestamp": "2019-01-29T19:17:22.541+0000",
    "status": 401,
    "error": "Unauthorized",
    "message": "could not execute statement; SQL [n/a]; constraint [null]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement",
    "path": "/sign-up"
}

但我应该关注类似的东西

{
    "apierror": {
        "status": ...,
        "message": ..."
    }
}

我是本教程的基础

https://www.toptal.com/java/spring-boot-rest-api-error-handling https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-error-handling https://medium.com/@jovannypcg/understanding-springs-controlleradvice-cd96a364033f

我做错了什么?我缺少任何配置?

【问题讨论】:

标签: spring spring-boot kotlin error-handling exception-handling


【解决方案1】:

我的解决方法是,但不是正确的答案

application.yaml

server:
  error:
    include-exception: true

在我的控制器上,我正在检查电子邮件和用户名是否存在并将客户消息抛出异常

@RestController
@RequestMapping("/register")
class RegisterController: BaseController() {

    @ResponseStatus(HttpStatus.CREATED)
    @PostMapping("/save")
    fun register(@RequestBody user: ApplicationUser) {
        if (userRepository.existsByEmail(user.email)) {
            throw DataIntegrityViolationException("Email already exists")
        }
        if (userRepository.existsByUsername(user.username)) {
            throw DataIntegrityViolationException("Username already exists")
        }
        user.password = bCryptPasswordEncoder.encode(user.password)
        userRepository.save(user)
    }
}

返回效果很好

{
    "timestamp": "2019-01-31T17:08:40.832+0000",
    "status": 500,
    "error": "Internal Server Error",
    "exception": "org.springframework.dao.DataIntegrityViolationException",
    "message": "Email already exists", //here is
    "path": "/register/save"
}

【讨论】:

    【解决方案2】:

    您需要使用以下内容注释您的 ApiError 类:

    @Data 
    @JsonTypeInfo(
                include = JsonTypeInfo.As.WRAPPER_OBJECT,
                use = JsonTypeInfo.Id.CUSTOM, 
                property = "error",
                visible = true
    ) 
    @JsonTypeIdResolver(LowerCaseClassNameResolver.class)
    

    【讨论】:

      猜你喜欢
      • 2018-07-13
      • 1970-01-01
      • 1970-01-01
      • 2014-08-26
      • 1970-01-01
      • 2022-10-14
      • 2019-07-06
      • 1970-01-01
      相关资源
      最近更新 更多