首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >JSON解析与Robospice

JSON解析与Robospice
EN

Stack Overflow用户
提问于 2014-08-20 07:00:28
回答 1查看 890关注 0票数 0

我正在使用Robospice构建一个Android应用程序,通过网络进行通信。从我的服务器返回的结果对象不能正确地反序列化。以下是相关的课程:

UserRequest.java

代码语言:javascript
复制
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

代码语言:javascript
复制
import java.util.ArrayList;

public class UserList extends ArrayList<User> {
}

User.java

代码语言:javascript
复制
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())时,将使用以下堆栈跟踪引发异常:

代码语言:javascript
复制
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 (我刚刚为测试目的编写的)中可以找到一个示例:

代码语言:javascript
复制
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那样做呢?我怎样才能解决这个问题?

谢谢

EN

回答 1

Stack Overflow用户

发布于 2014-11-27 12:49:16

答案在堆栈中

由:no empty constructor java.lang.InstantiationException: can't instantiate class trees.park.cal.smoke.models.User;引起

尝试将没有参数的构造器添加到User

代码语言:javascript
复制
public User() {
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25398592

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档