【问题标题】:Retrofit- Trouble with json parsing using Gson改造 - 使用 Gson 解析 json 时出现问题
【发布时间】:2017-10-05 06:42:10
【问题描述】:

我是 Retrofit 的新手。我已经将 volley 用于大多数 Web 服务,决定继续进行改造。但是我被困在 Json 解析上,我在我的 POJO 类中得到了空数据。 我试图检查Call<ResponseBoby> 的响应,当我用来解析我的模型类时,我的响应是正确的,我得到了空白数据。请指导我,任何帮助将不胜感激。

注意:POJO 类是 parcelable 并且还包含 cunstructor 和 gette/setter。由于文本限制,我将其从此处删除。

代码

Retrofit retrofit = new Retrofit.Builder()
            .baseUrl(PRODUCT_URL)
            .addConverterFactory(GsonConverterFactory.create())
            .build();
    ApiInterface apiService = retrofit.create(ApiInterface.class);
    JsonObject ob = new JsonObject();
    ob.addProperty("pro_id", model.getId());
    Call<Product> call = apiService.getProducts(ob);
    call.enqueue(new Callback<Product>() {
        @Override
        public void onResponse(Call<Product> call, Response<Product> response) {
            Product p = response.body();
            Toast.makeText(getActivity(), response.body().getTitle(), Toast.LENGTH_SHORT).show();
        }

        @Override
        public void onFailure(Call<Product> call, Throwable t) {
            Log.e("ERROR",call.toString());
        }
    });

API 接口

public interface ApiInterface {
     @POST("app/product.php")
     Call<Product> getProducts(@Body JsonObject jsonObject);
}

POJO 类

public class Product {

@SerializedName("title")
@Expose
public String title;
@SerializedName("id")
@Expose
public int id;
@SerializedName("created_at")
@Expose
public String createdAt;
@SerializedName("updated_at")
@Expose
public String updatedAt;
@SerializedName("type")
@Expose
public String type;
@SerializedName("status")
@Expose
public String status;
@SerializedName("downloadable")
@Expose
public boolean downloadable;
@SerializedName("virtual")
@Expose
public boolean virtual;
@SerializedName("permalink")
@Expose
public String permalink;
@SerializedName("sku")
@Expose
public String sku;
@SerializedName("price")
@Expose
public String price;
@SerializedName("regular_price")
@Expose
public String regularPrice;
@SerializedName("sale_price")
@Expose
public Object salePrice;
@SerializedName("price_html")
@Expose
public String priceHtml;
@SerializedName("taxable")
@Expose
public boolean taxable;
@SerializedName("tax_status")
@Expose
public String taxStatus;
@SerializedName("tax_class")
@Expose
public String taxClass;
@SerializedName("managing_stock")
@Expose
public boolean managingStock;
@SerializedName("stock_quantity")
@Expose
public int stockQuantity;
@SerializedName("in_stock")
@Expose
public boolean inStock;
@SerializedName("backorders_allowed")
@Expose
public boolean backordersAllowed;
@SerializedName("backordered")
@Expose
public boolean backordered;
@SerializedName("sold_individually")
@Expose
public boolean soldIndividually;
@SerializedName("purchaseable")
@Expose
public boolean purchaseable;
@SerializedName("featured")
@Expose
public boolean featured;
@SerializedName("visible")
@Expose
public boolean visible;
@SerializedName("catalog_visibility")
@Expose
public String catalogVisibility;
@SerializedName("on_sale")
@Expose
public boolean onSale;
@SerializedName("product_url")
@Expose
public String productUrl;
@SerializedName("button_text")
@Expose
public String buttonText;
@SerializedName("weight")
@Expose
public Object weight;
@SerializedName("dimensions")
@Expose
public Dimensions dimensions;
@SerializedName("shipping_required")
@Expose
public boolean shippingRequired;
@SerializedName("shipping_taxable")
@Expose
public boolean shippingTaxable;
@SerializedName("shipping_class")
@Expose
public String shippingClass;
@SerializedName("shipping_class_id")
@Expose
public Object shippingClassId;
@SerializedName("description")
@Expose
public String description;
@SerializedName("short_description")
@Expose
public String shortDescription;
@SerializedName("reviews_allowed")
@Expose
public boolean reviewsAllowed;
@SerializedName("average_rating")
@Expose
public String averageRating;
@SerializedName("rating_count")
@Expose
public int ratingCount;
@SerializedName("related_ids")
@Expose
public List<Integer> relatedIds = new ArrayList<Integer>();
@SerializedName("upsell_ids")
@Expose
public List<Object> upsellIds = new ArrayList<Object>();
@SerializedName("cross_sell_ids")
@Expose
public List<Integer> crossSellIds = new ArrayList<Integer>();
@SerializedName("parent_id")
@Expose
public int parentId;
@SerializedName("categories")
@Expose
public List<String> categories = new ArrayList<String>();
@SerializedName("tags")
@Expose
public List<Object> tags = new ArrayList<Object>();
@SerializedName("images")
@Expose
public List<Image> images = new ArrayList<Image>();
@SerializedName("featured_src")
@Expose
public String featuredSrc;
@SerializedName("attributes")
@Expose
public List<Attribute> attributes = new ArrayList<Attribute>();
@SerializedName("downloads")
@Expose
public List<Object> downloads = new ArrayList<Object>();
@SerializedName("download_limit")
@Expose
public int downloadLimit;
@SerializedName("download_expiry")
@Expose
public int downloadExpiry;
@SerializedName("download_type")
@Expose
public String downloadType;
@SerializedName("purchase_note")
@Expose
public String purchaseNote;
@SerializedName("total_sales")
@Expose
public int totalSales;
@SerializedName("variations")
@Expose
public List<Variation> variations = new ArrayList<Variation>();
@SerializedName("parent")
@Expose
public List<Object> parent = new ArrayList<Object>();

public String getTitle() {
    return title;
}

public void setTitle(String title) {
    this.title = title;
}
}

