使用Retrofit 2

时间:2016-07-15 10:11:46

标签: java android arraylist retrofit2

我知道这已被多次询问,但是看看已有的答案,我可以解决我的问题,所以任何帮助都会非常感激。

我正在尝试使用Retrofit 2使用自定义反序列化器将我的JSON响应解析为数组列表。但是它给了我错误

com.google.gson.JsonSyntaxException:java.lang.IllegalStateException:预期为BEGIN_ARRAY,但路径为$ 时为BEGIN_OBJECT

这是我试图解析的json响应

[
  {
    "category": "Accessories"
  },
  {
    "category": "Apparel"
  },
  {
    "category": "Audio CD"
  },
  {
    "keyword": "Accessories & Supplies"
  },
  {
    "keyword": "Audio & Video Accessories"
  },
  {
    "keyword": "Combination Deodorants & Antiperspirants"
  },
  {
    "_id": "57442700d0fcd01100d45cd8",
    "prodName": "2015 High-end Case Cover zzzzzzz Animals dobermans nature puppies Samsung Galaxy S7 phone Case 3236386XK945021729S7 Jordan Dowdy's Shop"
  },
  {
    "_id": "575a95fbb9167e100054f5ab",
    "prodName": "30 Piece Brand New & Sealed Hard Candy' Cosmetics Makeup Excellent Assorted Mixed Lot"
  },
  {
    "_id": "57442700d0fcd01100d45cd5",
    "prodName": "8274363XK945021729I5S New Premium zzzzzzz Animals dobermans nature puppies Skin Case Cover Excellent Fitted For iPhone SE/iPhone 5/5s Gary R. Morones's Shop"
  },
  {
    "_id": "575a95fbb9167e100054f5b0",
    "prodName": "ACE Fashion Women Professional 15 Color Makeup Cosmetic Contour Concealer Palette Make Up+Sponge+Concealer Brush"
  }
]

这是Custom Deserializer

public static class HomeSearchDeserializer implements JsonDeserializer<ArrayList<HomeSearchItems>> {
    @Override
    public ArrayList<HomeSearchItems> deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws Js

        Log.v("JSON RESPONSE " + String.valueOf(countlog++), String.valueOf(json));
        Gson gson = new Gson();
        Type listType = new TypeToken<ArrayList<HomeSearchItems>>() {
        }.getType();
        ArrayList<HomeSearchItems> HomeSearchItemsList = new Gson().fromJson(json, listType);
        final JsonArray jsonArray = json.getAsJsonArray();
        for (int i = 0; i < jsonArray.size(); i++) {
            HomeSearchItems homeSearchItems = new HomeSearchItems();
            JsonObject jsonObject = jsonArray.get(i).getAsJsonObject();
            if (!jsonObject.get("prodName").isJsonNull()) {
                homeSearchItems.set_id(jsonObject.get("_id").getAsString());
                homeSearchItems.setTitle(jsonObject.get("prodName").getAsString());
                homeSearchItems.setType(HomeSearchItems.ItemType.product);
            } else if (!jsonObject.get("category").isJsonNull()) {
                homeSearchItems.setTitle(jsonObject.get("category").getAsString());
                homeSearchItems.setType(HomeSearchItems.ItemType.category);
            } else {
                homeSearchItems.setTitle(jsonObject.get("keyword").getAsString());
                homeSearchItems.setType(HomeSearchItems.ItemType.keyword);
            }
            HomeSearchItemsList.add(homeSearchItems);
        }
        return HomeSearchItemsList;
    }
}
public static GsonConverterFactory HomeSearchGsonConverter() {
    GsonBuilder gsonBuilder = new GsonBuilder();
    // Adding custom deserializers
    gsonBuilder.registerTypeAdapter(HomeSearchItems.class, new Search.HomeSearchDeserializer());
    Gson myGson = gsonBuilder.create();
    return GsonConverterFactory.create(myGson);
}

这是改装的GET征集

public interface SearchCalls {
    @GET("/products/search")
    Call<ArrayList<HomeSearchItems>> HomeSearch(@Header("Authorization") String Token, @Query("queryString") String query);
}

这是我正在进行网络通话的功能

public void callSearch(String query) {
                //Toast.makeText(getApplicationContext(),query,Toast.LENGTH_SHORT);
                Log.v("query", query);


                HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor();
                httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);

                OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
                httpClient.addInterceptor(new Interceptor() {
                    @Override
                    public okhttp3.Response intercept(Chain chain) throws IOException {
                        Request original = chain.request();

                        Request request = original.newBuilder()
                                .header("Content-Type", "application/json")
                                .method(original.method(), original.body())
                                .build();

                        return chain.proceed(request);
                    }
                });

                httpClient.addInterceptor(httpLoggingInterceptor);


                OkHttpClient client = httpClient.build();
                Retrofit retrofit = new Retrofit.Builder()
                        .baseUrl(baseURL)
                        .addConverterFactory(HomeSearchGsonConverter())
                        .client(client)
                        .build();

                Search.SearchCalls service = retrofit.create(Search.SearchCalls.class);
                Call<ArrayList<HomeSearchItems>> HomeSearch = service.HomeSearch("Bearer " +appSettings.getToken(),query);


                HomeSearch.enqueue(new Callback<ArrayList<HomeSearchItems>>() {
                    @Override
                    public void onResponse(Call<ArrayList<HomeSearchItems>> call, Response<ArrayList<HomeSearchItems>> response) {
                        Log.v("onResponse,Code", String.valueOf(response.code()));
                        if (response.isSuccessful()) {
                            HomeSearchItemsList = response.body();
                            Log.v("onResponse", "isSuccessful TRUE");
                        } else {
                            Log.v("onResponse", "isSuccessful FALSE");
                        }
                    }

                    @Override
                    public void onFailure(Call<ArrayList<HomeSearchItems>> call, Throwable t) {
                        Log.v("onFailure", t.toString());
                    }
                });

            }

