Spring Download: various ObjectMapper instances for request and response

I have a controller in my spring boot application:

@RequestMapping(method = RequestMethod.POST)
public ResponseEntity<ResponseDto<MyClass> process(@RequestBody RequestDto<MyClass> request){
    return null;
}

MyClasshas a field, say 'myField', and I need a different configuration NamingStrategyfor request and response for this field (this is because I do not want to create a new class for only one field). I configured the instance ObjectMapperas shown below:

@Bean
public ObjectMapper objectMapper(){
    ObjectMapper objectMapper = new ObjectMapper();
    objectMapper.setPropertyNamingStrategy(namingStrategy);
    return objectMapper;
}

This will be used for both request and response (for example, deserialization and serialization), is there any way to load spring, with which I can instruct the controller to use different instances ObjectMapper?

+4
source share
3 answers

. -, HttpMessageConverter. , , Content-Type application/test+json:

@Bean
public HttpMessageConverters customConverters() {
    final AbstractJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(new ObjectMapper());
    converter.setSupportedMediaTypes(Collections.singletonList(MediaType.valueOf("application/test+json")));

    return new HttpMessageConverters(true, Collections.singletonList(converter));
}

ObjectMapper - .

, , appliction/test+json ( , Content-Type:application/test+json ):

@RequestMapping(method = RequestMethod.POST, consumes = "application/test+json")
public ResponseEntity<ResponseDto<MyClass> process(@RequestBody RequestDto<MyClass> request){
    return null;
}

, , Content-Type:application/test+json . , , .

+2

: MyClass, mapper ( ) ( ).

.

spring.
0

ObjectMapper, . :

    public class FeatureModifyingBeanDeserializerModifier extends BeanDeserializerModifier {

        private Collection<Class<?>> modifiedClasses;

        public FeatureModifyingBeanDeserializerModifier(Collection<Class<?>> modifiedClasses) {
            this.modifiedClasses = Collections.unmodifiableSet(new HashSet<Class<?>>(modifiedClasses));
        }

        @Override
        public JsonDeserializer<?> modifyDeserializer(
                DeserializationConfig config, BeanDescription beanDesc, final JsonDeserializer<?> deserializer) {
            JsonDeserializer<?> result = deserializer;
            Class<?> beanClass = beanDesc.getBeanClass();

            if (modifiedClasses.contains(beanClass)) {
                result = new FeatureModifyingStdDeserializer(deserializer, beanClass);
            }
            return result;
        }

        private static class FeatureModifyingStdDeserializer extends StdDeserializer<Object> {

            private JsonDeserializer<?> deserializer;

            private FeatureModifyingStdDeserializer(
JsonDeserializer<?> deserializer, Class<?> beanClass) {
                super(beanClass);
                this.deserializer = deserializer;
            }

            @Override
            public Object deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
                p.enable(JsonParser.Feature.ALLOW_BACKSLASH_ESCAPING_ANY_CHARACTER);
                return deserializer.deserialize(p, ctxt);
            }
        }      
    }

You need to register it using ObjectMapper as a module:

ObjectMapper objectMapper = new ObjectMapper();
SimpleModule module = new SimpleModule();

module.setDeserializerModifier(new FeatureModifyingBeanDeserializerModifer(Arrays.asList(Journey.class)));
objectMapper.registerModule(module);

For serialization, you can add the @JsonSerialize annotation to the Journey class and serialize it in any way. If you need to write a string without saving, you can use writeRaw from JsonGenerator.

0
source

Source: https://habr.com/ru/post/1671867/


All Articles