我想通过杰克逊连载一篇Map<String,Foo> foosMap分的文章.现在,我想对序列化过程进行以下两个设置:

  1. The Map can have have plenty of null values and null keys and I don't want nulls to be serialized.
  2. For all those Foos that are getting serialized, I do not want to serialize null objects referenced inside Foo.

实现这一目标的最佳方式是什么?我用的是jackson-core1.9和jackson-mapper1.我的项目中有9个罐子.

推荐答案

If it's reasonable to alter the original Map data structure to be serialized to better represent the actual value wanted to be serialized, that's probably a decent approach, which would possibly reduce the amount of Jackson configuration necessary. For example, just remove the null key entries, if possible, before calling Jackson. That said...


要禁止使用空值序列化Map个条目,请执行以下操作:

Before Jackson 2.9

您仍然可以使用WRITE_NULL_MAP_VALUES,但请注意,它已移动到SerializationFeature:

mapper.configure(SerializationFeature.WRITE_NULL_MAP_VALUES, false);

Since Jackson 2.9

The WRITE_NULL_MAP_VALUES is deprecated, you can use the below equivalent:

mapper.setDefaultPropertyInclusion(
   JsonInclude.Value.construct(Include.ALWAYS, Include.NON_NULL))

要禁止使用空值序列化属性,可以使用configure the ObjectMapper directly@JsonInclude注释:

mapper.setSerializationInclusion(Include.NON_NULL);

or:

@JsonInclude(Include.NON_NULL)
class Foo
{
  public String bar;

  Foo(String bar)
  {
    this.bar = bar;
  }
}

据我所知,要处理null Map键,一些自定义序列化是必要的.

A simple approach to serialize null keys as empty strings (including complete examples of the two previously mentioned configurations):

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.SerializerProvider;

public class JacksonFoo
{
  public static void main(String[] args) throws Exception
  {
    Map<String, Foo> foos = new HashMap<String, Foo>();
    foos.put("foo1", new Foo("foo1"));
    foos.put("foo2", new Foo(null));
    foos.put("foo3", null);
    foos.put(null, new Foo("foo4"));

    // System.out.println(new ObjectMapper().writeValueAsString(foos));
    // Exception: Null key for a Map not allowed in JSON (use a converting NullKeySerializer?)

    ObjectMapper mapper = new ObjectMapper();
    mapper.configure(SerializationFeature.WRITE_NULL_MAP_VALUES, false);
    mapper.setSerializationInclusion(Include.NON_NULL);
    mapper.getSerializerProvider().setNullKeySerializer(new MyNullKeySerializer());
    System.out.println(mapper.writeValueAsString(foos));
    // output: 
    // {"":{"bar":"foo4"},"foo2":{},"foo1":{"bar":"foo1"}}
  }
}

class MyNullKeySerializer extends JsonSerializer<Object>
{
  @Override
  public void serialize(Object nullKey, JsonGenerator jsonGenerator, SerializerProvider unused) 
      throws IOException, JsonProcessingException
  {
    jsonGenerator.writeFieldName("");
  }
}

class Foo
{
  public String bar;

  Foo(String bar)
  {
    this.bar = bar;
  }
}

要禁止使用null个键序列化Map个条目,需要进行进一步的自定义序列化处理.

Json相关问答推荐

Elasticsearch Go客户端错误:无效的SON格式:在中间件中索引文档时出错

无法根据vega规范中的条件设置文本 colored颜色

Vega-Lite:文本笔画在外部

使用Jolt将字符串数组转换为JSON对象数组

属性错误:';ActivitiesClient';对象没有属性';base_url';

JQ:获取该值的较短语法是什么

bash用jq获取第二条JSON记录

使用 jolt 变换压平具有公共列 JSON 的复杂嵌套

Golang jsonrpc2 服务器在哪里监听?

Jolt 变换以展平 json 字符串数组

在 PowerShell 中通过 aws cli 创建 cloudwatch alert 时出现字符串解析错误

如何强制仅有一个元素的数组在JSON中生成方括号

使用 serde 和 csv crates 将嵌套的 json 对象序列化为 csv

如何对使用转换器的 Grails 服务进行单元测试?

Rails:format.js 或 format.json,或两者兼而有之?

如何从 HttpClient 解析 JSON 字符串?

在 Apache Spark 中读取多行 JSON

如何将 LinkedTreeMap 转换为 gson JsonObject

带有 Jackson 的不可变 Lombok 注释类

Microsoft.Net.Http 与 Microsoft.AspNet.WebApi.Client