JSON 响应

{
  "product": {
    "title": "Flying Ninja",
    "id": 70,
    "created_at": "2013-06-07T11:25:01Z",
    "updated_at": "2017-09-26T05:55:35Z",
    "type": "simple",
    "status": "publish",
    "downloadable": false,
    "virtual": false,
    "permalink": "http:\/\/codiixx.com\/product\/flying-ninja\/",
    "sku": "",
    "price": "12.00",
    "regular_price": "15.00",
    "sale_price": "12.00",
    "price_html": "<del><span class=\"woocommerce-Price-amount amount\"><span class=\"woocommerce-Price-currencySymbol\">&#36;<\/span>15.00<\/span><\/del> <ins><span class=\"woocommerce-Price-amount amount\"><span class=\"woocommerce-Price-currencySymbol\">&#36;<\/span>12.00<\/span><\/ins>",
    "taxable": true,
    "tax_status": "taxable",
    "tax_class": "",
    "managing_stock": false,
    "stock_quantity": null,
    "in_stock": true,
    "backorders_allowed": false,
    "backordered": false,
    "sold_individually": false,
    "purchaseable": true,
    "featured": false,
    "visible": true,
    "catalog_visibility": "visible",
    "on_sale": true,
    "product_url": "",
    "button_text": "",
    "weight": null,
    "dimensions": {
      "length": "",
      "width": "",
      "height": "",
      "unit": "cm"
    },
    "shipping_required": true,
    "shipping_taxable": true,
    "shipping_class": "",
    "shipping_class_id": null,
    "description": "<p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.<\/p>\n",
    "short_description": "<p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.<\/p>\n",
    "reviews_allowed": true,
    "average_rating": "4.00",
    "rating_count": 4,
    "related_ids": [
      76,
      79,
      73,
      67
    ],
    "upsell_ids": [

    ],
    "cross_sell_ids": [

    ],
    "parent_id": 0,
    "categories": [
      "Posters"
    ],
    "tags": [

    ],
    "images": [
      {
        "id": 71,
        "created_at": "2013-06-07T11:24:19Z",
        "updated_at": "2013-06-07T11:24:19Z",
        "src": "http:\/\/codiixx.com\/wp-content\/uploads\/2013\/06\/poster_2_up.jpg",
        "title": "poster_2_up",
        "alt": "",
        "position": 0
      },
      {
        "id": 72,
        "created_at": "2013-06-07T11:24:47Z",
        "updated_at": "2013-06-07T11:24:47Z",
        "src": "http:\/\/codiixx.com\/wp-content\/uploads\/2013\/06\/Poster_2_flat.jpg",
        "title": "Poster_2_flat",
        "alt": "",
        "position": 1
      },
      {
        "id": 10260,
        "created_at": "2017-07-10T06:51:22Z",
        "updated_at": "2017-07-10T06:51:22Z",
        "src": "http:\/\/codiixx.com\/wp-content\/uploads\/2017\/07\/images.jpeg",
        "title": "images",
        "alt": "",
        "position": 2
      },
      {
        "id": 10261,
        "created_at": "2017-07-10T06:52:18Z",
        "updated_at": "2017-07-10T06:52:18Z",
        "src": "http:\/\/codiixx.com\/wp-content\/uploads\/2017\/07\/Jazbaa-Movie-Full-Audio-Album-Free-Download-Mp3-Song-2015.jpg",
        "title": "Jazbaa-Movie-Full-Audio-Album-Free-Download-Mp3-Song-2015",
        "alt": "",
        "position": 3
      },
      {
        "id": 10264,
        "created_at": "2017-07-10T09:34:49Z",
        "updated_at": "2017-07-10T09:34:49Z",
        "src": "http:\/\/codiixx.com\/wp-content\/uploads\/2017\/07\/entrepreneur-593371_640.jpg",
        "title": "entrepreneur-593371_640",
        "alt": "",
        "position": 4
      },
      {
        "id": 10234,
        "created_at": "2017-04-06T06:01:10Z",
        "updated_at": "2017-04-06T06:01:10Z",
        "src": "http:\/\/codiixx.com\/wp-content\/uploads\/2017\/04\/img1.jpg",
        "title": "img1",
        "alt": "",
        "position": 5
      },
      {
        "id": 469,
        "created_at": "2016-11-04T06:26:58Z",
        "updated_at": "2017-04-06T05:03:30Z",
        "src": "http:\/\/codiixx.com\/wp-content\/uploads\/2016\/11\/test1-1.jpg",
        "title": "test1",
        "alt": "",
        "position": 6
      },
      {
        "id": 10215,
        "created_at": "2017-03-28T06:17:00Z",
        "updated_at": "2017-04-06T05:03:29Z",
        "src": "http:\/\/codiixx.com\/wp-content\/uploads\/2017\/03\/download.jpg",
        "title": "download",
        "alt": "",
        "position": 7
      },
      {
        "id": 327,
        "created_at": "2016-06-24T10:42:33Z",
        "updated_at": "2016-06-24T10:42:33Z",
        "src": "http:\/\/codiixx.com\/wp-content\/uploads\/2016\/06\/logo-phoeniixx.jpg",
        "title": "logo-phoeniixx",
        "alt": "",
        "position": 8
      },
      {
        "id": 98,
        "created_at": "2013-06-07T11:37:17Z",
        "updated_at": "2013-06-07T11:37:17Z",
        "src": "http:\/\/codiixx.com\/wp-content\/uploads\/2013\/06\/cd_5_flat.jpg",
        "title": "cd_5_flat",
        "alt": "",
        "position": 9
      }
    ],
    "featured_src": "http:\/\/codiixx.com\/wp-content\/uploads\/2013\/06\/poster_2_up.jpg",
    "attributes": [

    ],
    "downloads": [

    ],
    "download_limit": -1,
    "download_expiry": -1,
    "download_type": "standard",
    "purchase_note": "",
    "total_sales": 91,
    "variations": [

    ],
    "parent": [

    ]
  }
}

