在我的应用程序中,我将Jackson配置为全局使用SerializationFeature.WRAP_ROOT_VALUE
和DeserializationFeature.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响应。因此,我有一个服务类,该服务类使用RestTemplate
和RestTemplateBuilder
到REST-Webservice的一些数据来构建POST
。
@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
?
答案 0 :(得分:0)
就像JB Nizet所说,可能是通过将Jakson的MappingJackson2HttpMessageConverter
和ObjectMapper
的新实例设置为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;
}