首页 > 解决方案 > Android Retrofit 2.1.0 Response.body() 为空,状态码为 404

问题描述

我正在尝试调用此 api,但由于 response.body() 返回 null 时遇到了困难。 http://demo.museum.vebrary.vn/api/stuff/getall

我想获取列表的名称并显示给我的回收站视图。

我的模型:

public class SOAnswersResponse {

@SerializedName("StuffModels")
@Expose
private List<StuffModel> stuffModels = null;

public List<StuffModel> getStuffModels() {
    return stuffModels;
}

public void setStuffModels(List<StuffModel> stuffModels) {
    this.stuffModels = stuffModels;
}

public class StuffModel {

@SerializedName("STUFFID")
@Expose
private Integer sTUFFID;
@SerializedName("STUFFCODE")
@Expose
private String sTUFFCODE;
@SerializedName("STUFFNAME")
@Expose
private String sTUFFNAME;
@SerializedName("STUFFNOTE")
@Expose
private String sTUFFNOTE;
@SerializedName("STUFFORDER")
@Expose
private Integer sTUFFORDER;
@SerializedName("CUSTOMERID")
@Expose
private String cUSTOMERID;
@SerializedName("EXHIBITS")
@Expose
private List<Object> eXHIBITS = null;

json响应

{  
"StuffModels":[  
  {  
     "STUFFID":2,
     "STUFFCODE":"Gi",
     "STUFFNAME":"Giấy",
     "STUFFNOTE":"",
     "STUFFORDER":2,
     "CUSTOMERID":"CAMAU",
     "EXHIBITS":[  

     ]
  },

ApiUtils 类

public class ApiUtils {


private ApiUtils() {
}

public static final String BASE_URL = "http://demo.museum.vebrary.vn/api/";

public static SOService getSOService() {

    return RetrofitClient.getClient(BASE_URL).create(SOService.class);
}
}

服务接口

public interface SOService {

@GET("/stuff/getall")
Call<SOAnswersResponse> getAnswers();
}

改造客户端类

public class RetrofitClient {

private static Retrofit retrofit = null;

public static Retrofit getClient(String baseUrl) {
    if (retrofit==null) {
        retrofit = new Retrofit.Builder()
                .baseUrl(baseUrl)
                .addConverterFactory(GsonConverterFactory.create())
                .build();
    }
    return retrofit;
}
}

我的 RecyclerView 适配器

public class CategogyNameRecyclerViewAdapter extends RecyclerView.Adapter<CategogyNameRecyclerViewAdapter.ViewHolder> {

private List<StuffModel> mItems;
private Context mContext;
private PostItemListener mItemListener;

public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{

    public TextView titleTv;

    PostItemListener mItemListener;

    public ViewHolder(View itemView, PostItemListener postItemListener) {
        super(itemView);
        titleTv = itemView.findViewById(R.id.tvListMenuCategogy);

        this.mItemListener = postItemListener;
        itemView.setOnClickListener(this);
    }

    @Override
    public void onClick(View view) {
        StuffModel item = getItem(getAdapterPosition());
        this.mItemListener.onPostClick(item.getSTUFFID());

        notifyDataSetChanged();

    }
}

public CategogyNameRecyclerViewAdapter(Context context, List<StuffModel> posts, PostItemListener itemListener) {
    mItems = posts;
    mContext = context;
    mItemListener = itemListener;
}

@Override
public CategogyNameRecyclerViewAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

    Context context = parent.getContext();
    LayoutInflater inflater = LayoutInflater.from(context);

    View postView = inflater.inflate(R.layout.item_list_text, parent, false);

    ViewHolder viewHolder = new ViewHolder(postView, this.mItemListener);
    return viewHolder;
}

@Override
public void onBindViewHolder(CategogyNameRecyclerViewAdapter.ViewHolder holder, int position) {

    StuffModel item = mItems.get(position);
    TextView textView = holder.titleTv;
    textView.setText(item.getSTUFFNAME());
}

@Override
public int getItemCount() {
    return mItems.size();
}

public void updateAnswers(List<StuffModel> items) {
    mItems = items;
    notifyDataSetChanged();
}

private StuffModel getItem(int adapterPosition) {
    return mItems.get(adapterPosition);
}

public interface PostItemListener {
    void onPostClick(long id);
}

}

我的主要活动

public class Testttt extends AppCompatActivity {

private CategogyNameRecyclerViewAdapter mAdapter;
private RecyclerView mRecyclerView;
private SOService mService;

@Override
protected void onCreate (Bundle savedInstanceState)  {
    super.onCreate( savedInstanceState );
    setContentView(R.layout.test );

    mService = ApiUtils.getSOService();

    mRecyclerView = (RecyclerView) findViewById(R.id.rcvCategogyNameMenuTest);
    mAdapter = new CategogyNameRecyclerViewAdapter(this, new ArrayList<StuffModel>(0), new CategogyNameRecyclerViewAdapter.PostItemListener() {

        @Override
        public void onPostClick(long id) {
            Toast.makeText(Testttt.this, "Post id is" + id, Toast.LENGTH_SHORT).show();
        }
    });

    RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(this);
    mRecyclerView.setLayoutManager(layoutManager);
    mRecyclerView.setAdapter(mAdapter);
    mRecyclerView.setHasFixedSize(true);
    RecyclerView.ItemDecoration itemDecoration = new DividerItemDecoration(this, DividerItemDecoration.VERTICAL_LIST);
    mRecyclerView.addItemDecoration(itemDecoration);

    loadAnswers();
}

public void loadAnswers() {


    mService.getAnswers().enqueue(new Callback<SOAnswersResponse>() {
        @Override
        public void onResponse(Call<SOAnswersResponse> call, Response<SOAnswersResponse> response) {
            Toast.makeText(Testttt.this, "333333333333333333"+response.body(), Toast.LENGTH_SHORT).show();
            if(response.isSuccessful()) {
                mAdapter.updateAnswers(response.body().getStuffModels());
                Log.d("AnswersPresenter", "posts loaded from API");
            }else {
                int statusCode  = response.code();

            }
        }

        @Override
        public void onFailure(Call<SOAnswersResponse> call, Throwable t) {
            showErrorMessage();
            Log.d("AnswersPresenter", "error loading from API");

        }
    });
}


public void showErrorMessage() {
    Toast.makeText(this, "Error loading posts", Toast.LENGTH_SHORT).show();
}

}

标签: androidasp.net-web-apiretrofit2

解决方案


我首先想到的是:

您的

public static final String BASE_URL = "http://demo.museum.vebrary.vn/api/";

最后有一个“/”,你的

@GET("/stuff/getall")
Call<SOAnswersResponse> getAnswers();

以“/”开头。所以 url 中有一个双反斜杠可能会导致 404 代码。这能解决问题吗?

当我调用您的 URL 时,我会收到 XML。也许 API 配置不正确?


推荐阅读