java.util.LinkedHashMap 无法转换为 DataList
java.util.LinkedHashMap cannot be cast to DataList
我正在尝试使用改造库实现服务器连接。
一切似乎都很好,但是当我收到成功回调的数据时,它崩溃并出现以下异常。
java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to aandroid.com.retrofitframework.requestData.DataList
at cuiserve.com.volleyframework.activity.RetrofitActivity.onDataReceived(RetrofitActivity.java:18)
at cuiserve.com.volleyframework.httpConnection.ConnectionHelper.success(ConnectionHelper.java:44)
at retrofit.CallbackRunnable.run(CallbackRunnable.java:45)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5001)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
at dalvik.system.NativeStart.main(Native Method)
这里是 activity class 进行服务器调用
public class RetrofitActivity extends SuperActivity {
private ConnectionHelper.ServerListener<DataList> httpListener = new ConnectionHelper.ServerListener<DataList>() {
@Override
public void onDataReceived(DataList data) {
hideProgressBar();
Log.d("ANSH",data.getBalance());
}
@Override
public void onErrorReceived(String errorMsg) {
hideProgressBar();
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
showProgressBar();
ConnectionHelper<DataList> helper = new ConnectionHelper<DataList>(HttpRequestConstant.LOGIN_REQUEST,httpListener);
helper.getResponse();
}
@Override
public View getLayoutResource() {
return null;
}
@Override
protected void internetAvailable() {
}
}
ConnectionHelper.class 发出请求
public class ConnectionHelper<T> implements Callback<T> {
private int requestType;
private ServerListener<T> listener;
public ConnectionHelper(int requestType, ServerListener listener) {
this.requestType = requestType;
this.listener = listener;
}
public void getResponse() {
switch (requestType) {
case HttpRequestConstant.LOGIN_REQUEST:
IServerConnection<T> connection = restAdapter.create(IServerConnection.class);
connection.login(this);
break;
}
}
RestAdapter restAdapter = new RestAdapter.Builder()
.setEndpoint("http://www.json-generator.com/api")
.setLogLevel(RestAdapter.LogLevel.FULL)
.setConverter(new JacksonConverter(Mapper.get()))
.build();
@Override
public void success(T t, Response response) {
listener.onDataReceived(t);
// success callback false here with the exception
// as ClassCastException and says LinkedHashMap can not be cast to DataList(which i pass as class that the response has to be mapped to)
}
@Override
public void failure(RetrofitError error) {
}
public interface ServerListener<T> {
public void onDataReceived(T data);
public void onErrorReceived(String errorMsg);
}
}
带有retrofit注解的接口和方法
public interface IServerConnection<T> {
@GET(HttpRequestConstant.JACKSON_FETCH)
void login(Callback<T> cb);
}
我怀疑是自定义的 JacksonConverter
public class JacksonConverter implements Converter {
private ObjectMapper mapper = new ObjectMapper();
public JacksonConverter(ObjectMapper objectMapper) {
this.mapper = objectMapper;
}
@Override
public Object fromBody(TypedInput body, Type type) throws ConversionException {
JavaType javaType = mapper.getTypeFactory().constructType(type);
try {
return mapper.readValue(body.in(), javaType);
} catch (IOException e) {
throw new ConversionException(e);
}
}
@Override
public TypedOutput toBody(Object object) {
try {
String charset = "UTF-8";
String json = mapper.writeValueAsString(object);
return new JsonTypedOutput(json.getBytes(charset));
} catch (IOException e) {
throw new AssertionError(e);
}
}
private static class JsonTypedOutput implements TypedOutput {
private final byte[] jsonBytes;
JsonTypedOutput(byte[] jsonBytes) {
this.jsonBytes = jsonBytes;
}
@Override
public String fileName() {
return null;
}
@Override
public String mimeType() {
return "application/json; charset=UTF-8";
}
@Override
public long length() {
return jsonBytes.length;
}
@Override
public void writeTo(OutputStream out) throws IOException {
out.write(jsonBytes);
}
}
}
和数据列表
package cuiserve.com.volleyframework.requestData;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
/**
* Created by ansh on 5/4/15.
*/
@JsonIgnoreProperties(ignoreUnknown = true)
public class DataList extends SomeClass{
private String _id;
private int index;
private String guid;
private boolean isActive;
private String balance;
private String picture;
private int age;
public String get_id() {
return _id;
}
public void set_id(String _id) {
this._id = _id;
}
public int getIndex() {
return index;
}
public void setIndex(int index) {
this.index = index;
}
public String getGuid() {
return guid;
}
public void setGuid(String guid) {
this.guid = guid;
}
public boolean isActive() {
return isActive;
}
public void setActive(boolean isActive) {
this.isActive = isActive;
}
public String getBalance() {
return balance;
}
public void setBalance(String balance) {
this.balance = balance;
}
public String getPicture() {
return picture;
}
public void setPicture(String picture) {
this.picture = picture;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
现在的问题是当我在不使用泛型的情况下(我已经在代码中完成了)工作正常并且没有给出任何异常但是在泛型的情况下它会失败。
为什么我得到 LinkedHashMap classCastException,而在我的 code.Please 帮助中没有任何相关内容。
通过使用泛型参数,实际类型信息在运行时完全丢失,无法推断。它基本上最终与 Object
相同。当 Gson 发现您需要 Object
类型时,它会使用 Map
来放置 JSON 信息。这样,如果您重新序列化该对象实例,数据将被保留。
您不能将通用接口与 Retrofit 一起使用。当您尝试这样做时添加了一个例外,而不是让它在下一个版本中以这种方式失败。
以下是我处理此类情况的方法:
import retrofit.Callback;
import retrofit.RetrofitError;
import retrofit.client.Response;
public abstract class ModelCallback<Model> implements Callback<Object> {
Class classOfT;
public ModelCallback(Class modelClass){
this.classOfT = modelClass;
}
@Override
public void success(Object model, Response response) {
Gson gson = new Gson();
onSuccess((Model) gson.fromJson(gson.toJson(model),classOfT));
}
@Override
public void failure(RetrofitError error) {
onError(new Exception(error.getMessage()));
}
public abstract void onSuccess(Model model);
public abstract void onError(ClyngException e);
}
我正在尝试使用改造库实现服务器连接。 一切似乎都很好,但是当我收到成功回调的数据时,它崩溃并出现以下异常。
java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to aandroid.com.retrofitframework.requestData.DataList
at cuiserve.com.volleyframework.activity.RetrofitActivity.onDataReceived(RetrofitActivity.java:18)
at cuiserve.com.volleyframework.httpConnection.ConnectionHelper.success(ConnectionHelper.java:44)
at retrofit.CallbackRunnable.run(CallbackRunnable.java:45)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5001)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
at dalvik.system.NativeStart.main(Native Method)
这里是 activity class 进行服务器调用
public class RetrofitActivity extends SuperActivity {
private ConnectionHelper.ServerListener<DataList> httpListener = new ConnectionHelper.ServerListener<DataList>() {
@Override
public void onDataReceived(DataList data) {
hideProgressBar();
Log.d("ANSH",data.getBalance());
}
@Override
public void onErrorReceived(String errorMsg) {
hideProgressBar();
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
showProgressBar();
ConnectionHelper<DataList> helper = new ConnectionHelper<DataList>(HttpRequestConstant.LOGIN_REQUEST,httpListener);
helper.getResponse();
}
@Override
public View getLayoutResource() {
return null;
}
@Override
protected void internetAvailable() {
}
}
ConnectionHelper.class 发出请求
public class ConnectionHelper<T> implements Callback<T> {
private int requestType;
private ServerListener<T> listener;
public ConnectionHelper(int requestType, ServerListener listener) {
this.requestType = requestType;
this.listener = listener;
}
public void getResponse() {
switch (requestType) {
case HttpRequestConstant.LOGIN_REQUEST:
IServerConnection<T> connection = restAdapter.create(IServerConnection.class);
connection.login(this);
break;
}
}
RestAdapter restAdapter = new RestAdapter.Builder()
.setEndpoint("http://www.json-generator.com/api")
.setLogLevel(RestAdapter.LogLevel.FULL)
.setConverter(new JacksonConverter(Mapper.get()))
.build();
@Override
public void success(T t, Response response) {
listener.onDataReceived(t);
// success callback false here with the exception
// as ClassCastException and says LinkedHashMap can not be cast to DataList(which i pass as class that the response has to be mapped to)
}
@Override
public void failure(RetrofitError error) {
}
public interface ServerListener<T> {
public void onDataReceived(T data);
public void onErrorReceived(String errorMsg);
}
}
带有retrofit注解的接口和方法
public interface IServerConnection<T> {
@GET(HttpRequestConstant.JACKSON_FETCH)
void login(Callback<T> cb);
}
我怀疑是自定义的 JacksonConverter
public class JacksonConverter implements Converter {
private ObjectMapper mapper = new ObjectMapper();
public JacksonConverter(ObjectMapper objectMapper) {
this.mapper = objectMapper;
}
@Override
public Object fromBody(TypedInput body, Type type) throws ConversionException {
JavaType javaType = mapper.getTypeFactory().constructType(type);
try {
return mapper.readValue(body.in(), javaType);
} catch (IOException e) {
throw new ConversionException(e);
}
}
@Override
public TypedOutput toBody(Object object) {
try {
String charset = "UTF-8";
String json = mapper.writeValueAsString(object);
return new JsonTypedOutput(json.getBytes(charset));
} catch (IOException e) {
throw new AssertionError(e);
}
}
private static class JsonTypedOutput implements TypedOutput {
private final byte[] jsonBytes;
JsonTypedOutput(byte[] jsonBytes) {
this.jsonBytes = jsonBytes;
}
@Override
public String fileName() {
return null;
}
@Override
public String mimeType() {
return "application/json; charset=UTF-8";
}
@Override
public long length() {
return jsonBytes.length;
}
@Override
public void writeTo(OutputStream out) throws IOException {
out.write(jsonBytes);
}
}
}
和数据列表
package cuiserve.com.volleyframework.requestData;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
/**
* Created by ansh on 5/4/15.
*/
@JsonIgnoreProperties(ignoreUnknown = true)
public class DataList extends SomeClass{
private String _id;
private int index;
private String guid;
private boolean isActive;
private String balance;
private String picture;
private int age;
public String get_id() {
return _id;
}
public void set_id(String _id) {
this._id = _id;
}
public int getIndex() {
return index;
}
public void setIndex(int index) {
this.index = index;
}
public String getGuid() {
return guid;
}
public void setGuid(String guid) {
this.guid = guid;
}
public boolean isActive() {
return isActive;
}
public void setActive(boolean isActive) {
this.isActive = isActive;
}
public String getBalance() {
return balance;
}
public void setBalance(String balance) {
this.balance = balance;
}
public String getPicture() {
return picture;
}
public void setPicture(String picture) {
this.picture = picture;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
现在的问题是当我在不使用泛型的情况下(我已经在代码中完成了)工作正常并且没有给出任何异常但是在泛型的情况下它会失败。
为什么我得到 LinkedHashMap classCastException,而在我的 code.Please 帮助中没有任何相关内容。
通过使用泛型参数,实际类型信息在运行时完全丢失,无法推断。它基本上最终与 Object
相同。当 Gson 发现您需要 Object
类型时,它会使用 Map
来放置 JSON 信息。这样,如果您重新序列化该对象实例,数据将被保留。
您不能将通用接口与 Retrofit 一起使用。当您尝试这样做时添加了一个例外,而不是让它在下一个版本中以这种方式失败。
以下是我处理此类情况的方法:
import retrofit.Callback;
import retrofit.RetrofitError;
import retrofit.client.Response;
public abstract class ModelCallback<Model> implements Callback<Object> {
Class classOfT;
public ModelCallback(Class modelClass){
this.classOfT = modelClass;
}
@Override
public void success(Object model, Response response) {
Gson gson = new Gson();
onSuccess((Model) gson.fromJson(gson.toJson(model),classOfT));
}
@Override
public void failure(RetrofitError error) {
onError(new Exception(error.getMessage()));
}
public abstract void onSuccess(Model model);
public abstract void onError(ClyngException e);
}