1. Přehled
V tomto předchozím článku jsme viděli, jak načíst dokumenty BSON jako objekty Java z MongoDB.
Toto je velmi běžný způsob, jak vyvinout REST API, protože můžeme chtít tyto objekty před převedením na JSON (například pomocí Jacksona) upravit.
Možná však nebudeme chtít na našich dokumentech nic měnit. Abychom si ušetřili potíže s kódováním podrobného mapování objektů Java, můžeme použít přímou konverzi dokumentů BSON na JSON .
Podívejme se, jak funguje MongoDB BSON API pro tento případ použití.
2. Vytváření dokumentů BSON v MongoDB pomocí Morphia
Nejprve si nastavíme závislosti pomocí Morphie, jak je popsáno v tomto článku.
Zde je náš příklad entita, která zahrnuje různé typy atributů:
@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 ...
}
Poté vytvořte novou entitu BSON pro náš test a uložte ji do 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. Výchozí konverze dokumentů BSON na JSON
Nyní otestujeme výchozí konverzi, která je velmi jednoduchá:jednoduše zavolejte toJson metoda z dokumentu BSON třída :
@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 hodnota je:
{
"_id": "isbn",
"className": "com.baeldung.morphia.domain.Book",
"publisher": {
"_id": {
"$oid": "fffffffffffffffffffffffa"
},
"name": "publisher"
},
"price": 3.95,
"publishDate": {
"$date": 1577898812000
}
}
Zdá se, že to odpovídá standardnímu mapování JSON.
Můžeme však vidět, že datum bylo ve výchozím nastavení převedeno jako objekt s $date pole ve formátu času epochy. Podívejme se nyní, jak můžeme změnit tento formát data.
4. Uvolněná konverze data BSON na JSON
Pokud například chceme klasičtější reprezentaci data ISO (například pro klienta JavaScriptu), můžeme předat uvolněnou Režim JSON na toJson pomocí JsonWriterSettings.builder :
bson.toJson(JsonWriterSettings
.builder()
.outputMode(JsonMode.RELAXED)
.build());
V důsledku toho vidíme publishDate „uvolněná“ konverze pole:
{
...
"publishDate": {
"$date": "2020-01-01T17:13:32Z"
}
...
}
Tento formát se zdá být správný, ale stále máme $date pole — podívejme se, jak se toho zbavit pomocí vlastního převodníku.
5. Vlastní převod data BSON na JSON
Nejprve musíme implementovat BSON Converter rozhraní pro typ Long , protože hodnoty data jsou vyjádřeny v milisekundách od doby epochy. Používáme DateTimeFormatter.ISO_INSTANT získat očekávaný výstupní formát:
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);
}
}
}
Potom můžeme předat instanci této třídy jako převodník DateTime do JsonWriterSettings stavitela :
bson.toJson(JsonWriterSettings
.builder()
.dateTimeConverter(new JsonDateTimeConverter())
.build());
Nakonec získáme prostý formát data JSON ISO :
{
...
"publishDate": "2020-01-01T17:13:32Z"
...
}