【问题标题】:JSON String tidy/formatter for Java [closed]Java的JSON字符串整洁/格式化程序[关闭]
【发布时间】:2012-01-25 15:20:29
【问题描述】:

我有一个有效的 JSON 字符串,我想对其进行整理/格式化,这样每个属性/值对都在其自己的行上,等等(目前它在一行上,没有空格/换行符)。

我正在使用 Apache Sling JSONObject 对我的 JSON 对象进行建模并将其转换为字符串,因此如果可以将 Sling JSONObject 设置为输出一个整洁的字符串(我认为它不能),那将也可以工作。

如果我需要一个 3rd 方库,我会更喜欢依赖项尽可能少的库(例如 Jackson,它只需要 std JDK 库)。

【问题讨论】:

    标签: java json string formatting


    【解决方案1】:

    使用 gson 你可以做到:

    JsonParser parser = new JsonParser();
    Gson gson = new GsonBuilder().setPrettyPrinting().create();
    
    JsonElement el = parser.parse(jsonString);
    jsonString = gson.toJson(el); // done
    

    【讨论】:

    • “更好的 Java JSON 库”链接已损坏
    【解决方案2】:

    许多 JSON 库都有一个特殊的 .toString(int indentation) 方法

    // if it's not already, convert to a JSON object
    JSONObject jsonObject = new JSONObject(jsonString);
    // To string method prints it with specified indentation
    System.out.println(jsonObject.toString(4));
    

    【讨论】:

    • 这适用于org.apache.sling.commons.json.JSONObjectorg.json.JSONObject
    【解决方案3】:

    您不需要外部库。

    使用 Sling 的 JSONObject 中内置的漂亮打印机:http://sling.apache.org/apidocs/sling5/org/apache/sling/commons/json/JSONObject.html#toString(int)

    public java.lang.String toString(int indentFactor) 抛出 JSONException

    制作此 JSONObject 的漂亮打印 JSON 文本。警告:此方法假定 数据结构是非循环的。

    参数:

    indentFactor - 添加到每个级别的空格数 的缩进。

    返回:可打印、可显示、可移植、 对象的可传输表示,以 { 开头(左 大括号)并以 } 结尾(右大括号)。

    抛出:JSONException - 如果 对象包含无效数字。

    【讨论】:

    • JSONObject.getString(value) 方法是否有效,当有一些意图时?
    • @Erich - 不知道。试试看!
    【解决方案4】:
    public static String formatJSONStr(final String json_str, final int indent_width) {
        final char[] chars = json_str.toCharArray();
        final String newline = System.lineSeparator();
    
        String ret = "";
        boolean begin_quotes = false;
    
        for (int i = 0, indent = 0; i < chars.length; i++) {
            char c = chars[i];
    
            if (c == '\"') {
                ret += c;
                begin_quotes = !begin_quotes;
                continue;
            }
    
            if (!begin_quotes) {
                switch (c) {
                case '{':
                case '[':
                    ret += c + newline + String.format("%" + (indent += indent_width) + "s", "");
                    continue;
                case '}':
                case ']':
                    ret += newline + ((indent -= indent_width) > 0 ? String.format("%" + indent + "s", "") : "") + c;
                    continue;
                case ':':
                    ret += c + " ";
                    continue;
                case ',':
                    ret += c + newline + (indent > 0 ? String.format("%" + indent + "s", "") : "");
                    continue;
                default:
                    if (Character.isWhitespace(c)) continue;
                }
            }
    
            ret += c + (c == '\\' ? "" + chars[++i] : "");
        }
    
        return ret;
    }
    

    【讨论】:

    • 很好,这在没有任何外部库的情况下工作。不过,我会在这里做一些更改:遵循 java 编码约定并使用 StringBuilder 而不是字符串连接。
    【解决方案5】:

    +1 表示 JohnS 的 gson 答案,但这是使用“标准”JSONObject 库的一种方式:

    public class JsonFormatter{
    
        public static String format(final JSONObject object) throws JSONException{
            final JsonVisitor visitor = new JsonVisitor(4, ' ');
            visitor.visit(object, 0);
            return visitor.toString();
        }
    
        private static class JsonVisitor{
    
            private final StringBuilder builder = new StringBuilder();
            private final int indentationSize;
            private final char indentationChar;
    
            public JsonVisitor(final int indentationSize, final char indentationChar){
                this.indentationSize = indentationSize;
                this.indentationChar = indentationChar;
            }
    
            private void visit(final JSONArray array, final int indent) throws JSONException{
                final int length = array.length();
                if(length == 0){
                    write("[]", indent);
                } else{
                    write("[", indent);
                    for(int i = 0; i < length; i++){
                        visit(array.get(i), indent + 1);
                    }
                    write("]", indent);
                }
    
            }
    
            private void visit(final JSONObject obj, final int indent) throws JSONException{
                final int length = obj.length();
                if(length == 0){
                    write("{}", indent);
                } else{
                    write("{", indent);
                    final Iterator<String> keys = obj.keys();
                    while(keys.hasNext()){
                        final String key = keys.next();
                        write(key + " :", indent + 1);
                        visit(obj.get(key), indent + 1);
                        if(keys.hasNext()){
                            write(",", indent + 1);
                        }
                    }
                    write("}", indent);
                }
    
            }
    
            private void visit(final Object object, final int indent) throws JSONException{
                if(object instanceof JSONArray){
                    visit((JSONArray) object, indent);
                } else if(object instanceof JSONObject){
                    visit((JSONObject) object, indent);
                } else{
                    if(object instanceof String){
                        write("\"" + (String) object + "\"", indent);
                    } else{
                        write(String.valueOf(object), indent);
                    }
                }
    
            }
    
            private void write(final String data, final int indent){
                for(int i = 0; i < (indent * indentationSize); i++){
                    builder.append(indentationChar);
                }
                builder.append(data).append('\n');
            }
    
            @Override
            public String toString(){
                return builder.toString();
            }
    
        }
    
    }
    

    用法:

    public static void main(final String[] args) throws JSONException{
        final JSONObject obj =
                new JSONObject("{\"glossary\":{\"title\": \"example glossary\", \"GlossDiv\":{\"title\": \"S\", \"GlossList\":{\"GlossEntry\":{\"ID\": \"SGML\", \"SortAs\": \"SGML\", \"GlossTerm\": \"Standard Generalized Markup Language\", \"Acronym\": \"SGML\", \"Abbrev\": \"ISO 8879:1986\", \"GlossDef\":{\"para\": \"A meta-markup language, used to create markup languages such as DocBook.\", \"GlossSeeAlso\": [\"GML\", \"XML\"]}, \"GlossSee\": \"markup\"}}}}}");
        System.out.println(JsonFormatter.format(obj));
    }
    

    输出:

    {
        glossary :
        {
            title :
            "example glossary"
            ,
            GlossDiv :
            {
                GlossList :
                {
                    GlossEntry :
                    {
                        SortAs :
                        "SGML"
                        ,
                        GlossDef :
                        {
                            GlossSeeAlso :
                            [
                                "GML"
                                "XML"
                            ]
                            ,
                            para :
                            "A meta-markup language, used to create markup languages such as DocBook."
                        }
                        ,
                        GlossSee :
                        "markup"
                        ,
                        GlossTerm :
                        "Standard Generalized Markup Language"
                        ,
                        ID :
                        "SGML"
                        ,
                        Acronym :
                        "SGML"
                        ,
                        Abbrev :
                        "ISO 8879:1986"
                    }
                }
                ,
                title :
                "S"
            }
        }
    }
    

    【讨论】:

      【解决方案6】:

      杰克逊方式:

      private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
      ...
      OBJECT_MAPPER.writerWithDefaultPrettyPrinter().writeValueAsString(node);
      

      【讨论】:

      • objectMapper.valueToTree(obj).toPrettyString() 解决了我的问题。
      【解决方案7】:

      JSON 字符串将有一个前导“[”和一个尾随“]”。删除这些,然后使用 String 中的 split 方法将项目分隔到一个数组中。然后,您可以遍历您的数组并将数据放入相关区域。

      【讨论】:

        【解决方案8】:

        如果您使用 CQ5 或任何基于 JCR 的 CMS,我猜 :)

        您可以使用 java json 解析器来完成这项工作。它有一个 JSONObject 类和一个 toString() 方法将其转换为字符串。

        更多参考参考

        http://json.org/java/

        【讨论】:

        • 不知道我是如何忽略它的,但是 JSONObject.toString() 有一个覆盖方法 .toString(int indent) ,它在使用时会美化 JSON 字符串表示。然而,仅仅调用 JSONObject.toString() 并没有。
        【解决方案9】:

        Underscore-java 有统计方法U.formatJson(json)。我是图书馆的维护者。

        U.formatJson("{\"a\":{\"b\":\"data\"}}");
        
        // {
        //    "a": {
        //      "b": "data"
        //    }
        // }
        

        【讨论】:

          猜你喜欢
          • 2010-09-28
          • 1970-01-01
          • 1970-01-01
          • 2011-08-27
          • 2021-01-12
          • 2022-09-30
          • 2022-01-22
          • 2013-09-24
          相关资源
          最近更新 更多