【问题讨论】:

  • 我认为你的 pojo 类是错误的,请从此链接创建并检查 pojo 类 jsonschema2pojo.org
  • @Lingeshwaran 我从那里创建
  • 您是否尝试打印您的回复?来对了吗?
  • @AbhishekSingh 我创建并检查了它与您的班级不同的节目
  • 终于让它工作了..谢谢大家帮助我

标签: android retrofit2 gson


【解决方案1】:

虽然您使用 json 对象将 json 数据发送到 URL,但主要目的是获取数据,因此应该获取注释而不是 post

public interface ApiInterface {
     @GET("app/product.php")
     Call<Product> getProducts(@Body JsonObject jsonObject);
}

【讨论】:

  • 通过使用 post im 得到这个错误java.lang.IllegalArgumentException: Non-body HTTP method cannot contain @Body
  • 你想做什么?我猜你想获取数据,同时你还需要向服务器发布一些数据来获取数据?对吧?
  • 如果是这种情况,您应该使用 GET 而不是 POST
  • 你想发布 id?那回复是什么?
  • response 包含产品的全部信息,如 json 所示
【解决方案2】:

您正在公开您的字段。

只要您不使用 GSON 设置恢复公开,所有@EXPOSE'd 注释字段都将被忽略以进行序列化和反序列化。如果名称与您的 var 匹配,则不需要使用序列化名称注释(注意 proguard)

