首页 > 解决方案 > 如何在Java中重新排序json字符串中的字段

问题描述

我从抽象源收到一个String带有 json 的文件,我想重新排序该 json 中的字段,以便某些字段按指定顺序排在第一位,而其他未指定的字段可以按任何顺序排在前面。是否有一个库方法可以让我这样做:

// String reorderFields(String json, String[] orderedFields);

String res = reorderFields("{\"b\":2, \"c\": 3, \"a\":1}", new String[] {"a", "b", "c"});

Assertions.assertEquals("{\"a\":1,\"b\":2,\"c\":3}", res);

标签: javajsonstring

解决方案


以下是应该可以解决问题的解决方案。它仅适用于一级字段。它使用杰克逊进行 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}

推荐阅读