I\'m saving an object with a java.util.Date field into a MongoDB 3.2 instance.
ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsStr
It looks like you are using Date object inside "myObject". In that case, you should use a DateSerializer
that implements JsonSerializer<LocalDate>, JsonDeserializer<LocalDate>
and then register it with GsonBuilder
. Sample code follows:
public class My_DateSerializer implements JsonSerializer<LocalDate>,
JsonDeserializer<LocalDate> {
@Override
public LocalDate deserialize(JsonElement json, Type typeOfT,
JsonDeserializationContext context) throws JsonParseException {
final String dateAsString = json.getAsString();
final DateTimeFormatter dtf = DateTimeFormat.forPattern(DATE_FORMAT);
if (dateAsString.length() == 0)
{
return null;
}
else
{
return dtf.parseLocalDate(dateAsString);
}
}
@Override
public JsonElement serialize(LocalDate src, Type typeOfSrc,
JsonSerializationContext context) {
String retVal;
final DateTimeFormatter dtf = DateTimeFormat.forPattern(DATE_FORMAT);
if (src == null)
{
retVal = "";
}
else
{
retVal = dtf.print(src);
}
return new JsonPrimitive(retVal);
}
}
Now register it with GsonBuilder:
final GsonBuilder builder = new GsonBuilder()
.registerTypeAdapter(LocalDate.class, new My_DateSerializer());
final Gson gson = builder.create();
You should define and use custom JsonWriterSettings to fine-tune JSON generation:
JsonWriterSettings settings = JsonWriterSettings.builder()
.int64Converter((value, writer) -> writer.writeNumber(value.toString()))
.build();
String json = new Document("a", 12).append("b", 14L).toJson(settings);
Will produce:
{ "a" : 12, "b" : 14 }
If you will not use custom settings then document will produce extended json:
{ "a" : 12, "b" : { "$numberLong" : "14" } }
I save a tag with my mongo document that specifies the original type of the object stored. I then use Gson to parse it with the name of that type. First, to create the stored Document
private static Gson gson = new Gson();
public static Document ConvertToDocument(Object rd) {
if (rd instanceof Document)
return (Document)rd;
String json = gson.toJson(rd);
Document doc = Document.parse(json);
doc.append(TYPE_FIELD, rd.getClass().getName());
return doc;
}
then to read the document back into the Java,
public static Object ConvertFromDocument(Document doc) throws CAAException {
String clazzName = doc.getString(TYPE_FIELD);
if (clazzName == null)
throw new RuntimeException("Document was not stored in the DB or got stored without becing created by itemToStoredDocument()");
Class<?> clazz;
try {
clazz = (Class<?>) Class.forName(clazzName);
} catch (ClassNotFoundException e) {
throw new CAAException("Could not load class " + clazzName, e);
}
json = com.mongodb.util.JSON.serialize(doc);
return gson.fromJson(json, clazz);
}
Thanks to Aleksey for pointing out JSON.serialize().
This looks like Mongo Java driver bug, where Document.toJson profuces non-standard JSON even if JsonMode.STRICT is used. This problem is described in the following bug https://jira.mongodb.org/browse/JAVA-2173 for which I encourage you to vote.
A workaround is to use com.mongodb.util.JSON.serialize(document).