skip to Main Content

Hello Web API gives me following JSON. It’s for comment.

{
  "comment_count": 9,
  "comments": [
    {
      "comment_ID": "2",
      "comment_post_ID": "167",
      "comment_author": "admin",
      "comment_author_email": "[email protected]",
      "comment_author_url": "",
      "comment_author_IP": "::1",
      "comment_date": "2019-01-21 10:45:59",
      "comment_date_gmt": "2019-01-21 02:45:59",
      "comment_content": "asdada asda sda sd asdsada sd as",
      "comment_karma": "0",
      "comment_approved": "1",
      "comment_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)",
      "comment_type": "",
      "comment_parent": "0",
      "user_id": "1",
      "like_cnt": "1",
      "image": "",
      "author_image": "52263886_2292810744295258_5904172631346642944_n-150x150.jpg",
      "is_liked": true
    },
    {
      "comment_ID": "3",
      "comment_post_ID": "167",
      "comment_author": "admin",
      "comment_author_email": "[email protected]",
      "comment_author_url": "",
      "comment_author_IP": "::1",
      "comment_date": "2019-01-21 11:12:37",
      "comment_date_gmt": "2019-01-21 03:12:37",
      "comment_content": "a",
      "comment_karma": "0",
      "comment_approved": "1",
      "comment_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)",
      "comment_type": "",
      "comment_parent": "0",
      "user_id": "1",
      "like_cnt": "0",
      "image": "",
      "author_image": "52263886_2292810744295258_5904172631346642944_n-150x150.jpg",
      "is_liked": false
    }
  ]
}

Comment reply levels are unlimited. It can be many level. But I want to do it like facebook comment section. Which means:

A: comment - level 0
B: comment - level 0
   C: reply of comment B - level 1
      D: reply of comment C - level 2 

Comment D level is 2. D comment is reply of C comment.
I want to tag C comment’s author name in D comment. Because I don’t want to add level 2.

But how do I store data in adapter? As you can see there’s no level.
So far what I wrote is: /Edited/

  for(int i = 0; i < result.getComments().size(); i++){
                    Comment comment = result.getComments().get(i);
                    if(comment.getComment_parent().equals("0")) continue;
                    String parentId = comment.getComment_parent();
                    boolean parentFound = false;
                    boolean rootFound = false;

                    while(!parentFound || !rootFound){

                        int parentPosition = binarySearch(result.getComments(),0, result.getComments().size(), parentId);
                        if(parentPosition == -1) break;
                        Comment temp = result.getComments().get(parentPosition);

                        if(temp.getComment_ID().equals(parentId)){
                            if (!parentFound){
                                parentFound = true;
                                comment.setTag(temp.getComment_author());
                            }

                            if (temp.getComment_parent().equals("0")) {
                                rootFound = true;
                                comment.setRootId(temp.getComment_ID());
                                temp.addChildComment(comment);
                            } else {
                                parentId = temp.getComment_parent();
                            }
                        }
                    }
                }


                Iterator itr = result.getComments().iterator();
                while (itr.hasNext()) {
                    Comment comment = (Comment) itr.next();
                    if(!comment.getComment_parent().equals("0")){
                        itr.remove();
                    }
                }

private int binarySearch(List<Comment> arr, int l, int r, String x)
    {
        if (r>=l)
        {
        int mid = l + (r - l)/2;
        if (arr.get(mid).getComment_ID().equals(x))
            return mid;

        if (Integer.valueOf(arr.get(mid).getComment_ID()) > Integer.valueOf(x))
            return binarySearch(arr, l, mid-1, x);

        return binarySearch(arr, mid+1, r, x);
    }
    return -1;
}

public class Comment {

private String comment_ID;
private String comment_post_ID;
private String comment_author;
private String comment_author_email;
private String comment_author_url;
private String comment_author_IP;
private String comment_date;
private String comment_date_gmt;
private String comment_content;
private String comment_karma;
private String comment_approved;
private String comment_agent;
private String comment_type;
private String comment_parent;
private String user_id;
private boolean isSend = true;
private List<Comment> commentList;

private String rootId;
private String tag;

3

Answers


