【问题标题】:Expecting a string but was BEGIN_OBJECT: JsonReader期待一个字符串,但 BEGIN_OBJECT:JsonReader
【发布时间】:2015-10-19 17:40:57
【问题描述】:

这里有这个问题的其他答案,但不确定如何让它们与我的代码一起使用。

我有很多 JSON 要传递,所以我需要流式传输而不是一次全部完成。我无法完全从代码中找出错误。这是我的代码:

HttpGet request = new HttpGet(getUri + "&"
                + credentials.getOauthStructure());
        HttpResponse response = client.execute(request);

        ICustomerDAO customerDAO = (ICustomerDAO) DAOFactory.getDAO(
                ICustomerDAO.class.getName(), context);
        customerDAO.open();

        Gson gson = new GsonBuilder().serializeNulls()
                .excludeFieldsWithoutExposeAnnotation().create();

        Reader streamReader = new InputStreamReader(response
                .getEntity().getContent());
        JsonReader reader = new JsonReader(streamReader);
        reader.beginArray();

        while (reader.hasNext()) {
            //Do the JSON parsing and data saving here
            Customer customer = gson.fromJson(reader.nextString(), Customer.class);<-----error here
            customerDAO.saveCustomer(customer);
        }
        reader.endArray();
        reader.close();
        customerDAO.close();

我得到错误:

期待一个字符串,但是是 BEGIN_OBJECT:

在上面代码中的标记行上。

编辑:“reader”的值是“JsonReader near [{"Action":null,"Addr"。所以似乎在 JSON 开头附近被切断了。

我以前是这样获取 JSON 的:

HttpGet request = new HttpGet(getUri + "&"
                + credentials.getOauthStructure());
        String content = client.execute(request, new BasicResponseHandler());

但它返回了大量的json,所以将其更改为我目前使用的方式,以尝试对其进行流式传输。

编辑 2:我的原始代码是:

public class CustomerSync implements ICustomerSync {
    public static final int QUANTITY = 0;
    private long offset;
    private ProgressDialog progressDialog;
    private Context context;
    private HttpClient client;
    private final String HTTPS_GET_CUSTOMERS = "https://plcloud.c6.ixsecure.com/PLService.svc/GetCustomers";
    private final String GET_URL = "{0}?quant={1}&offset={2}";
    private final String HTTPS_SYNC_CUSTOMERS = "https://plcloud.c6.ixsecure.com/PLService.svc/SyncCustomers";

    private CustomerSync() {
        client = new DefaultHttpClient();
    }

    public CustomerSync(Context context, ProgressDialog progressDialog) {
        this();
        this.context = context;
        this.progressDialog = progressDialog;
    }

    public Customer[] initCustomersFromJson(Credentials credentials)
            throws ClientProtocolException, IOException, URISyntaxException {
        String getUri;
        getUri = MessageFormat.format(GET_URL, HTTPS_GET_CUSTOMERS,
                QUANTITY + "", offset + "");

        credentials.initGetOAuthStructure(HTTPS_GET_CUSTOMERS);

        HttpGet request = new HttpGet(getUri + "&"
                + credentials.getOauthStructure());
        String content = client.execute(request, new BasicResponseHandler());

        Gson gson = new GsonBuilder().serializeNulls()
                .excludeFieldsWithoutExposeAnnotation().create();
        return gson.fromJson(content, Customer[].class);
    }

    @Override
    public void getCustomers(Credentials credentials)
            throws ClientProtocolException, IOException, URISyntaxException {
        ICustomerDAO customerDAO = (ICustomerDAO) DAOFactory.getDAO(
                ICustomerDAO.class.getName(), context);
        customerDAO.open();

        Customer[] customers;

        //do {
            customers = initCustomersFromJson(credentials);
            progressDialog.setMax(customers.length);
            progressDialog.setProgress(0);
            customerDAO.saveCustomers(customers, progressDialog);

            if (customers.length > 0) {
                offset = customers[customers.length - 1].getId();
            }
        //} while (customers.length > 0);

        customerDAO.close();

        Settings.getInstance().setLastSyncCustomerDatetime(new Date());
    }

但这并没有流式传输数据,因此会导致内存问题。

【问题讨论】:

  • 请向我们展示 Customer 类以及您尝试解析的 JSON。该错误很可能发生,因为客户没有准确反映 JSON 格式
  • 打印reader.nextString()给你的东西
  • @njzk2 似乎认为这不是JsonReader的有效方法
  • 我觉得可以参考parseRecursive方法here
  • 您正在尝试同时使用 2 个不同的 json 解析器。不能工作。如果您对第一个代码的问题是流式传输,那么为什么不使用gson.fromJson(content, client.execute(request).getEntity().getContent(), Customer[].class)

标签: android json gson inputstreamreader jsonreader


【解决方案1】:

推荐的http请求方式如下:

URL url = new URL(sUrl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();


String sResult = null;
InputStream in = new BufferedInputStream(conn.getInputStream());
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
try 
{
    StringBuilder out = new StringBuilder();
    String line;
    while ((line = reader.readLine()) != null) {
        out.append(line);
    }
    sResult = out.toString();
}   
finally 
{
    // Do cleanup
    try{
        in.close();
        reader.close();
    } catch (IOException e) {
        Log.wtf(AsyncRestHelper.class.getSimpleName(), "Could not close Input Stream!");
        e.printStackTrace();
    }
}

然后,您可以使用 sResult 将 GSON 解析为 Customers,就像您当前所做的那样

【讨论】:

  • 干杯,我现在在 sResult 中得到了 JSON。但是,现在在解析阶段,您是否建议我按照我在“编辑 2”中发布的方式进行操作?因为这会导致内存问题。
  • @user3935156 你得到了sResult中的JSON,用什么?使用@Cigogne 的方法?
  • 它是如何导致内存问题的?你能发布确切的错误吗?另外,让我们看看你的 JSON 字符串
猜你喜欢
  • 2019-03-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多