API 接口中的空数组怎么表示?

最近开发一个 API, 使用者说这个 API 中返回数组如果为空, 按照规范应该返回空数组[], 而我现在使用 Java 的 jackson-databind 返回的是 null, 要问改成[].

例子:
Java POJO 类:

class Person {
    String name = "eric";
    List<String> events = Collections.emptyList();
    //省略 getter, setter
}
  1. 我的返回:

    {"name":"eric","events":null}
  2. 他期望的返回:

    {"name":"eric","events":[]}

    可以看到, 主要区别是如何序列化空数组. 除了上面的2种方式, 还有一种方式:

  3. 忽略空值:

    {"name":"eric"}

首先, 我们先介绍如何实现上面的1, 2, 3 各种方式的序列化, 然后再对比这个所谓"规范"到底值得推荐吗?

  1. 如何实现第一种方式: Jackson 的默认实现, 不需要做任何改动.
  2. 如何实现第三种方式:
    2.1 如果你只有1个或很少的 POJO Java bean, 可以使用这个 Annotation

    @JsonInclude(JsonInclude.Include.NON_EMPTY)
    class Person {

    2.2 如果你有多个或不确定的个数, 可以更改 ObjectMapper 的配置:

    ObjectMapper om = new ObjectMapper();
    om.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);
  3. 如何实现第二种方式:
    3.1 如果你有少数的几个 POJO Java bean,可以把那个列表给个默认值, 如:

    List<String> events = new ArrayList<>();
    //或者:
    List<String> events = Collections.emptyList();

    3.2 定制 Jackson 的序列化机制 JacksonAnnotationIntrospector & ArrayNullSerializer:

    class EmptyArrayJacksonAnnotationIntrospector extends JacksonAnnotationIntrospector {
      
      @Override
      public Object findNullSerializer(Annotated a) {
          if (List.class.isAssignableFrom(a.getRawType())) {
              return ArrayNullSerializer.INSTANCE;
          }
          return super.findNullSerializer(a);
      }
    }
    
    final class ArrayNullSerializer extends StdSerializer<Object> {
      public static final ArrayNullSerializer INSTANCE = new ArrayNullSerializer();
      
      protected ArrayNullSerializer() {
          super(Object.class);
      }
    
      @Override
      public void serialize(Object value, JsonGenerator gen, SerializerProvider provider) throws IOException {
          gen.writeStartArray();
          gen.writeEndArray();
      }
    }
    
    //然后使用:
    ObjectMapper om = new ObjectMapper();
    om.setAnnotationIntrospector(new EmptyArrayJacksonAnnotationIntrospector());

虽然上面3种实现我们都做到了, 那么到底他说的这种规范是真的有用吗? 还是混乱制造者?

标签: none

添加新评论