【问题标题】:Serializer/Deserializer for Vavr objectsVavr 对象的序列化器/反序列化器
【发布时间】:2018-02-27 08:44:04
【问题描述】:

您好,我正在尝试将 vavr 添加到我的项目中,现在我正在努力正确序列化 Vavr.List 对象。下面是我的控制器:

import io.vavr.collection.List;

 @GetMapping(value = "/xxx")
    public List<EntityDeleted> getFile() {
        return List.of(new EntityDeleted(true),new EntityDeleted(true),new EntityDeleted(true),new EntityDeleted(true));
}

EntityDeleted 是我的自定义对象,List 是 Vavr 集合,如导入语句中所示。我在 Postman 中得到的响应是:

{
    "empty": false,
    "lazy": false,
    "async": false,
    "traversableAgain": true,
    "sequential": true,
    "singleValued": false,
    "distinct": false,
    "ordered": false,
    "orNull": {
        "deleted": true
    },
    "memoized": false
}

我期望我的对象的 JSON 列表。以下是我的配置:

@SpringBootApplication
public class PlomberApplication {

    public static void main(String[] args) {
        SpringApplication.run(PlomberApplication.class, args);
    }

    @Bean
    public ObjectMapper jacksonBuilder() {
        ObjectMapper mapper = new ObjectMapper();
        return mapper.registerModule(new VavrModule());
    }
}

还有一些 pom.xml

 <dependency>
            <groupId>io.vavr</groupId>
            <artifactId>vavr</artifactId>
            <version>0.9.0</version>
        </dependency>
        <dependency>
            <groupId>io.vavr</groupId>
            <artifactId>vavr-jackson</artifactId>
            <version>0.9.0</version>
        </dependency>

【问题讨论】:

    标签: java spring-boot jackson vavr


    【解决方案1】:

    Spring Boot 检索 com.fasterxml.jackson.databind.Module 类的所有实例并用它们初始化 ObjectMapper。不需要额外的魔法。

    我的依赖如下(Spring Boot 1.5.7.RELEASE):

    dependencies {
        compile('org.springframework.boot:spring-boot-starter-web')
        testCompile('org.springframework.boot:spring-boot-starter-test')
        compile group: 'io.vavr', name: 'vavr', version: '0.9.1'
        compile group: 'io.vavr', name: 'vavr-jackson', version: '0.9.1'
    }
    

    应用程序配置如下:

    @SpringBootApplication
    public class BootvavrApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(BootvavrApplication.class, args);
        }
    
        @Bean
        Module vavrModule() {
            return new VavrModule();
        }
    }
    

    和控制器映射如下:

    import io.vavr.collection.List;
    @RestController
    class TestController {
    
        @GetMapping("/test")
        List<String> testing() {
            return List.of("test", "test2");
        }
    }
    

    输出是:

    ["test","test2"]
    

    您可以在此处查看代码:https://github.com/mihn/bootvavr

    【讨论】:

    • 我找到了解决方案,我在我的一个配置类中有 @EnableWebMvc 注释,它以某种方式将我的配置覆盖到映射器
    • 哦!那可能会这样做。 :)
    • 删除@EnableWebMvc 也为我解决了完全相同的问题。
    • 我的 WebFlux 应用程序中遇到了完全相同的问题。删除 @EnableWebFlux 对我也有帮助。
    【解决方案2】:

    我不熟悉 SpringBoot,但您似乎应该在 jacksonBuilder() 方法中返回 VavrModule 对象而不是 ObjectMapper

    我基于这些链接:

    【讨论】:

    • 试过@Bean public Module jacksonBuilder() { return new VavrModule(); } 但它不工作。我认为某些东西正在覆盖我的 Mapper..
    【解决方案3】:

    您注册为 bean 的 ObjectMapper 不是用于序列化为 JSON 的那个,Spring MVC 不会使用它,因为它不是他想要的。

    要处理 HTTP Spring MVC 的内容,使用 HttpMessageConverter,如果他在类路径中检测到 Jackson,如果未指定,则会自动配置 MappingJackson2HttpMessageConverter

    在 Spring Boot 中添加应该足以注册自定义 MessageConverter:

    @Bean  
    public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() {
        MappingJackson2HttpMessageConverter jacksonConverter = new MappingJackson2HttpMessageConverter();   
        ObjectMapper mapper = new ObjectMapper();
    
        mapper.registerModule(new VavrModule());
    
        // Spring MVC default Objectmapper configuration
        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        mapper.configure(MapperFeature.DEFAULT_VIEW_INCLUSION, false);
    
        jacksonConverter.setObjectMapper(mapper);   
        return jacksonConverter;  
    }
    

    在纯 Spring MVC 应用程序中,您必须在 WebMvcConfigurerAdapter 类中包含以下代码:

    @Bean  
    public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() {
        MappingJackson2HttpMessageConverter jacksonConverter = new MappingJackson2HttpMessageConverter();   
        ObjectMapper mapper = new ObjectMapper();
    
        mapper.registerModule(new VavrModule());
    
        // Spring MVC default Objectmapper configuration
        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        mapper.configure(MapperFeature.DEFAULT_VIEW_INCLUSION, false);
    
        jacksonConverter.setObjectMapper(mapper);   
        return jacksonConverter;  
    }
    
    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        converters.add(customJackson2HttpMessageConverter());
        super.addDefaultHttpMessageConverters();
    }
    

    Some Documentation about ObjectMapper in Spring MVC

    希望对您有所帮助!

    【讨论】:

    • 我也试过了,但仍然得到与第一篇文章相同的结果
    • 除了@Bean 之外,您是否尝试添加@Primary?您使用的是哪个版本的 Spring Boot?
    猜你喜欢
    • 2021-08-14
    • 2018-07-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-15
    相关资源
    最近更新 更多