DataSerializer adds additional escape characters...

3,283 views
Skip to first unread message

Athadu

unread,
Aug 3, 2011, 1:16:11 PM8/3/11
to google-gson
import java.lang.reflect.Type;
import java.util.Date;
Hi

I have the following serializer for Date field - to serialize it to
the .NET form - which in 'escaped'
form should look like '\/Date(13455662727)\/'
The date is in milliseconds.

When I have the format string as "/Date(%1$s)/" in the following code,
I was expecting
the JsonPrimitive to escape it to the way I want it, which is '\/
Date(13455662727)\/'
But it doesn't escape the '/' (forward slash) character.

If I put '\/Date(%1$s)\/' in the format string in the code, the
JsonPrimitive results in
additional escape characters - '\\/Date(13455662727)\\/' that the .NET
side doesn't like.

I looked into overriding JsonElement and coming up with my own
'primitive' - but looks like the serializer only supports gson defined
ones - I get the following exception.

08-03 12:22:24.381: WARN/System.err(4251):
java.lang.IllegalArgumentException: Couldn't write class
com.google.gson.JsonDatePrimitive
08-03 12:22:25.550: WARN/System.err(4251): at
com.google.gson.Streams.write(Streams.java:141)

Could you suggest any workarounds - other than using JsonObject -
which would mean I have to 'hardcode' the name of the field (I have
bunch of different entity types with Date fields that I want to
generate JSON for)?

I appreciate any pointers.

Here is the serializer code:

import org.json.JSONObject;

import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import com.google.gson.JsonElement;

public class DateSerializer implements JsonSerializer<Date> {

public JsonElement serialize(Date arg0, Type arg1,
JsonSerializationContext arg2) {

JSONObject j = new JSONObject();

String dateVal = String.format("/Date(%1$s)/", arg0.getTime());
JsonElement retVal = new JsonPrimitive(dateVal);

return retVal;
}
}

Regards
Athadu

Karim Varela

unread,
Mar 12, 2012, 6:53:45 PM3/12/12
to googl...@googlegroups.com
I'm experiencing the same problem. Did you ever find a solution?

Basically, I'm saving dates as:
String date = "\\/Date(1294380482000-0800)\\/";   \\The first '\' is to escape the 2nd one. Escaped String would look like this: "\/Date(1294380482000-0800)\/" which is the format my server expects.

The GSON serializer is serializing this string directly as "\\/Date(1294380482000-0800)\\/" without escaping the backslashes. 

Any help appreciated!

-K

Brandon Mintern

unread,
Mar 12, 2012, 7:56:30 PM3/12/12
to googl...@googlegroups.com
It looks like JsonWriter is extensible, but unfortunately it has some
private methods that we would like to use. The easiest solution I can
come up with (making an inadvisable use of reflection to hack around
private methods) looks something like this: (Note! I haven't actually
tried to compile or run this code; treat it as pseudocode that happens
to look a LOT like Java.)

Gson gson = new Gson();
JsonElement asTree = gson.toJsonTree(someObject);
StringWriter sw = new StringWriter();
JsonWriter jw = new MyJsonWriter(sw);
gson.toJson(asTree, jw);
sw.toString(); // your escaped string

public class MyJsonWriter extends JsonWriter {

private static Method JsonWriterWriteDeferredName;
private static Method JsonWriterBeforeValue;

static {
try {
JsonWriterWriteDeferredName =
JsonWriter.class.getDeclaredMethod("writeDeferredName");
JsonWriterWriteDeferredName.setAccessible(true);
JsonWriterBeforeValue =
JsonWriter.class.getDeclaredMethod("beforeValue", boolean.class);
JsonWriterBeforeValue.setAccessible(true);
} catch (Exception e) {
// This indicates a bug in the code above or a change in
one of the JsonWriter private methods
throw new RuntimeException(e);
}
}

private final Writer out;

public MyJsonWriter(Writer out) {
super(out);
this.out = out;
}

public JsonWriter value(String value) throws IOException {
if (value == null) {
return nullValue();
}
try {
try {
JsonWriterWriteDeferredName.invoke(this);
JsonWriterBeforeValue.invoke(this, false);
} catch (InvocationTargetException e) {
throw e.getCause();
}
} catch (IOException e) {
throw e;
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
// This represents a bug in this code somewhere
throw new RuntimeException(e);
}
string(value);
return this;
}

/* This version escapes only double-quote. If you need to escape
more, refer to JsonWriter.string */
private void string(String value) throws IOException {
out.write("\"");
for (int i = 0; length = value.length(); i < length; i++) {
char c = value.charAt(i);
if (c == '"') { // That's ' " '
out.write("\\\""); // That's " \ \ \ \ " "
} else {
out.write(c);
}
}
}
}

> --
> You received this message because you are subscribed to the Google Groups
> "google-gson" group.
> To view this discussion on the web visit
> https://groups.google.com/d/msg/google-gson/-/DpE_I9coXy0J.
> To post to this group, send email to googl...@googlegroups.com.
> To unsubscribe from this group, send email to
> google-gson...@googlegroups.com.
> For more options, visit this group at
> http://groups.google.com/group/google-gson?hl=en.

Brandon Mintern

unread,
Mar 12, 2012, 8:07:28 PM3/12/12
to googl...@googlegroups.com
Oops.

On Mon, Mar 12, 2012 at 4:56 PM, Brandon Mintern <min...@easyesi.com> wrote:
...


>                out.write("\\\""); // That's " \ \ \ \ " "

The comment should have read:
// That's " \ \ \ " "

It's an escaped backslash and an escaped quote.

Karim Varela

unread,
Mar 12, 2012, 8:22:14 PM3/12/12
to googl...@googlegroups.com
Thanks Brandon,

I ended up writing a simple wrapper class that looks like this:

public static String toJson( Object object )
{
try 
{
String json = _gson.toJson(object);
json = json.replaceAll("\\\\/", "\\/");
return json;
catch(Exception e)
{
MuveLog.e(e);
}
return "";
}

Regards,

Karim Varela
323.250.2181
“Let Silence speak to you about the secrets of the universe.” – Jalaluddin Rumi



--
You received this message because you are subscribed to the Google Groups "google-gson" group.
Reply all
Reply to author
Forward
0 new messages