2011-12-21 9 views
14

Tengo una cadena JSON válida que quiero ordenar/formatear de modo que cada par propiedad/valor esté en su propia línea, etc. (actualmente está en una línea sin espacios/línea descansos).JSON String tidy/formateador para Java

estoy usando el Apache Sling JSONObject para modelar mi JSON objeto y convertirlo en una cadena, por lo que si la honda JSONObject se puede ajustar a la salida de una cadena ordenada (que no creo que se puede) que funcionaría también.

Si necesito una lib de 3ra parte, preferiría una pocas dependencias como sea posible (como Jackson, que solo requiere las libs estándar de JDK).

Respuesta

18

usted no necesita una biblioteca exterior.

utiliza el incorporado en la impresora bonita en JSONObject de honda: http://sling.apache.org/apidocs/sling5/org/apache/sling/commons/json/JSONObject.html#toString(int)

public java.lang.String toString (int indentFactor) lanza JSONException

Hacer un texto JSON prettyprinted de esta JSONObject. Advertencia: Este método asume que la estructura de datos es acíclica.

Parámetros:

indentFactor - El número de espacios para añadir a cada nivel de sangría.

Devuelve: una representación transmisible, visualizable, portátil, transmisible del objeto, que comienza con {(a la izquierda corsé) y termina con} (corchete derecho).

Throws: JSONException - Si el objeto contiene un número no válido.

+0

¿Funciona el método 'JSONObject.getString (value)', cuando hay alguna intención? – Erich

+1

@Erich - No tengo idea. Pruébalo y mira! – Freiheit

+3

Sí, lo he probado. – Erich

1

La cadena JSON tendrá un "[" inicial y un final "]". Quítelos y luego use el método de división de String para separar los elementos en una matriz. Luego puede iterar a través de su matriz y colocar los datos en áreas relevantes.

1

si el uso de CQ5 o cualquier CMS basado JCR ya que supongo :)

puede utilizar Java JSON analizador para hacer el trabajo. tiene una clase JSONObject y un método toString() para convertirlo a String.

para mayor referencia se refieren

http://json.org/java/

+1

No estoy seguro de cómo me lo pasó por alto, pero el JSONObject.toString() tiene un método de reemplazo .toString (int guión) que cuando se utiliza prettifies la representación JSON de cadena. Simplemente llamando a JSONObject.toString() sin embargo, no lo hace. – empire29

31

Con GSON que puede hacer:

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

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

"Una mejor biblioteca Java JSON" está roto – Jay

7

+1 para la respuesta GSON de Johns, pero aquí es una manera con la biblioteca JSONObject "estándar":

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

    } 

} 

Uso:

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

Salida:

{ 
    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

Muchas bibliotecas JSON tienen un método especial .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

esto funciona con 'org.apache.sling.commons.json.JSONObject' y' 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

Bueno, esto funcionó sin ninguna biblioteca externa. Sin embargo, haré aquí algunos cambios: siga las convenciones de codificación Java y use StringBuilder en lugar de la concatenación de cadenas. – andronix