Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Retrofit GsonConverterFactory 解析带有转义符的数据 #742

Open
KKaKa opened this issue Mar 27, 2019 · 3 comments
Open

Retrofit GsonConverterFactory 解析带有转义符的数据 #742

KKaKa opened this issue Mar 27, 2019 · 3 comments

Comments

@KKaKa
Copy link

KKaKa commented Mar 27, 2019

  • 后台返回的数据:
{
    "code": "00",
    "mobileData": "[{\"publish_type\":\"00\",\"uv_value\":3,\"app_type\":\"02\",\"page_type\":\"\",\"customer_level\":\"ALL_CUSTOMER\",\"partner_level\":\"0\",\"rule_number\":0,\"click_number\":0,\"title\":\"超时\",\"create_operator\":\"zexin\",\"publish_operator\":\"wangchaocheng\",\"optimistic\":0,\"update_time\":\"2019-03-20 14:28:43\",\"pv_value\":10,\"publish_time\":\"2019-03-20 14:28:51\",\"link_url\":\"https://www.cnblogs.com/ailiailan/p/7388784.html\",\"id\":32,\"click_type\":\"H5\",\"create_time\":\"2019-02-26 09:36:33\",\"end_time\":\"2019-03-30 10:00:04\",\"link_title\":\"CNBLOGS\",\"message_type\":\"02\",\"optimistic_lastsync\":0,\"update_operator\":\"wangchaocheng\",\"start_time\":\"2019-02-25 09:36:01\",\"image_path\":\"http://.www.baidu.com\",\"popup_rule\":\"02\",\"region\":\"\",\"status\":\"NORMAL\"}]",
    "msg": "广告请求成功"
}
  • api代码:
    @POST(ACTION)
    @FormUrlEncoded
    Observable<ResponseBean<AdBaseBeanList>> getAds2(
            @Field("requestType") String requestType,
            @Field("encryptData") String encryptData,
            @Field("signature") String signature,
            @Field("validate") boolean validate
    );
  • retrofit代码:
            apiService.getAds2(Constant.PUSH_MESSAGE_HANDLE,encrypt,sign,true)
                    .map(new BaseFunc1<>())
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(observe); 
  • 问题:
I: │ com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 28 path $.mobileData
I: │ 	at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:224)
I: │ 	at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.read(ReflectiveTypeAdapterFactory.java:129)
I: │ 	at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:220)
I: │ 	at retrofit2.converter.gson.GsonResponseBodyConverter.convert(GsonResponseBodyConverter.java:37)
I: │ 	at retrofit2.converter.gson.GsonResponseBodyConverter.convert(GsonResponseBodyConverter.java:25)
I: │ 	at retrofit2.ServiceMethod.toResponse(ServiceMethod.java:119)
I: │ 	at retrofit2.OkHttpCall.parseResponse(OkHttpCall.java:218)
I: │ 	at retrofit2.OkHttpCall.execute(OkHttpCall.java:180)
I: │ 	at retrofit2.adapter.rxjava2.CallExecuteObservable.subscribeActual(CallExecuteObservable.java:41)
I: │ 	at io.reactivex.Observable.subscribe(Observable.java:10901)
I: │ 	at retrofit2.adapter.rxjava2.BodyObservable.subscribeActual(BodyObservable.java:34)
I: │ 	at io.reactivex.Observable.subscribe(Observable.java:10901)
I: │ 	at io.reactivex.internal.operators.observable.ObservableMap.subscribeActual(ObservableMap.java:33)
I: │ 	at io.reactivex.Observable.subscribe(Observable.java:10901)
I: │ 	at io.reactivex.internal.operators.observable.ObservableSubscribeOn$SubscribeTask.run(ObservableSubscribeOn.java:96)
I: │ 	at io.reactivex.Scheduler$DisposeTask.run(Scheduler.java:452)
I: │ 	at io.reactivex.internal.schedulers.ScheduledRunnable.run(ScheduledRunnable.java:61)
I: │ 	at io.reactivex.internal.schedulers.ScheduledRunnable.call(ScheduledRunnable.java:52)
I: │ 	at java.util.concurrent.FutureTask.run(FutureTask.java:237)
I: │ 	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:272)
I: │ 	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
I: │ 	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
I: │ 	at java.lang.Thread.run(Thread.java:762)
I: │ Caused by: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 28 path $.mobileData
I: │ 	at com.google.gson.stream.JsonReader.beginObject(JsonReader.java:385)
I: │ 	at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:213)
I: │ 	... 22 more


  • 有人遇到这种吗,需要怎么解决好
@lazy-ai
Copy link

