2011-12-21 20 views
14

Ho una stringa JSON valida che desidero ordinare/formattare in modo tale che ogni coppia di proprietà/valore si trovi sulla propria riga, ecc. (Attualmente si trova su una riga w nessuno spazio/riga pause).JSON String tidy/formatter per Java

Sto usando Apache Sling JSONObject per modellare il mio JSON oggetto e trasformarlo in una stringa, quindi se la Sling JSONObject può essere impostato per l'uscita di una stringa ordinata (che non credo che si può), che avrebbe funzionato anche.

Se ho bisogno di una libreria di terze parti, preferirei che meno dipendenze possibili (come Jackson che richiede solo le librerie JDK std).

risposta

18

non hai bisogno di una libreria esterna.

utilizzare il costruito nel bel stampante JSONObject di Sling: http://sling.apache.org/apidocs/sling5/org/apache/sling/commons/json/JSONObject.html#toString(int)

java.lang.String toString (int indentFactor) getta JSONException

Fare un testo prettyprinted JSON di questo JSONObject. Avviso: questo metodo presuppone che la struttura dati sia aciclica.

Parametri:

indentFactor - Il numero di spazi da aggiungere ad ogni livello di rientro.

Restituzioni: una rappresentazione trasmissibile stampabile, visualizzabile, dell'oggetto, che inizia con {(sinistra parentesi graffa) e termina con} (parentesi graffa destra).

Generi: JSONException - Se l'oggetto contiene un numero non valido.

+0

Il metodo 'JSONObject.getString (valore)' funziona, quando c'è qualche intenzione? – Erich

+1

@Erich - Nessuna idea. Provalo e guarda! – Freiheit

+3

Sì, l'ho provato. – Erich

1

La stringa JSON avrà un "[" e un finale "]" iniziali. Rimuovere questi e quindi utilizzare il metodo split da String per separare gli elementi in un array. È quindi possibile scorrere l'array e posizionare i dati in aree pertinenti.

1

Se la vostra utilizzando CQ5 o qualsiasi basato JCR CMS come io immagino :)

è possibile utilizzare Java JSON parser per fare il lavoro. ha una classe JSONObject e un metodo toString() per convertirlo in String.

per ulteriore riferimento si riferiscono

http://json.org/java/

+1

Non so quanto ho trascurato, ma il JSONObject.toString() ha un metodo di override .toString (int trattino), che quando viene utilizzato prettifies la rappresentazione JSON String. Tuttavia, chiamare semplicemente JSONObject.toString() non lo fa. – empire29

31

Con GSON si può fare:

JsonParser parser = new JsonParser(); 
Gson gson = new GsonBuilder().setPrettyPrinting().create(); 

JsonElement el = parser.parse(jsonString); 
jsonString = gson.toJson(el); // done 
+0

Il collegamento "Una libreria Java JSON migliore" è interrotto – Jay

7

+1 per la risposta GSON di Johns, ma ecco un modo con la libreria "standard" 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(); 
     } 

    } 

} 

Usage:

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)); 
} 

uscita:

{ 
    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" 
     } 
    } 
} 
13

Molte librerie JSON hanno uno speciale metodo .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)); 
+0

funziona con 'org.apache.sling.commons.json.JSONObject' e' org.json.JSONObject' –

2
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; 
} 
+0

Nice, questo ha funzionato senza alcuna libreria esterna. Tuttavia, apporterei alcune modifiche: seguire le convenzioni di codifica java e utilizzare StringBuilder anziché la concatenazione di stringhe. – andronix