The BSON library for MongoDB Java Driver - A high-performance binary serialization format and library for MongoDB documents
—
The BSON codec system provides flexible serialization and deserialization between Java objects and BSON documents. It includes built-in codecs for all standard Java types, support for custom POJO mapping with annotations, and an extensible framework for creating custom codecs.
public interface Codec<T> extends Encoder<T>, Decoder<T> {
// Combines encoding and decoding capabilities
// Inherits from Encoder<T> and Decoder<T> interfaces
}public interface Encoder<T> {
/**
* Encode an instance of the type parameter {@code T} into a BSON value.
* @param writer the BSON writer to encode into
* @param value the value to encode
* @param encoderContext the encoder context
*/
void encode(BsonWriter writer, T value, EncoderContext encoderContext);
/**
* Returns the Class instance that this encodes.
* @return the Class instance that this encodes
*/
Class<T> getEncoderClass();
}public interface Decoder<T> {
/**
* Decodes a BSON value from the given reader into an instance of the type parameter {@code T}.
* @param reader the BSON reader
* @param decoderContext the decoder context
* @return an instance of the type parameter {@code T}
*/
T decode(BsonReader reader, DecoderContext decoderContext);
}The CodecRegistry manages codec lookup and provides access to codecs for specific types.
public interface CodecRegistry {
/**
* Gets a Codec for the given Class.
* @param clazz the class
* @param <T> the type of the class
* @return a codec for the given class
* @throws CodecConfigurationException if the registry does not contain a codec for the given class
*/
<T> Codec<T> get(Class<T> clazz);
/**
* Gets a Codec for the given Class, or null if this registry doesn't contain a codec for the class.
* @param clazz the class
* @param registry a CodecRegistry to use as a fallback
* @param <T> the type of the class
* @return a codec for the given class, or null
*/
<T> Codec<T> get(Class<T> clazz, CodecRegistry registry);
}public interface CodecProvider {
/**
* Get a Codec using the given context, which includes, most importantly, the Class for which a Codec is required.
* @param clazz the Class for which to get a Codec
* @param registry the registry to use for resolving dependent Codec instances
* @param <T> the type of the class
* @return the Codec instance, which may be null, if this source is unable to provide one for the requested Class
*/
<T> Codec<T> get(Class<T> clazz, CodecRegistry registry);
}public final class CodecRegistries {
/**
* A codec registry containing codecs for all the default supported types.
* @return the default codec registry
*/
public static CodecRegistry fromRegistries(CodecRegistry... registries);
/**
* A codec registry containing codecs for all the default supported types.
* @return the default codec registry
*/
public static CodecRegistry fromProviders(CodecProvider... providers);
/**
* A codec registry containing codecs for all the default supported types.
* @return the default codec registry
*/
public static CodecRegistry fromProviders(List<? extends CodecProvider> providers);
/**
* A codec registry containing codecs for all the default supported types.
* @return the default codec registry
*/
public static CodecRegistry fromCodecs(Codec<?>... codecs);
/**
* A codec registry containing codecs for all the default supported types.
* @return the default codec registry
*/
public static CodecRegistry fromCodecs(List<? extends Codec<?>> codecs);
/**
* Gets the default codec registry.
* @return the default codec registry
*/
public static CodecRegistry getDefaultCodecRegistry();
}The PojoCodecProvider enables automatic codec generation for Plain Old Java Objects.
public final class PojoCodecProvider implements CodecProvider {
/**
* Create a Builder for the PojoCodecProvider.
* @return the Builder
*/
public static Builder builder();
/**
* A convenience method that automatically creates a PojoCodecProvider.
* @param packages the packages to scan for entities
* @return the PojoCodecProvider builder
*/
public static PojoCodecProvider.Builder automatic(String... packages);
public static final class Builder {
/**
* Registers a class for use in the PojoCodecProvider.
* @param clazz the class to register
* @return this
*/
public Builder register(Class<?> clazz);
/**
* Registers classes for use in the PojoCodecProvider.
* @param classes the classes to register
* @return this
*/
public Builder register(Class<?>... classes);
/**
* Sets the conventions to use when creating POJOs.
* @param conventions the list of conventions
* @return this
*/
public Builder conventions(List<Convention> conventions);
/**
* Sets the discriminator key to use when storing type information for polymorphic classes.
* @param discriminatorKey the discriminator key
* @return this
*/
public Builder discriminatorKey(String discriminatorKey);
/**
* Sets the property naming strategy to use for POJO fields.
* @param propertyNamingStrategy the property naming strategy
* @return this
*/
public Builder propertyNamingStrategy(PropertyNamingStrategy propertyNamingStrategy);
/**
* Build the PojoCodecProvider.
* @return the PojoCodecProvider
*/
public PojoCodecProvider build();
}
}/**
* An annotation that configures the discriminator key and value for a class.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface BsonDiscriminator {
/**
* The discriminator key.
* @return the discriminator key
*/
String key() default "";
/**
* The discriminator value.
* @return the discriminator value
*/
String value() default "";
}
/**
* An annotation that marks a field or property to be ignored when encoding/decoding.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.FIELD})
public @interface BsonIgnore {
}
/**
* An annotation that specifies the field name to use when encoding/decoding.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.FIELD})
public @interface BsonProperty {
/**
* The name of the field in the BSON document.
* @return the name of the field
*/
String value();
/**
* Whether to use the discriminator as a property in the BSON document when writing.
* @return true if the discriminator should be used as a property
*/
boolean useDiscriminator() default false;
}
/**
* An annotation that marks a field or property as the id property.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.FIELD})
public @interface BsonId {
}
/**
* An annotation that marks a constructor or static factory method as the creator to use when deserializing.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.CONSTRUCTOR, ElementType.METHOD})
public @interface BsonCreator {
}
/**
* An annotation that marks a parameter in a creator as a property.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
public @interface BsonProperty {
/**
* The property name.
* @return the property name
*/
String value();
}public class StringCodec implements Codec<String> {
public void encode(BsonWriter writer, String value, EncoderContext encoderContext);
public String decode(BsonReader reader, DecoderContext decoderContext);
public Class<String> getEncoderClass();
}
public class IntegerCodec implements Codec<Integer> {
public void encode(BsonWriter writer, Integer value, EncoderContext encoderContext);
public Integer decode(BsonReader reader, DecoderContext decoderContext);
public Class<Integer> getEncoderClass();
}
public class LongCodec implements Codec<Long> {
public void encode(BsonWriter writer, Long value, EncoderContext encoderContext);
public Long decode(BsonReader reader, DecoderContext decoderContext);
public Class<Long> getEncoderClass();
}
public class DoubleCodec implements Codec<Double> {
public void encode(BsonWriter writer, Double value, EncoderContext encoderContext);
public Double decode(BsonReader reader, DecoderContext decoderContext);
public Class<Double> getEncoderClass();
}
public class BooleanCodec implements Codec<Boolean> {
public void encode(BsonWriter writer, Boolean value, EncoderContext encoderContext);
public Boolean decode(BsonReader reader, DecoderContext decoderContext);
public Class<Boolean> getEncoderClass();
}public class ListCodec<T> implements Codec<List<T>> {
public ListCodec(Class<T> clazz, CodecRegistry codecRegistry);
public ListCodec(Class<T> clazz, Codec<T> codec);
public void encode(BsonWriter writer, List<T> list, EncoderContext encoderContext);
public List<T> decode(BsonReader reader, DecoderContext decoderContext);
public Class<List<T>> getEncoderClass();
}
public class MapCodec implements Codec<Map<String, Object>> {
public MapCodec();
public MapCodec(CodecRegistry codecRegistry);
public void encode(BsonWriter writer, Map<String, Object> map, EncoderContext encoderContext);
public Map<String, Object> decode(BsonReader reader, DecoderContext decoderContext);
public Class<Map<String, Object>> getEncoderClass();
}public class BsonDocumentCodec implements CollectibleCodec<BsonDocument> {
public void encode(BsonWriter writer, BsonDocument document, EncoderContext encoderContext);
public BsonDocument decode(BsonReader reader, DecoderContext decoderContext);
public Class<BsonDocument> getEncoderClass();
public BsonDocument generateIdIfAbsentFromDocument(BsonDocument document);
public boolean documentHasId(BsonDocument document);
public BsonValue getDocumentId(BsonDocument document);
}
public class BsonArrayCodec implements Codec<BsonArray> {
public void encode(BsonWriter writer, BsonArray array, EncoderContext encoderContext);
public BsonArray decode(BsonReader reader, DecoderContext decoderContext);
public Class<BsonArray> getEncoderClass();
}public enum UuidRepresentation {
/**
* The canonical representation of UUID.
*/
STANDARD,
/**
* The legacy representation of UUID used by the C# driver.
*/
C_SHARP_LEGACY,
/**
* The legacy representation of UUID used by the Java driver.
*/
JAVA_LEGACY,
/**
* The legacy representation of UUID used by the Python driver.
*/
PYTHON_LEGACY,
/**
* An unspecified representation of UUID.
*/
UNSPECIFIED
}
public class UuidCodec implements Codec<UUID> {
public UuidCodec();
public UuidCodec(UuidRepresentation uuidRepresentation);
public void encode(BsonWriter writer, UUID value, EncoderContext encoderContext);
public UUID decode(BsonReader reader, DecoderContext decoderContext);
public Class<UUID> getEncoderClass();
public UuidRepresentation getUuidRepresentation();
}public final class EncoderContext {
/**
* Create a builder.
* @return the builder
*/
public static Builder builder();
/**
* Returns true if the encoder should encode a value as a document that includes an _id if the value is missing one.
* @return true if the encoder should encode a collectible document
*/
public boolean isEncodingCollectibleDocument();
/**
* Create an encoder context that is a child of this.
* @return the child encoder context
*/
public EncoderContext getChildContext();
public static final class Builder {
/**
* Set to true if the value to be encoded is a document that should be handled as a collectible document.
* @param encodingCollectibleDocument true if the value to be encoded is a collectible document
* @return this
*/
public Builder isEncodingCollectibleDocument(boolean encodingCollectibleDocument);
/**
* Build the encoder context.
* @return the encoder context
*/
public EncoderContext build();
}
}
public final class DecoderContext {
/**
* Create a builder.
* @return the builder
*/
public static Builder builder();
/**
* Create a decoder context that is a child of this.
* @return the child decoder context
*/
public DecoderContext getChildContext();
public static final class Builder {
/**
* Build the decoder context.
* @return the decoder context
*/
public DecoderContext build();
}
}import org.bson.codecs.*;
import org.bson.*;
import org.bson.io.BasicOutputBuffer;
// Get the default codec registry
CodecRegistry codecRegistry = CodecRegistries.getDefaultCodecRegistry();
// Get a codec for a specific type
Codec<String> stringCodec = codecRegistry.get(String.class);
// Encode a string
BasicOutputBuffer buffer = new BasicOutputBuffer();
BsonBinaryWriter writer = new BsonBinaryWriter(buffer);
writer.writeStartDocument();
writer.writeName("message");
stringCodec.encode(writer, "Hello, World!", EncoderContext.builder().build());
writer.writeEndDocument();
writer.close();
// Decode the string back
BsonBinaryReader reader = new BsonBinaryReader(ByteBuffer.wrap(buffer.toByteArray()));
reader.readStartDocument();
reader.readName(); // "message"
String decoded = stringCodec.decode(reader, DecoderContext.builder().build());
reader.readEndDocument();
reader.close();import org.bson.codecs.pojo.annotations.*;
public class Person {
@BsonId
private ObjectId id;
@BsonProperty("full_name")
private String name;
private int age;
@BsonIgnore
private String password;
@BsonCreator
public Person(@BsonProperty("full_name") String name, @BsonProperty("age") int age) {
this.name = name;
this.age = age;
}
// getters and setters
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public int getAge() { return age; }
public void setAge(int age) { this.age = age; }
}
// Register the POJO codec
CodecRegistry pojoCodecRegistry = CodecRegistries.fromRegistries(
CodecRegistries.getDefaultCodecRegistry(),
CodecRegistries.fromProviders(PojoCodecProvider.builder().automatic(true).build())
);
// Use the POJO codec
Codec<Person> personCodec = pojoCodecRegistry.get(Person.class);import org.bson.codecs.*;
import org.bson.codecs.configuration.*;
// Create a custom codec registry
CodecRegistry customRegistry = CodecRegistries.fromRegistries(
// Default codecs
CodecRegistries.getDefaultCodecRegistry(),
// Custom codecs
CodecRegistries.fromCodecs(
new UuidCodec(UuidRepresentation.STANDARD)
),
// POJO support
CodecRegistries.fromProviders(
PojoCodecProvider.builder()
.register(Person.class)
.conventions(Arrays.asList(
Conventions.ANNOTATION_CONVENTION,
Conventions.CLASS_AND_PROPERTY_CONVENTION
))
.build()
)
);@BsonDiscriminator(key = "type", value = "vehicle")
public abstract class Vehicle {
@BsonId
private ObjectId id;
private String brand;
// constructors, getters, setters
}
@BsonDiscriminator(value = "car")
public class Car extends Vehicle {
private int doors;
// constructors, getters, setters
}
@BsonDiscriminator(value = "truck")
public class Truck extends Vehicle {
private double cargoCapacity;
// constructors, getters, setters
}
// Register all types in the hierarchy
CodecRegistry registry = CodecRegistries.fromRegistries(
CodecRegistries.getDefaultCodecRegistry(),
CodecRegistries.fromProviders(
PojoCodecProvider.builder()
.register(Vehicle.class, Car.class, Truck.class)
.build()
)
);Install with Tessl CLI
npx tessl i tessl/maven-org-mongodb--bson