我是Android应用程序开发的新手。我正在开发一个购物车应用程序。我试图使用android在GET方法中调用Web服务。但是我该怎么做呢?我试过的是这里。但它给了我一个错误PostResponseAsyncTask: 405 Method not allowed
。如何解决?有人可以帮帮我吗?提前谢谢。
MainFragment Class
public class MainFragment extends Fragment implements AsyncResponse, AdapterView.OnItemClickListener{
public static final String PREFS = "prefFile";
final String LOG = "MainFragment";
final static String url = "http://10.0.3.2:8080/WebService/rest/get/products";
private ArrayList<Products> productList;
private ListView lv;
FunDapter<Products> adapter;
View view;
public MainFragment() {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_main, container, false);
ImageLoader.getInstance().init(UILConfig.config(MainFragment.this.getActivity()));
PostResponseAsyncTask taskRead = new PostResponseAsyncTask(MainFragment.this.getActivity(), this);
taskRead.execute(url);
return view;
}
@Override
public void processFinish(String s) {
productList = new JsonConverter<Products>().toArrayList(s, Products.class);
BindDictionary dic = new BindDictionary();
dic.addStringField(R.id.tvName, new StringExtractor<Products>() {
@Override
public String getStringValue(Products item, int position) {
return item.name;
}
});
dic.addStringField(R.id.tvDesc, new StringExtractor<Products>() {
@Override
public String getStringValue(Products item, int position) {
return item.description;
}
}).visibilityIfNull(View.GONE);
dic.addStringField(R.id.tvPrice, new StringExtractor<Products>() {
@Override
public String getStringValue(Products item, int position) {
return ""+item.price;
}
});
dic.addDynamicImageField(R.id.ivImage, new StringExtractor<Products>() {
@Override
public String getStringValue(Products item, int position) {
return item.pic;
}
}, new DynamicImageLoader() {
@Override
public void loadImage(String url, ImageView img) {
//Set image
ImageLoader.getInstance().displayImage(url, img);
}
});
dic.addBaseField(R.id.btnCart).onClick(new ItemClickListener() {
});
adapter = new FunDapter<>(MainFragment.this.getActivity(), productList, R.layout.product_row, dic);
lv = (ListView)view.findViewById(R.id.lvProduct);
lv.setAdapter(adapter);
lv.setOnItemClickListener(this);
}
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
}
}
答案 0 :(得分:2)
尝试使用一些库,如Retrofit,Volley,Loopj等,用于Asynchrous GET或POST HTTP请求。
对于从URL或文件路径实现动态图像,请使用Piccasso或Glide Library。
以下是有关这些库的一些示例和文档
<强>毕加索强>
<强>滑翔强>
希望这些可以帮到你
implementation 'com.google.code.gson:gson:2.6.2'
implementation 'com.squareup.retrofit2:retrofit:2.0.2'
implementation 'com.squareup.retrofit2:converter-gson:2.0.2'
public class MainFragment extends Fragment {
public static final String PREFS = "prefFile";
final String LOG = "MainFragment";
private ArrayList<Product> productList;
private ListView lv;
FunDapter adapter;
private ApiInterface apiInterface;
View view;
public MainFragment() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_main, container, false);
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
lv = (ListView) view.findViewById(R.id.lvProduct);
apiInterface = ApiClient.getRetrofitApiClient().create(ApiInterface.class);
productList = new ArrayList<Product>();
adapter= new FunDapter (getContext(), 0, productList);
lv.setAdapter(adapter);
getProduct();
}
private void getProduct() {
Call<List<Product>> call = apiInterface.getProducts();
call.enqueue(new Callback<List<Product>>() {
@Override
public void onResponse(Call<List<Product>> call, Response<List<Product>> response) {
List<Product> products= response.body();
Log.d("TEST", "onResponse: "+response.body().size());
if(products.size()>0){
productList.addAll(products);
}
adapter.notifyDataSetChanged();
}
@Override
public void onFailure(Call<List<Product>> call, Throwable t) {
}
});
}
}
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
/**
* Created by android on 3/10/17.
*/
class ApiClient {
public static final String BASE_URL = "http://10.0.2.2:8080/WebService/rest/";
public static Retrofit retrofit = null;
public static Retrofit getRetrofitApiClient() {
if (retrofit == null) {
retrofit = new Retrofit.Builder().baseUrl(BASE_URL).addConverterFactory(GsonConverterFactory.create()).build();
}
return retrofit;
}
}
import java.util.List;
import retrofit2.Call;
import retrofit2.http.Body;
import retrofit2.http.GET;
import retrofit2.http.POST;
import retrofit2.http.Query;
public interface ApiInterface {
@GET("get/products")
Call<List<Product>> getProducts();
}
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
class Product {
@SerializedName("name")
@Expose
private String name;
@SerializedName("ram")
@Expose
private String ram;
@SerializedName("price")
@Expose
private String price;
@SerializedName("pic")
@Expose
private String pic;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getRam() {
return ram;
}
public void setRam(String ram) {
this.ram = ram;
}
public String getPrice() {
return price;
}
public void setPrice(String price) {
this.price = price;
}
public String getPic() {
return pic;
}
public void setPic(String pic) {
this.pic = pic;
}
}
class FunDapter extends ArrayAdapter<Product> {
private Context context;
private ArrayList<Product> objects;
private static LayoutInflater inflater = null;
public FunDapter(@NonNull Context context, int resource, @NonNull ArrayList<Product> objects) {
super(context, resource, objects);
try {
this.context = context;
this.objects = objects;
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
} catch (Exception e) {
}
}
public int getCount() {
return objects.size();
}
public Product getItem(Product position) {
return position;
}
public long getItemId(int position) {
return position;
}
public static class ViewHolder {
public TextView display_name;
public TextView display_number;
public ImageView image;
}
public View getView(int position, View convertView, ViewGroup parent) {
View vi = convertView;
final ViewHolder holder;
try {
if (convertView == null) {
vi = inflater.inflate(R.layout.singlerow_mylistview, null);
holder = new ViewHolder();
holder.display_name = (TextView) vi.findViewById(R.id.title_listview);
holder.display_number = (TextView) vi.findViewById(R.id.subtitle_listview);
holder.image = (ImageView) vi.findViewById(R.id.icon_listview);
vi.setTag(holder);
} else {
holder = (ViewHolder) vi.getTag();
}
holder.display_name.setText(objects.get(position).getName());
holder.display_number.setText(objects.get(position).getPrice());
Picasso.with(context)
.load(objects.get(position).getPic())
.resize(50, 50)
.centerCrop()
.into(holder.image);
} catch (Exception e) {
}
return vi;
}
}
别忘了在Manifest中添加<uses-permission android:name="android.permission.INTERNET" />
答案 1 :(得分:1)
尝试使用改造,首先添加以下依赖项
compile 'com.squareup.retrofit2:retrofit:2.3.0'
compile 'com.squareup.retrofit2:converter-gson:2.3.0'
首先尝试找出从后端获得的json响应类型 - 它可以是数组响应/对象响应。
Json数组响应的形式 对象,
[{"field1":"value1",..},{"field2":"value2",..}..]
回复的格式为{"field1":"value1",..}
您可以检查this tutorial以了解解析json响应
如果您检查后端并找出响应,那么您可以使用http://www.jsonschema2pojo.org/
中的相同类型生成模型类 案例1:假设您有json object
回复({"field1":"value1",..}
)
首先使用上面提到的来自jsonschema2pojo
的回复创建一个模型类,然后将其称为如下(假设YourObjectModel
是您的模型类)
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://10.0.3.2:8080/WebService/")
.addConverterFactory(GsonConverterFactory.create())
.build();
SampleInterface request = retrofit.create(SampleInterface.class);
Call<YourObjectModel> call1=request.getResponse();
call1.enqueue(new Callback<YourObjectModel>() {
@Override
public void onResponse(Call<YourObjectModel> call, Response<YourObjectModel> response) {
Toast.makeText(MainActivity.this,response.body().toString(),Toast.LENGTH_SHORT).show();
}
@Override
public void onFailure(Call<YourObjectModel> call, Throwable t) {
Toast.makeText(MainActivity.this,t.toString(),Toast.LENGTH_SHORT).show();
}
});
SampleInterface.java
public interface SampleInterface {
@GET("rest/get/products")
Call<YourObjectModel> getResponse();
}
案例2:假设您有json array
回复([{"field1":"value1",..},{"field2":"value2",..}..]
)
首先创建一个类似于上述情况的模型类,因为它是一个数组响应,您可能需要将响应作为列表获取,因此将所有call
方法从Call<YourObjectModel>
更改为{{1} }
其中Call<List<YourArrayModel>>
是json数组响应的模型类
答案 2 :(得分:0)
您正在执行此PostResponseAsyncTask
执行POST请求,这就是您获取405 Method not allowed
的原因。如果该端点接受GET,则执行GET请求。最好使用 Volley 或 Retrofit 库进行网络通信。
答案 3 :(得分:0)
试试这个例子,这个例子很容易帮助你。