其中 HomeSearchItemsList 是Type HomeSearchItems

的ArrayList

这是HomeSearchItems类

public class HomeSearchItems {

    public enum ItemType {
        product, keyword, category
    }

    private String title;
    private ItemType type;
    private String _id;


    public HomeSearchItems() {

    }

    public String getTitle() {
        return title;
    }

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

    public ItemType getType() {
        return type;
    }

    public void setType(ItemType type) {
        this.type = type;
    }

    public String get_id() {
        return _id;
    }

    public void set_id(String _id) {
        this._id = _id;
    }
}

编辑1 STACK TRACE

V/query: a
D/OkHttp: --> GET https://houston.tm.smartfission.com:3030/products/search?queryString=a http/1.1
D/OkHttp: Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOjE2NCwiZXhwIjoxNDczNjY0Mjg5fQ.ROBvKkoC0Gud4AFghYtUku_OXBRYWjzHeR5Dkhd1mOc
D/OkHttp: --> END GET
D/OkHttp: <-- 200 OK https://houston.tm.smartfission.com:3030/products/search?queryString=a (2010ms)
D/OkHttp: X-Powered-By: Express
D/OkHttp: Access-Control-Allow-Origin: *
D/OkHttp: Access-Control-Allow-Methods: GET,PUT,POST,DELETE,PATCH,OPTIONS
D/OkHttp: Access-Control-Allow-Headers: Content-Type, Authorization, Accept-Encoding, Accept-Language
D/OkHttp: Content-Type: application/json; charset=utf-8
D/OkHttp: Content-Length: 891
D/OkHttp: ETag: W/"37b-Qfnf0ExmUd0oo2dJpmXG2g"
D/OkHttp: Vary: Accept-Encoding
D/OkHttp: Date: Fri, 15 Jul 2016 11:02:31 GMT
D/OkHttp: Connection: keep-alive
D/OkHttp: [{"category":"Accessories"},{"category":"Apparel"},{"category":"Audio CD"},{"keyword":"Accessories & Supplies"},{"keyword":"Audio & Video Accessories"},{"keyword":"Combination Deodorants & Antiperspirants"},{"_id":"57442700d0fcd01100d45cd8","prodName":"2015 High-end Case Cover zzzzzzz Animals dobermans nature puppies Samsung Galaxy S7 phone Case 3236386XK945021729S7 Jordan Dowdy's Shop"},{"_id":"575a95fbb9167e100054f5ab","prodName":"30 Piece Brand New & Sealed Hard Candy' Cosmetics Makeup Excellent Assorted Mixed Lot"},{"_id":"57442700d0fcd01100d45cd5","prodName":"8274363XK945021729I5S New Premium zzzzzzz Animals dobermans nature puppies Skin Case Cover Excellent Fitted For iPhone SE/iPhone 5/5s Gary R. Morones's Shop"},{"_id":"575a95fbb9167e100054f5b0","prodName":"ACE Fashion Women Professional 15 Color Makeup Cosmetic Contour Concealer Palette Make Up+Sponge+Concealer Brush"}]
D/OkHttp: <-- END HTTP (891-byte body)
V/onFailure: com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BEGIN_OBJECT at path $

编辑2

这一行被抛出:

ArrayList<HomeSearchItems> HomeSearchItemsList = new Gson().fromJson(json, listType);

文档说,

抛出: JsonSyntaxException - 如果json不是typeOfT类型的对象的有效表示

1 个答案:

答案 0 :(得分:0)

您的JSON未根据您的要求进行格式化。

以下JSON结构可能适合您 -

[
    { 
     "category": "Accessories", 
     "keyword": "Accessories & Supplies", 
     "_id": "57442700d0fcd01100d45cd8",
     "prodName": "2015 High-end Case Cover zzzzzzz Animals dobermans nature puppies Samsung Galaxy S7 phone Case 3236386XK945021729S7 Jordan Dowdy's Shop" 
    },
    {
     "category": "Apparel", 
     "keyword": "Audio & Video Accessories", 
     "_id": "575a95fbb9167e100054f5ab"
     "prodName": "30 Piece Brand New & Sealed Hard Candy' Cosmetics Makeup Excellent Assorted Mixed Lot"
    }
]

这可能适用于您的数据模型,但您的反序列化程序中有一些很常见的内容,您可能需要再次查看。

请参阅this链接,详细了解如何定义JSON数据。这肯定会有所帮助。