1. Oversigt
I denne tidligere artikel har vi set, hvordan man henter BSON-dokumenter som Java-objekter fra MongoDB.
Dette er en meget almindelig måde at udvikle en REST API på, da vi måske ønsker at ændre disse objekter, før de konverteres til JSON (ved at bruge Jackson for eksempel).
Dog vil vi måske ikke ændre noget i vores dokumenter. For at spare os for besværet med at kode omfattende kortlægning af Java-objekter, kan vi bruge direkte BSON til JSON dokumentkonvertering .
Lad os se, hvordan MongoDB BSON API fungerer til denne brugssituation.
2. BSON-dokumentoprettelse i MongoDB med Morphia
Lad os først og fremmest opsætte vores afhængigheder ved hjælp af Morphia som beskrevet i denne artikel.
Her er vores eksempel enhed, som inkluderer forskellige attributtyper:
@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 ...
}
Lad os derefter oprette en ny BSON-entitet til vores test og gemme den i 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. Standard BSON til JSON-dokumentkonvertering
Lad os nu teste standardkonverteringen, som er meget enkel:kald blot toJson metode fra BSON Document klasse :
@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());
}
}
expectedJson værdien er:
{
"_id": "isbn",
"className": "com.baeldung.morphia.domain.Book",
"publisher": {
"_id": {
"$oid": "fffffffffffffffffffffffa"
},
"name": "publisher"
},
"price": 3.95,
"publishDate": {
"$date": 1577898812000
}
}
Dette ser ud til at svare til en standard JSON-mapping.
Vi kan dog se, at datoen blev konverteret som standard som et objekt med en $date felt i epoketidsformat. Lad os nu se, hvordan vi kan ændre dette datoformat.
4. Afslappet BSON til JSON-datokonvertering
For eksempel, hvis vi ønsker en mere klassisk ISO-datorepræsentation (såsom for en JavaScript-klient), kan vi videregive den afslappede JSON-tilstand til toJson metode ved at bruge JsonWriterSettings.builder :
bson.toJson(JsonWriterSettings
.builder()
.outputMode(JsonMode.RELAXED)
.build());
Som et resultat kan vi se udgivelsesdatoen feltets "afslappede" konvertering:
{
...
"publishDate": {
"$date": "2020-01-01T17:13:32Z"
}
...
}
Dette format ser ud til at være korrekt, men vi har stadig $date felt — lad os se, hvordan man slipper af med det ved hjælp af en brugerdefineret konverter.
5. Tilpasset BSON til JSON-datokonvertering
Først skal vi implementere BSON konverteren grænseflade for typen Lang , da datoværdier er udtrykt i millisekunder siden epoketid. Vi bruger DateTimeFormatter.ISO_INSTANT for at få det forventede outputformat:
public class JsonDateTimeConverter implements Converter<Long> {
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);
}
}
}
Derefter kan vi videregive en forekomst af denne klasse som en DateTime-konvertering til JsonWriterSettings bygmester :
bson.toJson(JsonWriterSettings
.builder()
.dateTimeConverter(new JsonDateTimeConverter())
.build());
Endelig får vi et almindeligt JSON ISO-datoformat :
{
...
"publishDate": "2020-01-01T17:13:32Z"
...
}