1。概要
この前回の記事では、BSONドキュメントをMongoDBからJavaオブジェクトとして取得する方法を見てきました。
これは、REST APIを開発するための非常に一般的な方法です。これらのオブジェクトをJSONに変換する前に変更したい場合があるためです(たとえば、Jacksonを使用)。
ただし、ドキュメントに何も変更したくない場合があります。冗長なJavaオブジェクトマッピングをコーディングする手間を省くために、直接BSONからJSONドキュメントへの変換を使用することができます。 。
このユースケースでMongoDBBSONAPIがどのように機能するかを見てみましょう。
2。 Morphiaを使用したMongoDBでのBSONドキュメントの作成
まず、この記事で説明されているように、Morphiaを使用して依存関係を設定しましょう。
これが私たちの例です さまざまな属性タイプを含むエンティティ:
@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 ...
}
次に、テスト用の新しいBSONエンティティを作成し、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。デフォルトのBSONからJSONドキュメントへの変換
次に、非常に単純なデフォルトの変換をテストしてみましょう。 toJsonを呼び出すだけです。 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());
}
}
expectedJson 値は次のとおりです:
{
"_id": "isbn",
"className": "com.baeldung.morphia.domain.Book",
"publisher": {
"_id": {
"$oid": "fffffffffffffffffffffffa"
},
"name": "publisher"
},
"price": 3.95,
"publishDate": {
"$date": 1577898812000
}
}
これは、標準のJSONマッピングに対応しているようです。
ただし、日付はデフォルトで $ dateのオブジェクトとして変換されていることがわかります。 エポックタイム形式のフィールド。 この日付形式を変更する方法を見てみましょう。
4。リラックスしたBSONからJSONへの日付変換
たとえば、より古典的なISO日付表現(JavaScriptクライアントなど)が必要な場合は、リラックスを渡すことができます。 toJsonへのJSONモード メソッド、 JsonWriterSettings.builderを使用 :
bson.toJson(JsonWriterSettings
.builder()
.outputMode(JsonMode.RELAXED)
.build());
その結果、 publishDateを確認できます。 フィールドの「リラックスした」変換:
{
...
"publishDate": {
"$date": "2020-01-01T17:13:32Z"
}
...
}
この形式は正しいようですが、まだ $ dateがあります フィールド—カスタムコンバーターを使用してそれを取り除く方法を見てみましょう。
5。カスタムBSONからJSONへの日付変換
まず、BSONコンバーターを実装する必要があります インターフェース タイプLongの場合 、日付値はエポック時間からのミリ秒で表されるため。 DateTimeFormatter.ISO_INSTANTを使用しています 期待される出力形式を取得するには:
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);
}
}
}
次に、このクラスのインスタンスをDateTimeコンバーターとしてJsonWriterSettingsに渡すことができます。 ビルダー :
bson.toJson(JsonWriterSettings
.builder()
.dateTimeConverter(new JsonDateTimeConverter())
.build());
最後に、プレーンなJSONISO日付形式を取得します :
{
...
"publishDate": "2020-01-01T17:13:32Z"
...
}