Jackson 不抛出自定义异常

Jackson Not Throwing Custom Exception

提问人:Jossany Moura 提问时间:11/14/2023 更新时间:11/23/2023 访问量:50

问:

我的申请中有以下字段

@NotNull
    @JsonDeserialize(using = LocalDateDeserializer.class)
    @Schema(description = "BIRTH DATE", example = "1992-02-15")
    private LocalDate birthDate;

因此,我设置了以下 jackson 反序列化程序:

public class LocalDateDeserializer extends StdDeserializer<LocalDate> {

    private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd");

    protected LocalDateDeserializer() {
        super(LocalDate.class);
    }

    @Override
    public LocalDate deserialize(
            final JsonParser jsonParser,
            final DeserializationContext deserializationContext)
            throws IOException {
        JsonNode node = jsonParser.getCodec().readTree(jsonParser);
        String date = node.asText();

        try {
            return LocalDate.parse(date, DATE_TIME_FORMATTER);
        } catch (Exception e) {
            throw new InvalidDateFormatException("Invalid format" + date);
        }
    }
}

这是我的自定义异常类:

public class InvalidDateFormatException extends RuntimeException {
    public InvalidDateFormatException(final String message) {
        super(message);
    }
}

这是我的 ApplicationExceptionHandler 类:

@ControllerAdvice
public class ApplicationExceptionHandler extends ResponseEntityExceptionHandler {

    public static final String MISSING_HEADER_MESSAGE = "{0} header must be informed";

    @ExceptionHandler(InvalidDateFormatException.class)
    public ResponseEntity<String> handleInvalidDateFormatException(InvalidDateFormatException ex) {
        // Customize the response based on your needs
        return new ResponseEntity<>(ex.getMessage(), HttpStatus.BAD_REQUEST);
    }

当我发送格式错误的 birthDate 请求时,代码在反序列化程序中输入,捕获异常,但不会引发自定义错误。我刚刚得到了一个通用的 400,如下图所示:enter image description here

我没有更多关于如何解决这个问题的线索。

Java Spring-Boot 杰克逊

评论

0赞 Honza Zidek 11/14/2023
目前尚不清楚会发生什么。你说“异常被捕获,但自定义错误没有被抛出”,标题是“杰克逊没有抛出自定义异常”,但你真的确定这是真正发生的事情吗?将一些打印放入异常构造函数中,或使用调试器。我怀疑异常被抛出,但未错误处理程序捕获。请验证。顺便说一句,什么是“请购”?你是说请求吗?:)
0赞 Honza Zidek 11/14/2023
我有一个简单的理论,你应该使用 (docs.spring.io/spring-framework/docs/current/javadoc-api/org/...) 而不仅仅是 .什么是原始响应?是一些html代码吗?@RestControllerAdvice@ControllerAdvice

答:

1赞 Honza Zidek 11/14/2023 #1

请尝试使用 @RestControllerAdvice 而不是 。@ControllerAdvice

我相信您的代码实际上确实抛出了 ,但它没有像您预期的那样在以后处理。InvalidDateFormatException

您的问题的标题可能不应该是“Jackson Not Throwing Custom Exception”,而是“Rest Controller doesn't return error as JSON”或类似内容。

1赞 Henry Xiloj Herrera 11/22/2023 #2

只是我做了一些改变,希望能对你有所帮助。

我创建了 JacksonConfig,您可以检查我是否在此处调用了您的类(LocalDateDeserializer())

 import com.fasterxml.jackson.databind.ObjectMapper;
    import com.fasterxml.jackson.databind.module.SimpleModule;
    import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
    import com.henry.stackoverflowdemo.exception.LocalDateDeserializer;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;

    import java.time.LocalDate;

    @Configuration
    public class JacksonConfig {

    @Bean
    public ObjectMapper objectMapper() {
        ObjectMapper objectMapper = new ObjectMapper();

     
        objectMapper.registerModule(new JavaTimeModule());

       
        SimpleModule simpleModule = new SimpleModule();
        simpleModule.addDeserializer(LocalDate.class, new LocalDateDeserializer());
        objectMapper.registerModule(simpleModule);

        return objectMapper;
    } }

因此,请公开您的构造函数而不是受保护的构造函数

public LocalDateDeserializer() {
        super(LocalDate.class);
    }

ApplicationExceptionHandler 类中的一些更改:

@ControllerAdvice
public class ApplicationExceptionHandler {

    @ExceptionHandler({ InvalidDateFormatException.class })
    @ResponseStatus(value = HttpStatus.BAD_REQUEST)
    @ResponseBody
    public ResponseEntity<Object> handleInvalidDateFormatException(InvalidDateFormatException ex) {
        return new ResponseEntity<>(ex.getMessage(), createHeader(), HttpStatus.BAD_REQUEST);
    }
    
    private HttpHeaders createHeader() {
        HttpHeaders headers = new HttpHeaders();
        headers.add("Content-Type", "application/json; charset=UTF-8");
        return headers;
    }
}

删除@JsonDeserialize

@NotNull
    @Schema(description = "BIRTH DATE", example = "1992-02-15")
    private LocalDate birthDate;

我想在这种情况下,您使用 POST 请求应该是有效的。

0赞 Jossany Moura 11/23/2023 #3

真正解决我问题的是在bootstrap.yml中添加以下配置:

jackson:
    deserialization:
      wrap-exceptions: false