以下是应该可以解决问题的解决方案。它仅适用于一级字段。它使用杰克逊进行 json 处理。由于它仅对基本类型进行操作(没有自定义序列化器/反序列化器),因此可以安全地用于所有可能的 json 类型。
import java.util.Arrays;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
public class ReorderFieldsTest {
public static String reorderFieldsInJson(String json, String[] fields) {
ObjectMapper objectMapper = new ObjectMapper();
Map<String, Object> jsonMap;
try {
jsonMap = objectMapper.readValue(json, new TypeReference<Map<String, Object>>() {
});
} catch (Exception e) {
throw new RuntimeException("Error converting json to map", e);
}
Map<String, Object> resMap = new LinkedHashMap<>();
Set<String> orderedFields = new HashSet<>(Arrays.asList(fields));
for (String fieldName : fields) {
Object val = jsonMap.get(fieldName);
if (val != null) {
resMap.put(fieldName, val);
}
}
for (Entry<String, Object> entry : jsonMap.entrySet()) {
if (orderedFields.contains(entry.getKey())) {
continue;
}
resMap.put(entry.getKey(), entry.getValue());
}
try {
return objectMapper.writeValueAsString(resMap);
} catch (JsonProcessingException e) {
throw new RuntimeException("Error converting map to json", e);
}
}
@Test
public void jsonReorder_validInput_reorderedOutput() {
String src = "{\"b\":2, \"c\": 3, \"a\":1}";
String res = reorderFieldsInJson(src, new String[] {"a", "b"});
Assertions.assertEquals("{\"a\":1,\"b\":2,\"c\":3}", res);
}
}
Java 11 和 jackson 2.11.3 上的结果:
org:
{"b":2, "c": 3, "a":1}
ordered:
{"a":1,"b":2,"c":3}