Convert a JSON string to a shared object in JAVA (using GSON)

I have an Api that returns JSON. The answer is in some format, which can fit into the ApiResult object and contains Context <T> and int Code.

ApiResult is declared in a general way, for example. ApiResult<SomeObject>

I would like to know how to get GSON to convert incoming JSON string to ApiResult<T>

So far I:

 Type apiResultType = new TypeToken<ApiResult<T>>() { }.getType(); ApiResult<T> result = gson.fromJson(json, apiResultType); 

But this still returns a Context conversion to LinkedHashMap (which I assume is what GSON is returning to)

+7
java gson
source share
4 answers

You need to know what T will be. Incoming JSON is fundamentally plain text. GSON has no idea who you want to become. If there is something in this JSON that you can specify in order to create your own instance of T, you can do something like this:

 public static class MyJsonAdapter<X> implements JsonDeserializer<ApiResult<X>> { public ApiResult<X> deserialize( JsonElement jsonElement, Type type, JsonDeserializationContext context ) throws JsonParseException { String className = jsonElement.getAsJsonObject().get( "_class" ).getAsString(); try { X myThing = context.deserialize( jsonElement, Class.forName( className ) ); return new ApiResult<>(myThing); } catch ( ClassNotFoundException e ) { throw new RuntimeException( e ); } } } 

I use the "_class" field to decide what my X should do and create it using reflection (similar to the PomPom example). You probably don't have such an obvious field, but there should be some way for you to take a look at JsonElement and decide, based on what it is, what type X should be.

This code is a hacked version of something similar that I did with GSON some time ago, see line 184+ at: https://github.com/chriskessel/MyHex/blob/master/src/kessel/hex/domain /GameItem.java

+4
source share

You must specify Gson type T Since gson does not know which adapter to use, it simply returns a data structure.

You need to provide a generic type, for example:

 Type apiResultType = new TypeToken<ApiResult<String>>() { }.getType(); 

If type T is known only at run time, I use something complicated:

  static TypeToken<?> getGenToken(final Class<?> raw, final Class<?> gen) throws Exception { Constructor<ParameterizedTypeImpl> constr = ParameterizedTypeImpl.class.getDeclaredConstructor(Class.class, Type[].class, Type.class); constr.setAccessible(true); ParameterizedTypeImpl paramType = constr.newInstance(raw, new Type[] { gen }, null); return TypeToken.get(paramType); } 

Your call will (but replace String.class with a variable):

 Type apiResultType = getGenToken(ApiResult.class, String.class); 
+1
source share

I use the JacksonJson library, very similar to GSon. It is possible to convert a json string to some kind of generic object like this:

 String data = getJsonString(); ObjectMapper mapper = new ObjectMapper(); List<AndroidPackage> packages = mapper.readValue(data, List.class); 

Perhaps this is correct with GSON in your case:

 ApiResult<T> result = gson.fromJson(json, ApiResult.class); 
0
source share

My solution uses org.json

The following are methods to wrap a json object in an array, convert the object to a list, and convert the json string to type.

 public <T> List<T> parseJsonObjectsToList(JSONObject parentJson, String key, Class<T> clazz) throws IOException { Object childObject = parentJson.get(key); if(childObject == null) { return null; } if(childObject instanceof JSONArray) { JSONArray jsonArray = parentJson.getJSONArray(key); return getList(jsonArray.toString(), clazz); } JSONObject jsonObject = parentJson.getJSONObject(key); List<T> jsonList = new ArrayList<>(); jsonList.add(getObject(jsonObject.toString(), clazz)); return jsonList; } public <T> List<T> getList(String jsonStr, Class clazz) throws IOException { ObjectMapper objectMapper = StringUtils.INSTANCE.getOBJECT_MAPPER(); TypeFactory typeFactory = objectMapper.getTypeFactory(); return objectMapper.readValue(jsonStr, typeFactory.constructCollectionType(List.class, clazz)); } public <T> T getObject(String jsonStr, Class<T> clazz) throws IOException { ObjectMapper objectMapper = StringUtils.INSTANCE.getOBJECT_MAPPER(); return objectMapper.readValue(jsonStr, clazz); } // To call parseJsonObjectsToList(creditReport, JSON_KEY, <YOU_CLASS>.class); 
0
source share

All Articles