为什么我无法通过Retrofit2获得响应?

时间:2019-09-30 11:22:01

标签: java android json retrofit2

我以前没有使用过很多改造。但是在这个项目中,我将使用改造。当我尝试从服务器获取响应时,无法获得响应。会导致此错误:

  

java.lang.IllegalStateException:应该为BEGIN_OBJECT,但是   BEGIN_ARRAY在第1行第2列路径$

这是什么问题?

这是我的邮递员结果: enter image description here

ApiInterface.java

public interface ApiInterface {
    @GET("/categories/0")
    Call<Category> getCategoryList();
}

ApiClient.java

public class ApiClient {

    private static Retrofit retrofit;
    private static final String BASE_URL = MyConstants.URL;

    public static Retrofit getRetrofitInstance() {

        if (retrofit == null) {
            retrofit = new retrofit2.Retrofit.Builder()
                    .baseUrl(BASE_URL)
                    .addConverterFactory(GsonConverterFactory.create())
                    .build();
        }
        return retrofit;
    }

CategoryFragment.java

public class CategoriesFragment extends Fragment {

    RecyclerView mRecyclerView;
    List<Category> categoryList;
    Category category;

    public CategoriesFragment() {
        // Required empty public constructor
    }
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null) {
            mParam1 = getArguments().getString(ARG_PARAM1);
            mParam2 = getArguments().getString(ARG_PARAM2);

        }

    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View view = inflater.inflate(R.layout.fragment_categories, container, false);
        mRecyclerView = view.findViewById(R.id.recyclerview);
        GridLayoutManager mGridLayoutManager = new GridLayoutManager(getActivity(), 2);
        mRecyclerView.setLayoutManager(mGridLayoutManager);

        ApiInterface apiInterface = ApiClient.getRetrofitInstance().create(ApiInterface.class);
        Call<Category> call = apiInterface.getCategoryList();
        call.enqueue(new Callback<Category>() {
            @Override
            public void onResponse(Call<Category> call, Response<Category> response) {
                if (response.isSuccessful()) {
                    Category category_list = response.body();
                    Log.d("cateogry", "");
                    // CategoryAdapter myAdapter = new CategoryAdapter(getActivity(), categoryList);
                    //      mRecyclerView.setAdapter(new CategoryAdapter(category, R.layout.category_item_view, ));
                    // mRecyclerView.setAdapter(myAdapter);
                }
                else
                  //  ApiErrorUtils.parseError(response);
                  Log.d("Api hata", "");
            }

            @Override
            public void onFailure(Call<Category> call, Throwable t) {
                Log.d("Error", t.getMessage());
            }
        });

        return view;
    }

    // TODO: Rename method, update argument and hook method into UI event
    public void onButtonPressed(Uri uri) {
        if (mListener != null) {
            mListener.onFragmentInteraction(uri);
        }
    }

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        if (context instanceof OnFragmentInteractionListener) {
            mListener = (OnFragmentInteractionListener) context;
        } else {
//            throw new RuntimeException(context.toString()
  //                  + " must implement OnFragmentInteractionListener");
        }
    }

    @Override
    public void onDetach() {
        super.onDetach();
        mListener = null;
    }


    public interface OnFragmentInteractionListener {
        // TODO: Update argument type and name
        void onFragmentInteraction(Uri uri);
    }
}

4 个答案:

答案 0 :(得分:1)

您的API响应期望Object,但实际响应为Array。您应该使用List<Category>而不是<Category>。喜欢

public interface ApiInterface {

    @GET("/categories/0")
    Call<List<Category>> getCategoryList();
}

API调用应如下所示。

Call<List<Category>> call = apiInterface.getCategoryList();
        call.enqueue(new Callback<List<Category>>() {
            @Override
            public void onResponse(Call<List<Category>> call, Response<List<Category>> response) {
                if (response.isSuccessful()) {
                    List<Category> category_list = response.body();
                    Log.d("cateogry",category_list.size());
                    // CategoryAdapter myAdapter = new CategoryAdapter(getActivity(), categoryList);
                    //      mRecyclerView.setAdapter(new CategoryAdapter(category, R.layout.category_item_view, ));
                    // mRecyclerView.setAdapter(myAdapter);
                }
                else
                  //  ApiErrorUtils.parseError(response);
                  Log.d("Api hata", "");
            }

            @Override
            public void onFailure(Call<List<Category>> call, Throwable t) {
                Log.d("Error", t.getMessage());
            }
        });

答案 1 :(得分:1)

这是后端团队将数组更改为对象时遇到的常见错误。

问题是模型类(pojo类)中的某个地方被声明为数组,但实际上它是对象(反之亦然)。

答案 2 :(得分:1)

您使用的响应不正确,您需要像这样纠正它

示例json响应

{
  "category": [
    {
      "categoryID": 5,
      "categoryName": "Name",
      "categoryImage": "path",
      "categoryProductCount": 0,
      "hasSubCategory": false  
    },
{
    "categoryID": 5,
    "categoryName": "Name",
    "categoryImage": "path",
    "categoryProductCount": 0,
    "hasSubCategory": false
    }
  ]
}

现在您应该在接口中使用的POJO类

