Retrofit - handle JSON key which has a dynamic str

2019-05-30 17:38发布

I'm using POJO classes which have getters and setters. However, due to this dynamic behaviour i would be forced to use the deserialising part. I've implemented the code for that as well, however is there any other way to handle this. Because, the below pasted response is just a small part of the actual response (which is massive and i'm using POJO getters and setters for it)

OBJECT

 secondaryUser: {
    id: 1,
    username: "admin",
    numberOfFollowers: 1,
    displayName: "admin"
    }

ARRAY

 secondaryUser: [
    {
    id: 18150,
    activityDateTime: "2015-07-20 14:46:02",
    user: {
    id: 1,
    username: "admin",
    numberOfFollowers: 1,
    displayName: "admin"
    }
    },
    {
    id: 18148,
    activityDateTime: "2015-07-20 13:35:02",
    user: {
    id: 3,
    username: "USER_1",
    numberOfFollowers: 4,
    displayName: "USER_1"
    }
    },
    {
    id: 18146,
    activityDateTime: "2015-07-20 11:29:41",
    user: {
    id: 2468,
    username: "USER_2",
    numberOfFollowers: 1,
    displayName: "USER_2"
    }
    }
    ]
    }

1条回答
做个烂人
2楼-- · 2019-05-30 17:48

I hope this will solve your problem.

First of all, in your case, if you have declared secondaryUser as object or Array, change it to List<SecondaryUser> secondaryUser

Create a deserializer.

DynamicJsonConverter.java

public class DynamicJsonConverter implements Converter {

    private static String fromStream(InputStream in) throws IOException {
        BufferedReader reader = new BufferedReader(new InputStreamReader(in));
        StringBuilder out = new StringBuilder();
        String line;
        while ((line = reader.readLine()) != null) {
            out.append(line);

        }
        return out.toString();
    }

    @Override
    public Object fromBody(TypedInput typedInput, Type type) throws ConversionException {
        try {
            InputStream in = typedInput.in(); // convert the typedInput to String
            String string = fromStream(in);
            in.close(); // we are responsible to close the InputStream after use
            return string;

        } catch (Exception e) { // a lot may happen here, whatever happens
            throw new ConversionException(e); // wrap it into ConversionException so retrofit can process it
        }

    }

    @Override
    public TypedOutput toBody(Object object) { // not required
        return null;
    }
}

Your Rest Adapter class.

BasePathAdapterForDynamicJSONKeys.java

 public class BasePathAdapterForDynamicJSONKeys {
        private static RetroFitInterface topRecommendationsInterface;

        public static RetroFitInterface getCommonPathInterface() {

            RestAdapter restAdapter = new RestAdapter.Builder()
                    .setEndpoint(baseURL)
                    .setConverter(new DynamicJsonConverter())

                    .build();
            topRecommendationsInterface = restAdapter.create(RetroFitInterface.class);
            return topRecommendationsInterface;
        }

Also, use the callback as Callback<String>() instead of Callback<YourObject>()

Now, inside the your activity/fragment, inside the success method of retrofit callback, use this.

@Override
 public void success(String myData, Response response) {
 JSONObject mainObject = null;
 mainObject = new JSONObject(myData);

//You can also use JSONObject, depends on what type the response is

 JSONArray myJsonArray = mainObject.getJSONArray("yourkey");

And finally, dump this inside your arraylist.(This is basically conversion of JSON array to arraylist :))

 ArrayList<MyObj> menuDetails = new Gson().fromJson(myJsonArray.toString(), new TypeToken<List<MyObj>>(){}.getType());
查看更多
登录 后发表回答