sql >> Database >  >> NoSQL >> MongoDB

Lees BSON (mongoDB) in POJO met behulp van GSON en TypeAdapter

Ik heb het opgelost met behulp van een CustomizedTypeAdapterFactory. Zie deze vraag

Schrijf in principe eerst een aangepaste adapter:

public abstract class CustomizedTypeAdapterFactory<C>
        implements TypeAdapterFactory
{
    private final Class<C> customizedClass;

    public CustomizedTypeAdapterFactory(Class<C> customizedClass) {
        this.customizedClass = customizedClass;
    }

    @SuppressWarnings("unchecked") // we use a runtime check to guarantee that 'C' and 'T' are equal
    public final <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
        return type.getRawType() == customizedClass
                ? (TypeAdapter<T>) customizeMyClassAdapter(gson, (TypeToken<C>) type)
                : null;
    }

    private TypeAdapter<C> customizeMyClassAdapter(Gson gson, TypeToken<C> type) {
        final TypeAdapter<C> delegate = gson.getDelegateAdapter(this, type);
        final TypeAdapter<JsonElement> elementAdapter = gson.getAdapter(JsonElement.class);
        return new TypeAdapter<C>() {
            @Override public void write(JsonWriter out, C value) throws IOException
            {
                JsonElement tree = delegate.toJsonTree(value);
                beforeWrite(value, tree);
                elementAdapter.write(out, tree);
            }
            @Override public C read(JsonReader in) throws IOException {
                JsonElement tree = elementAdapter.read(in);
                afterRead(tree);
                return delegate.fromJsonTree(tree);
            }
        };
    }

    /**
     * Override this to muck with {@code toSerialize} before it is written to
     * the outgoing JSON stream.
     */
    protected void beforeWrite(C source, JsonElement toSerialize) {
    }

    /**
     * Override this to muck with {@code deserialized} before it parsed into
     * the application type.
     */
    protected void afterRead(JsonElement deserialized) {
    }
}

En maak vervolgens een subklasse aan voor alle klassen waarmee rekening moet worden gehouden. Je moet er wel een maken voor elke klasse die een long bevat (in dit geval). Maar u hoeft niets anders te serialiseren dan de lange waarde (en eventuele andere bson-specifieke waarden)

public class MyTestObjectTypeAdapterFactory extends CustomizedTypeAdapterFactory<MyTestObject>
{
    public MyTestObjectTypeAdapterFactory()
    {
        super(MyTestObject.class);
    }

    @Override
    protected void beforeWrite(MyTestObject source, JsonElement toSerialize)
    {
        //you could convert back the other way here, I let mongo's document parser take care of that.
    }

    @Override
    protected void afterRead(JsonElement deserialized)
    {
        JsonObject timestamp = deserialized.getAsJsonObject().get("timestamp").getAsJsonObject();
        deserialized.getAsJsonObject().remove("timestamp");
        deserialized.getAsJsonObject().add("timestamp",timestamp.get("$numberLong"));
    }
}

en genereer vervolgens Gson met:

Gson gson = new GsonBuilder().registerTypeAdapterFactory(new MyTestObjectTypeAdapterFactory()).create();



  1. Geen reactie na verbinding van selderij naar redis via ssl

  2. MongoDB verwerkt geen aggregatie met allowDiskUsage:True

  3. MongoDB-zelfstudie:verbinding maken met MongoDB in Scala

  4. Is er een limiet op het aantal argumenten dat redis-commando's zoals ZADD of HMGET aankunnen?