Comments (12)
Extra info on the deserializing:
json = {"id":123,"thing":"AZ"}
Map<String, Object> decoded = gson.fromJson(data, new TypeToken<Map<String,
Object>>() {}.getType());
produces a map with: {id=java.lang.Object@e6612c, thing=java.lang.Object@d704f0}
(seems to be instances of Object with no data)
Original comment by azeckoski
on 15 Sep 2008 at 1:29
from gson.
First off, I'd like to start with some background information. When you are
defining
types (or local variables) that have type parameters, the JVM drops the actual
type
parameters and associates everything as "Object". This is known as "type
erasure".
In order for a Java Program to retrieve the actual type parameters at run-time,
you
need to leverage the TypeToken object (this methodology was established by
GUICE ---
see
http://google-guice.googlecode.com/svn/trunk/javadoc/com/google/inject/TypeLiter
al.html).
Originally, we implemented Gson so that it could "serialize" these kinds of
objects
without requiring the use of TypeToken; however, deserializing it back into the
real
object requires it since the JSON output has no type information in it. As
well,
with this approach, it meant you were serializing the "real" object which meant
that
some fields on the real object would be added to the JSON output. Therefore,
if you
had a List<A> and added both A and B objects (i.e. B extends A) some objects
would
expose extra fields in the output. We decided to take the more explicit route
and
force the client to provide us the type parameters of the top-level object that
is
being serialized.
The common use of a Map or List is that you populate the List with the same
object
types. Passing in Object means that you can add any instance of a class that
you
desire to the data structure. I know there are exceptions to this best
practice, but
we do not want to implement this corner case scenario. Instead, if you really
do
want to use a list of Objects, then do as the exception message says and write a
"custom" (de)serializer (you can bind it specifically to a Map<String, Object>
and
have the default Gson map serializer handle everything else).
As for a Map of Maps (i.e. Map<String, Map<String, Integer>>) this is already
supported and works well as long as you pass in the actual type object (i.e. new
TypeToken<Map<String, Map<String, Integer>>>() {}.getType())
Here's an example:
public static void main(String[] args) {
Type mapType = new TypeToken<Map<String, Map<String, Integer>>>() {}.getType();
Map<String, Map<String, Integer>> map = new HashMap<String, Map<String, Integer>>();
Map<String, Integer> value1 = new HashMap<String, Integer>();
value1.put("lalala", 78);
value1.put("haha", 9999);
map.put("id", value1);
Map<String, Integer> value2 = new HashMap<String, Integer>();
value2.put("nahhd", 121112);
value2.put("uuywss", 19987);
map.put("thing", value2);
Map<String, Integer> value3 = new HashMap<String, Integer>();
map.put("other", value3);
Gson gson = new Gson();
String json = gson.toJson(map, mapType);
System.out.println(json);
Map<String, Map<String, Integer>> deserializedMap = gson.fromJson(json, mapType);
System.out.println(deserializedMap);
}
=========== OUTPUT ===========
{"thing":456,"id":123}
{"other":{},"thing":{"nahhd":121112,"uuywss":19987},"id":{"lalala":78,"haha":999
9}}
{other={}, thing={nahhd=121112, uuywss=19987}, id={lalala=78, haha=9999}}
For now, I am closing this off as "Working as Designed". Maybe I am not
completely
following your issue and if that is the case, please start up a new discussion
in our
Gson discussion group.
Thanks,
Joel
Original comment by [email protected]
on 16 Sep 2008 at 8:57
- Changed state: Invalid
from gson.
We solved our problem by using a different library but I wanted to put a
comment here
anyway.
So what happens if I want to do this?
Map<String, Number>
or
Map<String, Serializable>
(it seems to fail)
It seems that this is designed to only work for the basic case where I have
really
simple and non-nested structures where all the beans are easily instantiable
and not
superclasses. It is a shame that this is considered working as designed.
Original comment by azeckoski
on 18 Sep 2008 at 9:01
from gson.
I am glad to hear that you found something that works for you, but it's too bad
you
are unable to use Gson. I'd still like to follow up on this issue because it is
user's like yourself that will help to advance this library.
First off, are you serializing and deserializing an object of type Map<String,
Number>? If it is serialization only, than that is a much "easier" problem to
solve
because we have the runtime types. As for "deserializing" this kind of object,
we
have provided our clients with the concept of a custom "Type Adapter". You
should be
able to write a type as follows to get it to work with "Number":
public static class NumberTypeAdapter
implements JsonSerializer<Number>, JsonDeserializer<Number>,
InstanceCreator<Number> {
public JsonElement serialize(Number src, Type typeOfSrc, JsonSerializationContext
context) {
return new JsonPrimitive(src);
}
public Number deserialize(JsonElement json, Type typeOfT,
JsonDeserializationContext context)
throws JsonParseException {
JsonPrimitive jsonPrimitive = json.getAsJsonPrimitive();
if (jsonPrimitive.isNumber()) {
return jsonPrimitive.getAsNumber();
} else {
throw new IllegalStateException("Expected a number field, but was " + json);
}
}
public Number createInstance(Type type) {
return 1L;
}
}
public static void main(String[] args) {
Map<String, Number> map = new HashMap<String, Number>();
map.put("int", 123);
map.put("long", 1234567890123456789L);
map.put("double", 1234.5678D);
map.put("float", 1.2345F);
Type mapType = new TypeToken<Map<String, Number>>() {}.getType();
Gson gson = new GsonBuilder().registerTypeAdapter(Number.class, new
NumberTypeAdapter()).create();
String json = gson.toJson(map, mapType);
System.out.println(json);
Map<String, Number> deserializedMap = gson.fromJson(json, mapType);
System.out.println(deserializedMap);
}
========== OUTPUT ==========
{"double":1234.5678,"float":1.2345,"int":123,"long":1234567890123456789}
{double=1234.5678, float=1.2345, int=123, long=1234567890123456789}
We should probably just include the above type adapter as a default in Gson and
I
will discuss this with Inderjeet. There is a bug, however, since you actually
have
to specify a "instance creator" for this type of object (i.e. primitive), but I
will
have that fixed by the next release. You should be able to write something
similar
as above for "Serializable".
I hope this information is helpful and thanks for the all the feedback on this
library.
Original comment by [email protected]
on 27 Sep 2008 at 8:32
from gson.
I modify the MapTypeAdapter to match the jdk14's Map
======================================================
public JsonElement serialize(Map src, Type typeOfSrc, JsonSerializationContext
context) {
JsonObject map = new JsonObject();
//Type childType = new TypeInfoMap(typeOfSrc).getValueType();
for (Iterator iterator = src.entrySet().iterator(); iterator.hasNext(); ) {
Map.Entry entry = (Map.Entry) iterator.next();
Object obj = entry.getValue();
JsonElement valueElement = context.serialize(obj, obj.getClass());
---------------------------------------------------------------------modified
map.add(entry.getKey().toString(), valueElement);
}
return map;
}
--------------------------------------------------------------------------------
and then the map class can be used like this:
HashMap aaaa = new HashMap();
aaaa.put("aa", 1212);
aaaa.put("bb", "fasdfa");
System.out.println(gson.toJson(aaaa));
==========output=================
{"bb":"fasdfa","aa":1212}
=================================
It can run, good or bad? because there are lot's of jdk14's source code in many
project's.
Original comment by [email protected]
on 21 Oct 2008 at 9:53
from gson.
Thanks for providing the code snippet. This will not work properly in case of
genericized maps since in those cases it is important to use the type specified
in
the field declaration instead of the actual type. I have made similar fixes for
Issue
54 and 58 that I will apply in this case as well.
Original comment by inder123
on 21 Oct 2008 at 3:32
from gson.
I have fixed this issue in r277
Now, you should be able to serialize raw maps. The deserialization continues to
require parameterized type.
Original comment by inder123
on 21 Oct 2008 at 10:41
- Changed state: Fixed
from gson.
Thank you for fixing this issue:
In java land, you really shouldn't be instantiating Map<String, Object> but
since
we're dealing with JSON world, it actually makes a lot of sense.
Consider Map<String, Object> map;
map.put("field1", 123);
map.put("field2", "myfield2");
What is gson.toJson(map)???
It's a javascript object o where o.field1 is the number 123 and o.field2 is the
string myfield2!
Original comment by [email protected]
on 22 Jan 2010 at 9:43
from gson.
json convert to map<Integer,MyClass> it have problem !
how to do ?
Original comment by [email protected]
on 6 Mar 2010 at 6:43
from gson.
If you do json eval() in javascript or python, you get a dictionary. Inside the
dictionary, it has String/Number or nested dictionaries. eval doesnt expect
these type declarations.
I would expect the same on static language as well - Maps with default Number
(lossless datatype like Double) datatype for deserialization.
Original comment by [email protected]
on 25 Jun 2010 at 6:12
from gson.
Hi demograp,
Did you forget to implement a default constructor for MyClass ?
It was my case, and I solved it doing this.
Hope it helps.
Original comment by [email protected]
on 6 Aug 2010 at 2:45
from gson.
I faced similar problems. Easiest solution for me was wrapping the desired map
in a wrapper object and passing that to gson. I guess in the end that just
boils down to be the same as providing the TypeToken, but it is a much more
straightforward solution for those who want a quick fix.
Original comment by [email protected]
on 1 Sep 2011 at 12:23
from gson.
Related Issues (20)
- Need a gson-2.10.1 jar build without module-info.class HOT 4
- Unicodes bug? HOT 4
- Build failure with Java 21 HOT 8
- Error on compose multiplatform release package (enabled proguard) HOT 2
- WARNING: Illegal reflective access by com.google.gson.internal.reflect.ReflectionHelper HOT 3
- @SerializedName not working HOT 12
- Request to enhance some tests performance to avoid random getDeclaredFields() results HOT 3
- gson-2.10.1 failed with jdk:21 (test phase): "Tests run: 1231, Failures: 8" HOT 7
- Bug Parse Date 1966-11-01 HOT 4
- `DateFormat` time zone is not restored after parsing, affecting subsequent serialization HOT 2
- Internal packages are not exported in OSGI jar HOT 1
- Parse nested json into flat model class objects HOT 1
- Generic deserializer should extract type information from generic boundary HOT 15
- L
- Yep
- Hua HOT 1
- fromJson(String json, Class<T> classOfT) throws JsonSyntaxException is not thawing exception HOT 1
- 打个广告 gson 10倍速度提升 https://github.com/NBXXF/gson_plugin HOT 1
- About gson multiple field conflict error reporting HOT 1
- Using gson to deserialize error reporting, the gson version I use is 2.10.1 HOT 4
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from gson.