Đây là cách chúng tôi giải quyết vấn đề này (kết quả cuối cùng là siêu mượt mà giữa Lombok, Jackson và MongoDB):
Nhà cung cấp:
public class JacksonCodecProvider implements CodecProvider {
private final ObjectMapper objectMapper;
public JacksonCodecProvider(final ObjectMapper bsonObjectMapper) {
this.objectMapper = bsonObjectMapper;
}
@Override
public <T> Codec<T> get(final Class<T> type, final CodecRegistry registry) {
return new JacksonCodec<>(objectMapper, registry, type);
}
}
Và chính Codec:
class JacksonCodec<T> implements Codec<T> {
private final ObjectMapper objectMapper;
private final Codec<RawBsonDocument> rawBsonDocumentCodec;
private final Class<T> type;
public JacksonCodec(ObjectMapper objectMapper,
CodecRegistry codecRegistry,
Class<T> type) {
this.objectMapper = objectMapper;
this.rawBsonDocumentCodec = codecRegistry.get(RawBsonDocument.class);
this.type = type;
}
@Override
public T decode(BsonReader reader, DecoderContext decoderContext) {
try {
RawBsonDocument document = rawBsonDocumentCodec.decode(reader, decoderContext);
String json = document.toJson();
return objectMapper.readValue(json, type);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
@Override
public void encode(BsonWriter writer, Object value, EncoderContext encoderContext) {
try {
String json = objectMapper.writeValueAsString(value);
rawBsonDocumentCodec.encode(writer, RawBsonDocument.parse(json), encoderContext);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
@Override
public Class<T> getEncoderClass() {
return this.type;
}
}
Khi được kết hợp với Lombok và các chú thích mới nhất của Jackson, nó cho phép chúng ta thực hiện những thứ như thế này (hầu như không giống mã Java, phải không?):
@JsonIgnoreProperties(ignoreUnknown=true)
@JsonDeserialize(builder = Account.AccountBuilder.class)
@Builder(toBuilder=true)
@Value
public class Account {
@JsonProperty private String _id;
@JsonProperty private long _version;
@JsonProperty private String organizationName;
@JsonPOJOBuilder(withPrefix = "")
public static final class AccountBuilder {
}
}
Sau đó:
Account account = collection.find(eq("_id", id)).first();
System.out.println(account.getOrganizationName());