改造2 - POST请求变得GET?

时间:2016-09-01 10:56:52

标签: android retrofit2

我的POST请求一直以GET&被API端点拒绝

MyService类

@FormUrlEncoded
@POST("api/users/")
Call<List<User>> getUsers(@FieldMap HashMap<String, String> parameters);

请求代码

Gson builder = new GsonBuilder().setLenient().create();
Retrofit client = new Retrofit.Builder()
        .baseUrl(Constants.API_ENDPOINT_TEST_URL)
        .addConverterFactory(GsonConverterFactory.create(builder))
        .build();
mApiService = client.create(MyService.class);
Call<List<User>> call = mApiService.getUsers(mParameters);
call.enqueue(new Callback<List<User>>() {
    @Override
    public void onResponse(Call<List<User>> call, Response<List<User>> response) {
        mResponse = response.body();
        mResponseObserver.onFinish(mResponse);
    }

    @Override
    public void onFailure(Call<List<User>> call, Throwable t) {
        mResponseObserver.onFailure();
    }
});

但服务器在GET请求表单中到达服务器时拒绝它!用调试器检查后,我看到了:

rawResponse.request.method = GET

以下是观察窗口的屏幕截图,显示了改造的请求对象:

screenshot

如您所见,请求方法为GET。但奇怪的部分在tag,它显示了一个POST方法的请求对象?

我在这里想念一下吗?

更新

我添加了日志拦截器&amp;这是日志:

D/OkHttp: --> POST http://***/api/users/ http/1.1
D/OkHttp: Content-Type: application/x-www-form-urlencoded
D/OkHttp: Content-Length: 56
D/OkHttp: --> END POST
D/OkHttp: <-- 200 OK https://***/api/users/ (388ms)
D/OkHttp: Date: Thu, 01 Sep 2016 11:50:23 GMT
D/OkHttp: Server: Apache
D/OkHttp: X-Powered-By: PHP/5.4.34
D/OkHttp: Cache-Control: max-age=2592000
D/OkHttp: Expires: Sat, 01 Oct 2016 11:50:23 GMT
D/OkHttp: Vary: Accept-Encoding
D/OkHttp: Content-Type: application/json; charset=UTF-8
D/OkHttp: Set-Cookie: SESSION_DEFAULT=***; expires=Sun, 04-Sep-2016 11:50:24 GMT; path=/; HttpOnly
D/OkHttp: Set-Cookie: COOKIE[***]=***; path=/; httponly
D/OkHttp: Connection: close
D/OkHttp: <-- END HTTP

看起来请求是POST。但是,服务器仍然响应错误消息,说请求方法是GET

嗯,我会再深入研究一下。

5 个答案:

答案 0 :(得分:4)

实际上,问题在于两个因素的结合:

  1. 提出了错误的请求协议(http而不是https)
  2. 服务器在错误的协议上回复了一个奇怪的消息:&#34;不支持GET&#34;。
  3. ANyway,感谢@nshmura为您的助手。

答案 1 :(得分:1)

我使用日志记录检查了您的程序,并确认已发送POST请求。 我建议你这样检查一下:

class TestClass {

    private void testRequest() {
        HashMap<String, String> mParameters = new HashMap<>();

        HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
        logging.setLevel(HttpLoggingInterceptor.Level.HEADERS);

        OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
        httpClient.addInterceptor(logging);  // <-- this is the important line!

        Gson builder = new GsonBuilder().setLenient().create();
        Retrofit client = new Retrofit.Builder()
                .baseUrl(Constants.API_ENDPOINT_TEST_URL)
                .addConverterFactory(GsonConverterFactory.create(builder))
                .client(httpClient.build())
                .build();
        MyService mApiService = client.create(MyService.class);
        Call<List<User>> call = mApiService.getUsers(mParameters);
        call.enqueue(new Callback<List<User>>() {
            @Override
            public void onResponse(Call<List<User>> call, Response<List<User>> response) {
            }

            @Override
            public void onFailure(Call<List<User>> call, Throwable t) {
            }
        });
    }


    interface MyService {
        @FormUrlEncoded
        @POST("api/users/")
        Call<List<User>> getUsers(@FieldMap HashMap<String, String> parameters);
    }

    class User {

    }

    class Constants {
        public static final String API_ENDPOINT_TEST_URL = "http://.........";
    }
}

这是请求日志:

 D/OkHttp: --> POST http://......... http/1.1
 D/OkHttp: Content-Type: application/x-www-form-urlencoded
 D/OkHttp: Content-Length: 0
 D/OkHttp: --> END POST

以下是回复:

 D/OkHttp: <-- 200 OK http://.............../ (167ms)
 D/OkHttp: Server: nginx
 D/OkHttp: Date: Thu, 01 Sep 2016 11:30:32 GMT
 D/OkHttp: Content-Type: text/html; charset=UTF-8
 D/OkHttp: Connection: close
....
 D/OkHttp: <-- END HTTP

答案 2 :(得分:0)

可以试试

  

@POST( “/ API /用户/”)

在“api”之前使用斜线?

使用Fiddler或smth。再次检查请求会很有帮助。

答案 3 :(得分:0)

我遇到了类似的问题。在我的情况下,我收到回复301,重定向和更改方法POST - &gt; GET。

首先,检查您的BASE_URL,它必须是&#34; h ttps://www.YourSite.com/" www - 非常重要。如果一切就绪并且问题仍然存在,那么您可以按照以下说明进行更改:

okhttp wikibased on this image,您需要更改以下内容:

...
OkHttpClient.Builder httpClient = new OkHttpClient.Builder();

final RequestBody requestBody = new FormBody.Builder().build();
httpClient.addNetworkInterceptor(new Interceptor() {
    @Override public Response intercept(Chain chain) throws IOException {
        Request request = chain.request();
        HttpUrl.Builder builder = request.url().newBuilder();

        HttpUrl url = builder.build();

        request = request.newBuilder()
                .url(url)
                .post(requestBody)
                .build();

        return chain.proceed(request);
    }
})

httpClient.addInterceptor(logging);
...

答案 4 :(得分:0)

这部分是正确的http客户端行为。根据{{​​3}}

  

如果收到307状态代码以响应GET或HEAD以外的请求,则用户代理不得自动重定向请求,除非用户可以确认,因为这可能会改变请求的条件。发出的。

有时候无法更改后端API。所以这里有一个解决方法,您可以添加到拦截器,以使用正确的方法手动重定向请求。

fun forceRedirectMethod(chain: Interceptor.Chain, originResponse: Response): Response {

    /* TODO
        one more request is made; disable followRedirect and make it manually?
      */
    if (originResponse.priorResponse()?.code() == 302) {
        val priorResponse: Response = originResponse.priorResponse() as Response
        val redirectRequest = priorResponse.request()
        val builder = originResponse.request().newBuilder()
                .method(redirectRequest.method(), redirectRequest.body())
        val newRequest = builder.build()
        return chain.proceed(newRequest)
    } else {
        return originResponse
    }
}