lazy-ai commented Mar 28, 2019

比较笨的方法可以把 AdBaseBeanList 改成 String,数据接收到之后 用gson在转一下。

class mobileData{

    /**
     * publish_type : 00
     * uv_value : 3
     * app_type : 02
     * page_type :
     * customer_level : ALL_CUSTOMER
     * partner_level : 0
     * rule_number : 0
     * click_number : 0
     * title : 超时
     * create_operator : zexin
     * publish_operator : wangchaocheng
     * optimistic : 0
     * update_time : 2019-03-20 14:28:43
     * pv_value : 10
     * publish_time : 2019-03-20 14:28:51
     * link_url : https://www.cnblogs.com/ailiailan/p/7388784.html
     * id : 32
     * click_type : H5
     * create_time : 2019-02-26 09:36:33
     * end_time : 2019-03-30 10:00:04
     * link_title : CNBLOGS
     * message_type : 02
     * optimistic_lastsync : 0
     * update_operator : wangchaocheng
     * start_time : 2019-02-25 09:36:01
     * image_path : http://.www.baidu.com
     * popup_rule : 02
     * region :
     * status : NORMAL
     */

    private String publish_type;
    private int uv_value;
    private String app_type;
    private String page_type;
    private String customer_level;
    private String partner_level;
    private int rule_number;
    private int click_number;
    private String title;
    private String create_operator;
    private String publish_operator;
    private int optimistic;
    private String update_time;
    private int pv_value;
    private String publish_time;
    private String link_url;
    private int id;
    private String click_type;
    private String create_time;
    private String end_time;
    private String link_title;
    private String message_type;
    private int optimistic_lastsync;
    private String update_operator;
    private String start_time;
    private String image_path;
    private String popup_rule;
    private String region;
    private String status;

    public String getPublish_type() {
        return publish_type;
    }

    public void setPublish_type(String publish_type) {
        this.publish_type = publish_type;
    }

    public int getUv_value() {
        return uv_value;
    }

    public void setUv_value(int uv_value) {
        this.uv_value = uv_value;
    }

    public String getApp_type() {
        return app_type;
    }

    public void setApp_type(String app_type) {
        this.app_type = app_type;
    }

    public String getPage_type() {
        return page_type;
    }

    public void setPage_type(String page_type) {
        this.page_type = page_type;
    }

    public String getCustomer_level() {
        return customer_level;
    }

    public void setCustomer_level(String customer_level) {
        this.customer_level = customer_level;
    }

    public String getPartner_level() {
        return partner_level;
    }

    public void setPartner_level(String partner_level) {
        this.partner_level = partner_level;
    }

    public int getRule_number() {
        return rule_number;
    }

    public void setRule_number(int rule_number) {
        this.rule_number = rule_number;
    }

    public int getClick_number() {
        return click_number;
    }

    public void setClick_number(int click_number) {
        this.click_number = click_number;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getCreate_operator() {
        return create_operator;
    }

    public void setCreate_operator(String create_operator) {
        this.create_operator = create_operator;
    }

    public String getPublish_operator() {
        return publish_operator;
    }

    public void setPublish_operator(String publish_operator) {
        this.publish_operator = publish_operator;
    }

    public int getOptimistic() {
        return optimistic;
    }

    public void setOptimistic(int optimistic) {
        this.optimistic = optimistic;
    }

    public String getUpdate_time() {
        return update_time;
    }

    public void setUpdate_time(String update_time) {
        this.update_time = update_time;
    }

    public int getPv_value() {
        return pv_value;
    }

    public void setPv_value(int pv_value) {
        this.pv_value = pv_value;
    }

    public String getPublish_time() {
        return publish_time;
    }

    public void setPublish_time(String publish_time) {
        this.publish_time = publish_time;
    }

    public String getLink_url() {
        return link_url;
    }

    public void setLink_url(String link_url) {
        this.link_url = link_url;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getClick_type() {
        return click_type;
    }

    public void setClick_type(String click_type) {
        this.click_type = click_type;
    }

    public String getCreate_time() {
        return create_time;
    }

    public void setCreate_time(String create_time) {
        this.create_time = create_time;
    }

    public String getEnd_time() {
        return end_time;
    }

    public void setEnd_time(String end_time) {
        this.end_time = end_time;
    }

    public String getLink_title() {
        return link_title;
    }

    public void setLink_title(String link_title) {
        this.link_title = link_title;
    }

    public String getMessage_type() {
        return message_type;
    }

    public void setMessage_type(String message_type) {
        this.message_type = message_type;
    }

    public int getOptimistic_lastsync() {
        return optimistic_lastsync;
    }

    public void setOptimistic_lastsync(int optimistic_lastsync) {
        this.optimistic_lastsync = optimistic_lastsync;
    }

    public String getUpdate_operator() {
        return update_operator;
    }

    public void setUpdate_operator(String update_operator) {
        this.update_operator = update_operator;
    }

    public String getStart_time() {
        return start_time;
    }

    public void setStart_time(String start_time) {
        this.start_time = start_time;
    }

    public String getImage_path() {
        return image_path;
    }

    public void setImage_path(String image_path) {
        this.image_path = image_path;
    }

    public String getPopup_rule() {
        return popup_rule;
    }

    public void setPopup_rule(String popup_rule) {
        this.popup_rule = popup_rule;
    }

    public String getRegion() {
        return region;
    }

    public void setRegion(String region) {
        this.region = region;
    }

    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }
}

String json= "[{"publish_type":"00","uv_value":3,"app_type":"02","page_type":"","customer_level":"ALL_CUSTOMER","partner_level":"0","rule_number":0,"click_number":0,"title":"超时","create_operator":"zexin","publish_operator":"wangchaocheng","optimistic":0,"update_time":"2019-03-20 14:28:43","pv_value":10,"publish_time":"2019-03-20 14:28:51","link_url":"https://www.cnblogs.com/ailiailan/p/7388784.html","id":32,"click_type":"H5","create_time":"2019-02-26 09:36:33","end_time":"2019-03-30 10:00:04","link_title":"CNBLOGS","message_type":"02","optimistic_lastsync":0,"update_operator":"wangchaocheng","start_time":"2019-02-25 09:36:01","image_path":"http://.www.baidu.com","popup_rule":"02","region":"","status":"NORMAL"}]";

