Impresionante JSON desde el ObjectMapper de Jackson 2.2

141

En este momento tengo una instancia de org.fasterxml.jackson.databind.ObjectMappery me gustaría obtener una Stringcon JSON bonita. Todos los resultados de mis búsquedas en Google han encontrado formas Jackson 1.x de hacer esto y parece que no puedo encontrar la forma adecuada y no desaprobada de hacerlo con 2.2. Aunque no creo que el código sea absolutamente necesario para esta pregunta, esto es lo que tengo ahora:

ObjectMapper mapper = new ObjectMapper();
mapper.setSerializationInclusion(Include.NON_NULL);
System.out.println("\n\n----------REQUEST-----------");
StringWriter sw = new StringWriter();
mapper.writeValue(sw, jsonObject);
// Want pretty version of sw.toString() here
Anthony Atkinson
fuente

Respuestas:

277

Puede habilitar la impresión bonita configurando SerializationFeature.INDENT_OUTPUTen su ObjectMappergusto así:

mapper.enable(SerializationFeature.INDENT_OUTPUT);
gregwhitaker
fuente
1
También he intentado esto, pero parece que SerializationConfigestá resuelto pero SerializationConfig.Featureno lo está. Este parece ser otro método de impresión bonita que también está en desuso a menos que me falte algo. Hay una Featureclase que se separa por sí sola, pero que no tiene una INDENT_OUTPUTconstante en su interior. :(
Anthony Atkinson
¡Excelente! Me encantaría saber cómo lo encontraste;)
Anthony Atkinson
1
Miré uno de mis proyectos, pero parece que también está aquí: github.com/FasterXML/jackson-databind en "Características de uso común"
gregwhitaker
La importación relevante necesaria es import com.fasterxml.jackson.databind. {SerializationFeature, ObjectMapper}
dgh
2
en 2.2.1 esto es lo que me tomó: import org.codehaus.jackson.map.SerializationConfig.Feature; mapper.enable (Feature.INDENT_OUTPUT);
harschware
46

De acuerdo con mkyong , el encantamiento mágico es defaultPrintingWritera imprimir bastante JSON :

Nuevas versiones:

System.out.println(mapper.writerWithDefaultPrettyPrinter().writeValueAsString(jsonInstance));

Versiones mas antiguas:

System.out.println(mapper.defaultPrettyPrintingWriter().writeValueAsString(jsonInstance));

Parece que salté el arma un poco rápidamente. Puede probar gson , cuyo constructor admite la impresión bonita :

Gson gson = new GsonBuilder().setPrettyPrinting().create();
String jsonOutput = gson.toJson(someObject);

Espero que esto ayude...

hd1
fuente
1
Encontré este artículo y me decepcionó descubrir que esta es una de esas formas obsoletas de impresión bonita. defaultPrettyPrintingWriter()ya no está disponible (incluso como método obsoleto) en la ObjectMapperclase.
Anthony Atkinson
En realidad estaba pensando en hacer esto, pero mi aplicación ya está muy orientada a Jackson y toda la funcionalidad está realmente completa. El servidor de aplicaciones web en el que se alojará esto ya está sometido a grandes impuestos, y no me gustaría cargar bibliotecas adicionales simplemente para registrar solicitudes y respuestas. Sin embargo, definitivamente votaré tu respuesta.
Anthony Atkinson
77
@AnthonyAtkinson en Jackson 2.3 hay un métodoObjectMapper.writerWithDefaultPrettyPrinter()
mate b
36

La API de jackson ha cambiado:

new ObjectMapper()
.writer()
.withDefaultPrettyPrinter()
.writeValueAsString(new HashMap<String, Object>());
Rian
fuente
3
Todavía es posible (con Jackson 2.7.6) de usar new ObjectMapper().configure(SerializationFeature.INDENT_OUTPUT, true).writer().writeValueAsString(new HashMap<String, Object>());. Solo tiene que asegurarse de usar el escritor que obtiene de la configuración ObjectMapper.
Martin
3

IDENT_OUTPUT no hizo nada por mí, y para dar una respuesta completa que funcione con mis tarros jackson 2.2.3:

public static void main(String[] args) throws IOException {

byte[] jsonBytes = Files.readAllBytes(Paths.get("C:\\data\\testfiles\\single-line.json"));

ObjectMapper objectMapper = new ObjectMapper();

Object json = objectMapper.readValue( jsonBytes, Object.class );

System.out.println( objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString( json ) );
}
Stan Towianski
fuente
0

Si desea activar esto de forma predeterminada para TODAS las instancias de ObjectMapper en un proceso, aquí hay un pequeño truco que establecerá el valor predeterminado de INDENT_OUTPUT en verdadero:

val indentOutput = SerializationFeature.INDENT_OUTPUT
val defaultStateField = indentOutput.getClass.getDeclaredField("_defaultState")
defaultStateField.setAccessible(true)
defaultStateField.set(indentOutput, true)
Graham Lea
fuente
0

si está utilizando la combinación de primavera y jackson, puede hacerlo de la siguiente manera. Estoy siguiendo @gregwhitaker como se sugiere, pero implementando en estilo de primavera.

<bean id="objectMapper" class="com.fasterxml.jackson.databind.ObjectMapper">
    <property name="dateFormat">
        <bean class="java.text.SimpleDateFormat">
            <constructor-arg value="yyyy-MM-dd" />
            <property name="lenient" value="false" />
        </bean>
    </property>
    <property name="serializationInclusion">
        <value type="com.fasterxml.jackson.annotation.JsonInclude.Include">
            NON_NULL
        </value>
    </property>
</bean>

<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
    <property name="targetObject">
        <ref bean="objectMapper" />
    </property>
    <property name="targetMethod">
        <value>enable</value>
    </property>
    <property name="arguments">
        <value type="com.fasterxml.jackson.databind.SerializationFeature">
            INDENT_OUTPUT
        </value>
    </property>
</bean>
MohanaRao SV
fuente
0

Si otros que ven esta pregunta solo tienen una cadena JSON (no en un objeto), entonces puede ponerla en una HashMapy aún así hacer ObjectMapperque funcione. La resultvariable es su cadena JSON.

import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.HashMap;
import java.util.Map;

// Pretty-print the JSON result
try {
    ObjectMapper objectMapper = new ObjectMapper();
    Map<String, Object> response = objectMapper.readValue(result, HashMap.class);
    System.out.println(objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(response));
} catch (JsonParseException e) {
    e.printStackTrace();
} catch (JsonMappingException e) {
    e.printStackTrace();
} catch (IOException e) {
    e.printStackTrace();
} 
Azurespot
fuente
-8

Prueba esto.

 objectMapper.enable(SerializationConfig.Feature.INDENT_OUTPUT);
sentirse bien y programar
fuente
13
Duplicar la respuesta elegida después de 7 meses no es realmente útil.
Igor Rodriguez
1
podría ser útil para alguien como mencioné en una línea, me siento bien al compartir lo que sé.
sentirse bien y programar el