添加自定义HttpMessageConverter <t>

时间:2018-05-20 06:58:41

标签: java spring rest jackson spring-rest

我正在尝试向我的(Spring-powered)REST API添加自定义HttpMessageConverter<T>

@Configuration
public class SpringWebConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new BodyPrinterInterceptor());
    }

    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        final List<HttpMessageConverter> injectedConverters = new ArrayList<>();
        final SimpleModule module = new SimpleModule("module", new Version(1, 0, 0, null, null, null))
                .addSerializer(LocalDate.class, new LocalDateSerializer())
                .addDeserializer(LocalDate.class, new LocalDateDeserializer())
                .addSerializer(Type2_Numbers.class, new Type2_Numbers_Serializer())
                .addDeserializer(Type2_Numbers.class, new Type2_Numbers_Deserializer());

        final ObjectMapper objectMapper = new ObjectMapper()
                .enable(SerializationFeature.INDENT_OUTPUT)
                .registerModule(module);
        final MappingJackson2HttpMessageConverter converter1 = new MappingJackson2HttpMessageConverter();
        converter1.setObjectMapper(objectMapper);
        injectedConverters.add(converter1);

        final XmlMapper xmlMapper = new XmlMapper();
        xmlMapper.registerModule(module);
        xmlMapper.enable(SerializationFeature.INDENT_OUTPUT);
        final Jackson2ObjectMapperBuilder builder = Jackson2ObjectMapperBuilder.xml();
        final MappingJackson2XmlHttpMessageConverter converter2 = new MappingJackson2XmlHttpMessageConverter(builder.build());
        converter2.setObjectMapper(xmlMapper);
        injectedConverters.add(converter2);

        for (HttpMessageConverter injectedConverter : injectedConverters) {
            converters.add(injectedConverter);
        }
    }
}

似乎添加的转换器无法正常工作。 (不会调用序列化程序和反序列化程序)

问题 我如何正确添加HttpMessageConverters?

3 个答案:

答案 0 :(得分:1)

我相信您忘记在功能结束时致电super.configureMessageConverters(converters)

答案 1 :(得分:0)

<强>原因

在我的案例中导致问题的问题是添加一个已提供的HttpMessageConverters列表中已存在类型的自定义HttpMessageConverter将不会导致添加新的HttpMessageConverter,也不会更新相同类型的现有HttpMessageConverter。

<强>解决方案

如果它共享与要添加的新自定义HttpMessageConverter对象的相同类型,则首先从列表中删除现有的HttpMessageConverter对象来解决该问题。然后添加新的自定义HttpMessageConverter。

实施解决方案

Utils.java

public class Utils {
    public static void injectConverter(HttpMessageConverter converterToInject, List<HttpMessageConverter<?>> convertersList) {
        convertersList.removeIf(new Predicate<HttpMessageConverter<?>>() {
            @Override
            public boolean test(HttpMessageConverter<?> httpMessageConverter) {
                return converterToInject.getClass() == httpMessageConverter.getClass();
            }
        });
        convertersList.add(converterToInject);
    }
}

SpringWebConfig.java

@Configuration
public class SpringWebConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new BodyPrinterInterceptor());
    }

    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        final List<HttpMessageConverter> injectedConverters = new ArrayList<>();
        final SimpleModule module = new SimpleModule("module", new Version(1, 0, 0, null, null, null))
                .addSerializer(LocalDate.class, new LocalDateSerializer())
                .addDeserializer(LocalDate.class, new LocalDateDeserializer())
                .addSerializer(Type2_Numbers.class, new Type2_Numbers_Serializer())
                .addDeserializer(Type2_Numbers.class, new Type2_Numbers_Deserializer());

        final ObjectMapper objectMapper = new ObjectMapper()
                .enable(SerializationFeature.INDENT_OUTPUT)
                .registerModule(module);
        final MappingJackson2HttpMessageConverter converter1 = new MappingJackson2HttpMessageConverter();
        converter1.setObjectMapper(objectMapper);
        injectedConverters.add(converter1);

        final XmlMapper xmlMapper = new XmlMapper();
        xmlMapper.registerModule(module);
        xmlMapper.enable(SerializationFeature.INDENT_OUTPUT);
        final Jackson2ObjectMapperBuilder builder = Jackson2ObjectMapperBuilder.xml();
        final MappingJackson2XmlHttpMessageConverter converter2 = new MappingJackson2XmlHttpMessageConverter(builder.build());
        converter2.setObjectMapper(xmlMapper);
        injectedConverters.add(converter2);

        for (HttpMessageConverter injectedConverter : injectedConverters) {
            Utils.injectConverter(injectedConverter, converters);
        }

    }
}

答案 2 :(得分:0)

建议使用以下

@Bean
public HttpMessageConverters additionalConverters() {
    return new HttpMessageConverters(new YourCustomHttpMsgConverter());
}

然后使用GenericHttpMessageConverter扩展YourCustomHttpMsgConverter类

进一步编写覆盖方法的实现,包括canRead,read,canWrite,write,canRead,canWrite,getSupportedMediaTypes