    List<mobileData> list = null;
    try {
        list = gson.fromJson(json, new TypeToken<List<mobileData>>(){}.getType());
    }catch (Exception e){
        e.printStackTrace();
    }`

@KKaKa
Copy link
Author

KKaKa commented Mar 28, 2019

比较笨的方法可以把 AdBaseBeanList 改成 String,数据接收到之后 用gson在转一下。

class mobileData{

    /**
     * publish_type : 00
     * uv_value : 3
     * app_type : 02
     * page_type :
     * customer_level : ALL_CUSTOMER
     * partner_level : 0
     * rule_number : 0
     * click_number : 0
     * title : 超时
     * create_operator : zexin
     * publish_operator : wangchaocheng
     * optimistic : 0
     * update_time : 2019-03-20 14:28:43
     * pv_value : 10
     * publish_time : 2019-03-20 14:28:51
     * link_url : https://www.cnblogs.com/ailiailan/p/7388784.html
     * id : 32
     * click_type : H5
     * create_time : 2019-02-26 09:36:33
     * end_time : 2019-03-30 10:00:04
     * link_title : CNBLOGS
     * message_type : 02
     * optimistic_lastsync : 0
     * update_operator : wangchaocheng
     * start_time : 2019-02-25 09:36:01
     * image_path : http://.www.baidu.com
     * popup_rule : 02
     * region :
     * status : NORMAL
     */

    private String publish_type;
    private int uv_value;
    private String app_type;
    private String page_type;
    private String customer_level;
    private String partner_level;
    private int rule_number;
    private int click_number;
    private String title;
    private String create_operator;
    private String publish_operator;
    private int optimistic;
    private String update_time;
    private int pv_value;
    private String publish_time;
    private String link_url;
    private int id;
    private String click_type;
    private String create_time;
    private String end_time;
    private String link_title;
    private String message_type;
    private int optimistic_lastsync;
    private String update_operator;
    private String start_time;
    private String image_path;
    private String popup_rule;
    private String region;
    private String status;

    public String getPublish_type() {
        return publish_type;
    }

    public void setPublish_type(String publish_type) {
        this.publish_type = publish_type;
    }

    public int getUv_value() {
        return uv_value;
    }

    public void setUv_value(int uv_value) {
        this.uv_value = uv_value;
    }

    public String getApp_type() {
        return app_type;
    }

    public void setApp_type(String app_type) {
        this.app_type = app_type;
    }

    public String getPage_type() {
        return page_type;
    }

    public void setPage_type(String page_type) {
        this.page_type = page_type;
    }

    public String getCustomer_level() {
        return customer_level;
    }

    public void setCustomer_level(String customer_level) {
        this.customer_level = customer_level;
    }

    public String getPartner_level() {
        return partner_level;
    }

    public void setPartner_level(String partner_level) {
        this.partner_level = partner_level;
    }

    public int getRule_number() {
        return rule_number;
    }

    public void setRule_number(int rule_number) {
        this.rule_number = rule_number;
    }

    public int getClick_number() {
        return click_number;
    }

    public void setClick_number(int click_number) {
        this.click_number = click_number;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getCreate_operator() {
        return create_operator;
    }

    public void setCreate_operator(String create_operator) {
        this.create_operator = create_operator;
    }

    public String getPublish_operator() {
        return publish_operator;
    }

    public void setPublish_operator(String publish_operator) {
        this.publish_operator = publish_operator;
    }

    public int getOptimistic() {
        return optimistic;
    }

    public void setOptimistic(int optimistic) {
        this.optimistic = optimistic;
    }

    public String getUpdate_time() {
        return update_time;
    }

    public void setUpdate_time(String update_time) {
        this.update_time = update_time;
    }

    public int getPv_value() {
        return pv_value;
    }

    public void setPv_value(int pv_value) {
        this.pv_value = pv_value;
    }

    public String getPublish_time() {
        return publish_time;
    }

    public void setPublish_time(String publish_time) {
        this.publish_time = publish_time;
    }

    public String getLink_url() {
        return link_url;
    }

    public void setLink_url(String link_url) {
        this.link_url = link_url;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getClick_type() {
        return click_type;
    }

    public void setClick_type(String click_type) {
        this.click_type = click_type;
    }

    public String getCreate_time() {
        return create_time;
    }

    public void setCreate_time(String create_time) {
        this.create_time = create_time;
    }

    public String getEnd_time() {
        return end_time;
    }

    public void setEnd_time(String end_time) {
        this.end_time = end_time;
    }

    public String getLink_title() {
        return link_title;
    }

    public void setLink_title(String link_title) {
        this.link_title = link_title;
    }

    public String getMessage_type() {
        return message_type;
    }

    public void setMessage_type(String message_type) {
        this.message_type = message_type;
    }

    public int getOptimistic_lastsync() {
        return optimistic_lastsync;
    }

    public void setOptimistic_lastsync(int optimistic_lastsync) {
        this.optimistic_lastsync = optimistic_lastsync;
    }

    public String getUpdate_operator() {
        return update_operator;
    }

    public void setUpdate_operator(String update_operator) {
        this.update_operator = update_operator;
    }

    public String getStart_time() {
        return start_time;
    }

    public void setStart_time(String start_time) {
        this.start_time = start_time;
    }

    public String getImage_path() {
        return image_path;
    }

    public void setImage_path(String image_path) {
        this.image_path = image_path;
    }

    public String getPopup_rule() {
        return popup_rule;
    }

    public void setPopup_rule(String popup_rule) {
        this.popup_rule = popup_rule;
    }

    public String getRegion() {
        return region;
    }

    public void setRegion(String region) {
        this.region = region;
    }

    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }
}

String json= "[{"publish_type":"00","uv_value":3,"app_type":"02","page_type":"","customer_level":"ALL_CUSTOMER","partner_level":"0","rule_number":0,"click_number":0,"title":"超时","create_operator":"zexin","publish_operator":"wangchaocheng","optimistic":0,"update_time":"2019-03-20 14:28:43","pv_value":10,"publish_time":"2019-03-20 14:28:51","link_url":"https://www.cnblogs.com/ailiailan/p/7388784.html","id":32,"click_type":"H5","create_time":"2019-02-26 09:36:33","end_time":"2019-03-30 10:00:04","link_title":"CNBLOGS","message_type":"02","optimistic_lastsync":0,"update_operator":"wangchaocheng","start_time":"2019-02-25 09:36:01","image_path":"http://.www.baidu.com","popup_rule":"02","region":"","status":"NORMAL"}]";

    List<mobileData> list = null;
    try {
        list = gson.fromJson(json, new TypeToken<List<mobileData>>(){}.getType());
    }catch (Exception e){
        e.printStackTrace();
    }`

感谢。
是的,这也是我目前采用的 ,但感觉很不舒服,既然我用了GsonConverterFactory,就势必想要一步到位,直接返回bean。我试图重写Converter但没有成功,我希望通过重写Converter来解决这个问题。

@diov
Copy link

diov commented Mar 28, 2019

这很明显是后端同学偷懒的结果,json 写成这样...我觉得与其在端上妥协,做这种 trick 的处理。还不如跟后端沟通一下,给过来标准的 json 格式。
另外我觉得 @bricklazy 提到的处理方式是最简单有效的。其实你也已经用了 RxJava,只需要再 map 一次就 ok 了。重写 Converter 就复杂了,而且也不通用。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants