BSON naar JSON-documentconversie in Java

Java Top

Ik heb zojuist het nieuwe aangekondigd Leer de lente natuurlijk, gericht op de basisprincipes van Spring 5 en Spring Boot 2:

>> BEKIJK DE CURSUS

1. Overzicht

In dit vorige artikel hebben we gezien hoe u BSON-documenten als Java-objecten uit MongoDB kunt ophalen.

Dit is een veel voorkomende manier om een ​​REST API te ontwikkelen, omdat we deze objecten misschien willen wijzigen voordat we ze naar JSON converteren (met bijvoorbeeld Jackson).

Het kan echter zijn dat we niets aan onze documenten willen veranderen. Om ons de moeite te besparen om uitgebreide Java-objecttoewijzingen te coderen, kunnen we gebruik directe BSON naar JSON-documentconversie.

Laten we eens kijken hoe MongoDB BSON API werkt voor deze use case.

2. Creatie van BSON-documenten in MongoDB met Morphia

Laten we allereerst onze afhankelijkheden instellen met Morphia zoals beschreven in dit artikel.

Hier is ons voorbeeldentiteit die verschillende attribuuttypen bevat:

@Entity ("Boeken") openbare klasse Boek {@Id private String isbn; @Embedded private Publisher-uitgever; @Property ("prijs") dubbele privékosten; @Property privé LocalDateTime publishDate; // Getters en setters ...}

Laten we vervolgens een nieuwe BSON-entiteit maken voor onze test en deze opslaan in MongoDB:

openbare klasse BsonToJsonIntegrationTest {privé statische laatste String DB_NAME = "bibliotheek"; privé statische Datastore datastore; @BeforeClass openbare statische leegte setUp () {Morphia morphia = nieuwe Morphia (); morphia.mapPackage ("com.baeldung.morphia"); datastore = morphia.createDatastore (nieuwe MongoClient (), DB_NAME); datastore.ensureIndexes (); datastore.save (new Book () .setIsbn ("isbn") .setCost (3.95) .setPublisher (new Publisher (new ObjectId ("fffffffffffffffffffffffffa"), "publisher")) .setPublishDate (LocalDateTime.parse ("2020-01 -01T18: 13: 32Z ", DateTimeFormatter.ISO_DATE_TIME))); }}

3. Standaard BSON naar JSON-documentconversie

Laten we nu de standaardconversie testen, die heel eenvoudig is: gewoon bellennaar Json methode van de BSON Document klasse:

@ Test openbare ongeldige gegevenBsonDocument_whenUsingStandardJsonTransformation_thenJsonDateIsObjectEpochTime () {String json = null; probeer (MongoClient mongoClient = nieuwe MongoClient ()) {MongoDatabase mongoDatabase = mongoClient.getDatabase (DB_NAME); Document bson = mongoDatabase.getCollection ("Boeken"). Find (). First (); assertEquals (verwachteJson, bson.toJson ()); }}

De verwacht Json waarde is:

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

Dit lijkt overeen te komen met een standaard JSON-toewijzing.

Dat kunnen we echter zien de datum is standaard geconverteerd naar een object met een $ datum veld in epoch-tijdnotatie. Laten we nu kijken hoe we dit datumnotatie kunnen wijzigen.

4. Ontspannen BSON naar JSON datumconversie

Als we bijvoorbeeld een meer klassieke ISO-datumweergave willen (zoals voor een JavaScript-client), kunnen we de ontspannen JSON-modus naar het naar Json methode, met behulp van JsonWriterSettings.builder:

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

Als resultaat kunnen we de publiceer datum veld 'ontspannen' conversie:

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

Dit formaat lijkt correct, maar we hebben nog steeds de $ datum field - laten we eens kijken hoe we er vanaf kunnen komen met behulp van een aangepaste converter.

5. Aangepaste datumconversie van BSON naar JSON

Ten eerste moeten we het BSON Converter koppel voor type Lang, aangezien datumwaarden worden uitgedrukt in milliseconden sinds epoch-tijd. We gebruiken DateTimeFormatter.ISO_INSTANT om het verwachte uitvoerformaat te krijgen:

openbare klasse JsonDateTimeConverter implementeert Converter {privé statische laatste Logger LOGGER = LoggerFactory.getLogger (JsonDateTimeConverter.class); statische laatste 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 (uitzondering e) {LOGGER.error (String.format ("Kan offset% d niet converteren naar JSON-datum", waarde), e); }}}

Dan kunnen we een instantie van deze klasse doorgeven als een DateTime-converter naar het JsonWriterSettings bouwer:

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

Eindelijk krijgen we een gewoon JSON ISO-datumnotatie:

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

6. Conclusie

In dit artikel hebben we het standaardgedrag van BSON naar JSON-documentconversie gezien.

We hebben uitgelegd hoe pas de datumnotatie aan, wat een veelvoorkomend probleem is, met BSON Converter.

Natuurlijk, we kunnen op dezelfde manier doorgaan met het converteren van andere gegevenstypen: getal, boolean, null-waarde of object-id, bijvoorbeeld.

Zoals altijd is de code te vinden op GitHub.

Java onderkant

Ik heb zojuist het nieuwe aangekondigd Leer de lente natuurlijk, gericht op de basisprincipes van Spring 5 en Spring Boot 2:

>> BEKIJK DE CURSUS