如何用@JsonValue移除JSON的items属性名且保留对象其他属性
如何在Jackson中生成包含无键数组的JSON结构?
我需要生成包含数组、Status和id三个属性的JSON,但不想显示数组对应的items属性名。尝试过以下方法但都有问题:
- 使用
@JsonValue注解时,生成的JSON会丢失status和id属性; - 试过
@JsonUnwrapped注解,无效; - 自定义了
ResponseSerializer序列化器,但存在多列表时服务会抛出异常。
期望的JSON格式
{ [ { "property1": "property", "property2": "property" } ], "Status": { "code": "code", "messages": [ { "message1": "message", "message2": "message" } ] }, "id": "123" }
不期望的JSON格式
{ "items": [ { "property1": "property", "property2": "property" } ], "Status": { "code": "code", "messages": [ { "message1": "message", "message2": "message" } ] }, "id": "123" }
现有代码
RetrieveResponse类
public class RetrieveResponse { //@JsonUnwrapped even i try this. @JsonValue private List<Response> items; private Status status; private String id; // 省略getter/setter }
Status类
public class Status { private String code; private List<Message> messages; // 省略getter/setter }
自定义序列化器(原)
public class ResponseSerializer extends JsonSerializer<List<Response>> { public static final TypeFactory TYPE_FACTORY = TypeFactory.defaultInstance(); public static final JavaType LIST_TYPE = TYPE_FACTORY.constructCollectionType(List.class, Response.class); @Override public void serialize(List<Response> responses, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException { jsonGenerator.writeStartArray(); for (Response item : responses) { jsonGenerator.writeObject(item); } jsonGenerator.writeEndArray(); } @Override public Class<List<Response>> handledType() { return (Class<List<Response>>) LIST_TYPE.getRawClass(); } }
解决方案:为RetrieveResponse编写自定义序列化器
问题出在之前的序列化器只针对List,无法同时处理整个对象的其他属性。我们需要为RetrieveResponse类编写专属的序列化器,手动控制整个JSON的生成逻辑:
1. 实现RetrieveResponseSerializer
public class RetrieveResponseSerializer extends JsonSerializer<RetrieveResponse> { @Override public void serialize(RetrieveResponse response, JsonGenerator gen, SerializerProvider serializers) throws IOException { gen.writeStartObject(); // 直接写入数组,不指定键名 gen.writeRawValue(serializers.findValueSerializer(List.class).serialize(response.getItems(), gen)); // 写入Status属性 gen.writeObjectField("Status", response.getStatus()); // 写入id属性 gen.writeStringField("id", response.getId()); gen.writeEndObject(); } }
2. 在RetrieveResponse类上添加注解
修改RetrieveResponse类,去掉@JsonValue,添加@JsonSerialize指定自定义序列化器:
@JsonSerialize(using = RetrieveResponseSerializer.class) public class RetrieveResponse { private List<Response> items; private Status status; private String id; // 保留getter/setter方法 }
为什么之前的方法无效?
@JsonValue:该注解会将整个对象序列化为注解属性的值,因此其他属性(status、id)会被忽略;@JsonUnwrapped:Jackson不支持对集合类型使用该注解,无法实现无键数组的效果;- 原自定义序列化器:仅针对List类型,当存在多个集合属性时会出现序列化逻辑冲突,导致异常。
内容的提问来源于stack exchange,提问作者LastMazon
相关产品推荐
相关产品推荐

