Java >> Java tutorial >  >> Tag >> Json

BSON til JSON-dokumentkonvertering i Java

1. Oversigt

I denne tidligere artikel har vi set, hvordan man henter BSON-dokumenter som Java-objekter fra MongoDB.

Dette er en meget almindelig måde at udvikle en REST API på, da vi måske ønsker at ændre disse objekter, før vi konverterer dem til JSON (ved at bruge Jackson for eksempel).

Men vi vil måske ikke ændre noget i vores dokumenter. For at spare os besværet med at kode omfattende kortlægning af Java-objekter, kan vi bruge direkte BSON til JSON dokumentkonvertering .

Lad os se, hvordan MongoDB BSON API fungerer til denne brugssituation.

2. BSON-dokumentoprettelse i MongoDB med Morphia

Først og fremmest, lad os opsætte vores afhængigheder ved hjælp af Morphia som beskrevet i denne artikel.

Her er vores eksempel  enhed, som inkluderer forskellige 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 ...
}

Lad os derefter oprette en ny BSON-entitet til vores test og gemme 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 til JSON-dokumentkonvertering

Lad os nu teste standardkonverteringen, som er meget enkel:kald blot toJson metode fra BSON Document klasse :

@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ærdien er:

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

Dette ser ud til at svare til en standard JSON-mapping.

Vi kan dog se, at datoen blev konverteret som standard som et objekt med en $date felt i epoketidsformat. Lad os nu se, hvordan vi kan ændre dette datoformat.

4. Afslappet BSON til JSON-datokonvertering

Hvis vi f.eks. ønsker en mere klassisk ISO-datorepræsentation (såsom for en JavaScript-klient), kan vi videregive den afslappede JSON-tilstand til toJson metode ved at bruge JsonWriterSettings.builder :

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

Som et resultat kan vi se udgivelsesdatoen feltets "afslappede" konvertering:

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

Dette format ser ud til at være korrekt, men vi har stadig $date felt — lad os se, hvordan man slipper af med det ved hjælp af en brugerdefineret konverter.

5. Tilpasset BSON til JSON-datokonvertering

Først skal vi implementere BSON konverteren grænseflade for typen Lang , da datoværdier er udtrykt i millisekunder siden epoketid. Vi bruger DateTimeFormatter.ISO_INSTANT for at få det forventede outputformat:

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

Derefter kan vi overføre en forekomst af denne klasse som en DateTime-konvertering til JsonWriterSettings bygmester :

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

Endelig får vi et almindeligt JSON ISO-datoformat :

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

6. Konklusion

I denne artikel har vi set standardadfærden for BSON til JSON-dokumentkonvertering.

Vi fremhævede, hvordan man tilpasser datoformatet, hvilket er et almindeligt problem, ved hjælp af BSON Converter .

Selvfølgelig kan vi fortsætte på samme måde for at konvertere andre datatyper :tal, boolesk værdi, nullværdi eller objekt-id, for eksempel.

Som altid kan koden findes på GitHub.


Java tag