sql >> Databasteknik >  >> NoSQL >> MongoDB

BSON till JSON-dokumentkonvertering i Java

1. Översikt

I den här tidigare artikeln har vi sett hur man hämtar BSON-dokument som Java-objekt från MongoDB.

Detta är ett mycket vanligt sätt att utveckla ett REST API, eftersom vi kanske vill modifiera dessa objekt innan vi konverterar dem till JSON (med hjälp av Jackson till exempel).

Men vi kanske inte vill ändra något i våra dokument. För att rädda oss besväret med att koda omfattande Java-objektmappning kan vi använda direkt BSON till JSON-dokumentkonvertering .

Låt oss se hur MongoDB BSON API fungerar för detta användningsfall.

2. BSON Document Creation i MongoDB med Morphia

Först av allt, låt oss ställa in våra beroenden med Morphia som beskrivs i den här artikeln.

Här är vårt exempel  entitet som inkluderar olika attributtyper:

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

Låt oss sedan skapa en ny BSON-entitet för vårt test och spara den i 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. Standard BSON till JSON-dokumentkonvertering

Låt oss nu testa standardkonverteringen som är väldigt enkel:ring helt enkelt toJson metod från BSON Dokument klass :

@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 värde är:

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

Detta verkar motsvara en standard JSON-mappning.

Vi kan dock se att datumet konverterades som standard som ett objekt med en $date fält i epoktidsformat. Låt oss nu se hur vi kan ändra detta datumformat.

4. Avslappnad BSON till JSON-datumkonvertering

Om vi ​​till exempel vill ha en mer klassisk ISO-datumrepresentation (som för en JavaScript-klient), kan vi passera den avslappnade JSON-läge till toJson metod med JsonWriterSettings.builder :

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

Som ett resultat kan vi se publiceringsdatumet fältets "avslappnade" konvertering:

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

Det här formatet verkar korrekt, men vi har fortfarande $date field — låt oss se hur man blir av med det med en anpassad omvandlare.

5. Anpassad BSON till JSON-datumkonvertering

Först måste vi implementera BSON omvandlaren gränssnitt för typ Lång , eftersom datumvärden uttrycks i millisekunder sedan epoktid. Vi använder DateTimeFormatter.ISO_INSTANT för att få det förväntade utdataformatet:

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

Sedan kan vi skicka en instans av den här klassen som en DateTime-omvandlare till JsonWriterSettings byggare :

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

Slutligen får vi ett vanligt JSON ISO-datumformat :

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

  1. Undvik sammanlagd 16MB-gräns

  2. hur man flyttar data från mysql till redis

  3. Python-ordbok:ta bort u' tecken

  4. Mongo DB relationer mellan objekt