我的 API 基本网址是:
https://locodealapi.herokuapp.com/api/deals
在邮递员中传递以下标头,效果很好。
x-access-token:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoxLCJ1c2VyX25hbWUiOiJkZWFsQWRtaW4iLCJ1c2VyX3Bhc3N3b3JkIjoiY2U5MDZkNDkzMWY3NmFhZWFmZTViNjM0YTg3Y2RkYzQ4YjMzNmUzYmVlZDU1N2ZhZTI0YzMxZTY3YmQyN2NhZDg4NDJmNzJlNTJlNGUyODc5ZWVkODY1MDljYzY5ODJlNDYwMjU0Mzk4ODQzMTljMTQxMGMwOTcxNGU0Y2MxMDNiMDQwYjkwOTQ1OTMyMjYwMGI1MjgwMmRkOTc2YTE4OGE5MTZiMWU4ZmU1YmY1ZWZiNTlkYjc2NDhmMjQxOTg0ODdiMWE5OGVhMjg2ZWZjZDI1M2Y5ZWUxNTQ0OTI3ODZiYjY3NzNmZTZjNGY3ODhmNzJjMzQ0NTEwMzg2NjkyNzIzMjNiMjZmYjFhMmUzYjE0ZTQ0Nzc0NzljMTExMzNkZjIwMmE3ODY2OGIxZjdiY2NlZjQ5NTM0YTJhYzk5N2Y0MTc0NzU2OTkwOTg5NjQ1YzljNWQxYTZkYmUyZTI1ZjFlNDE3YjdhYWI1N2QyZGJhNmVmOWEwNzk5N2Q5ZDcyNTgxMzUyYzc4Y2IxY2RiMDRmNDFkZjMwNzdjYzAxMGM2YmYzYWMzOTQ5OTJjN2Y3ZGVmYmE3YzllZWMxMzI5ODhlODBiM2RmYWE5NTVhMzE3NTgxNThiZjYxYjYyN2U4Y2UzOTg2NmRkODk2YzBlZDkzNDJlMzhiMzhkM2Q0ZTY0YWIzZWIwNGU4YmU5MGQwNmM2NTg2OWYyNzZkMzgyOTU3MTFkODgyNjI4NGIxMjkzYzQ0ZGNjMWM3ZjU2YmE4OGM5MTkyNDMzZWY0YTcwZGE2NTkzMzAwZmUzMGMxYjkwOWY5YmJjMDhmY2M5Zjk3NjUwYmJkOTVhNzExNWVlOGY3MjI5N2Q4ZGY4MjZiMTk0MTBlZjQ0OWZkMTQ1NTg3Nzc2NjUxZDI5OGMyYzMwMTZiMDMxMGEwZjRlMWQ4NzgwZTExYmVkOTZhYzg3MDU2YzIwYWU4ODZiYjI3NGZkNGVhZGMzMjQ0ZjlmMmZkMGIyMGMzZTAyZjI1NGQ3OWYzYzhiM2FmZGJiM2UzYTM1YTA2MjNjMTQwY2JmNzMxZWMxYjE2Y2VmNmIwY2RhMjQ1YjkzZmY4NzQ1MGRjNWFhZDE2MzdkNTQ5ZjM5ZDkwZjk5MWFiNWMxNTcwNWExYWJjYWQxYzQyYjNmMTViN2Y5N2I0YTc1ZDA2YTgwYjkwOWI0ZDJlZjRiNWE0NzdhMTMzYWI0ODkwMmIyNWFiM2VmYTMzNDdjMDcxODQ4NmMwYmU2NGQxYzUxMjA1ZTMwYjU5NjY3Yjk5ZTVlYTdkZWNiMWE4MWRkNjcyYzEwMzU5YmM2NGNlZWI3ZTEyOWJlYjZjYWUzYTM0ZjM0M2NiYjk4NyIsImNyZWF0ZXRpbWUiOm51bGwsImZpcnN0X25hbWUiOm51bGwsImxhc3RfbmFtZSI6bnVsbCwiYWdlIjpudWxsLCJzZXgiOm51bGwsImRvYiI6bnVsbCwic3RhdHVzIjpudWxsLCJpdGVyYXRpb24iOjEwMDAwLCJ1c2VyX3R5cGUiOiIwIiwidXNlcl9pbWFnZSI6bnVsbCwic2FsdCI6Ikh1dm9VQ3FRak81Mi9BbkJIdmp2MldEMERod2JmM0R4ZXV6ZWJMSlFYK3hZTUptMmRJSUw3VFYvcnFVVXFVNUpmRlY0dHhkMHNCcXhLbnVNakU2YlNzVnpaQ0dWVXg3YmY4MGNubTR5WnB5OElEUWowY1crTXhCUXdvMFNja2UzT0FnVk4zd2pnNmlxSVk3VnJwRmw1WTNLRzFwY1NMelZjREJiME9XdXdjcz0iLCJpYXQiOjE1MTAxMjY1OTUsImV4cCI6MTUxODc2NjU5NX0.5XFJnJqTsfID9uqOwkNf46oraj9jDxic7qNSqBdunD0
在改造界面中,我有以下内容,但收到 400 错误请求
@POST("api/deals")
Call<ResponseBody> deals(@Header("x-access-token") String x_access_token)
调用代码:
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://locodealapi.herokuapp.com")
.addConverterFactory(GsonConverterFactory.create())
.client(httpClient.build())
.build();
AppRestAPI client = retrofit.create(AppRestAPI.class);
Call<ResponseBody> call1 = client.deals(
token
);
call1.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
Log.i(TAG, "The response is " + response.message());
Log.i(TAG, "The response is " + response.body());
try {
Log.i(TAG, "The response is " + response.errorBody().string());
if (response.code() == 400) {
Log.v("Error code 400",response.errorBody().string());
}
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
Log.e(TAG, "onFailure: Failed", t);
}
});
OKHTTP日志拦截器
11-21 21:14:30.939 3253-3342/? D/OkHttp: --> POST https://locodealapi.herokuapp.com/api/deals
11-21 21:14:30.939 3253-3342/? D/OkHttp: Content-Length: 0
11-21 21:14:30.940 3253-3342/? D/OkHttp: x-access-token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoyNSwidXNlcl9uYW1lIj....
11-21 21:14:30.942 3253-3342/? D/OkHttp: --> END POST (0-byte body)
11-21 21:14:34.188 3253-3342/? D/OkHttp: <-- 400 Bad Request https://locodealapi.herokuapp.com/api/deals (3246ms)
11-21 21:14:34.189 3253-3342/? D/OkHttp: Connection: close
11-21 21:14:34.189 3253-3342/? D/OkHttp: Server: Cowboy
11-21 21:14:34.189 3253-3342/? D/OkHttp: Date: Tue, 21 Nov 2017 15:29:33 GMT
11-21 21:14:34.190 3253-3342/? D/OkHttp: Content-Length: 0
11-21 21:14:34.191 3253-3342/? D/OkHttp: <-- END HTTP (0-byte body)
11-21 21:14:34.196 3253-3253/? I/BaseDrawerActivity: The response is Bad Request
11-21 21:14:34.196 3253-3253/? I/BaseDrawerActivity: The response is null
11-21 21:14:34.196 3253-3253/? I/BaseDrawerActivity: The response is
注意: 相同的代码在本地 Nodejs 服务器上运行良好(仅限 http)
1.首先你的 api 是 GET 方法,所以使用 @GET 而不是 @POST
第二次尝试在改造中更改 url 基本 url .baseUrl("https://locodealapi.herokuapp.com") 到 .baseUrl("https://locodealapi.herokuapp.com/") 这会起作用。或在评论中留下您的问题 2.这是示例代码
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient okHttpClient = new OkHttpClient.Builder().addInterceptor(
new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException{
Request original = chain.request();
// Request customization: add request headers
Request.Builder requestBuilder =original.newBuilder().
method(original.method(), original.body());
Request request = requestBuilder.build();
return chain.proceed(request);
}
})
.addInterceptor(interceptor).connectTimeout(60,TimeUnit.SECONDS).readTimeout(60, TimeUnit.SECONDS).build();
Retrofit retrofit = new Retrofit.Builder().baseUrl("https://locodealapi.herokuapp.com/")
.addConverterFactory(GsonConverterFactory.create())
.client(okHttpClient).build();
UserApi userApi = retrofit.create(UserApi.class);
Call<ResponseBody> call = userApi.deals("your token");
call.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call,retrofit2.Response<ResponseBody> response) {
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {}
});
}
@GET(“api/交易”) 调用 deal(@Header("x-access-token") String x_access_token);
今天的问候!
试试这个:
@FormUrlEncoded
@POST("/api/deals")
Call<ResponseBody> deals(@Header("x-access-token") String x_access_token, @Field("<parameter_name>") String parameter);
调用api如下:
Call<ResponseBody> call = client.deals(token,"<parameter>");
在这里,我假设 API 有一个参数,可以作为 deal() 方法中的第二个参数传递。您可以传递多个参数作为方法的参数。
请参阅以下链接了解更多详情: https://futurestud.io/tutorials/retrofit-send-data-form-urlencoded
我希望这能解决您的问题。如果没有,请提供您要调用的 API 的完整详细信息。
A
400 response
表示您的请求与服务器之间存在分歧,但请求已创建、发送,并且响应已解析。这意味着 Retrofit
工作正常。您可以使用 OkHttp 的日志拦截器来记录原始请求并将其与服务器期望的内容进行比较。
您的
Response
尺寸约为 5.96 MB
。这反应太大了。您可以实现分页或类似的分解数据的方法,而不是在单个响应中接收这么多数据。这可能是原因之一。
//Your Main connection Class
public class ApiClient {
public static final int DEFAULT_TIMEOUT_SEC = 90;
public static OkHttpClient client;
private static Retrofit retrofit = null;
public static Retrofit getClient() {
OkHttpClient.Builder httpClient = new OkHttpClient.Builder()
.connectTimeout(DEFAULT_TIMEOUT_SEC, TimeUnit.SECONDS)
.readTimeout(DEFAULT_TIMEOUT_SEC, TimeUnit.SECONDS)
.writeTimeout(DEFAULT_TIMEOUT_SEC, TimeUnit.SECONDS);
httpClient.addInterceptor(new Interceptor() {
@Override
public Response intercept(Interceptor.Chain chain) throws IOException {
Request original = chain.request();
System.out.println("API_KEY"+PrefManager.getActiveInstance(RecrouteCandidateApplication.getsCurrentContext()).getDeviceToken());
Request request = original.newBuilder()
.header("x-access-token",YOUR_ACCESS_TOKEN"")
.method(original.method(), original.body())
.build();
return chain.proceed(request);
}
});
//For logging the call on Logcat
HttpLoggingInterceptor interceptor1 = new HttpLoggingInterceptor();
interceptor1.setLevel(HttpLoggingInterceptor.Level.BODY);
httpClient.addInterceptor(interceptor1);
client = httpClient.build();
if (retrofit == null) {
retrofit = new Retrofit.Builder()
.baseUrl(AppConstants.BASE_URL)
.client(client)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return retrofit;
}
在您的班级中使用,这将像这样启动连接
ApiInterface apiService =
ApiClient.getClient().create(ApiInterface.class);
这将是你的 Api 接口
public interface ApiInterface {
@POST("Your url here")
Call<JsonObject> sampleMethod();
/*For non-empty body use this*/
//Call<JsonObject> getSignUpResponse(@Body JsonObject register);
//For form data use this
@FormUrlEncoded
@POST("Your url here")
Call<String> sampleMethod1(@Field(value= "param1_key", encoded = true) String param1_value);
}
对 json 进行这样的调用
JsonObject obj= new JsonObject();
obj.addProperty("key1","keyvalue");
Call<JsonObject> call = apiService.sample1(obj);
call.enqueue(new Callback<JsonObject>() {
@Override
public void onResponse(Call<JsonObject> call, Response<JsonObject> response) {
if (response.body().get("status").getAsString().equals("1")) {
Toast.makeText(context, response.body().get("msg").getAsString(), Toast.LENGTH_LONG).show();
} else {
Toast.makeText(context, response.body().get("msg").getAsString(), Toast.LENGTH_LONG).show();
}
}
@Override
public void onFailure(Call<JsonObject> call, Throwable t) {
Toast.makeText(context, AppConstants.NO_DATA_AVAILABLE, Toast.LENGTH_LONG).show();
}
});
对我来说,问题是因为我在 Gson 构建器中有这一行:
.excludeFieldsWithoutExposeAnnotation()
使用上面的行,如果模型类中未使用
@Exposed
注释进行注释,则在改造中作为主体发送的所有字段都将被忽略。
删除.excludeFieldsWithoutExposeAnnotation()
解决了我的问题。
要处理响应中的 400 Bad Request 错误,请使用以下代码。
if (response.isSuccessful()) {
if (response.body().getStatus().equals(1)) {
progressBar.setVisibility(View.GONE);
Toast.makeText(UploadPDFActivity.this, "Success",
Toast.LENGTH_SHORT).show();
}
} else {
int statusCode = response.code();
Log.e("hello 4001", "else condition");
if (statusCode == 400) {
progressBar.setVisibility(View.GONE);
if (!response.isSuccessful()) {
JSONObject jsonObject = null;
try {
jsonObject = new JSONObject(response.errorBody().string());
String entityId = jsonObject.getString("entity_id");
String errorMessage = jsonObject.getString("message");
String errorStatus = jsonObject.getString("status");
Log.e("hello entityId", entityId);
Log.e("hello errorMessage", errorMessage);
Log.e("hello errorStatus", errorStatus);
Toast.makeText(UploadPDFActivity.this, errorMessage, Toast.LENGTH_SHORT).show();
} catch (JSONException | IOException e) {
e.printStackTrace();
}
}
}
else {
// Handle other error cases
}
}
}