【问题标题】:Build Jacksons ObjectMapper in particular case when global settings are configured在配置全局设置的特定情况下构建 Jacksons ObjectMapper
【发布时间】:2019-11-14 19:49:10
【问题描述】:

在我的应用程序中,我将 Jackson 配置为全局使用 SerializationFeature.WRAP_ROOT_VALUEDeserializationFeature.UNWRAP_ROOT_VALUE

@Configuration
public class AppConfig {

    public Jackson2ObjectMapperBuilder jacksonBuilder() {
        Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
        builder.featuresToEnable(SerializationFeature.WRAP_ROOT_VALUE, DeserializationFeature.UNWRAP_ROOT_VALUE);
        return builder;
    }
}

此配置工作正常,但现在我处于deserialization 的情况下,我得到一个没有rootname 的 JSON 响应。所以我有一个服务类,它使用RestTemplateBuilderPOST 构建一个RestTemplate 一些数据到一个REST-Webservice。

@Service
public class ApiServiceImpl
        implements ApiService<RegisterResponse> {

    private RestTemplate restTemplate;

    public ApiServiceImpl(RestTemplateBuilder restTemplateBuilder) {
        restTemplate = restTemplateBuilder
                .errorHandler(new RestTemplateResponseErrorHandler()).build();
    }

    @Override
    public ResponseEntity<RegisterResponse> callAPI(String requestAsJson,
            String username, String password) {
        ResponseEntity<RegisterResponse> result = null;
        HttpHeaders headers = getHeaders(username, password);

        result = restTemplate.exchange(uri, HttpMethod.POST,
                new HttpEntity<String>(requestAsJson, headers),
                RegisterResponse.class);

        return result;
    }
}

响应如下所示:

{
    "redirect-url": "https://any-url.com/?with=params"
}

我想直接将其反序列化为以下 POJO。 (就像在 restTemplate.exchange 中配置的一样)

public class RegisterResponse {

    @JsonProperty("redirect-url")
    private String redirectUrl;
    //getter/setter
}

由于UNWRAP_ROOT_VALUE 特性,很明显会得到这个异常:

com.fasterxml.jackson.databind.exc.MismatchedInputException: Root name 'redirect-url' does not match expected ('RegisterResponse') for type [simple type, class xxx.xxx.xxxservice.xxx.model.response.entity.RegisterResponse]
 at [Source: (String)"{
    "redirect-url": "https://any-url.com/?with=params"
}"; line: 2, column: 5]
    at com.fasterxml.jackson.databind.exc.MismatchedInputException.from(MismatchedInputException.java:59)
    at com.fasterxml.jackson.databind.DeserializationContext.reportInputMismatch(DeserializationContext.java:1356)
    at com.fasterxml.jackson.databind.ObjectMapper._unwrapAndDeserialize(ObjectMapper.java:4087)

如何将Jackson 配置为在这种特殊情况下不使用DeserializationFeature.UNWRAP_ROOT_VALUE

【问题讨论】:

  • 在 RestTemplate 的转换器列表中获取 MappingJackson2HttpMessageConverter 类型的消息转换器,并将其 ObjectMapper 设置为禁用 UNWRAP_ROOT_VALUE 功能的另一个 ObjectMapper 实例。

标签: java spring spring-boot jackson resttemplate


【解决方案1】:

就像 JB Nizet 评论的那样,它可能通过将 Jakson 的 MappingJackson2HttpMessageConverterObjectMapper 的新实例设置到 MessageConverters 列表中。

restTemplate.getMessageConverters().add(getCustomConverter());

private MappingJackson2HttpMessageConverter getCustomConverter() {
        ObjectMapper mapper = new ObjectMapper();
        mapper.enable(DeserializationFeature.UNWRAP_ROOT_VALUE);
        mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);

        MappingJackson2HttpMessageConverter customConverter = 
            new MappingJackson2HttpMessageConverter(mapper);
        if (!restTemplate.getMessageConverters()
                .removeIf(MappingJackson2HttpMessageConverter.class::isInstance)) {
            new RuntimeException("Custom MappingJackson2HttpMessageConverter not found");
        }
        return customConverter;
    }

【讨论】:

    猜你喜欢
    • 2022-12-10
    • 2011-02-02
    • 2014-10-19
    • 1970-01-01
    • 1970-01-01
    • 2015-12-25
    • 1970-01-01
    • 1970-01-01
    • 2018-12-11
    相关资源
    最近更新 更多