如何使用Android调用Web服务

时间:2018-04-17 05:07:08

标签: android rest web-services

我是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) {

    }
}

4 个答案:

答案 0 :(得分:2)

尝试使用一些库,如Retrofit,Volley,Loopj等,用于Asynchrous GET或POST HTTP请求。

对于从URL或文件路径实现动态图像,请使用Piccasso或Glide Library。

以下是有关这些库的一些示例和文档

循环J

  1. Loopj official Documentation and Example
  2. 改造

    1. Retrofit official Documentation By SquareUp
    2. Retrofit Tutorial from JournelDev
    3. 排球

      1. Volley official Documenation By Android Developers
      2. Volley tutorial from Journeldev
      3. 动态图像处理

        <强>毕加索

        Android Picasso Library

        <强>滑翔

        Glide Library for Android

        希望这些可以帮到你

        改造示例

        的build.gradle(APP)

                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'
        

        MainFragment

        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) {
        
                    }
                });
        
            }
        }
        

        ApiClient

        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;
                }
            }
        

        ApiInterface

        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;
            }
        
        }
        

        FunDapter

        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)

试试这个例子,这个例子很容易帮助你。

  1. asynctask-callback
  2. volley-callback
相关问题