2

I made a function : input ID card numbers, click the submit button, then get the basic info of the ID card.

the MODEL I used:

public class IdCardInfo {

    private int errNum;
    private String retMsg;
    private RetDataBean retData;

    public int getErrNum() {
        return errNum;
    }

    public void setErrNum(int errNum) {
        this.errNum = errNum;
    }

    public String getRetMsg() {
        return retMsg;
    }

    public void setRetMsg(String retMsg) {
        this.retMsg = retMsg;
    }

    public RetDataBean getRetData() {
        return retData;
    }

    public void setRetData(RetDataBean retData) {
        this.retData = retData;
    }

    public static class RetDataBean {

        private String sex;
        private String birthday;
        private String address;

        public String getSex() {
            return sex;
        }

        public void setSex(String sex) {
            this.sex = sex;
        }

        public String getBirthday() {
            return birthday;
        }

        public void setBirthday(String birthday) {
            this.birthday = birthday;
        }

        public String getAddress() {
            return address;
        }

        public void setAddress(String address) {
            this.address = address;
        }
    }
}

the retrofit interface I used:

@GET("apistore/idservice/id")
Observable<IdCardInfo> getIdCardInfo(@Query("id") String id);

when I input the correct ID card numbers, everything works well. the returned result is:

{
    "errNum": 0,
    "retMsg": "success",
    "retData": {
        "sex": "M", 
        "birthday": "1987-04-20", 
        "address": "some place" 
    }
}

Everything works well.

However when I input a incorrect ID card numbers, the bad things happens:

Caused by: java.lang.IllegalStateException: 
Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 86 path $.retData

the returned result is:

{
    "errNum": -1, 
    "retMsg": "Incorrect ID card number!", 
    "retData": [ ]
}

How could I fix the bugs?

1
  • show your request code Commented Jan 2, 2017 at 8:50

3 Answers 3

2

The api @ apistore/idservice/id is returning an empty json array instead of an empty json object. You are expecting a json object here, so it throws. Do you have control over what the API returns? Please return

{
    "errNum": -1, 
    "retMsg": "Incorrect ID card number!", 
    "retData": { }
}

in the response.

Sign up to request clarification or add additional context in comments.

1 Comment

@singdhu I'm sorry to say that: I can't control what the API returns.
1

This is the issue with server in case of no data it is returning empty array ,your server API most probably based on some PHP framework.

it can be sorted only from backend not from app , as you can't parse Array instead of object without changing the class structure.

so ask your backend team if it is possible to change that thing ie. empty array to null object or no key should be sent.

possible hack in such cases :

Yes i know the exact issue, it cant be changed easily because it is at framework level. what i suggest you can change your code something like this

@GET("apistore/idservice/id")
Observable<JsonObject> getIdCardInfo(@Query("id") String id);

so after this you need to parse your code manually then you need to put that particular key parsing in try-catch block. ie. in try block you will try to parse data as object if face exception then just assign null to that object value.

2 Comments

Thanks for your advice, but what the pity is that the server API is a common API, whose return can't be changed. So the problem comes out.
Thanks a lot. I got much from your answer.
0

you should use List of response when you return array for example:

@GET("apistore/idservice/id")
 Observable<List<IdCardInfo>> getIdCardInfo(@Query("id") String id);

in place of

@GET("apistore/idservice/id")
 Observable<IdCardInfo> getIdCardInfo(@Query("id") String id);

also replace in your retrofit call

Call<List<IdCardInfo>> call = service.getIdCardInfo("query");
        call.enqueue(new Callback<List<IdCardInfo>>() {

            @Override
            public void onResponse(Call<List<IdCardInfo>> variant, Response<List<IdCardInfo>> response) {
                if (response != null && response.isSuccessful() && response.errorBody() == null) {


                }
            }

            @Override
            public void onFailure(Call<List<IdCardInfo>> variant, Throwable t) {
                t.printStackTrace();

            }
        });

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.