我是Retrofit的新手,試圖構建一個Android應用程序來對在LocalHost上運行的Servlet進行REST查詢。Retrofit不返回響應+空對象參考
我知道這樣的錯誤是由不正確的POJO通過Retrofit接收JSON響應引起的。我根據我的JSON響應在this的幫助下修復了我的POJO。
但不幸的是,錯誤依然存在。所有的幫助表示讚賞。
JSON響應
{"businesses":[{"business_name":"Starbucks","city":"San Francisco","avg.rating":2.0,"neighbourhood":"SOMA","latitude":10.02203,"state":"CA","type":"restaurant","business_id":"2","longitude":10.02203}]}
企業級
public class Businesses {
@SerializedName("businesses")
@Expose
private List<Business> businesses = null;
public Businesses() {}
public Businesses(List<Business> businesses) {
super();
this.businesses = businesses;
}
public List<Business> getBusinesses() {
return businesses;
}
public void setBusinesses(List<Business> businesses) {
this.businesses = businesses;
}
}
商務艙
public class Business {
@SerializedName("business_name")
@Expose
private String businessName;
@SerializedName("city")
@Expose
private String city;
@SerializedName("avg.rating")
@Expose
private float avgRating;
@SerializedName("neighbourhood")
@Expose
private String neighbourhood;
@SerializedName("latitude")
@Expose
private Double latitude;
@SerializedName("state")
@Expose
private String state;
@SerializedName("type")
@Expose
private String type;
@SerializedName("business_id")
@Expose
private String businessId;
@SerializedName("longitude")
@Expose
private Double longitude;
public Business() {
}
/**
*
* @param businessName
* @param state
* @param longitude
* @param businessId
* @param latitude
* @param type
* @param avgRating
* @param neighbourhood
* @param city
*/
public Business(String businessName, String city, float avgRating, String neighbourhood, Double latitude, String state, String type, String businessId, Double longitude) {
super();
this.businessName = businessName;
this.city = city;
this.avgRating = avgRating;
this.neighbourhood = neighbourhood;
this.latitude = latitude;
this.state = state;
this.type = type;
this.businessId = businessId;
this.longitude = longitude;
}
public String getBusinessName() {
return businessName;
}
public void setBusinessName(String businessName) {
this.businessName = businessName;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public float getAvgRating() {
return avgRating;
}
public void setAvgRating(float avgRating) {
this.avgRating = avgRating;
}
public String getNeighbourhood() {
return neighbourhood;
}
public void setNeighbourhood(String neighbourhood) {
this.neighbourhood = neighbourhood;
}
public Double getLatitude() {
return latitude;
}
public void setLatitude(Double latitude) {
this.latitude = latitude;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getBusinessId() {
return businessId;
}
public void setBusinessId(String businessId) {
this.businessId = businessId;
}
public Double getLongitude() {
return longitude;
}
public void setLongitude(Double longitude) {
this.longitude = longitude;
}
}
logcat的
FATAL EXCEPTION: main
Process: mdnaseemashraf.yapapp, PID: 20528
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String java.lang.Object.toString()' on a null object reference
at mdnaseemashraf.yapapp.BusinessActivity$1.onResponse(BusinessActivity.java:73)
at retrofit2.ExecutorCallAdapterFactory$ExecutorCallbackCall$1$1.run(ExecutorCallAdapterFactory.java:70)
at android.os.Handler.handleCallback(Handler.java:743)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:171)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
我的回收站適配器
public class BusinessRecyclerAdapter extends RecyclerView.Adapter<BusinessRecyclerAdapter.BusinessViewHolder> {
private Businesses yapBusinesses;
public class BusinessViewHolder extends RecyclerView.ViewHolder
{
public TextView tvBusinessName, tvType, tvCity;
public RatingBar ratingBar;
public BusinessViewHolder(View itemView) {
super(itemView);
tvBusinessName = (TextView) itemView.findViewById(R.id.tvBusinessName);
tvType = (TextView) itemView.findViewById(R.id.tvType);
tvCity = (TextView) itemView.findViewById(R.id.tvCity);
ratingBar = (RatingBar) itemView.findViewById(R.id.ratingBar);
}
}
public BusinessRecyclerAdapter(Businesses yapBusinessesIn)
{
this.yapBusinesses = yapBusinessesIn;
}
@Override
public BusinessRecyclerAdapter.BusinessViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
{
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.list_item_business, parent, false);
return new BusinessViewHolder(itemView);
}
@Override
public void onBindViewHolder(BusinessRecyclerAdapter.BusinessViewHolder holder, int position)
{
Business yapBusiness = yapBusinesses.getBusinesses().get(position);
holder.tvBusinessName.setText(yapBusiness.getBusinessName());
holder.tvBusinessName.setText(yapBusiness.getBusinessName());
holder.tvBusinessName.setText(yapBusiness.getBusinessName());
holder.ratingBar.setRating(yapBusiness.getAvgRating());
}
@Override
public int getItemCount() {
return yapBusinesses.getBusinesses().size();
}
}
BusinessActivity
public class BusinessActivity extends AppCompatActivity {
private Businesses yapBusinesses = new Businesses();
private RecyclerView businessRecyclerView;
private BusinessRecyclerAdapter businessRecyclerAdapter;
//RETROFIT
public static final String BASE_URL = "http://192.168.1.4:8080/Yap/";
private static Retrofit retrofit = null;
private final static int APP_ID = 11;
private final static String REQUEST_TYPE = "search";
private final static String FORM = "strict"; //"lenient" or "strict",
private final static String KEYWORDS = "sta";
private final static String CITY = "San";
private final static String STATE = "C";
private final static String TYPE = "restaurant"; //"restaurant", "shop", "hotel", "cafe" & "bar".
//
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_business);
businessRecyclerView = (RecyclerView) findViewById(R.id.business_recycler_view);
RecyclerView.LayoutManager businesslayoutManager = new LinearLayoutManager(getApplicationContext());
businessRecyclerView.setLayoutManager(businesslayoutManager);
businessRecyclerView.setItemAnimator(new DefaultItemAnimator());
connectAndGetApiData();
}
public void connectAndGetApiData(){
if (retrofit == null) {
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
YapApiService yapApiService = retrofit.create(YapApiService.class);
Call<BusinessResponse> call = yapApiService.getSearchedBusiness(APP_ID, REQUEST_TYPE, FORM,
KEYWORDS, CITY, STATE, TYPE);
call.enqueue(new Callback<BusinessResponse>() {
@Override
public void onResponse(Call<BusinessResponse> call, Response<BusinessResponse> response) {
Businesses businessesIN = response.body().getResults();
Log.println(Log.INFO, "Response Body", response.body().toString()); //Response Body: [email protected]
Log.println(Log.INFO, "Response Results", response.body().getResults().toString()); //Shows NUll ERROR - No Results?
businessRecyclerView.setAdapter(new BusinessRecyclerAdapter(businessesIN));
Log.d("Retrofit Data Tag", "Number of Businesses received: " + businessesIN.getBusinesses().size());
businessRecyclerView.getAdapter().notifyDataSetChanged();
}
@Override
public void onFailure(Call<BusinessResponse> call, Throwable throwable) {
Log.e("Retrofit Data Error", throwable.toString());
}
});
}
}
BusinessResponse類
public class BusinessResponse
{
@SerializedName("page")
private int page;
@SerializedName("results")
private Businesses results;
@SerializedName("total_results")
private int totalResults;
@SerializedName("total_pages")
private int totalPages;
public int getPage() {
return page;
}
public void setPage(int page) {
this.page = page;
}
public Businesses getResults() {
return results;
}
public void setResults(Businesses results) {
this.results = results;
}
public int getTotalResults() {
return totalResults;
}
public void setTotalResults(int totalResults) {
this.totalResults = totalResults;
}
public int getTotalPages() {
return totalPages;
}
public void setTotalPages(int totalPages) {
this.totalPages = totalPages;
}
}
它將有助於瞭解如何創建'BusinessRecyclerAdapter'對象。 – Titus
添加了我的Business Activity類,該類使用onResponse中提取的數據構建Businesses對象,並進一步使用它構建新的適配器,並將此新適配器設置爲回收視圖。 –
@MDNaseemAshraf查看我的回答 – akhilesh0707