Closed GoogleCodeExporter closed 9 years ago
I add something similar to your problem, issue 209.
I "fix" your problem as following on version 1;3 (1.4 is beta did not look at
it):
Class: com.google.gson.JsonSerializationVisitor
Method: visitArray
Old content
public void visitArray(Object array, Type arrayType) {
assignToRoot(new JsonArray());
int length = Array.getLength(array);
TypeInfoArray fieldTypeInfo = TypeInfoFactory.getTypeInfoForArray(arrayType);
Type componentType = fieldTypeInfo.getSecondLevelType();
for (int i = 0; i < length; ++i) {
Object child = Array.get(array, i);
Type childType = componentType;
// we should not get more specific component type yet since it is possible
// that a custom
// serializer is registered for the componentType
addAsArrayElement(new ObjectTypePair(child, childType, false));
}
}
New content
public void visitArray(Object array, Type arrayType) {
assignToRoot(new JsonArray());
int length = Array.getLength(array);
for (int i = 0; i < length; ++i) {
Object child = Array.get(array, i);
// we should not get more specific component type yet since it is possible
// that a custom
// serializer is registered for the componentType
addAsArrayElement(new ObjectTypePair(child, child.getClass(), false));
}
}
Etienne
Original comment by lapinouj...@gmail.com
on 15 May 2010 at 1:02
Sorry my thread was for the current version in trunk.
For version 1.3 I did the folowwing:
Class: com.google.gson.JsonSerializationVisitor
Method: visitArray
Old content
public void visitArray(Object array, Type arrayType) {
assignToRoot(new JsonArray());
int length = Array.getLength(array);
TypeInfoArray fieldTypeInfo = TypeInfoFactory.getTypeInfoForArray(arrayType);
Type componentType = fieldTypeInfo.getSecondLevelType();
for (int i = 0; i < length; ++i) {
Object child = Array.get(array, i);
addAsArrayElement(componentType, child);
}
}
New content
public void visitArray(Object array, Type arrayType) {
assignToRoot(new JsonArray());
int length = Array.getLength(array);
for (int i = 0; i < length; ++i) {
Object child = Array.get(array, i);
addAsArrayElement(child.getClass(), child);
}
}
Etienne
Original comment by lapinouj...@gmail.com
on 15 May 2010 at 1:10
Original comment by inder123
on 3 Nov 2010 at 1:48
FYI - you can work around this by providing static type information when
calling toJson().
toJson(array, Integer[][].class);
In general GSON works better when it knows the types of everything!
Original comment by limpbizkit
on 3 Nov 2010 at 4:43
@limpbizkit: Understood.
In the situation that led to this report, those arrays were buried deep within
a Map<String, Object>, which contained many nested maps, collections, and
arrays of various types. I was building this data structure up in Java and
wanted to convert it to JSON in one pass, so that solution would not have been
practical for me.
Original comment by michael.hixson@gmail.com
on 3 Nov 2010 at 5:44
Yup, good to know. One thing we should consider doing is using runtime types
whenever "Object" is the static type.
Original comment by limpbizkit
on 3 Nov 2010 at 5:54
Original comment by limpbizkit
on 4 Nov 2010 at 10:52
Issue 245 has been merged into this issue.
Original comment by limpbizkit
on 4 Nov 2010 at 10:53
I have an inkling that this works in Gson 1.7.
We have a test for a Collection<Object>, Object[] and a Map<String,Object>.
Original comment by joel.leitch@gmail.com
on 13 Apr 2011 at 9:16
The array of object arrays is actually assigned to an "Object[][]" instead of
Object[] than it does work as expected.
Marking this as fixed because since it would be a super crazy use case if
someone actually need to assign an array of object arrays to a type object
array.
Original comment by joel.leitch@gmail.com
on 15 Apr 2011 at 5:19
I think you've misunderstood the use case and the bug report, and you've marked
this "fixed" when you meant "closed" or "won't fix".
Gson gson = new Gson();
System.out.println(
gson.toJson(new Object[] { 1, 2, new Object[] { "foo", 3 } })
);
Expected output:
[1,2,["foo",3]]
Actual output:
[1,2,{}]
Obviously, that code won't compile if you put "new Object[][]" in place of "new
Object[]". What type would you suggest instead, to hold "{ 1, 2, new Object[]
{ "foo", 3 } }" ?
This report didn't come from a contrived use case designed to break Gson.
Please see comment #5.
Original comment by michael.hixson@gmail.com
on 15 Apr 2011 at 5:46
OK, I see. I did misunderstand your initial example, but the above example
makes it more clear because now I see you are mixing primitives (or objects)
and arrays within an array.
Again, I stand by my statement that is is a super crazy use-case to support,
but I'd like to hear the your reasoning as to why this is wanted. The only
thing that I can think of is that you are trying to form some object that will
object the correct JSON value for you. If that's the case then I recommend that
you build up the output using the JsonElement objects (i.e. JsonArray,
JsonObject, JsonPrimitive) and generate the output that way.
I will reopen this issue to hear your thoughts.
Original comment by joel.leitch@gmail.com
on 16 Apr 2011 at 10:08
I swear, I'm not crazy! :)
I was passing a large amount of data from a Java-based back end to a
JavaScript-based front end. It seemed only natural to form the container for
this data in Java using maps, arrays/collections, strings, and primitives,
which have counterparts in JSON. Then I'd use some Java-to-JSON tool to make
the data readable by the client.
The JavaScript didn't know or care about the Java types being used, or whether
they were being mixed - [ 1, 2, [ "foo", 3 ] ] is an array like any other. Why
should I avoid that mixing on the Java side when the JavaScript doesn't care?
The front end might (does) even encourage it in some cases. For instance, look
at the API for Flot:
http://people.iola.dk/olau/flot/API.txt
Specifically, see the section about gradients. What I declare as the
backgroundColor of a graph could be a string, or an array of strings, of an
array of maps of strings to numbers.
Why do I need to worry about that on the Java side? I shouldn't, but with
Gson, I do. Even with the weak example in my initial report:
new Object[] { new Object[] { 1, 2 } }
Who would want that to render in JSON as "[{}]" ? It seems plain that's not
the right representation. If I have to add a second set of square brackets,
then I'd be doing so only to appease Gson, because of the particulars in how
Gson was implemented.
Addressing your suggestion to use JsonElement objects: I wouldn't want to tie
myself to a particular Java-to-JSON library in this way. If my Java object is
made of things that have an obvious counterpart in JavaScript, then I'd think a
number of tools could do the JSON conversion for me. I could choose between
them based on correctness and performance. Meanwhile, using Gson's API for
building the entire structure would marry me to Gson.
Original comment by michael.hixson@gmail.com
on 18 Apr 2011 at 1:26
To paraphrase, you want to build up a JSON parse tree using Java constructs
instead of using the Gson parse tree constructs. JsonObject --> Map<String,
Object>, JsonArray --> List<Object> or Object[], JsonPrimitive --> (String,
int, long, ....), JsonNull ---> null.
We talked about getting rid of the JsonElement parse tree hierarchy and have
Gson use the common Java classes to map to JSON structures; however, this makes
writing JsonSerializers and deserializers very difficult and hard to
understand. That said, Gson should definitely be able to handle this use case
and it is a bug.
Original comment by joel.leitch@gmail.com
on 20 Apr 2011 at 10:22
Fixed in r828.
Original comment by joel.leitch@gmail.com
on 20 Apr 2011 at 10:33
See the new test added here:
http://code.google.com/p/google-gson/source/browse/trunk/gson/src/test/java/com/
google/gson/functional/ArrayTest.java?r=829#280
FYI, we are planning to launch a version 1.7.2 in the next two weeks that will
contain only bug fixes and performance enhancements. Stay tuned.
Original comment by joel.leitch@gmail.com
on 20 Apr 2011 at 10:44
Awesome!
Gson can't deserialize its own JSON output for these mixed-type objects,
correct? That is, unless the user writes a custom deserializer? (I'm not
suggesting it should; I'm wondering about the nature of your changes above.)
Original comment by michael.hixson@gmail.com
on 21 Apr 2011 at 12:25
Original issue reported on code.google.com by
michael.hixson@gmail.com
on 23 Apr 2010 at 10:51