【问题标题】:Parse JSON with GSON/POJO使用 GSON/POJO 解析 JSON
【发布时间】:2016-03-29 06:38:35
【问题描述】:

我正在使用 volley + OkHttp 从服务器获取一些数据。

响应是一个包含 JSON 的字符串,我想使用 GSON/POJO 对其进行解析。

我得到错误:

预期为 BEGIN_OBJECT,但在第 1 行第 1 列路径 $ 处为 STRING

尝试解析时。

原因:java.lang.IllegalStateException:应为 BEGIN_OBJECT,但在第 1 行第 1 列路径 $
在 com.google.gson.stream.JsonReader.beginObject(JsonReader.java:388)
在 com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:209)
在 com.google.gson.Gson.fromJson(Gson.java:879)
在 com.google.gson.Gson.fromJson(Gson.java:844)
在 com.google.gson.Gson.fromJson(Gson.java:793)
在 com.google.gson.Gson.fromJson(Gson.java:765)
在 test.com.example.buddy.myapplication.MainActivity$8.onResponse(MainActivity.java:192) //

第 192 行是Post component = gson.fromJson(response, Post.class);

另一方面,当我在下面使用 JSON_STRING 时,它按预期工作,我使用 POJO 类获取值。

String JSON_STRING = "{\"currentBalance\":{\"amount\":0.0,\"currencyCode\":\"EUR\"},\"currentBalanceDisplay\":true,\"overdueAmount\":null,\"overdueAmountDisplay\":false," +
                     "\"creditAmount\":null,\"creditAmountDisplay\":false,\"noOfBillsToShow\":3,\"recentBills\":[{\"period\":\"03 2016\",\"amount\":{\"amount\":22.76," +
                     "\"currencyCode\":\"EUR\"},\"status\":\"PAID\",\"dueDate\":\"14-03-2016\",\"sortOrder\":\"20160308\",\"periodType\":\"MONTHLY\"," +
                     "\"invoiceId\":\"277726719\",\"invoiceDate\":\"08-03-2016\"}]}";

如果有人可以提供帮助,我将不胜感激。提前谢谢你。

编辑:我觉得自己完全是个白痴 :) 原来我查询的是错误的 URL,一切正常。再次感谢大家帮助我。

来自服务器的字符串响应:

{
  "currentBalance": {
    "amount": 0.0,
    "currencyCode": "EUR"
  },
  "currentBalanceDisplay": true,
  "overdueAmount": null,
  "overdueAmountDisplay": false,
  "creditAmount": null,
  "creditAmountDisplay": false,
  "noOfBillsToShow": 3,
  "recentBills": [
    {
      "period": "03 2016",
      "amount": {
        "amount": 12.53,
        "currencyCode": "EUR"
      },
      "status": "PAID",
      "dueDate": "14-03-2016",
      "sortOrder": "2548264",
      "periodType": "MONTHLY",
      "invoiceId": "012345678",
      "invoiceDate": "08-03-2016"
    }
  ]
}

截击请求:

