Spring Boot 2.5.0 Jersey JSON反序列化未生效自定义ObjectMapper配置
问题:Jersey Client无法使用Spring Boot自定义ObjectMapper
场景概述
我正在搭建一个Kotlin Spring Boot应用,服务层通过Jersey调用DropWizard API,API层控制器使用Spring MVC类与注解。已将Jersey配置为过滤器,将404请求转发给Spring MVC,以支持两种请求类型。
我抽象出ApiUtils类处理JAX-RS请求的构建、执行与响应处理,该类标记为@Component,通过@Autowired构造器注入初始化:
public ApiUtils(Client jerseyClient, ObjectMapper mapper, ServiceNameProvider serviceNameProvider) { this.client = jerseyClient; // this.client = ClientBuilder.newClient(); this.mapper = mapper; this.serviceName = serviceNameProvider.getServiceName(); //in case a jersey client is inserted with a ClientBuilder.newClient() no object mapper //is registered; to avoid fall back to default register the given mapper if (this.client != null && this.client.getConfiguration() != null && !this.client.getConfiguration().isRegistered(JacksonJsonProvider.class) && !this.client.getConfiguration().isRegistered(JacksonFeature.class) ) { this.client.register(new JacksonJsonProvider(this.mapper)); } }
问题现象
尽管Spring Boot配置的@Primary自定义ObjectMapper已注入到ApiUtils中,但其配置始终不生效。即使创建新Client并注册该ObjectMapper,结果仍相同——ApiUtils中打印的ObjectMapper配置与预期一致,但实际反序列化时就是不生效。
例如我已将DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES设为false,但遇到未知属性时反序列化仍失败,只有给待反序列化类添加@JsonIgnoreProperties(ignoreUnknown = true)注解后才成功。
启动时能看到自定义ObjectMapper在Jersey和Jackson自动配置类中注册,但报错信息显示使用的是未自定义的默认ObjectMapper。
当前配置代码
MyCustomObjectMapper(自定义ObjectMapper)
@Configuration @Primary class MyCustomObjectMapper : ObjectMapper() { init { val kotlinModule: KotlinModule = KotlinModule.Builder() .configure(KotlinFeature.NullIsSameAsDefault, true) .configure(KotlinFeature.StrictNullChecks, true) .configure(KotlinFeature.NullToEmptyCollection, true) .configure(KotlinFeature.NullToEmptyMap, true) .configure(KotlinFeature.SingletonSupport, true) .build() this.registerModules( kotlinModule, JavaTimeModule(), Jdk8Module(), ) ... // deserialization configuration this.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) ... } }
JacksonConfig(Jersey的ObjectMapper上下文解析器)
@Provider class JacksonConfig : ContextResolver<ObjectMapper> { @Autowired private lateinit var objectMapper: MyCustomObjectMapper override fun getContext(type: Class<*>?): ObjectMapper { return objectMapper } }
JerseyConfig(Jersey配置类)
@Configuration @ApplicationPath(JERSEY_API_PATH) class JerseyConfig : ResourceConfig() { init { register(packages("eu.mypackage.services.web.cg.configuration")); register(packages("eu.mypackage.services.web.cg.controller")); register(EndpointJerseyLoggingListener(JERSEY_API_PATH)); properties = mapOf( ServerProperties.RESPONSE_SET_STATUS_OVER_SEND_ERROR to true, ServletProperties.FILTER_FORWARD_ON_404 to true ) } }
疑问
- 是否是Spring MVC导致了该问题?尽管ApiUtils中并未使用它。
- 有无其他方式让Jersey Client使用自定义ObjectMapper并注入到外部Java ApiUtils类中?
内容的提问来源于stack exchange,提问作者Slice of Code
相关产品推荐
相关产品推荐

