fyhack / google-gson

Automatically exported from code.google.com/p/google-gson
0 stars 0 forks source link

Cannot serialize or deserialize Maps with complex keys #210

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
import java.util.HashMap;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

public class GsonTest {

    public static void main(String[] args) {

        new GsonTest();

    }

    public GsonTest() {
        HashMap<ComplexKey, String> map = new HashMap<ComplexKey, String>();

        map.put(new ComplexKey("Test1", "Test2"), "Value1");

        Gson gson = new Gson();
        System.out.println(gson.toJson(map, new TypeToken<HashMap<ComplexKey,
String>>(){}.getType()));
    }

    public class ComplexKey {

        private String keyOne;
        private String keyTwo;

        public ComplexKey(String keyOne, String keyTwo) {
            this.keyOne = keyOne;
            this.keyTwo = keyTwo;
        }

        public String getKeyOne() {
            return keyOne;
        }

        public void setKeyOne(String keyOne) {
            this.keyOne = keyOne;
        }

        public String getKeyTwo() {
            return keyTwo;
        }

        public void setKeyTwo(String keyTwo) {
            this.keyTwo = keyTwo;
        }
    }
}

Expected Output:
{"{"keyOne":"Test1","keyTwo":"Test2"}":"Value1"}

Actual Output:
{"GsonTest$ComplexKey@1172e08":"Value1"}

Original issue reported on code.google.com by rev...@paradise.net.nz on 25 May 2010 at 2:53

GoogleCodeExporter commented 9 years ago
[deleted comment]
GoogleCodeExporter commented 9 years ago
I have investigated this a bit and written some code (got toJson to work, but 
parsing
fails), but what is really the expected behavior? What you expect is probably 
not
legal JSON, as the quotation marks are nested.

I am beginning to wonder if the best solution for complex keys is to encode it 
as:

{"key":{"keyOne":"Test1","keyTwo":"Test2"},"value":"Value1"}

Original comment by marius.k...@gmail.com on 6 Jun 2010 at 3:56

GoogleCodeExporter commented 9 years ago
I have implemented the solution mentioned above (with those in an array) in the 
cases the key consists of a complex key (not representable as text).

Patch is attached. The code could maybe be cleaner, but all tests and a new for 
this case passes.

Original comment by marius.k...@gmail.com on 9 Jun 2010 at 12:19

Attachments:

GoogleCodeExporter commented 9 years ago
Adopting something like the above patch would make my life so much better. :)

Original comment by jsha...@google.com on 28 Aug 2010 at 6:36

GoogleCodeExporter commented 9 years ago
Issue 224 has been merged into this issue.

Original comment by limpbizkit on 28 Aug 2010 at 8:26

GoogleCodeExporter commented 9 years ago
Issue 228 has been merged into this issue.

Original comment by limpbizkit on 3 Sep 2010 at 6:50

GoogleCodeExporter commented 9 years ago
Issue 214 has been merged into this issue.

Original comment by limpbizkit on 3 Sep 2010 at 6:51

GoogleCodeExporter commented 9 years ago
I did some exploring and it's possible to fix this by registering a type 
adapter. I've created a type adapter that takes any map and serializes it as a 
JSON array. It's pretty fantastic and it should work for anyone stuck on this 
bug.

I'd like to get this patch included in GSON 1.7. I'm not committing it directly 
because we're still stabilizing GSON 1.6.

Original comment by limpbizkit on 8 Nov 2010 at 9:06

Attachments:

GoogleCodeExporter commented 9 years ago
Well, the only problem with this patch is that you need to explicitly add the 
type adapter. It will not work automatically work and be compatible with data 
saved with older versions, thus it can't be added as default.

My approach above tries to detect if we are dealing with a type that can be 
serialized as string and choose strategy (but i don't remember if it works 
fully, as I don't know too much of the internals of GSon).

Original comment by marius.k...@gmail.com on 9 Nov 2010 at 9:01

GoogleCodeExporter commented 9 years ago
Fixed in r702 with one explicit type adapter for all maps. This new type 
adapter works for arbitrary maps with both complex and non-complex keys.

Original comment by limpbizkit on 12 Jan 2011 at 12:23

GoogleCodeExporter commented 9 years ago
For any internet travelers from the future (like myself)... you can enable this 
functionality in GSON 2.* with the enableComplexMapKeySerialization() method on 
GsonBuilder.

Original comment by jakewhar...@gmail.com on 9 Jan 2013 at 8:29