Ładnie drukuje JSON z ObjectMapper Jacksona 2.2

141

W tej chwili mam wystąpienie org.fasterxml.jackson.databind.ObjectMapperi chciałbym uzyskać plik Stringz ładnym JSON. Wszystkie wyniki moich wyszukiwań w Google przyniosły Jackson 1.x sposoby zrobienia tego i nie mogę znaleźć właściwego, niezalecanego sposobu zrobienia tego w wersji 2.2. Chociaż nie uważam, że kod jest absolutnie niezbędny do tego pytania, oto, co mam teraz:

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
źródło

Odpowiedzi:

277

Można włączyć całkiem-drukowania poprzez ustawienie SerializationFeature.INDENT_OUTPUTna własną ObjectMappertak:

mapper.enable(SerializationFeature.INDENT_OUTPUT);
gregwhitaker
źródło
1
Próbowałem również tego, ale wydaje się, że SerializationConfigjest to rozwiązane, ale SerializationConfig.Featuretak nie jest. Wydaje się, że jest to kolejna metoda ładnego drukowania, która również jest przestarzała, chyba że czegoś mi brakuje. Istnieje Featureklasa, która jest oddzielona od siebie, ale nie ma w sobie INDENT_OUTPUTstałej. :(
Anthony Atkinson
Doskonały! Bardzo chciałbym wiedzieć, jak to znalazłeś;)
Anthony Atkinson
1
Przyjrzałem się jednemu z moich projektów, ale wygląda na to, że jest też tutaj: github.com/FasterXML/jackson-databind w sekcji „Często używane funkcje”
gregwhitaker
Odpowiedni potrzebny import to import com.fasterxml.jackson.databind. {SerializationFeature, ObjectMapper}
dgh
2
w wersji 2.2.1 zajęło mi to: import org.codehaus.jackson.map.SerializationConfig.Feature; mapper.enable (Feature.INDENT_OUTPUT);
harschware
46

Według mkyong , magiczne zaklęcie jest defaultPrintingWriterdo całkiem wydrukować JSON :

Nowsze wersje:

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

Starsza wersja:

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

Wydaje się, że odrobinę szybko skoczyłem z pistoletu. Możesz wypróbować gson , którego konstruktor obsługuje ładne drukowanie :

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

Mam nadzieję że to pomoże...

hd1
źródło
1
Znalazłem ten artykuł i byłem rozczarowany, że jest to jeden z tych przestarzałych sposobów ładnego drukowania. defaultPrettyPrintingWriter()nie jest już dostępny (nawet jako przestarzała metoda) w ObjectMapperklasie.
Anthony Atkinson
Właściwie to myślałem o zrobieniu tego, ale moja aplikacja jest już mocno zorientowana na Jacksona i cała funkcjonalność jest kompletna. Serwer aplikacji internetowych, na którym będzie to hostowane, jest już dość mocno opodatkowany i nie chciałbym ładować dodatkowych bibliotek tylko do rejestrowania żądań i odpowiedzi. Jednak zdecydowanie zagłosuję za twoją odpowiedzią.
Anthony Atkinson
7
@AnthonyAtkinson w Jackson 2.3 jest metodaObjectMapper.writerWithDefaultPrettyPrinter()
Matt b
36

API jackson uległo zmianie:

new ObjectMapper()
.writer()
.withDefaultPrettyPrinter()
.writeValueAsString(new HashMap<String, Object>());
Rian
źródło
3
Nadal jest możliwe (z Jacksonem 2.7.6) new ObjectMapper().configure(SerializationFeature.INDENT_OUTPUT, true).writer().writeValueAsString(new HashMap<String, Object>());. Musisz tylko upewnić się, że używasz programu zapisującego, który otrzymasz od skonfigurowanego ObjectMapper.
Martin,
3

IDENT_OUTPUT nic nie zrobił dla mnie i aby dać pełną odpowiedź, która działa z moimi słoikami 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 Towiański
źródło
0

Jeśli chcesz włączyć to domyślnie dla WSZYSTKICH instancji ObjectMapper w procesie, oto mały hack, który ustawi domyślną wartość INDENT_OUTPUT na true:

val indentOutput = SerializationFeature.INDENT_OUTPUT
val defaultStateField = indentOutput.getClass.getDeclaredField("_defaultState")
defaultStateField.setAccessible(true)
defaultStateField.set(indentOutput, true)
Graham Lea
źródło
0

jeśli używasz kombinacji sprężyny i jackson, możesz to zrobić w następujący sposób. Śledzę @gregwhitaker zgodnie z sugestią, ale wdrażam w stylu wiosennym.

<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
źródło
0

Jeśli inni, którzy widzą to pytanie, mają tylko ciąg JSON (nie w obiekcie), możesz umieścić go w a HashMapi nadal ObjectMapperdziałać. resultZmienna jest ciąg 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
źródło
-8

Spróbuj tego.

 objectMapper.enable(SerializationConfig.Feature.INDENT_OUTPUT);
czuć się dobrze i programować
źródło
13
Powielanie wybranej odpowiedzi po 7 miesiącach nie jest zbyt pomocne.
Igor Rodriguez
1
może pomóc komuś, jak wspomniałem w jednej linijce, czuję się dobrze, dzieląc się tym, co wiem.
czuć się dobrze i programować