@ControllerAdvice处理异常,但不自定义响应

时间:2019-01-29 19:27:29

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

这是我的异常处理程序

@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?)

处理程序可以正常工作,但会引发错误,例如Follow

{
    "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

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

2 个答案:

答案 0 :(得分:-1)

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

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

答案 1 :(得分:-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"
}