public class MyPojo
{
    private List<Category> category;

    public List<Category>  getCategory ()
    {
        return category;
    }

    public void setCategory (List<Category> category)
    {
        this.category = category;
    }


}

Category类在哪里

public class Category
{
    private String categoryImage;

    private String hasSubCategory;

    private String categoryName;

    private String categoryID;

    private String categoryProductCount;

    public String getCategoryImage ()
    {
        return categoryImage;
    }

    public void setCategoryImage (String categoryImage)
    {
        this.categoryImage = categoryImage;
    }

    public String getHasSubCategory ()
    {
        return hasSubCategory;
    }

    public void setHasSubCategory (String hasSubCategory)
    {
        this.hasSubCategory = hasSubCategory;
    }

    public String getCategoryName ()
    {
        return categoryName;
    }

    public void setCategoryName (String categoryName)
    {
        this.categoryName = categoryName;
    }

    public String getCategoryID ()
    {
        return categoryID;
    }

    public void setCategoryID (String categoryID)
    {
        this.categoryID = categoryID;
    }

    public String getCategoryProductCount ()
    {
        return categoryProductCount;
    }

    public void setCategoryProductCount (String categoryProductCount)
    {
        this.categoryProductCount = categoryProductCount;
    }

  }

**Usage**

public interface ApiInterface {
    @GET("/categories/0")
    Call<MyPojo> getCategoryList();
}

在片段类别片段类中

public class CategoriesFragment extends Fragment {

    RecyclerView mRecyclerView;
    List<Category> categoryList;
    Category category;

    public CategoriesFragment() {
        // Required empty public constructor
    }
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null) {
            mParam1 = getArguments().getString(ARG_PARAM1);
            mParam2 = getArguments().getString(ARG_PARAM2);

        }

    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View view = inflater.inflate(R.layout.fragment_categories, container, false);
        mRecyclerView = view.findViewById(R.id.recyclerview);
        GridLayoutManager mGridLayoutManager = new GridLayoutManager(getActivity(), 2);
        mRecyclerView.setLayoutManager(mGridLayoutManager);

        ApiInterface apiInterface = ApiClient.getRetrofitInstance().create(ApiInterface.class);
        Call<MyPojo> call = apiInterface.getCategoryList();
        call.enqueue(new Callback<MyPojo>() {
            @Override
            public void onResponse(Call<MyPojo> call, Response<MyPojo> response) {
                if (response.isSuccessful()) {
                    categoryList = response.body().getCategory ();
                     CategoryAdapter myAdapter = new CategoryAdapter(getActivity(), categoryList);
                          mRecyclerView.setAdapter(new CategoryAdapter(category, R.layout.category_item_view, ));
                    // mRecyclerView.setAdapter(myAdapter);
                }
                else
                  //  ApiErrorUtils.parseError(response);
                  Log.d("Api hata", "");
            }

            @Override
            public void onFailure(Call<MyPojo> call, Throwable t) {
                Log.d("Error", t.getMessage());
            }
        });

        return view;
    }



     // TODO: Rename method, update argument and hook method into UI event
        public void onButtonPressed(Uri uri) {
            if (mListener != null) {
                mListener.onFragmentInteraction(uri);
            }
        }
    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        if (context instanceof OnFragmentInteractionListener) {
            mListener = (OnFragmentInteractionListener) context;
        } else {
//            throw new RuntimeException(context.toString()
  //                  + " must implement OnFragmentInteractionListener");
        }
    }

    @Override
    public void onDetach() {
        super.onDetach();
        mListener = null;
    }


    public interface OnFragmentInteractionListener {
        // TODO: Update argument type and name
        void onFragmentInteraction(Uri uri);
    }
}

答案 3 :(得分:0)

用kotlin编写的

RetrofitHelper库将使您能够使用几行代码来进行API调用。

在应用程序类中添加标头,如下所示:

class Application : Application() {

    override fun onCreate() {
    super.onCreate()

        retrofitClient = RetrofitClient.instance
                    //api url
                .setBaseUrl("https://reqres.in/")
                    //you can set multiple urls
        //                .setUrl("example","http://ngrok.io/api/")
                    //set timeouts
                .setConnectionTimeout(4)
                .setReadingTimeout(15)
                    //enable cache
                .enableCaching(this)
                    //add Headers
                .addHeader("Content-Type", "application/json")
                .addHeader("client", "android")
                .addHeader("language", Locale.getDefault().language)
                .addHeader("os", android.os.Build.VERSION.RELEASE)
            }

        companion object {
        lateinit var retrofitClient: RetrofitClient

        }
    }  

然后拨打电话:

retrofitClient.Get<GetResponseModel>()
            //set path
            .setPath("api/users/2")
            //set url params Key-Value or HashMap
            .setUrlParams("KEY","Value")
            // you can add header here
            .addHeaders("key","value")
            .setResponseHandler(GetResponseModel::class.java,
                object : ResponseHandler<GetResponseModel>() {
                    override fun onSuccess(response: Response<GetResponseModel>) {
                        super.onSuccess(response)
                        //handle response
                    }
                }).run(this)

有关更多信息,请参见documentation