Bonita impressão JSON do ObjectMapper de Jackson 2.2

141

No momento eu tenho uma instância org.fasterxml.jackson.databind.ObjectMappere gostaria de obter uma Stringcom JSON bonito. Todos os resultados de minhas pesquisas no Google criaram maneiras Jackson 1.x de fazer isso e parece que não consigo encontrar a maneira correta e não obsoleta de fazer isso com o 2.2. Mesmo que eu não acredite que o código seja absolutamente necessário para esta pergunta, eis o que tenho agora:

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
fonte

Respostas:

277

Você pode ativar pretty-impressão, definindo o SerializationFeature.INDENT_OUTPUTem seu ObjectMapperassim:

mapper.enable(SerializationFeature.INDENT_OUTPUT);
gregwhitaker
fonte
1
Eu também tentei isso, mas parece que SerializationConfigestá resolvido, mas SerializationConfig.Featurenão é. Este parece ser outro método de impressão bonita que também está obsoleto, a menos que esteja faltando alguma coisa. Há uma Featureclasse que é separada por si própria, mas não tem uma INDENT_OUTPUTconstante interna. :(
Anthony Atkinson
Excelente! Eu adoraria saber como você descobriu que;)
Anthony Atkinson
1
Olhei para um dos meus projetos, mas parece que ele também está aqui: github.com/FasterXML/jackson-databind em "recursos mais usados"
gregwhitaker
A importação relevante necessária é a importação com.fasterxml.jackson.databind. {SerializationFeature, ObjectMapper}
dgh
2
no 2.2.1, foi o que foi necessário para mim: import org.codehaus.jackson.map.SerializationConfig.Feature; mapper.enable (Feature.INDENT_OUTPUT);
harschware
46

De acordo com mkyong , o encantamento mágico é defaultPrintingWritera impressão bonita JSON :

Versões mais recentes:

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

Versões mais antigas:

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

Parece que eu pulei a arma um pouco rapidamente. Você pode tentar o gson , cujo construtor suporta a impressão bonita :

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

Espero que isto ajude...

hd1
fonte
1
Encontrei este artigo e fiquei desapontado ao descobrir que essa é uma dessas maneiras obsoletas de imprimir bonito. defaultPrettyPrintingWriter()não está mais disponível (mesmo como um método obsoleto) na ObjectMapperclasse.
Anthony Atkinson
Eu estava realmente pensando em fazer isso, mas meu aplicativo já é fortemente orientado a Jackson e toda a funcionalidade está realmente completa. O servidor de aplicativos da web em que esse host será hospedado já está sendo tributado bastante e eu não gostaria de carregar bibliotecas extras simplesmente para registrar solicitações e respostas. Definitivamente vou votar sua resposta, no entanto.
Anthony Atkinson
7
@AnthonyAtkinson em Jackson 2,3 há um métodoObjectMapper.writerWithDefaultPrettyPrinter()
mate b
36

A API jackson mudou:

new ObjectMapper()
.writer()
.withDefaultPrettyPrinter()
.writeValueAsString(new HashMap<String, Object>());
Rian
fonte
3
Ainda é possível (com Jackson 2.7.6) usar new ObjectMapper().configure(SerializationFeature.INDENT_OUTPUT, true).writer().writeValueAsString(new HashMap<String, Object>());. Você só precisa se certificar de usar o gravador que obtém do configurado ObjectMapper.
Martin
3

o IDENT_OUTPUT não fez nada por mim e, para dar uma resposta completa que funcione com meus frascos 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
fonte
0

Se você deseja ativar isso por padrão para TODAS as instâncias do ObjectMapper em um processo, aqui está um pequeno truque que definirá o valor padrão de INDENT_OUTPUT como true:

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

se você estiver usando a combinação primavera e jackson, poderá fazê-lo da seguinte maneira. Estou seguindo @gregwhitaker como sugerido, mas implementando no estilo 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
fonte
0

Se outras pessoas que visualizarem essa pergunta tiverem apenas uma string JSON (não em um objeto), você poderá colocá-la em HashMape ainda ObjectMappertrabalhar. A resultvariável é sua sequência 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
fonte
-8

Tente isso.

 objectMapper.enable(SerializationConfig.Feature.INDENT_OUTPUT);
se sentir bem e programação
fonte
13
Duplicar a resposta escolhida após 7 meses não é realmente útil.
Igor Rodriguez
1
Pode ser útil para alguém, como mencionei em uma linha, me sinto bem em compartilhar o que sei.
sinta