Ł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

Odpowiedzi:


277

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

mapper.enable(SerializationFeature.INDENT_OUTPUT);

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


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

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

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)

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>

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

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.