android-discuss
android-discuss copied to clipboard
Retrofit GsonConverterFactory 解析带有转义符的数据
- 后台返回的数据:
{
"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
- 问 有人遇到这种吗,需要怎么解决好
比较笨的方法可以把 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();
}`
比较笨的方法可以把 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来解决这个问题。
这很明显是后端同学偷懒的结果,json 写成这样...我觉得与其在端上妥协,做这种 trick 的处理。还不如跟后端沟通一下,给过来标准的 json 格式。 另外我觉得 @bricklazy 提到的处理方式是最简单有效的。其实你也已经用了 RxJava,只需要再 map 一次就 ok 了。重写 Converter 就复杂了,而且也不通用。