public class Product implements Parcelable{
private String title;
private int id;
private String created_at;
private String updated_at;
private String type;
// ....
}

您可以使用 excludeFieldsWithoutExposeAnnotation 恢复它

另一个原因可能是您将数据发布到您的网络服务器。只要您的网络服务器对您的 POST 的响应不是上面的数据,您就不会得到任何东西。你是说@GET()吗?

同时验证您是否仅获得 1 个产品作为回复。在改造服务中获得多个结果应该是Call&lt;List&lt;Product&gt;&gt;

【讨论】:

  • 通过使用 post im 得到这个错误java.lang.IllegalArgumentException: Non-body HTTP method cannot contain @Body
  • 是的,因为 GET() 不允许 Body annotation 发送数据。保留您的 POST 并重新设计您的网络服务器以接受帖子并返回正确的数据。
  • 我的网络服务接受发布数据.. 在volley 中也得到响应Call&lt;ResponseBody&gt;
  • 如上所述。删除暴露或创建适当的 GSON Builder 以恢复暴露注释
  • 所以我需要删除`@Expose1 注释。?以及如何创建 GSON Builder 能否通过代码在模型类中使用一两个变量向我展示
【解决方案3】:
JsonObject ob = new JsonObject();
ob.addProperty("pro_id", model.getId());

不要发送一个 json 对象,而是创建一个模型类来发送。请参阅以下模型类的实现,即 DTO:

PropertyDTO.java

public class PropertyDTO {
    @SerialisedName("pro_id")
    @Expose
    private String proId;

    public String getProId(){
        return proId;
    }

    public void setProId(String s) {
        this.proId = s;
    }
}

像这样更改 API 接口:

public interface ApiInterface {
     @POST("app/product.php")
     Call<Product> productsAPI(@Body PropertyDTO ob);
}

现在对于响应类,即产品,复制整个 json 数据并将其粘贴到 http://www.jsonschema2pojo.org/ 并在选项中选择目标语言:java,源类型:json,注释样式:gson 并勾选以下复选框:

"Use primitive types"
"Use double numbers"
"Allow additional properties"

现在在 android studio 中生成构造函数或 setter 和 getter。而已。如需进一步帮助,您可以查看以下教程。

https://www.youtube.com/watch?v=y8SYedH6wC8&list=PLCBuiMPCrrW1BDDxd91tCW1OMzCRzMvjX

使用 Stetho 网络拦截器来了解您在进行网络呼叫时发生了什么。对于 Stetho,请参阅此链接。

https://github.com/facebook/stetho

你的 Retrofit 实例会有一个小的变化:

OkHttpClient.Builder okHttpBuilder = new OkHttpClient.Builder()
                .addNetworkInterceptor(new StethoInterceptor());

Retrofit retrofit = new Retrofit.Builder()
            .baseUrl(PRODUCT_URL)
            .client(okHttpBuilder.build())
            .addConverterFactory(GsonConverterFactory.create())
            .build();

记得在 onCreate 方法中初始化 Stetho 并使用单例类,而不是在不同的活动中创建改造实例。点击此链接了解更多信息:

https://futurestud.io/tutorials/retrofit-getting-started-and-android-client

【讨论】:

  • 问题不在于发送数据.. 问题我在解析数据
  • 您是否尝试解析jsonschema2pojo.org 中的json 响应以获取类
猜你喜欢
  • 2018-01-04
  • 2016-02-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多