我正在使用Robospice构建一个Android应用程序,通过网络进行通信。从我的服务器返回的结果对象不能正确地反序列化。以下是相关的课程:
UserRequest.java
import com.google.api.client.http.GenericUrl;
import com.google.api.client.http.HttpRequest;
import com.google.api.client.http.HttpResponse;
import com.google.api.client.json.jackson.JacksonFactory;
import com.octo.android.robospice.request.googlehttpclient.GoogleHttpClientSpiceRequest;
import roboguice.util.temp.Ln;
import trees.park.cal.smoke.models.UserList;
public class UserRequest extends GoogleHttpClientSpiceRequest<UserList>{
private String baseUrl = "http://10.0.0.3:8181/users/";
public UserRequest() {
super(UserList.class);
}
@Override
public UserList loadDataFromNetwork() throws Exception {
Ln.d("Call web service " + baseUrl);
HttpRequest request = getHttpRequestFactory()
.buildGetRequest(new GenericUrl(baseUrl));
request.setParser( new JacksonFactory().createJsonObjectParser() );
HttpResponse response = request.execute();
return response.parseAs( getResultType() );
}
}UserList.java
import java.util.ArrayList;
public class UserList extends ArrayList<User> {
}User.java
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.Collections;
import java.util.List;
public class User {
@JsonProperty("id")private long id;
@JsonProperty("email")private String email;
@JsonProperty("password")private String password;
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
@JsonCreator
public User(@JsonProperty("id") long id, @JsonProperty("email") String email, @JsonProperty("password") String password) {
this.id = id;
this.email = email;
this.password = password;
}
}调用response.parseAs(getRequestType())时,将使用以下堆栈跟踪引发异常:
08-19 23:54:08.411 27117-27139/trees.park.cal.smoke E//DefaultRequestRunner.java:154﹕ 23:54:08.418 Thread-5533 An exception occurred during request network execution :
java.lang.IllegalArgumentException:
at com.google.api.client.json.JsonParser.parseValue(JsonParser.java:880)
at com.google.api.client.json.JsonParser.parse(JsonParser.java:381)
at com.google.api.client.json.JsonParser.parse(JsonParser.java:354)
at com.google.api.client.json.JsonObjectParser.parseAndClose(JsonObjectParser.java:87)
at com.google.api.client.json.JsonObjectParser.parseAndClose(JsonObjectParser.java:81)
at com.google.api.client.http.HttpResponse.parseAs(HttpResponse.java:459)
at trees.park.cal.smoke.server.UserRequest.loadDataFromNetwork(UserRequest.java:27)
at trees.park.cal.smoke.server.UserRequest.loadDataFromNetwork(UserRequest.java:12)
at com.octo.android.robospice.request.CachedSpiceRequest.loadDataFromNetwork(CachedSpiceRequest.java:48)
at com.octo.android.robospice.request.DefaultRequestRunner.processRequest(DefaultRequestRunner.java:150)
at com.octo.android.robospice.request.DefaultRequestRunner$1.run(DefaultRequestRunner.java:217)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:422)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:841)
Caused by: java.lang.IllegalArgumentException:
at com.google.api.client.json.JsonParser.parseValue(JsonParser.java:880)
at com.google.api.client.json.JsonParser.parseArray(JsonParser.java:647)
at com.google.api.client.json.JsonParser.parseValue(JsonParser.java:739)
at com.google.api.client.json.JsonParser.parse(JsonParser.java:381)
at com.google.api.client.json.JsonParser.parse(JsonParser.java:354)
at com.google.api.client.json.JsonObjectParser.parseAndClose(JsonObjectParser.java:87)
at com.google.api.client.json.JsonObjectParser.parseAndClose(JsonObjectParser.java:81)
at com.google.api.client.http.HttpResponse.parseAs(HttpResponse.java:459)
at trees.park.cal.smoke.server.UserRequest.loadDataFromNetwork(UserRequest.java:27)
at trees.park.cal.smoke.server.UserRequest.loadDataFromNetwork(UserRequest.java:12)
at com.octo.android.robospice.request.CachedSpiceRequest.loadDataFromNetwork(CachedSpiceRequest.java:48)
at com.octo.android.robospice.request.DefaultRequestRunner.processRequest(DefaultRequestRunner.java:150)
at com.octo.android.robospice.request.DefaultRequestRunner$1.run(DefaultRequestRunner.java:217)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:422)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:841)
Caused by: java.lang.IllegalArgumentException: unable to create new instance of class trees.park.cal.smoke.models.User because it has no accessible default constructor
at com.google.api.client.util.Types.handleExceptionForNewInstance(Types.java:165)
at com.google.api.client.util.Types.newInstance(Types.java:120)
at com.google.api.client.json.JsonParser.parseValue(JsonParser.java:763)
at com.google.api.client.json.JsonParser.parseArray(JsonParser.java:647)
at com.google.api.client.json.JsonParser.parseValue(JsonParser.java:739)
at com.google.api.client.json.JsonParser.parse(JsonParser.java:381)
at com.google.api.client.json.JsonParser.parse(JsonParser.java:354)
at com.google.api.client.json.JsonObjectParser.parseAndClose(JsonObjectParser.java:87)
at com.google.api.client.json.JsonObjectParser.parseAndClose(JsonObjectParser.java:81)
at com.google.api.client.http.HttpResponse.parseAs(HttpResponse.java:459)
at trees.park.cal.smoke.server.UserRequest.loadDataFromNetwork(UserRequest.java:27)
at trees.park.cal.smoke.server.UserRequest.loadDataFromNetwork(UserRequest.java:12)
at com.octo.android.robospice.request.CachedSpiceRequest.loadDataFromNetwork(CachedSpiceRequest.java:48)
at com.octo.android.robospice.request.DefaultRequestRunner.processRequest(DefaultRequestRunner.java:150)
at com.octo.android.robospice.request.DefaultRequestRunner$1.run(DefaultRequestRunner.java:217)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:422)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:841)
Caused by: java.lang.InstantiationException: can't instantiate class trees.park.cal.smoke.models.User; no empty constructor
at java.lang.Class.newInstanceImpl(Native Method)
at java.lang.Class.newInstance(Class.java:1208)
at com.google.api.client.util.Types.newInstance(Types.java:116)
at com.google.api.client.json.JsonParser.parseValue(JsonParser.java:763)
at com.google.api.client.json.JsonParser.parseArray(JsonParser.java:647)
at com.google.api.client.json.JsonParser.parseValue(JsonParser.java:739)
at com.google.api.client.json.JsonParser.parse(JsonParser.java:381)
at com.google.api.client.json.JsonParser.parse(JsonParser.java:354)
at com.google.api.client.json.JsonObjectParser.parseAndClose(JsonObjectParser.java:87)
at com.google.api.client.json.JsonObjectParser.parseAndClose(JsonObjectParser.java:81)
at com.google.api.client.http.HttpResponse.parseAs(HttpResponse.java:459)
at trees.park.cal.smoke.server.UserRequest.loadDataFromNetwork(UserRequest.java:27)
at trees.park.cal.smoke.server.UserRequest.loadDataFromNetwork(UserRequest.java:12)
at com.octo.android.robospice.request.CachedSpiceRequest.loadDataFromNetwork(CachedSpiceRequest.java:48)
at com.octo.android.robospice.request.DefaultRequestRunner.processRequest(DefaultRequestRunner.java:150)
at com.octo.android.robospice.request.DefaultRequestRunner$1.run(DefaultRequestRunner.java:217)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:422)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:841)但是,如果我使用一个ObjectMapper,反序列化就会完美无缺地发生。在我的LoginActivity (我刚刚为测试目的编写的)中可以找到一个示例:
public class LoginActivity extends Activity{
private SpiceManager spiceManager = new SpiceManager(JacksonGoogleHttpClientSpiceService.class);
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
String json = "[\n" +
" {\n" +
" \"id\": 1, \n" +
" \"email\": \"michaeldubyu@gmail.com\", \n" +
" \"password\": \"password\"\n" +
" }, \n" +
" {\n" +
" \"id\": 2, \n" +
" \"email\": \"asdf@adsf.com\", \n" +
" \"password\": \"\"\n" +
" }, \n" +
" {\n" +
" \"id\": 3, \n" +
" \"email\": \"paymahn1@gmail.com\", \n" +
" \"password\": \"\"\n" +
" }, \n" +
" {\n" +
" \"id\": 4, \n" +
" \"email\": \"michaeasdfldubyu@gmail.com\", \n" +
" \"password\": \"password\"\n" +
" }\n" +
"]";
ObjectMapper mapper = new ObjectMapper();
try {
UserList result = mapper.readValue(json, UserList.class);
System.out.println("test");
} catch (IOException e) {
e.printStackTrace();
}
//stuff
}
}如果手动将response.parseAs(getRequestType())替换为ObjectMapper,然后手动从HttpResponse获取输入流,那么我就可以完全反序列化响应。
为什么JsonObjectParser不能像ObjectMapper那样做呢?我怎样才能解决这个问题?
谢谢
发布于 2014-11-27 12:49:16
答案在堆栈中
由:no empty constructor java.lang.InstantiationException: can't instantiate class trees.park.cal.smoke.models.User;引起
尝试将没有参数的构造器添加到User类
public User() {
}https://stackoverflow.com/questions/25398592
复制相似问题