Konversi Dokumen BSON ke JSON di Java

Java Top

Saya baru saja mengumumkan kursus Learn Spring baru , yang berfokus pada dasar-dasar Spring 5 dan Spring Boot 2:

>> LIHAT KURSUSnya

1. Ikhtisar

Di artikel sebelumnya ini, kita telah melihat cara mengambil dokumen BSON sebagai objek Java dari MongoDB.

Ini adalah cara yang sangat umum untuk mengembangkan REST API, karena kita mungkin ingin memodifikasi objek ini sebelum mengonversinya menjadi JSON (menggunakan Jackson misalnya).

Namun, kami mungkin tidak ingin mengubah apa pun ke dokumen kami. Untuk menyelamatkan kita dari masalah pengkodean pemetaan objek Java verbose, kita dapat menggunakan konversi dokumen BSON langsung ke JSON .

Mari kita lihat cara kerja MongoDB BSON API untuk kasus penggunaan ini.

2. Pembuatan Dokumen BSON di MongoDB dengan Morphia

Pertama-tama, mari kita atur dependensi kita menggunakan Morphia seperti yang dijelaskan di artikel ini.

Inilah contoh kamientitas yang mencakup berbagai jenis 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 ... }

Kemudian mari buat entitas BSON baru untuk pengujian kita dan simpan ke 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. Konversi Dokumen BSON ke JSON default

Sekarang mari kita uji konversi default yang sangat sederhana: cukup panggil metode toJson dari kelas Dokumen BSON :

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

Nilai expectedJson adalah:

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

Ini sepertinya sesuai dengan pemetaan JSON standar.

Namun, kita dapat melihat bahwa tanggal diubah secara default sebagai objek dengan bidang $ tanggal dalam format waktu epoch. Mari kita lihat sekarang bagaimana kita bisa mengubah format tanggal ini.

4. Santai Konversi Tanggal BSON ke JSON

Misalnya, jika kita menginginkan representasi tanggal ISO yang lebih klasik (seperti untuk klien JavaScript), kita dapat meneruskan mode JSON santai ke metode toJson , menggunakan JsonWriterSettings.builder :

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

Hasilnya, kita dapat melihat konversi kolom " publishDate ":

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

Format ini tampaknya benar, tetapi kami masih memiliki bidang $ date - mari kita lihat cara menghilangkannya menggunakan konverter khusus.

5. Konversi Tanggal BSON ke JSON Kustom

Pertama, kita harus mengimplementasikan antarmuka Konverter BSON untuk tipe Long , karena nilai tanggal dinyatakan dalam milidetik sejak waktu epoch. Kami menggunakan DateTimeFormatter.ISO_INSTANT untuk mendapatkan format keluaran yang diharapkan:

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

Kemudian, kita dapat meneruskan instance kelas ini sebagai konverter DateTime ke pembuat JsonWriterSettings :

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

Akhirnya, kami mendapatkan format tanggal ISO JSON biasa :

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

6. Kesimpulan

Pada artikel ini, kita telah melihat perilaku default dari konversi dokumen BSON ke JSON.

Kami menyoroti cara menyesuaikan format tanggal, yang merupakan masalah umum, menggunakan BSON Converter .

Tentu saja, kita dapat melanjutkan dengan cara yang sama untuk mengonversi tipe data lain : bilangan, boolean, nilai null, atau id objek, misalnya.

Seperti biasa, kode dapat ditemukan di GitHub.

Jawa bawah

Saya baru saja mengumumkan kursus Learn Spring baru , yang berfokus pada dasar-dasar Spring 5 dan Spring Boot 2:

>> LIHAT KURSUSnya