gpt4 book ai didi

java - Jackson JsonParseExceptionMapper 和 JsonMappingExceptionMapper 阴影自定义映射器

转载 作者:行者123 更新时间:2023-12-01 10:13:17 25 4
gpt4 key购买 nike

我的项目使用 Spring Boot + Jersey 2。

我为 JsonParseException 创建了自定义 Jackson 映射器,但它没有被调用,而是使用了标准的 Jackson JsonParseExceptionMapper。

我的自定义映射器:

 package com.rmn.gfc.common.providers;
import ...

@Provider
public class JsonParseExceptionHandler implements ExceptionMapper<JsonParseException> {
@Override
public Response toResponse(JsonParseException exception) {
return Response
.status(Response.Status.BAD_REQUEST)
// entity ...
.build();
}
}

我像这样注册我的映射器:
@Component
public class OrderServiceResourceConfig extends ResourceConfig {
public OrderServiceResourceConfig() {
packages("com.rmn.gfc.common.providers");
}
}

我确信映射器注册很好,因为这个包中的其他自定义映射器正在工作,但 JsonParseException 的一个映射器被 Jersey 标准 JsonParseExceptionMapper 遮住了。

我如何用我的实现覆盖标准的 Jackson JsonParseExceptionMapper?

最佳答案

你可以怪JacksonFeature
JacksonFeature 如果 JacksonJaxbJsonProvider ,为 Jackson 异常注册默认异常映射器未注册。而这正是你不想要的。

相关部分见source code :

// Register Jackson.
if (!config.isRegistered(JacksonJaxbJsonProvider.class)) {
// add the default Jackson exception mappers
context.register(JsonParseExceptionMapper.class);
context.register(JsonMappingExceptionMapper.class);
...
}


Spring Boot 注册 JacksonFeature
Spring Boot 的 JerseyAutoConfiguration 类将注册 JacksonFeature 如果它在类路径上。相关部分见 source code :

@ConditionalOnClass(JacksonFeature.class)
@ConditionalOnSingleCandidate(ObjectMapper.class)
@Configuration
static class JacksonResourceConfigCustomizer {

...

@Bean
public ResourceConfigCustomizer resourceConfigCustomizer(
final ObjectMapper objectMapper) {
addJaxbAnnotationIntrospectorIfPresent(objectMapper);
return (ResourceConfig config) -> {
config.register(JacksonFeature.class);
config.register(new ObjectMapperContextResolver(objectMapper),
ContextResolver.class);
};
}

...
}


解决方法

作为解决方法,您可以注册 JacksonJaxbJsonProvider 然后注册您的自定义异常映射器(或者只是用 @Provider 注释它们以被 Jersey 自动发现):

@Component
public class OrderServiceResourceConfig extends ResourceConfig {

public OrderServiceResourceConfig() {
packages("com.rmn.gfc.common.providers");
register(JacksonJaxbJsonProvider.class);
// Register other providers
}
}

查看文档对 JacksonJaxbJsonProvider 的说明:

JSON content type provider automatically configured to use both Jackson and JAXB annotations (in that order of priority). Otherwise functionally same as JacksonJsonProvider.



替代方案

或者,您可以摆脱 jersey-media-json-jackson Artifact 和使用 jackson-jaxrs-json-provider 反而。有了这个,你将摆脱 JacksonFeature 然后你可以注册你自己的异常映射器。

这是在这个 answer中提到的.

什么似乎是正确的解决方案

请参阅以下来自 JAX-RS 2.1 specification 的引用:

4.1.3 Priorities

Application-supplied providers enable developers to extend and customize the JAX-RS runtime. Therefore, an application-supplied provider MUST always be preferred over a pre-packaged one if a single one is required.

Application-supplied providers may be annotated with @Priority. If two or more providers are candidates for a certain task, the one with the highest priority is chosen: the highest priority is defined to be the one with the lowest value in this case. That is, @Priority(1) is higher than @Priority(10). If two or more providers are eligible and have identical priorities, one is chosen in an implementation dependent manner.

The default priority for all application-supplied providers is javax.ws.rs.Priorities.USER. The general rule about priorities is different for filters and interceptors since these providers are collected into chains.



正如 Kysil Ivan 的 answer 中指出的那样, 编写自己的异常映射器并赋予高优先级,例如 1 .如果你使用自动发现,只需用 @Provider 注释它和 @Priority .

@Provider
@Priority(1)
public class JsonParseExceptionMapper implements ExceptionMapper<JsonParseException> {
...
}

如果您手动注册您的提供商,您可以 give your provider a binding priority :

@ApplicationPath("/")
public class MyResourceConfig extends ResourceConfig {

public MyResourceConfig() {
register(JsonParseExceptionMapper.class, 1);
}
}

关于java - Jackson JsonParseExceptionMapper 和 JsonMappingExceptionMapper 阴影自定义映射器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45478512/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com