tutorial servicios restful restcontroller mvc example español ejemplo spring jackson

spring - servicios - ¿Cómo podemos configurar el mapeador interno de Jackson cuando usamos RestTemplate?



spring rest tutorial (4)

Quiero actualizar SerializationConfig.Feature ... propiedades del mapeador de jackson utilizado por Spring RestTemplate, cualquier idea de cómo puedo acceder a él o dónde puedo / debo configurarlo.


Para completar las otras respuestas: si su ObjectMapper solo registra un Module Jackson con serializadores / deserializadores personalizados, es posible que desee registrar su módulo directamente en el ObjectMapper existente desde el RestTemplate predeterminado de MappingJackson2HttpMessageConverter siguiente manera (ejemplo sin DI, lo mismo aplica si usa 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);

Esto le permitirá completar la configuración del ObjectMapper original (como lo hizo Jackson2ObjectMapperBuilder ), en lugar de reemplazarlo.


RestTemplate inicializará sus conversores de mensajes predeterminados. Debería reemplazar el MappingJackson2HttpMessageConverter con su propio bean, que debería usar el asignador de objetos que desea usar. Esto funcionó para mí:

@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 }


Si no está utilizando Spring IOC, puede hacer algo como esto (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);


El constructor RestTemplate predeterminado registra un conjunto de HttpMessageConverter s:

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()); }

El MappingJacksonHttpMessageConverter por turnos, crea la instancia de ObjectMapper directamente. Puede encontrar este convertidor y reemplazar ObjectMapper o registrar uno nuevo antes. Esto debería funcionar:

@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 }

En XML, es algo en esta línea:

<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"/>

Tenga en cuenta que la transición no es realmente 1: 1 - Tengo que crear explícitamente la lista @Configuration en XML, mientras que con el enfoque @Configuration podría hacer referencia al existente y simplemente modificarlo. Pero esto debería funcionar