MongoDB
 sql >> база данни >  >> NoSQL >> MongoDB

Преобразуване на BSON в JSON документ в Java

1. Общ преглед

В тази предишна статия видяхме как да извличаме BSON документи като Java обекти от MongoDB.

Това е много често срещан начин за разработване на REST API, тъй като може да искаме да модифицираме тези обекти, преди да ги конвертираме в JSON (с помощта на Jackson например).

Въпреки това, може да не искаме да променяме нищо в нашите документи. За да ни спести проблемите с кодирането на подробно картографиране на Java обекти, можем да използваме директно преобразуване на BSON в JSON документ .

Нека видим как MongoDB BSON API работи за този случай на употреба.

2. Създаване на BSON документ в MongoDB с Morphia

Първо, нека настроим нашите зависимости с помощта на 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());
     }
}

очакваният Json стойността е:

{
    "_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 клиент), можем да предадем спокойно JSON режим към toJson метод, използвайки JsonWriterSettings.builder :

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

В резултат на това можем да видим Дата на публикуване „отпуснато“ преобразуване на полето:

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

Този формат изглежда правилен, но все още имаме $date поле — нека видим как да се отървем от него с помощта на персонализиран конвертор.

5. Персонализирано преобразуване на дата от BSON в JSON

Първо, трябва да внедрим BSON конвертора интерфейса за тип Дълги , тъй като стойностите на датата се изразяват в милисекунди от времето на епохата. Използваме 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());

Накрая получаваме обикновен JSON ISO формат за дата :

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

  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Отказ за MySQL репликация (и други) - Трябва ли да бъде автоматизирано?

  2. $unset е празен. Трябва да посочите поле така:{$unset:{<field>:...}}

  3. MongoDB $ съществува

  4. Актуализирайте елемента в масива, ако съществува, иначе вмъкнете нов елемент в този масив в MongoDb

  5. MongoDB - колекция от копия в java, без да се повтарят всички елементи