android开发post请求参数中有数组参数

用了接近两天终于完美找到方法!!!

话说,访问服务器一般用get请求,在url中拼接参数即可;或者post请求json对象也好呀,这次的接口可神奇了——

post方式访问+请求参数为字符串和数组(数组里面暂时只有一个对象)!

android主流网络请求框架有:okhttp,retrofit,RxVolley等。我想说的是,这三种我都试过了,汗颜。最终使用okhttp和retrofit 能成功请求服务器数据。

附上两种方式:

方式一:okhttp请求网络

代码如下:(亲测有效,可照葫芦画瓢直接使用)

try {
    // 创建json对象
    JSONObject jsonObject = new JSONObject();
    // 1个数组参数
    JSONArray jsonArray = new JSONArray();
    for (String tag : tags) {
        jsonArray.put(tag);
    }
    jsonObject.put("tags", jsonArray);
    // 3个字符串参数
    jsonObject.put("appId", appId);
    jsonObject.put("token", token);
    jsonObject.put("clientId", clientId);
    String data = jsonObject.toString();
    LogUtils.i(TAG, data);
    // 构造请求体
    RequestBody body = RequestBody.create(okhttp3.MediaType.parse("application/json;charset=UTF-8"), data);
    Request request = new Request.Builder()
            .url("https://api.ros.ai/player/cms/modules")
            .post(body)
            .build();
    // 向服务器异步请求数据
    OkHttpClient okHttpClient = new OkHttpClient();
    okHttpClient.newCall(request).enqueue(new okhttp3.Callback() {
        @Override
        public void onFailure(okhttp3.Call call, IOException e) {
            LogUtils.i(TAG, "失败");
        }

        @Override
        public void onResponse(okhttp3.Call call, okhttp3.Response response) throws IOException {
            ResponseBody body = response.body();
            LogUtils.i(TAG, "返回数据:" + body.string());
        }
    });
} catch (JSONException e) {
    e.printStackTrace();
}  

方式二:Retrofit请求网络

代码如下:(亲测有效,可照葫芦画瓢直接使用)

1、调用部分

try {
            // 创建json对象
            JSONObject jsonObject = new JSONObject();
            // 1个数组参数
            JSONArray jsonArray = new JSONArray();
            for (String tag : tags) {
                jsonArray.put(tag);
            }
            jsonObject.put("tags", jsonArray);
            // 3个字符串参数
            jsonObject.put("appId", appId);
            jsonObject.put("token", token);
            jsonObject.put("clientId", clientId);
            String data = jsonObject.toString();
            LogUtils.i(TAG, data);
            // retrofit方式
            Retrofit retrofit = new Retrofit.Builder()
                    .baseUrl(Route.GET_MODULES)
                    .addConverterFactory(GsonConverterFactory.create())
                    .build();
            Route.ModulesList modulesList = retrofit.create(Route.ModulesList.class);
            RequestBody requestBody = RequestBody.create(okhttp3.MediaType.parse("application/json;charset=UTF-8"), data);
            Call<ModuleBean> moduleBeanCall = modulesList.getModulesList(requestBody);
            moduleBeanCall.enqueue(new Callback<ModuleBean>() {
                @Override
                public void onResponse(Call<ModuleBean> call, Response<ModuleBean> response) {
                }

                @Override
                public void onFailure(Call<ModuleBean> call, Throwable t) {
                }
            });
        } catch (JSONException e) {
            e.printStackTrace();
        }

2、网络接口部分

public static final String GET_MODULES = "https://api.ros.ai/player/"; // 获取模块列表
public interface ModulesList {
        //        @FormUrlEncoded // 使用@Body时,就不要使用@FormUrlEncoded,否则会报错!
        @POST("cms/modules")
        Call<ModuleBean> getModulesList(@Body RequestBody data);
    }

// 至于ModuleBean部分,就根据接口返回数据,实际情况书写了。

后续:走过的坑(就是试过了,但是没成功,哎~)

如果上面的方式还没解决问题,可以看看我走过的坑,或许有帮助!

坑一:okhttp方式,没有使用RequestBody(主要是传那一个数组参数,遇到问题

FormBody.Builder builder = new FormBody.Builder()
        .add("appId", appId)
        .add("clientId", clientId)
        .add("token", token)
        .add("tags[0]",tags[0]);
 Request request = new Request.Builder()
                    .url("https://api.ros.ai/player/cms/modules")
                    .post(builder.build())
                    .build();

坑二:RxVolley方式

备注:此处的data为方式一中的data字符串。
HttpParams httpParams = new HttpParams();
httpParams.putHeaders("content-type", "application/json");
httpParams.putJsonParams(data); 

new RxVolley.Builder()
        .url("https://api.ros.ai/player/cms/modules")
        .shouldCache(false)
        .timeout(Route.HTTPS_REQUEST_TIMEOUT_MS)
        .retryPolicy(new RetryPolicy() {
            @Override
            public int getCurrentTimeout() {
                return 0;
            }

            @Override
            public int getCurrentRetryCount() {
                return 1;
            }

            @Override
            public void retry(VolleyError error) throws VolleyError {

            }
        })
        .httpMethod(RxVolley.Method.POST)
        .params(httpParams) 
        .getResult()
        .map(result -> {
            LogUtils.i(OpenLog, TAG, "请求是否成功" + result.isSuccess());
            return result;
        });

坑三、Retrofit方式

 网络接口部分改动如下(加粗部分是不同之处):

情况一、
    public interface ModulesList {
        @FormUrlEncoded // 使用@Body时,就不要使用@FormUrlEncoded,否则会报错!
        @POST("cms/modules")
        Call<ModuleBean> getModulesList(@Field("appId") String appId, @Field("clientId") String clientId, @Field("token") String token, @Field("tags[]") String tags);
    }

情况二、

 public interface ModulesList {
        @FormUrlEncoded // 使用@Body时,就不要使用@FormUrlEncoded,否则会报错!
        @POST("cms/modules")
        Call<ModuleBean> getModulesList(@Field("appId") String appId, @Field("clientId") String clientId, @Field("token") String token, @Field("tags") String[] tags);
    }

情况三、

public interface ModulesList {
        @FormUrlEncoded // 使用@Body时,就不要使用@FormUrlEncoded,否则会报错!
        @POST("cms/modules")
        Call<ModuleBean> getModulesList(@Field("data") String data);
    }

总结:

遇到问题不可怕,多去网上找找,多想想,总能解决的!

走一段令人留恋的路,做一个不负自己的人。——共勉

猜你喜欢

转载自blog.csdn.net/Agg_bin/article/details/81705512