SpringBoot 向前端返回数组对象,对象里面的键无序,@JsonPropertyOrder LinkedHashMap无效
时间: 2024-05-11 21:13:46 浏览: 258
问题描述
在 SpringBoot 中,当向前端返回一个数组对象时,对象里面的键是无序的。通过使用 @JsonPropertyOrder 注解指定键的顺序,但是该注解似乎无效。
问题分析
在 Java 中,Map 接口的实现类 HashMap 是无序的,LinkedHashMap 则是有序的。因此,当使用 @JsonPropertyOrder 注解来指定键的顺序时,实际上是针对 LinkedHashMap 的,而不是针对 HashMap。在 SpringBoot 中,默认使用的是 Jackson 库来处理 JSON 数据,Jackson 库在反序列化 JSON 数据时,会将 JSON 数据转换成 LinkedHashMap 对象,因此 @JsonPropertyOrder 注解对于 LinkedHashMap 是有效的。但是,在将 LinkedHashMap 对象序列化成 JSON 数据时,Jackson 库会将 LinkedHashMap 对象转换成 HashMap 对象,因此 @JsonPropertyOrder 注解对于 HashMap 是无效的。
解决方法
1. 使用 LinkedHashMap
将对象中的 Map 属性改为 LinkedHashMap 类型,这样在将对象序列化成 JSON 数据时,Jackson 库不会将 LinkedHashMap 对象转换成 HashMap 对象,@JsonPropertyOrder 注解就可以生效了。
2. 使用 @JsonSerialize
使用 @JsonSerialize 注解,可以指定自定义的序列化器来控制 JSON 数据的输出顺序。示例代码如下:
```java
@JsonSerialize(using = CustomSerializer.class)
public class CustomObject {
private Map<String, Object> data;
// getter and setter
}
public class CustomSerializer extends JsonSerializer<CustomObject> {
@Override
public void serialize(CustomObject value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
gen.writeStartObject();
LinkedHashMap<String, Object> data = new LinkedHashMap<>(value.getData());
for (Map.Entry<String, Object> entry : data.entrySet()) {
gen.writeObjectField(entry.getKey(), entry.getValue());
}
gen.writeEndObject();
}
}
```
在 CustomObject 类上,使用 @JsonSerialize 注解指定 CustomSerializer 作为序列化器。在 CustomSerializer 中,将 CustomObject 中的 Map 属性转换成 LinkedHashMap,然后遍历 LinkedHashMap,按照指定的顺序输出 JSON 数据,这样就可以实现键有序输出了。
参考链接
1. https://stackoverflow.com/questions/29214776/jsonpropertyorder-not-working-for-json-arrays
2. https://stackoverflow.com/questions/54952412/jsonpropertyorder-not-working-with-spring-boot-2-1-3-and-jackson-2-9-8
阅读全文