简体   繁体   中英

Response Code 400 Bad Request when use Json String param in Query tag Retrofit 2 Android

I'm using Retrofit 2 to call API in Android App. I have a API, using POST, which have a String param in Query Tag. I do everything like doc suppose and I test this API successfully in Test Page. I can run another API correctly so the problem is not the way I use Retrofit 2. Here is my interface:

@POST("/users/{userId}/get_list_friends")
    Call<GetListFriendDataResponse> getListFriend(@Path("userId") int userId, @Query("list") String list, @Query("page") int page, @Query("size") int size, @Header("hash") String hash);

Here is my implementation:

ArrayList<String> id = new ArrayList<>();
        id.add("4782947293");
        JSONArray jsonArray = new JSONArray(id);
        JSONObject jsonObject = new JSONObject();

        try {
            jsonObject.put("list", jsonArray);
        } catch (JSONException e) {
            e.printStackTrace();
        }
        String list = jsonObject.toString();
            Log.e(TAG, "list: " + list);
        apiInterface.getListFriend(21, list, 1,1,"AHHIGHTJGI").enqueue(new Callback<GetListFriendDataResponse>() {
            @Override
            public void onResponse(Call<GetListFriendDataResponse> call, Response<GetListFriendDataResponse> response) {
                Log.e(TAG, " response code: "+ response.code());
                               }

            @Override
            public void onFailure(Call<GetListFriendDataResponse> call, Throwable t) {

            }
        });

I always get response code: 400 when use this API. I'm focusing the "list" var. "list" is a JSON text but I wonder if method "jSon.toString()" is right to get a String from a JSONObject, which can using in Retrofit 2. List param form is:{"list":["12332"]} .

Please help me!

Questions 1) Why you are creating JSONObject and JSONArray on your own? 2) You are creating string using whatever you are creating json. Eg: {list:["123","456"]} you are trying pass whole json, I think, instead you need to pass just the array of string to the list key.

Request Sending

{
 list:["123","456"]
}

suppose the above json is the request you want to send to server Now, create model class goto http://jsonschema2pojo.org and paste your json and select json and gson at right side and click on preview.

It will show the classes to map you json to model. Use this model class to set the list to the key in your json

I found my problem. The JSON text contains some special character so I need to convert them to URL encode. Correct request URL like this:

http://54.169.215.161:8080/users/29/add_friend?list=%7B%22list%22%3A%5B%2215536%22%5D%7D&platform=google

By using Retrofit 2, it uses the URL:

http://54.169.215.161:8080/users/29/add_friend?list={%22list%22:[%2215536%22]}&platform=google

So I get Bad Request Response code. Retrofit 2 also provides method to convert char sequence to URL encode but it 's not enough. So I don't use Retrofit 's convert method by using this code: encode= true. so my interface is:

@POST("/users/{userId}/get_list_friends")
    Call<GetListFriendDataResponse> getListFriend(@Path("userId") int userId, @Query(value = "list",encoded = true) String list, @Query("page") int page, @Query("size") int size, @Header("hash") String hash);

And I manually convert JSON text to URL encode by code:

        list = list.replace("{", "%7B");
        list=list.replace("]", "%5D");
        list=list.replace("[", "%5B");
        list=list.replace(":", "%3A");
        list=list.replace("}","%7D");
        list = list.replace("\"", "%22");

That's all. Now I can get data by using API.

Suggestion: If u have the same problem, check the URL retrofit return in response and compare to correct URL to see special character, which is not converted to URL encode.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM