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

Respuestas:


277

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

mapper.enable(SerializationFeature.INDENT_OUTPUT);

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...


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

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

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)

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>

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

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.