private void FetchData() {

StringRequest finalrequest = new StringRequest(Request.Method.POST, FETCHURL,
      new Response.Listener<String>() {

          @Override
          public void onResponse(String response) {

                 Gson gson = new Gson();
                 Post component = gson.fromJson(response, Post.class);
                 System.out.println("JSON " + component.getRecentBills().get(0).getInvoiceDate());
                 // Output: JSON 08-03-2016 (success!)
            }
        },
        new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                Log.d("ERROR", "error finalrequest => " + error.toString());
            }
        }
) {
    @Override
    public String getBodyContentType() {
        return "application/x-www-form-urlencoded; charset=utf-8";
    }

    // this is the relevant method
    @Override
    public byte[] getBody() {

        String httpPostBody = "action=GET_CUST_BILLS&" + "user=" + CustID;
        try {
            httpPostBody = httpPostBody + URLEncoder.encode("", "UTF-8");

        } catch (UnsupportedEncodingException exception) {

            Log.e("ERROR", "exception", exception);
            // return null and don't pass any POST string if you encounter encoding error
            return null;
        }
        Log.d("POSTBODY ", httpPostBody.toString());
        return httpPostBody.getBytes();
    }
};
finalrequest.setRetryPolicy(new DefaultRetryPolicy(DefaultRetryPolicy.DEFAULT_TIMEOUT_MS * 5,
            DefaultRetryPolicy.DEFAULT_MAX_RETRIES,  DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
    TestController.getInstance().addToRequestQueue(finalrequest, "Final");
  }

POJO 帖子类:

public class Post {

    private CurrentBalanceBean currentBalance;
    private boolean currentBalanceDisplay;
    private Object overdueAmount;
    private boolean overdueAmountDisplay;
    private Object creditAmount;
    private boolean creditAmountDisplay;
    private int noOfBillsToShow;

    private List<RecentBillsBean> recentBills;

    public static Post objectFromData(String str) {

        return new Gson().fromJson(str, Post.class);
    }

    public static Post objectFromData(String str, String key) {

        try {
            JSONObject jsonObject = new JSONObject(str);

            return new Gson().fromJson(jsonObject.getString(str), Post.class);
        } catch (JSONException e) {
            e.printStackTrace();
        }

        return null;
    }

    public static List<Post> arrayPostFromData(String str) {

        Type listType = new TypeToken<ArrayList<Post>>() {
        }.getType();

        return new Gson().fromJson(str, listType);
    }

    public static List<Post> arrayPostFromData(String str, String key) {

        try {
            JSONObject jsonObject = new JSONObject(str);
            Type listType = new TypeToken<ArrayList<Post>>() {
            }.getType();

            return new Gson().fromJson(jsonObject.getString(str), listType);

        } catch (JSONException e) {
            e.printStackTrace();
        }

        return new ArrayList();


    }

    public CurrentBalanceBean getCurrentBalance() {
        return currentBalance;
    }

    public void setCurrentBalance(CurrentBalanceBean currentBalance) {
        this.currentBalance = currentBalance;
    }

    public boolean isCurrentBalanceDisplay() {
        return currentBalanceDisplay;
    }

    public void setCurrentBalanceDisplay(boolean currentBalanceDisplay) {
        this.currentBalanceDisplay = currentBalanceDisplay;
    }

    public Object getOverdueAmount() {
        return overdueAmount;
    }

    public void setOverdueAmount(Object overdueAmount) {
        this.overdueAmount = overdueAmount;
    }

    public boolean isOverdueAmountDisplay() {
        return overdueAmountDisplay;
    }

    public void setOverdueAmountDisplay(boolean overdueAmountDisplay) {
        this.overdueAmountDisplay = overdueAmountDisplay;
    }

    public Object getCreditAmount() {
        return creditAmount;
    }

    public void setCreditAmount(Object creditAmount) {
        this.creditAmount = creditAmount;
    }

    public boolean isCreditAmountDisplay() {
        return creditAmountDisplay;
    }

    public void setCreditAmountDisplay(boolean creditAmountDisplay) {
        this.creditAmountDisplay = creditAmountDisplay;
    }

    public int getNoOfBillsToShow() {
        return noOfBillsToShow;
    }

    public void setNoOfBillsToShow(int noOfBillsToShow) {
        this.noOfBillsToShow = noOfBillsToShow;
    }

    public List<RecentBillsBean> getRecentBills() {
        return recentBills;
    }

    public void setRecentBills(List<RecentBillsBean> recentBills) {
        this.recentBills = recentBills;
    }

    public static class CurrentBalanceBean {
        private int amount;
        private String currencyCode;

        public static CurrentBalanceBean objectFromData(String str) {

            return new Gson().fromJson(str, CurrentBalanceBean.class);
        }

        public static CurrentBalanceBean objectFromData(String str, String key) {

            try {
                JSONObject jsonObject = new JSONObject(str);

                return new Gson().fromJson(jsonObject.getString(str), CurrentBalanceBean.class);
            } catch (JSONException e) {
                e.printStackTrace();
            }

            return null;
        }

        public static List<CurrentBalanceBean> arrayCurrentBalanceBeanFromData(String str) {

            Type listType = new TypeToken<ArrayList<CurrentBalanceBean>>() {
            }.getType();

            return new Gson().fromJson(str, listType);
        }

        public static List<CurrentBalanceBean> arrayCurrentBalanceBeanFromData(String str, String key) {

            try {
                JSONObject jsonObject = new JSONObject(str);
                Type listType = new TypeToken<ArrayList<CurrentBalanceBean>>() {
                }.getType();

                return new Gson().fromJson(jsonObject.getString(str), listType);

            } catch (JSONException e) {
                e.printStackTrace();
            }

            return new ArrayList();


        }

        public int getAmount() {
            return amount;
        }

        public void setAmount(int amount) {
            this.amount = amount;
        }

        public String getCurrencyCode() {
            return currencyCode;
        }

        public void setCurrencyCode(String currencyCode) {
            this.currencyCode = currencyCode;
        }
    }

    public static class RecentBillsBean {
        private String period;
        /**
         * amount : 22.76
         * currencyCode : EUR
         */

        private AmountBean amount;
        private String status;
        private String dueDate;
        private String sortOrder;
        private String periodType;
        private String invoiceId;
        private String invoiceDate;

        public static RecentBillsBean objectFromData(String str) {

            return new Gson().fromJson(str, RecentBillsBean.class);
        }

        public static RecentBillsBean objectFromData(String str, String key) {

            try {
                JSONObject jsonObject = new JSONObject(str);

                return new Gson().fromJson(jsonObject.getString(str), RecentBillsBean.class);
            } catch (JSONException e) {
                e.printStackTrace();
            }

            return null;
        }

        public static List<RecentBillsBean> arrayRecentBillsBeanFromData(String str) {

            Type listType = new TypeToken<ArrayList<RecentBillsBean>>() {
            }.getType();

            return new Gson().fromJson(str, listType);
        }

        public static List<RecentBillsBean> arrayRecentBillsBeanFromData(String str, String key) {

            try {
                JSONObject jsonObject = new JSONObject(str);
                Type listType = new TypeToken<ArrayList<RecentBillsBean>>() {
                }.getType();

                return new Gson().fromJson(jsonObject.getString(str), listType);

            } catch (JSONException e) {
                e.printStackTrace();
            }

            return new ArrayList();


        }

        public String getPeriod() {
            return period;
        }

        public void setPeriod(String period) {
            this.period = period;
        }

        public AmountBean getAmount() {
            return amount;
        }

        public void setAmount(AmountBean amount) {
            this.amount = amount;
        }

        public String getStatus() {
            return status;
        }

        public void setStatus(String status) {
            this.status = status;
        }

        public String getDueDate() {
            return dueDate;
        }

        public void setDueDate(String dueDate) {
            this.dueDate = dueDate;
        }

        public String getSortOrder() {
            return sortOrder;
        }

        public void setSortOrder(String sortOrder) {
            this.sortOrder = sortOrder;
        }

        public String getPeriodType() {
            return periodType;
        }

        public void setPeriodType(String periodType) {
            this.periodType = periodType;
        }

        public String getInvoiceId() {
            return invoiceId;
        }

        public void setInvoiceId(String invoiceId) {
            this.invoiceId = invoiceId;
        }

        public String getInvoiceDate() {
            return invoiceDate;
        }

        public void setInvoiceDate(String invoiceDate) {
            this.invoiceDate = invoiceDate;
        }

        public static class AmountBean {
            private double amount;
            private String currencyCode;

            public static AmountBean objectFromData(String str) {

                return new Gson().fromJson(str, AmountBean.class);
            }

            public static AmountBean objectFromData(String str, String key) {

                try {
                    JSONObject jsonObject = new JSONObject(str);

                    return new Gson().fromJson(jsonObject.getString(str), AmountBean.class);
                } catch (JSONException e) {
                    e.printStackTrace();
                }

                return null;
            }

            public static List<AmountBean> arrayAmountBeanFromData(String str) {

                Type listType = new TypeToken<ArrayList<AmountBean>>() {
                }.getType();

                return new Gson().fromJson(str, listType);
            }

            public static List<AmountBean> arrayAmountBeanFromData(String str, String key) {

                try {
                    JSONObject jsonObject = new JSONObject(str);
                    Type listType = new TypeToken<ArrayList<AmountBean>>() {
                    }.getType();

                    return new Gson().fromJson(jsonObject.getString(str), listType);

                } catch (JSONException e) {
                    e.printStackTrace();
                }

                return new ArrayList();


            }

            public double getAmount() {
                return amount;
            }

            public void setAmount(double amount) {
                this.amount = amount;
            }

            public String getCurrencyCode() {
                return currencyCode;
            }

            public void setCurrencyCode(String currencyCode) {
                this.currencyCode = currencyCode;
            }
        }
    }
}

【问题讨论】:

  • 在 volley 中有一个名为 JsonRequest 的类,你最好使用它,因为它会为你做所有事情,你可以直接访问 Json
  • @Jois,谢谢回复,但我已经尝试过了,同样的错误。
  • 尝试使用 Log.v("json response", response); 记录您的响应在 Gson 之前 gson = new Gson(); Post 组件 = gson.fromJson(response, Post.class);并查看实际的服务器响应是否与您的预期响应相同。
  • @HendraWijayaDjiono 做到了,但我得到了以下信息:V/json 响应:如果没有适当的操作,则无法提供请求

标签: java android json gson


【解决方案1】:

我会为你解释清楚。 响应应该是:

{
  "currentBalance": {
    "amount": 0.0,
    "currencyCode": "EUR"
  },
  "currentBalanceDisplay": true,
  "overdueAmount": null,
  "overdueAmountDisplay": false,
  "creditAmount": null,
  "creditAmountDisplay": false,
  "noOfBillsToShow": 3,
  "recentBills": [
    {
      "period": "03 2016",
      "amount": {
        "amount": 12.53,
        "currencyCode": "EUR"
      },
      "status": "PAID",
      "dueDate": "14-03-2016",
      "sortOrder": "2548264",
      "periodType": "MONTHLY",
      "invoiceId": "012345678",
      "invoiceDate": "08-03-2016"
    }
  ]
}

但是,你得到:

"Request cannot be served without a proper action"

如果您不拥有服务器,我想您使用来自提供商的 API。您应该正确检查他们的文档。我猜,你错过了一个参数,或者他们可能需要你在你的请求中添加一些 cookie。

【讨论】:

  • Wijaya Dijono,好吧,我猜我的帖子请求仍然不正确。需要进一步挖掘。谢谢。我已正确登录到服务器,所以不是这样。
  • @Simon 很高兴我能帮上忙 :)
