RestTemplate을 사용할 때 내부 Jackson 매퍼를 어떻게 구성 할 수 있습니까?
Spring RestTemplate에서 사용하는 jackson 매퍼의 SerializationConfig.Feature ... 속성을 업데이트하고 싶습니다. 어떻게 액세스 할 수 있는지 또는 구성 할 수있는 위치를 알고 싶습니다.
기본 RestTemplate생성자는 다음 집합을 등록합니다 HttpMessageConverter.
this.messageConverters.add(new ByteArrayHttpMessageConverter());
this.messageConverters.add(new StringHttpMessageConverter());
this.messageConverters.add(new ResourceHttpMessageConverter());
this.messageConverters.add(new SourceHttpMessageConverter());
this.messageConverters.add(new XmlAwareFormHttpMessageConverter());
if (jaxb2Present) {
this.messageConverters.add(new Jaxb2RootElementHttpMessageConverter());
}
if (jacksonPresent) {
this.messageConverters.add(new MappingJacksonHttpMessageConverter());
}
if (romePresent) {
this.messageConverters.add(new AtomFeedHttpMessageConverter());
this.messageConverters.add(new RssChannelHttpMessageConverter());
}
는 MappingJacksonHttpMessageConverter회전에 만들어 ObjectMapper직접 인스턴스를. 이 변환기를 찾아서 그 ObjectMapper전에 새 변환기를 교체 하거나 등록 할 수 있습니다 . 이것은 작동합니다.
@Bean
public RestOperations restOperations() {
RestTemplate rest = new RestTemplate();
//this is crucial!
rest.getMessageConverters().add(0, mappingJacksonHttpMessageConverter());
return rest;
}
@Bean
public MappingJacksonHttpMessageConverter mappingJacksonHttpMessageConverter() {
MappingJacksonHttpMessageConverter converter = new MappingJacksonHttpMessageConverter();
converter.setObjectMapper(myObjectMapper());
return converter;
}
@Bean
public ObjectMapper myObjectMapper() {
//your custom ObjectMapper here
}
XML에서는 다음과 같은 내용이 있습니다.
<bean id="restOperations" class="org.springframework.web.client.RestTemplate">
<property name="messageConverters">
<util:list>
<bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter"/>
<bean class="org.springframework.http.converter.StringHttpMessageConverter"/>
<bean class="org.springframework.http.converter.ResourceHttpMessageConverter"/>
<bean class="org.springframework.http.converter.xml.SourceHttpMessageConverter"/>
<bean class="org.springframework.http.converter.xml.XmlAwareFormHttpMessageConverter"/>
<bean class="org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter"/>
<bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
<property name="objectMapper" ref="customObjectMapper"/>
</bean>
</util:list>
</property>
</bean>
<bean id="customObjectMapper" class="org.codehaus.jackson.map.ObjectMapper"/>
전환은 실제로 1 : 1이 아닙니다. messageConvertersXML 로 명시 적으로 목록을 만들어야 하는 반면, @Configuration접근 방식 을 사용 하면 기존 목록을 참조하고 간단히 수정할 수 있습니다. 그러나 이것은 작동합니다.
Spring IOC를 사용하지 않는 경우 다음과 같이 할 수 있습니다 (Java 8).
ObjectMapper objectMapper = new ObjectMapper();
// configure your ObjectMapper here
RestTemplate restTemplate = new RestTemplate();
MappingJackson2HttpMessageConverter messageConverter = new MappingJackson2HttpMessageConverter();
messageConverter.setPrettyPrint(false);
messageConverter.setObjectMapper(objectMapper);
restTemplate.getMessageConverters().removeIf(m -> m.getClass().getName().equals(MappingJackson2HttpMessageConverter.class.getName()));
restTemplate.getMessageConverters().add(messageConverter);
RestTemplate will initialize its default message converters. You should replace the MappingJackson2HttpMessageConverter with your own bean, which should use the object mapper you want to use. This worked for me:
@Bean
public RestTemplate restTemplate() {
final RestTemplate restTemplate = new RestTemplate();
//find and replace Jackson message converter with our own
for (int i = 0; i < restTemplate.getMessageConverters().size(); i++) {
final HttpMessageConverter<?> httpMessageConverter = restTemplate.getMessageConverters().get(i);
if (httpMessageConverter instanceof MappingJackson2HttpMessageConverter){
restTemplate.getMessageConverters().set(i, mappingJackson2HttpMessageConverter());
}
}
return restTemplate;
}
@Bean
public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() {
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
converter.setObjectMapper(myObjectMapper());
return converter;
}
@Bean
public ObjectMapper myObjectMapper() {
// return your own object mapper
}
To complete the other answers: if your ObjectMapper just registers a Jackson Module with custom serializers/deserializers, you might want to register your module directly on the existing ObjectMapper from RestTemplate's default MappingJackson2HttpMessageConverter as follows (example without DI but the same applies if using DI):
SimpleModule module = new SimpleModule();
module.addSerializer(...);
module.addDeserializer(...);
MappingJackson2HttpMessageConverter messageConverter = restTemplate.getMessageConverters().stream()
.filter(MappingJackson2HttpMessageConverter.class::isInstance)
.map(MappingJackson2HttpMessageConverter.class::cast)
.findFirst().orElseThrow( () -> new RuntimeException("MappingJackson2HttpMessageConverter not found"));
messageConverter.getObjectMapper().registerModule(module);
This will allow you to complete the configuration of the original ObjectMapper (as done by Spring's Jackson2ObjectMapperBuilder), instead of replacing it.
'Program Club' 카테고리의 다른 글
| 환경 설정이 변경되었는지 감지하는 방법은 무엇입니까? (0) | 2020.11.04 |
|---|---|
| THREE.js에서 텍스처 사용 (0) | 2020.11.04 |
| cmd 파일에서 %와 %%의 차이점은 무엇입니까? (0) | 2020.11.04 |
| Node.js에서 POST 요청을 사용하여 파일 업로드 (0) | 2020.11.04 |
| Elixir : .ex 사용시기 및 .exs 파일시기 (0) | 2020.11.04 |