  1. you should create 2 classes – one for Retrofit to parse WebAPI response to and the Comment entity itself.
    The following is a class for Retrofit response:

    public class Comments{
        @SerializedName("comment_count")
        private int commentCount; //this could be ignored
        private List<Comment> comments;
    }
    

    @SerializedName("comment_count") tells Retrofit the JSON key to commentCount field, without this annotation you have to declare field with the same name as JSON key, like private int comment_count;
    The Comment entity itself:

    public class Comment {
    
        private String comment_ID;
        private String comment_post_ID;
        private String comment_author;
        private String comment_author_email;
        private String comment_author_url;
        private String comment_author_IP;
        private String comment_date;
        private String comment_date_gmt;
        private String comment_content;
        private String comment_karma;
        private String comment_approved;
        private String comment_agent;
        private String comment_type;
        private String comment_parent;
        private String user_id;
        private boolean isSend = true;
    }
    

    You don’t have to parse response yourself, let this job to be done by Retrofit and you will get List<Comment> which you could use to fill your adapter freely or store this array into DB.

    The following shows you how to get response using Retrofit. Somewhere in your code you call method

    private void requestComments() {
        ApiManager.getCommentsAdapter().getComments(new IApiCallBackSuccess<Comments>() {
            @Override
            public void onApiSuccess(Comments response) {
                onGotComments(response); // do there whatever you like
            }
        }, this);
    }
    

    in ApiManager:

    public final class ApiManager {
        public static CommentsApiAdapter getCommentsAdapter() {
            return new CommentsApiAdapter();
        }
    }
    

    CommentsApiAdapter:

    public class CommentsApiAdapter extends MyApiAdapter<CommentsApiService> {
    
        @Override
        Class<CommentsApiService> provideServiceClass() {
            return CommentsApiService.class;
        }
    
        public void getComments(final IApiCallBackSuccess<Comments> callBackSuccess,
                                 final IApiCallBackError callBackError) {
            getService().getComments().enqueue();
        }
    }
    

    MyApiAdapter, ApiUrlHelper.BASE_URL – is just a static final string with base url like “www.mywebapi.com”

    public abstract class MyApiAdapter<ApiService> extends BaseApiAdapter<ApiService> {
    
        @Override
        String getBaseUrl() {
            return ApiUrlHelper.BASE_URL;
        }
    }
    

    CommentsApiService (representing Retrofit service)

    public interface CommentsApiService {
    
        @GET("/api/comments")
        Call<Comments> getComments();
    }
    

    BaseApiAdapter

    abstract class BaseApiAdapter<ApiService> {
    
        private final int TIME_OUT = ApiUrlHelper.TIME_OUT;
        private final ApiService mApiService;
        private final Gson mGson;
    
        BaseApiAdapter() {
            final OkHttpClient.Builder okClientBuilder = new OkHttpClient.Builder()
                    .connectTimeout(TIME_OUT, TimeUnit.MILLISECONDS)
                    .readTimeout(TIME_OUT, TimeUnit.MILLISECONDS)
                    .writeTimeout(TIME_OUT, TimeUnit.MILLISECONDS);
    
    
            mGson = gsonBuilder.create();
    
            final Retrofit retrofit = new Retrofit.Builder()
                    .baseUrl(getBaseUrl())
                    .addConverterFactory(GsonConverterFactory.create(mGson))
                    .client(okClientBuilder.build())
                    .build();
            mApiService = retrofit.create(provideServiceClass());
        }
    
        abstract Class<ApiService> provideServiceClass();
    }
    
    Login or Signup to reply.
  2. Dont create Model class manually, I will suggest you to make Model/POJO classes using ROBOPOJO Generator It will generate All model classes for you, you don’t need to make it by your self, Will also help you in future while creating model class. It just need JSON string and click will make your job done

    Login or Signup to reply.
  3. Simply use the jsonschema2pojo converter tool to get your plain old java object. This will give you a very effective data object as per your API response which you can further extend with whatever required logic in your application.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search