sql >> Database >  >> NoSQL >> MongoDB

BSON naar JSON-documentconversie in Java

1. Overzicht

In dit vorige artikel hebben we gezien hoe u BSON-documenten kunt ophalen als Java-objecten van MongoDB.

Dit is een veelgebruikte manier om een ​​REST API te ontwikkelen, omdat we deze objecten misschien willen wijzigen voordat ze naar JSON worden geconverteerd (bijvoorbeeld met Jackson).

Het kan echter zijn dat we niets willen veranderen aan onze documenten. Om ons de moeite te besparen om uitgebreide Java-objecten in kaart te brengen, kunnen we directe BSON naar JSON-documentconversie gebruiken .

Laten we eens kijken hoe MongoDB BSON API werkt voor deze use case.

2. BSON Documentcreatie in MongoDB met Morphia

Laten we allereerst onze afhankelijkheden instellen met Morphia zoals beschreven in dit artikel.

Hier is ons voorbeeld  entiteit die verschillende attribuuttypes bevat:

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

Laten we dan een nieuwe BSON-entiteit maken voor onze test en deze opslaan in 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. Standaard BSON naar JSON-documentconversie

Laten we nu de standaardconversie testen, die heel eenvoudig is:bel gewoon  toJson methode uit het BSON Document klas :

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

De verwachteJson waarde is:

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

Dit lijkt overeen te komen met een standaard JSON-mapping.

We kunnen echter zien dat de datum standaard is geconverteerd als een object met een $date veld in epoche-tijdformaat. Laten we nu kijken hoe we deze datumnotatie kunnen wijzigen.

4. Ontspannen BSON naar JSON-datumconversie

Als we bijvoorbeeld een meer klassieke ISO-datumweergave willen (zoals voor een JavaScript-client), kunnen we de relaxed doorgeven JSON-modus naar de toJson methode, met behulp van JsonWriterSettings.builder :

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

Als resultaat kunnen we de publishDate . zien "ontspannen" conversie van het veld:

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

Dit formaat lijkt correct, maar we hebben nog steeds de $date veld — laten we eens kijken hoe we er vanaf kunnen komen met een aangepaste converter.

5. Aangepaste BSON naar JSON-datumconversie

Eerst moeten we de BSON Converter . implementeren interface voor type Lang , aangezien datumwaarden worden uitgedrukt in milliseconden sinds tijdperk. We gebruiken DateTimeFormatter.ISO_INSTANT om het verwachte uitvoerformaat te krijgen:

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

Vervolgens kunnen we een instantie van deze klasse als een DateTime-converter doorgeven aan de JsonWriterSettings bouwer :

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

Ten slotte krijgen we een eenvoudig JSON ISO-datumformaat :

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

  1. Hoe verwijder ik vastgelopen/verouderde Resque-werknemers?

  2. Hoe het ISO-datumformaat terug te geven in PHP voor MongoDB?

  3. Hoe te controleren of een index verborgen is in MongoDB

  4. Collecties maken, tonen en neerzetten in MongoDB