MongoDB
 sql >> Baza danych >  >> NoSQL >> MongoDB

Konwersja dokumentów BSON do JSON w Javie

1. Przegląd

W poprzednim artykule widzieliśmy, jak pobierać dokumenty BSON jako obiekty Java z MongoDB.

Jest to bardzo powszechny sposób tworzenia interfejsu API REST, ponieważ możemy chcieć zmodyfikować te obiekty przed przekonwertowaniem ich do formatu JSON (na przykład przy użyciu Jacksona).

Jednak możemy nie chcieć niczego zmieniać w naszych dokumentach. Aby zaoszczędzić nam kłopotów z kodowaniem pełnego mapowania obiektów Java, możemy użyć bezpośredniej konwersji dokumentów BSON na JSON .

Zobaczmy, jak MongoDB BSON API działa w tym przypadku użycia.

2. Tworzenie dokumentów BSON w MongoDB za pomocą Morphia

Przede wszystkim skonfigurujmy nasze zależności za pomocą Morphii, jak opisano w tym artykule.

Oto nasz przykład encja, która zawiera różne typy atrybutów:

@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 ...
}

Następnie utwórzmy nową encję BSON dla naszego testu i zapiszmy ją w 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. Domyślna konwersja dokumentu BSON na JSON

Przetestujmy teraz domyślną konwersję, która jest bardzo prosta:wystarczy zadzwonić  toJson metoda z Dokumentu BSON klasa :

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

oczekiwany Json wartość to:

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

Wydaje się, że odpowiada to standardowemu mapowaniu JSON.

Widzimy jednak, że data została domyślnie przekonwertowana jako obiekt z $date pole w formacie czasu epoki. Zobaczmy teraz, jak możemy zmienić ten format daty.

4. Zrelaksowana konwersja daty BSON na JSON

Na przykład, jeśli chcemy bardziej klasycznej reprezentacji daty ISO (takiej jak dla klienta JavaScript), możemy przekazać zrelaksowany Tryb JSON na toJson przy użyciu metody JsonWriterSettings.builder :

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

W rezultacie widzimy data publikacji „relaksująca” konwersja pola:

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

Ten format wydaje się poprawny, ale nadal mamy $data pole — zobaczmy, jak się go pozbyć za pomocą niestandardowego konwertera.

5. Niestandardowa konwersja daty BSON na JSON

Najpierw musimy zaimplementować BSON Konwerter interfejs dla typu Długie , ponieważ wartości dat są wyrażone w milisekundach od czasu epoki. Używamy DateTimeFormatter.ISO_INSTANT aby uzyskać oczekiwany format wyjściowy:

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

Następnie możemy przekazać instancję tej klasy jako konwerter DateTime do JsonWriterSettings budowniczy :

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

Wreszcie otrzymujemy zwykły format daty JSON ISO :

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

  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Jak ustawić objętość danych docker mongo

  2. MongoDB $indexOfBytes

  3. MongoDB jaki jest domyślny użytkownik i hasło?

  4. Jak rozpocząć pracę z automatyzacją baz danych

  5. MongoDB :kolejność indeksów i kolejność zapytań muszą być zgodne?