3

I can't seem to figure out how to get android annotations rest client to work I'm having 2 main issues.

A)How to parse the generic json response and get the meaningful key

B)How to add parameters

For the first problem all responses come back as a json string fomatted like this

{"success":,"message":"","data":{}}

Where success is boolean message is a string and data is going to be the main data I want to parse that may be a boolean, an array, a string or an int

I'm pretty sure I need to intercept the response and handle the code but I'm not sure how to do that

Lets use a real response that look something like this

{"success":true,"message":"random message","data":{"profile":{"id":"44","user_id":"44","name":"Matt","username":"mitch","icon":"b1da7ae15027b7d6421c158d644f3220.png","med":"2a3df53fb39d1d8b5edbd0b93688fe4a.png","map":"b7bfed1f456ca4bc8ca748ba34ceeb47.png","background":null,"mobile_background":null}}

First in my interceptor I want to see if the boolean key "success" is true and then return the data value

@EBean
public class RestInterceptor implements ClientHttpRequestInterceptor {

    final String TAG = "rest";

    @Bean
    AuthStore authStore;

    @Override
    public ClientHttpResponse intercept(HttpRequest request, byte[] data, ClientHttpRequestExecution execution)
            throws IOException{

        //Need to set the api key here but nothing happens code quits
//        Log.d("Rest",authStore.getApiKey());

         HttpHeaders headers = request.getHeaders();

         headers.set("api_key","");

         ClientHttpResponse resp = execution.execute(request, data);

         HttpStatus code = resp.getStatusCode();


         if(code.value() == 200){
            Log.d(TAG,"success code 200"); 

            //valid http request but is it a valid API request?
                //perform some logic of if success == true in root json object
                //if true cast return data key 



         }
         else{
             Log.d(TAG,"fail code" + code.toString());
         }


         return resp;
    }

}

The second problem is sending params with the http request that have an api key and a session key, I define the application class like this

@EApplication
public class MyApp extends Application {

    final String TAG = "app";

    @Bean
    AuthStore authStore;

    @RestService
    RestClient restClient;


    public void onCreate() {
        super.onCreate();
        init();
    }

    @AfterInject
    public void init() {

        authStore.setApiKey("dummy_key");
        Log.d(TAG, "api key set to " + authStore.getApiKey());

    }
}

With the AuthStore class like this

@EBean(scope = Scope.Singleton)
public class AuthStore {

    public String apiKey,sessionKey;

    public String getApiKey() {
        return apiKey;
    }

    public void setApiKey(String apiKey) {
        this.apiKey = apiKey;
    }

    public String getSessionKey() {
        return sessionKey;
    }

    public void setSessionKey(String sessionKey) {
        this.sessionKey = sessionKey;
    }
}

Basically I'm setting a dummy api key at the application level in a singleton, which I should be able to access in the rest interceptor interface but the code just quits without errors I'm basically following this guide https://github.com/excilys/androidannotations/wiki/Authenticated-Rest-Client

Finally I have an activity class which injects the app dependency which has refrence to the rest http class and the authstore class

@EActivity(R.layout.activity_login)
public class LoginActivity extends Activity {

    @App
    MyApp app;
    @ViewById
    TextView email;
    @ViewById
    TextView password;
    @ViewById
    Button loginButton;


    @AfterInject
    public void init() {
        Log.d(app.TAG, "api in login key set to " + app.authStore.getApiKey());

    }

    @Click
    @Trace
    void loginButton() {

        login(email.toString(), password.toString());

    }

    @Background
    void login(String email, String password) {
         app.restClient.forceLogin();


    }
}

Sorry if it's a lot of info, I've been searching for a while and can't figure this out!

thanks in advance

Brian
  • 4,328
  • 13
  • 58
  • 103

2 Answers2

1

I'm not known with the library you're using (annotations, spring) but it seems to me that you are struggling with parsing the success = true because that is not supposed to be in the JSON.

The JSON should preferably represent a class in your app 1on1 so you can easily map that into an object. Communication between your app and the webservice, regarding the status of requests should go into the headers.

Like this you can check a request's headers, before parsing the JSON.

Stefan de Bruijn
  • 6,289
  • 2
  • 23
  • 31
0

This is mathod I am using to parse any JSON object recursively.

private void parseJson(JSONObject data) {

        if (data != null) {
            Iterator<String> it = data.keys();
            while (it.hasNext()) {
                String key = it.next();

                try {
                    if (data.get(key) instanceof JSONArray) {
                        JSONArray arry = data.getJSONArray(key);
                        int size = arry.length();
                        for (int i = 0; i < size; i++) {
                            parseJson(arry.getJSONObject(i));
                        }
                    } else if (data.get(key) instanceof JSONObject) {
                        parseJson(data.getJSONObject(key));
                    } else {
                        System.out.println("" + key + " : " + data.optString(key));
                    }
                } catch (Throwable e) {
                    System.out.println("" + key + " : " + data.optString(key));
                    e.printStackTrace();

                }
            }
        }
    }
Biraj Zalavadia
  • 28,348
  • 10
  • 61
  • 77