用了接近两天终于完美找到方法!!!
话说,访问服务器一般用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);
}
总结:
遇到问题不可怕,多想想,多去网上找找,总能解决的!