2014-04-14 21 views
5

nuova GSON(). ToJSON (nuova ObjectId())Conversione BSON Tipo ObjectId a JSON (conservazione in MongoDB) -Java

Quando faccio quanto sopra, l'uscita ottengo è

" _ID": { "_Time": 1374347520, "_LAVORAZIONE": -1.025,067326 millions, "_inc": 585.905.201, "_new": false}

ma in realtà io voglio che sia come

"_ID": { "$ OID": 51eae100c2e6b6c222ec3431}

che è il formato consueto MongoDB ID. Qual è il metodo preferibile in Java per questo?

Aggiornamento:

mio oggetto valore

import com.google.gson.annotations.SerializedName; 
import org.bson.types.ObjectId; 

public class TaskObject { 

    @SerializedName("_id") 
    private ObjectId _id; 

    @SerializedName("revNo") 
    private int revNo; 
} 

Sto cercando di salvare questo per MongoDB con un costume _id

TaskObject taskObject = new TaskObject(); 
taskObject.set_id(new ObjectId()); 
TaskMongoDBClient.getInstance(). 
     persistNewTaskData(new Gson().toJson(taskObject)); 

Ciò che è memorizzato nella MongoDB si presenta così.

_id: { "_Time": 1.397.464,341 mila, "_LAVORAZIONE": 1.441.187,434 mila, "_inc": -1.687,457948 millions, "_new": true}

Invece di _id: { "$ OID": xxxx} che posso interrogare usando un valore oid.

Cosa sto facendo male qui? per favore aiuto.

Grazie

+0

Ho aggiunto ulteriori dettagli. –

+0

Vuoi dire che vuoi aggiungere una nuova proprietà $ oid in Json –

+0

Mi dispiace, in questo momento non riesco a trovare un modo migliore per spiegare ulteriormente la mia domanda. Se qualcuno di voi è stato in questo contesto, per favore fatemi sapere quale fosse il vostro approccio o quali sono le librerie più compatibili con i tipi di dati BSON. –

risposta

9

Ci sono almeno due modi possibili per farlo. Probabilmente il modo più corretto è utilizzare GSON TypeAdapter per configurare il modo in cui l'oggetto ObjectId viene scritto (e letto da) JSON. Devi creare qualcosa che implementa lo TypeAdapter e registrarlo con lo GsonBuilder, in questo modo GSON sa che esiste un modo speciale per gestire ObjectIds.

ho scritto un piccolo test per dimostrare questo funziona, utilizzando il vostro caso d'uso e l'esempio di oggetto (ma omesso il campo revNo per brevità):

@Test 
public void shouldWriteCorrectJSON() { 
    // given 
    TaskObject taskObject = new TaskObject(); 
    taskObject._id = new ObjectId("51eae100c2e6b6c222ec3431"); 

    Gson gson = new GsonBuilder().registerTypeAdapter(ObjectId.class, new ObjectIdTypeAdapter()).create(); 

    // when 
    String gsonString = gson.toJson(taskObject); 

    // then 
    assertThat(gsonString, is("{\"_id\":{\"$oid\":\"51eae100c2e6b6c222ec3431\"}}")); 
} 

private class ObjectIdTypeAdapter extends TypeAdapter<ObjectId> { 
    @Override 
    public void write(final JsonWriter out, final ObjectId value) throws IOException { 
     out.beginObject() 
      .name("$oid") 
      .value(value.toString()) 
      .endObject(); 
    } 

    @Override 
    public ObjectId read(final JsonReader in) throws IOException { 
     in.beginObject(); 
     assert "$oid".equals(in.nextName()); 
     String objectId = in.nextString(); 
     in.endObject(); 
     return new ObjectId(objectId); 
    } 
} 

Nota che il test afferma la JSON sembra il modo lo si desidera, e che ho dovuto creare un ObjectIdTypeAdapter che conosce il nome del campo di ObjectId è "$ oid" e il valore è semplicemente il valore stringa dell'ObjectID e non serializza tutti i campi singolarmente.

Si noti inoltre che se si modifica il modo in cui l'oggetto viene scritto in JSON, è inoltre necessario modificare il modo in cui viene letto. Quindi ho anche implementato read per verificare che il nome del campo sia quello corretto (dovresti probabilmente lanciare un'eccezione qui invece di usare una semplice asser se non è corretta), quindi leggere il valore e creare l'ObjectId da questo valore di stringa .

Nella realtà, probabilmente si desidera verificare anche valori nulli in entrambi i casi.

Perché io sono un programmatore responsabile, ho scritto anche un test per mostrare il caso di lettura funziona anche:

@Test 
public void shouldReadFromJSON() { 
    // given 
    Gson gson = new GsonBuilder().registerTypeAdapter(ObjectId.class, new ObjectIdTypeAdapter()).create(); 

    // when 
    TaskObject actualTaskObject = gson.fromJson("{\"_id\":{\"$oid\":\"51eae100c2e6b6c222ec3431\"}}", TaskObject.class); 

    // then 
    TaskObject taskObject = new TaskObject(); 
    taskObject._id = new ObjectId("51eae100c2e6b6c222ec3431"); 
    assertThat(actualTaskObject._id, is(taskObject._id)); 
} 

Ulteriori approfondimenti:

+0

TypeAdapter sembra fornire una convalida del formato che è la risposta corretta per la mia domanda originale. Fammi provare questo e segna come la risposta accettata. Comunque, quello che ho fatto è stato, invece di riagganciare sul valore $ oid child nel campo _id, che è il formato predefinito in Mongo, ho fatto la seguente soluzione alternativa. L'oggetto _oggetto TaskObject è stato modificato Tipo stringa. Il mio compito sarebbe simile a questo. _id = ObjectId.get(). ToString(); che salva nel formato "_id: 535e3b090557f05f783c2805". –

+0

Sì, è abbastanza comune per le persone usare anche le stringhe per rappresentare l'ID - probabilmente questa è una risposta migliore, poiché impedisce la perdita della classe ObjectID Mongo-specifica negli oggetti del dominio. – Trisha

+0

@Trisha buona cosa hai scritto entrambi i test, ma sto avendo problemi con quello successivo (leggi). L'ho convertito leggermente (ho bisogno di leggere Long al posto degli objectid) ma è essenzialmente lo stesso. Puoi forse vedere cosa c'è che non va qui? http://stackoverflow.com/questions/36134737/read-bson-mongodb-into-pojo-using-gson-and-typeadapter –

Problemi correlati