API 接口中的空数组怎么表示?
最近开发一个 API, 使用者说这个 API 中返回数组如果为空, 按照规范应该返回空数组[]
, 而我现在使用 Java 的 jackson-databind 返回的是 null
, 要问改成[]
.
例子:
Java POJO 类:
class Person {
String name = "eric";
List<String> events = Collections.emptyList();
//省略 getter, setter
}
我的返回:
{"name":"eric","events":null}
他期望的返回:
{"name":"eric","events":[]}
可以看到, 主要区别是如何序列化空数组. 除了上面的2种方式, 还有一种方式:
忽略空值:
{"name":"eric"}
首先, 我们先介绍如何实现上面的1, 2, 3 各种方式的序列化, 然后再对比这个所谓"规范"到底值得推荐吗?
- 如何实现第一种方式: Jackson 的默认实现, 不需要做任何改动.
如何实现第三种方式:
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.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种实现我们都做到了, 那么到底他说的这种规范是真的有用吗? 还是混乱制造者?