Konvertierung von BSON in JSON-Dokumenten in Java

Java Top

Ich habe gerade den neuen Learn Spring- Kurs angekündigt , der sich auf die Grundlagen von Spring 5 und Spring Boot 2 konzentriert:

>> Überprüfen Sie den Kurs

1. Übersicht

In diesem vorherigen Artikel haben wir gesehen, wie BSON-Dokumente als Java-Objekte aus MongoDB abgerufen werden.

Dies ist eine sehr häufige Methode zum Entwickeln einer REST-API, da wir diese Objekte möglicherweise ändern möchten, bevor wir sie in JSON konvertieren (z. B. mit Jackson).

Möglicherweise möchten wir jedoch nichts an unseren Dokumenten ändern. Um die Codierung der ausführlichen Zuordnung von Java-Objekten zu vermeiden, können wir die direkte Konvertierung von BSON in JSON-Dokumente verwenden .

Mal sehen, wie die MongoDB BSON API für diesen Anwendungsfall funktioniert.

2. BSON-Dokumenterstellung in MongoDB mit Morphia

Lassen Sie uns zunächst unsere Abhängigkeiten mit Morphia einrichten, wie in diesem Artikel beschrieben.

Hier ist unser BeispielEntität, die verschiedene Attributtypen enthält:

@Entity("Books") public class Book { @Id private String isbn; @Embedded private Publisher publisher; @Property("price") private double cost; @Property private LocalDateTime publishDate; // Getters and setters ... }

Dann erstellen wir eine neue BSON-Entität für unseren Test und speichern sie in MongoDB:

public class BsonToJsonIntegrationTest { private static final String DB_NAME = "library"; private static Datastore datastore; @BeforeClass public static void setUp() { Morphia morphia = new Morphia(); morphia.mapPackage("com.baeldung.morphia"); datastore = morphia.createDatastore(new MongoClient(), DB_NAME); datastore.ensureIndexes(); datastore.save(new Book() .setIsbn("isbn") .setCost(3.95) .setPublisher(new Publisher(new ObjectId("fffffffffffffffffffffffa"),"publisher")) .setPublishDate(LocalDateTime.parse("2020-01-01T18:13:32Z", DateTimeFormatter.ISO_DATE_TIME))); } }

3. Standardmäßige Konvertierung von BSON in JSON-Dokumenten

Testen wir nun die Standardkonvertierung, die sehr einfach ist: Rufen Sie einfach die toJson- Methode aus der BSON Document- Klasse auf :

@Test public void givenBsonDocument_whenUsingStandardJsonTransformation_thenJsonDateIsObjectEpochTime() { String json = null; try (MongoClient mongoClient = new MongoClient()) { MongoDatabase mongoDatabase = mongoClient.getDatabase(DB_NAME); Document bson = mongoDatabase.getCollection("Books").find().first(); assertEquals(expectedJson, bson.toJson()); } }

Der erwartete Json- Wert ist:

{ "_id": "isbn", "className": "com.baeldung.morphia.domain.Book", "publisher": { "_id": { "$oid": "fffffffffffffffffffffffa" }, "name": "publisher" }, "price": 3.95, "publishDate": { "$date": 1577898812000 } }

Dies scheint einer Standard-JSON-Zuordnung zu entsprechen.

Wir können jedoch sehen, dass das Datum standardmäßig als Objekt mit einem $ date- Feld im Epochenzeitformat konvertiert wurde. Mal sehen, wie wir dieses Datumsformat ändern können.

4. Entspannte Datumskonvertierung von BSON zu JSON

Wenn wir beispielsweise eine klassischere ISO- Datumsdarstellung wünschen (z. B. für einen JavaScript-Client), können wir den entspannten JSON-Modus mithilfe von JsonWriterSettings.builder an die toJson- Methode übergeben :

bson.toJson(JsonWriterSettings .builder() .outputMode(JsonMode.RELAXED) .build());

Infolgedessen können wir die "entspannte" Konvertierung des Felds " PublishDate " sehen:

{ ... "publishDate": { "$date": "2020-01-01T17:13:32Z" } ... }

Dieses Format scheint korrekt zu sein, aber wir haben immer noch das Feld $ date - sehen wir uns an, wie Sie es mit einem benutzerdefinierten Konverter entfernen können.

5. Benutzerdefinierte Konvertierung von BSON in JSON-Datum

Zunächst müssen wir die BSON Converter- Schnittstelle für den Typ Long implementieren , da Datumswerte seit der Epoche in Millisekunden angegeben werden. Wir verwenden DateTimeFormatter.ISO_INSTANT , um das erwartete Ausgabeformat zu erhalten:

public class JsonDateTimeConverter implements Converter { private static final Logger LOGGER = LoggerFactory.getLogger(JsonDateTimeConverter.class); static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ISO_INSTANT .withZone(ZoneId.of("UTC")); @Override public void convert(Long value, StrictJsonWriter writer) { try { Instant instant = new Date(value).toInstant(); String s = DATE_TIME_FORMATTER.format(instant); writer.writeString(s); } catch (Exception e) { LOGGER.error(String.format("Fail to convert offset %d to JSON date", value), e); } } }

Dann können wir eine Instanz dieser Klasse übergeben als Datetime - Konverter an den JsonWriterSettings Builder :

bson.toJson(JsonWriterSettings .builder() .dateTimeConverter(new JsonDateTimeConverter()) .build());

Schließlich erhalten wir ein einfaches JSON-ISO-Datumsformat :

{ ... "publishDate": "2020-01-01T17:13:32Z" ... }

6. Fazit

In diesem Artikel haben wir das Standardverhalten der Konvertierung von BSON in JSON-Dokumenten gesehen.

Wir haben hervorgehoben, wie das Datumsformat mithilfe von BSON Converter angepasst werden kann. Dies ist ein häufiges Problem .

Natürlich können wir auch andere Datentypen konvertieren : z. B. Zahl, Boolescher Wert, Nullwert oder Objekt-ID.

Wie immer ist der Code auf GitHub zu finden.

Java unten

Ich habe gerade den neuen Learn Spring- Kurs angekündigt , der sich auf die Grundlagen von Spring 5 und Spring Boot 2 konzentriert:

>> Überprüfen Sie den Kurs