1. Overview
1.概述
In this previous article, we’ve seen how to retrieve BSON documents as Java objects from MongoDB.
在之前的文章中,我们看到了如何从 MongoDB 中检索 BSON 文档作为 Java 对象。
This is a very common way to develop a REST API, as we may want to modify these objects before converting them to JSON (using Jackson for example).
这是开发REST API的一种非常常见的方式,因为我们可能想在将这些对象转换为JSON之前对其进行修改(例如使用Jackson)。
However, we might not want to change anything to our documents. To save us the trouble of coding verbose Java objects mapping, we can use direct BSON to JSON document conversion.
然而,我们可能不想对我们的文档做任何改变。为了节省我们编写冗长的Java对象映射的麻烦,我们可以使用直接的BSON到JSON文档转换。
Let’s see how MongoDB BSON API works for this use case.
让我们看看MongoDB BSON API如何在此用例中发挥作用。
2. BSON Document Creation in MongoDB with Morphia
2.用Morphia在MongoDB中创建BSON文档
First of all, let’s set up our dependencies using Morphia as described in this article.
首先,让我们按照本文描述的方式使用Morphia设置我们的依赖关系。
Here is our example entity which includes various attribute types:
这里是我们的例子实体,其中包括各种属性类型。
@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 ...
}
Then let’s create a new BSON entity for our test and save it to MongoDB:
然后让我们为我们的测试创建一个新的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. Default BSON to JSON Document Conversion
3.默认的BSON到JSON文档转换
Now let’s test the default conversion which is very simple: simply call toJson method from the BSON Document class:
现在让我们测试一下默认的转换,它非常简单:简单地从BSON Document类中调用 toJson方法。
@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());
}
}
The expectedJson value is:
expectedJson值是。
{
"_id": "isbn",
"className": "com.baeldung.morphia.domain.Book",
"publisher": {
"_id": {
"$oid": "fffffffffffffffffffffffa"
},
"name": "publisher"
},
"price": 3.95,
"publishDate": {
"$date": 1577898812000
}
}
This seems to correspond to a standard JSON mapping.
这似乎对应于一个标准的JSON映射。
However, we can see that the date was converted by default as an object with a $date field in epoch time format. Let’s see now how we can change this date format.
然而,我们可以看到,日期被默认转换为$date字段的epoch时间格式的对象。现在让我们看看如何改变这个日期格式。
4. Relaxed BSON to JSON Date Conversion
4.宽松的BSON到JSON日期转换
For instance, if we want a more classic ISO date representation (such as for a JavaScript client), we can pass the relaxed JSON mode to the toJson method, using JsonWriterSettings.builder:
例如,如果我们想要一个更经典的ISO日期表示法(比如用于JavaScript客户端),我们可以使用JsonWriterSettings.builder,将relaxed JSON模式传递给toJson方法。
bson.toJson(JsonWriterSettings
.builder()
.outputMode(JsonMode.RELAXED)
.build());
As a result, we can see the publishDate field’s “relaxed” conversion:
因此,我们可以看到publishDate字段的 “放松 “转换。
{
...
"publishDate": {
"$date": "2020-01-01T17:13:32Z"
}
...
}
This format seems correct, but we still have the $date field — let’s see how to get rid of it using a custom converter.
这种格式似乎是正确的,但我们仍然有$date字段–让我们看看如何用一个自定义的转换器把它去掉。
5. Custom BSON to JSON Date Conversion
5.自定义BSON到JSON日期转换
First, we have to implement the BSON Converter interface for type Long, as date values are expressed in milliseconds since epoch time. We’re using DateTimeFormatter.ISO_INSTANT to get the expected output format:
首先,我们必须为Long类型实现BSON Converter接口,因为日期值是以自纪元时间起的毫秒表示的。我们使用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);
}
}
}
Then, we can pass an instance of this class as a DateTime converter to the JsonWriterSettings builder:
然后,我们可以把这个类的一个实例作为一个DateTime转换器传递给JsonWriterSettings构建器。
bson.toJson(JsonWriterSettings
.builder()
.dateTimeConverter(new JsonDateTimeConverter())
.build());
Finally, we get a plain JSON ISO date format:
最后,我们得到一个普通的JSON ISO日期格式。
{
...
"publishDate": "2020-01-01T17:13:32Z"
...
}
6. Conclusion
6.结语
In this article, we’ve seen the default behavior of BSON to JSON document conversion.
在这篇文章中,我们已经看到了BSON到JSON文档转换的默认行为。
We highlighted how to customize the date format, which is a common issue, using BSON Converter.
我们强调了如何使用BSON Converter定制日期格式,这是一个常见的问题。
Of course, we can proceed the same way to convert other data types: number, boolean, null value, or object id, for example.
当然,我们可以用同样的方法来转换其他数据类型:例如,数字、布尔值、空值或对象ID。
As always, the code can be found over on GitHub.
一如既往,代码可以在GitHub上找到over。