java - GSON - Deserialize primitive array -


consider simple json:

{     "test": [         0,         3     ] } 

now want deserialize in simple int array use custom deserializer:

class arraydeserializer implements jsondeserializer<int[]> {     @override     public int[] deserialize(jsonelement json, type typeoft, jsondeserializationcontext context) throws jsonparseexception {         return context.deserialize(json.getasjsonobject().getasjsonarray("test"), int[].class);     } } 

and then:

gson gson = new gsonbuilder().registertypeadapter(int[].class, new arraydeserializer()).create(); int[] arr = gson.fromjson(json, int[].class); 

which throws:

exception in thread "main" com.google.gson.jsonsyntaxexception: java.lang.illegalstateexception: not json object: [0,3] 

however when this:

class arraydeserializer implements jsondeserializer<int[]> {      private static final gson gson = new gson();      @override     public int[] deserialize(jsonelement json, type typeoft, jsondeserializationcontext context) throws jsonparseexception {         return gson.fromjson(json.getasjsonobject().getasjsonarray("test"), int[].class);     } } 

it works , expected output. why?

let's rewrite arraydeserializer in equivalent form more expressive

class arraydeserializer implements jsondeserializer<int[]> {     @override     public int[] deserialize(jsonelement json, type typeoft, jsondeserializationcontext context) throws jsonparseexception {         jsonarray jsonarray = json.getasjsonobject().getasjsonarray("test");         return context.deserialize(jsonarray, int[].class);     } } 

the jsondeserializationcontext#deserialize javadoc states

invokes default deserialization on specified object. should never invoked on element received parameter of jsondeserializer.deserialize(jsonelement, type, jsondeserializationcontext) method. doing result in infinite loop since gson in-turn call custom deserializer again.

so, if had worked, you'd more have stackoverflow on hands.

so why didn't work?

you called (in pseudo-code)

deserialize {test:[0,3]} int[] // --> gson finds arraydeserializer mapped int[] take given json object (ok), extract 'test' json array (ok) deserialize [0,3] int[] // --> gson finds arraydeserializer mapped int[] take given json object (fail) 

this last time recurred, json in form of json array arraydeserializer expecting json object.

in second attempt

return gson.fromjson(json.getasjsonobject().getasjsonarray("test"), int[].class); 

you're again extracting 'test' json array , feeding new gson instance on haven't registered arraydeserializer. in effect, you're invoking

new gson().fromjson("[0,3]", int[].class); 

which supported out of box , return int[] 2 elements 0 , 3, expected.


there simpler solutions.

define simple pojo type

class pojo {     private int[] test;     public int[] gettest() {         return test;     }     public void settest(int[] test) {         this.test = test;     } } 

and deserialize it

pojo pojo = new gson().fromjson(json, pojo.class); int[] arr = pojo.gettest();  

or

gson gson = new gson(); jsonarray jsonarray = gson.tojsontree(json).getasjsonobject().get("test").getasjsonarray(); int[] arr = gson.fromjson(jsonarray, int[].class); 

Comments

Popular posts from this blog

java - Spring Data JPA: Why findOne(id) executing delete query internally? -

python - Mongodb How to add addtional information when aggregating? -

java - Incorrect order of records in M-M relationship in hibernate -