在 Spring Boot 项目中启用 Multimap 的 json 序列化

hel*_*elt 3 serialization json jackson guava spring-boot

我想在 Spring Boot 应用程序中序列化一些 google guava Multimap。

public class SomeDTO {
    @JsonProperty
    Multimap<A, B> prop = HashMultimap.create();
}
Run Code Online (Sandbox Code Playgroud)

不使用定制的杰克逊序列化器,我得到一些结果

{
   "prop ":
   {
       "empty": false
   }
}
Run Code Online (Sandbox Code Playgroud)

这绝对不是我想要的。我想到了这样的事情:

{
  "nodes": {
    "key0": [
      {
        "prop0": 2,
        "prop1": 4
      },
      {
        "prop0": 5,
        "prop1": 6
      }
    ],
    "key1": [
      {
        "prop0": 23,
        "prop1": 0
      }
    ]
  }
}
Run Code Online (Sandbox Code Playgroud)

添加

        <dependency>
            <groupId>com.fasterxml.jackson.datatype</groupId>
            <artifactId>jackson-datatype-guava</artifactId>
            <version>${jackson.version}</version>
        </dependency>
Run Code Online (Sandbox Code Playgroud)

到 pom.xml 似乎还不够......但是,我只是从整个春天 // 关键宇宙开始,所以我想我错过了一些明显的东西。

hel*_*elt 8

我想出的解决方案只是@Bean在我的 main 中添加一个@Configuration:

import com.fasterxml.jackson.databind.Module;
import com.fasterxml.jackson.datatype.guava.GuavaModule;
// More-obvious imports missing

@Configuration
@EnableAutoConfiguration
@ComponentScan
public class Application extends SpringBootServletInitializer {

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

    @Override
    protected final SpringApplicationBuilder configure(final SpringApplicationBuilder application) {
        return application.sources(Application.class);
    }

    @Bean
    ObjectMapper customizeJacksonConfiguration() {
        ObjectMapper om = new ObjectMapper();
        om.registerModule(new GuavaModule());
        return om;
    }
}
Run Code Online (Sandbox Code Playgroud)

Afaik,ObjectMapperBean 方法有一个缺点:每次以这种方式创建 ObjectMapper 时,所有先前的配置都会被丢弃。

如果要向jackson添加模块- 而不是覆盖以前的配置,这种方法更好:

import com.fasterxml.jackson.databind.Module;
import com.fasterxml.jackson.datatype.guava.GuavaModule;
// More-obvious imports missing

@Configuration
@EnableAutoConfiguration
@ComponentScan
public class Application extends SpringBootServletInitializer {

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

    @Override
    protected final SpringApplicationBuilder configure(final SpringApplicationBuilder application) {
        return application.sources(Application.class);
    }

    @Bean
    public Module guavaModule() {
        return new GuavaModule();
    }
}
Run Code Online (Sandbox Code Playgroud)