【解决方案2】:

1) 将您的 Json 存储在 Pojo 类中 2)将Pojo类对象转换为Gson。

例子:

   @Override
       public void onResponse(String response) {

           Gson gson = new Gson();
                 Post object = new Post();
                 object.setResponse(response);
          String gson = gson.fromJson(object, Post.class);//as you have overrided toString() it will return you the response you have set
           System.out.println(gson);
                }
            },
            new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                        // Handle error
                }
            }

Pojo 类

          public class  Post{

                  private String resposne;
              private int example;
               ....

               public void setResponse(String Response){

                  this.response = Response;
          } 

      @Override
        public String toString() {
           return  response;
            }

       } 

我希望这对西蒙有帮助。谢谢你

【讨论】:

  • 谢谢!我没有得到一个绿色的勾号?? :D
【解决方案3】:

预期为 BEGIN_OBJECT,但在第 1 行第 1 列路径 $ 处为 STRING

当您从服务器收到HTML 响应时,这是一个常见的 JSON 解析问题。

<html>
<body>
<h1>404 Not Found</h1>
</body>
</html>

所以Gson 期待JSON 对象,并在未找到正确格式时引发此类异常。

这里可能会发生几种情况。请逐一检查。

  • 您的方法是 POST,请检查服务器端是否接受 application/x-www-form-urlencoded 格式的正文。正文可能期待 application/jsontext/plain 等。
  • 检查参数是否正确传递。
  • 如果您这边没有问题,您可能还需要检查服务器端。检查它是否可以处理您的请求并可以使用您期望的正确数据进行响应。

尝试使用 Postman 来模拟请求和响应。这对于调试这种情况要快得多。

【讨论】:

  • 那么你的问题解决了吗,或者我可能需要再看一遍?
  • 是的,我自己解决了,问题很简单。请参阅我的编辑。谢谢。
猜你喜欢
  • 2013-02-02
  • 2011-04-26
  • 2018-04-01
  • 2021-06-02
  • 2013-03-20
  • 1970-01-01
  • 2011-02-12
  • 2012-01-02
  • 1970-01-01
相关资源
最近更新 更多