简体   繁体   中英

Retrofit2 response is bad request while with OkHttp is working fine

( Edit I added a small demonstration test)

I'm new to Retrofit . What I need to do is the retrieve XML file from a server and convert it to POJO. The problem is that everything work perfect with static files on my test server, but when I'm trying this on the real server, I can't make it work with Retrofit2 , but it do work when I just use directly with OkHttp , so something is wrong with the generated Request I guess.

Edit: I switched the code to use String converter to simply things, as the problem is exclusively with the response.

Here is my base implementation.

public interface ZedoClient {
@retrofit2.http.Headers({
        "User-Agent: Mozilla/5.0 (Linux; Android 5.1; Quattro_L50_HD LMY47D/Quattro_L50_HD)",
        "Cookie : ZCBC=1;FFcat=3533,3,90;FFad=0;FFMChanCap=5345280B3533,3#2605191|0,1#0,24:"
})
@GET("fns.vast")
Call<Vast> getVast(@QueryMap(encoded=true) Map<String, String> options);

I added two Interceptor in order to set the headers and the cookies : AddCookiesInterceptor.class

class AddCookiesInterceptor implements Interceptor {
    private final Headers headers;

    AddCookiesInterceptor(Headers headers) {
        this.headers = headers;
    }
    @Override
    public okhttp3.Response intercept(Chain chain) throws IOException {
        Request.Builder builder = chain.request().newBuilder();
        builder.headers(headers);
        return chain.proceed(builder.build());
    }
}

ReceivedCookiesInterceptor.class

class ReceivedCookiesInterceptor implements Interceptor {
    @Override
    public okhttp3.Response intercept(Chain chain) throws IOException {
        okhttp3.Response originalResponse = chain.proceed(chain.request());

        if (!originalResponse.headers("Set-Cookie").isEmpty()) {
            HashSet<String> cookies = new HashSet<>();
            for (String header : originalResponse.headers("Set-Cookie")) {
                cookies.add(header);
            }
        }
        return originalResponse;
    }
}

And here is the test I make that shows how with the raw OkHttp everything working as expected, but with retrofit2 it fail:

public static Vast test(String baseUrl, Map<String, String> queryParams, final Headers headers) {
    try {
        HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
        logging.setLevel(HttpLoggingInterceptor.Level.BODY);
        OkHttpClient httpClient = new OkHttpClient.Builder().addInterceptor(logging).build();
        Request.Builder request = new Request.Builder()
                .url("http://********/fns.vast?v=vast2&d=90&ct=mnf%3AKARBONN%5Emdn%3AQuattro_L50_HD%5Emdu%3AQuattro_L50_HD%5Etyp%3ASmartPhone%5Econ%3Awifi%5Eosn%3AAndroid%5Evsn%3A5.1%5Eosv%3A22%5Ecn%3AUS%5Elng%3Aen%5E&s=3&n=3533&c=3&z=0.4933822377892413");
        if (headers != null) {
            request.headers(headers);
        }
        okhttp3.Response oldRespnse = httpClient.newCall(request.build()).execute();
        System.out.println("successsForOkhttp: " + oldResponse.isSuccessful());
        OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder();
        if (headers != null) {
            clientBuilder.networkInterceptors().add(logging);
            clientBuilder.networkInterceptors().add(new AddCookiesInterceptor(headers));
            clientBuilder.networkInterceptors().add(new ReceivedCookiesInterceptor());
        }
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(baseUrl)
                .client(clientBuilder.build())
                .addConverterFactory(SimpleXmlConverterFactory.create())
                .build();

        ZedoClient client = retrofit.create(ZedoClient.class);
        Call<Vast> call = client.getVast(queryParams);
        Response<Vast> response = call.execute();
        System.out.println("successsForRetrofit: " + response.isSuccessful());
        if (response.isSuccessful()) {
            return response.body();
        } else {
            MyLog.e("error:" + response.raw().message());
            return null;
        }
    } catch (IOException e) {
        e.printStackTrace();
        return null;
    }

}

Here is the output:

I/System.out: successsForOkhttp: true
I/System.out: successsForRetrofit: false
I/System.out: error:Bad Request

As suggested, I added Logging-Interceptor for both, the OkHttp request and the Retrofit2 request, here is the output:

D/OkHttp: --> GET http://**********/fns.vast?v=vast2&d=90&ct=mnf%3AKARBONN%5Emdn%3AQuattro_L50_HD%5Emdu%3AQuattro_L50_HD%5Etyp%3ASmartPhone%5Econ%3Awifi%5Eosn%3AAndroid%5Evsn%3A5.1%5Eosv%3A22%5Ecn%3AUS%5Elng%3Aen%5E&s=3&n=3533&c=3&z=0.4933822377892413 http/1.1
D/OkHttp: User-Agent: Mozilla/5.0 (Linux; Android 5.1; Quattro_L50_HD LMY47D/Quattro_L50_HD)
D/OkHttp: Cookie: ZCBC=1;FFcat=3533,3,90;FFad=0;FFMChanCap=5345280B3533,3#2605191|0,1#0,24:
D/OkHttp: --> END GET
D/OkHttp: <-- 200 OK http://**********/fns.vast?v=vast2&d=90&ct=mnf%3AKARBONN%5Emdn%3AQuattro_L50_HD%5Emdu%3AQuattro_L50_HD%5Etyp%3ASmartPhone%5Econ%3Awifi%5Eosn%3AAndroid%5Evsn%3A5.1%5Eosv%3A22%5Ecn%3AUS%5Elng%3Aen%5E&s=3&n=3533&c=3&z=0.4933822377892413 (720ms)

D/OkHttp: --> GET http://**********/fns.vast?v=vast2&d=90&ct=mnf%3AKARBONN%5Emdn%3AQuattro_L50_HD%5Emdu%3AQuattro_L50_HD%5Etyp%3ASmartPhone%5Econ%3Awifi%5Eosn%3AAndroid%5Evsn%3A5.1%5Eosv%3A22%5Ecn%3AUS%5Elng%3Aen%5E&s=3&n=3533&c=3&z=0.4933822377892413 http/1.1
D/OkHttp: User-Agent: Mozilla/5.0 (Linux; Android 5.1; Quattro_L50_HD LMY47D/Quattro_L50_HD)
D/OkHttp: Cookie : ZCBC=1;FFcat=3533,3,90;FFad=0;FFMChanCap=5345280B3533,3#2605191|0,1#0,24:
D/OkHttp: Host: xp1.zedo.com
D/OkHttp: Connection: Keep-Alive
D/OkHttp: Accept-Encoding: gzip
D/OkHttp: --> END GET
D/OkHttp: <-- 400 Bad Request http://**********/fns.vast?v=vast2&d=90&ct=mnf%3AKARBONN%5Emdn%3AQuattro_L50_HD%5Emdu%3AQuattro_L50_HD%5Etyp%3ASmartPhone%5Econ%3Awifi%5Eosn%3AAndroid%5Evsn%3A5.1%5Eosv%3A22%5Ecn%3AUS%5Elng%3Aen%5E&s=3&n=3533&c=3&z=0.4933822377892413 (208ms)
D/OkHttp: Server: ******Host
D/OkHttp: Mime-Version: 1.0
D/OkHttp: Content-Type: text/html
D/OkHttp: Content-Length: 272
D/OkHttp: Expires: Sun, 19 Feb 2017 05:43:47 GMT
D/OkHttp: Date: Sun, 19 Feb 2017 05:43:47 GMT
D/OkHttp: Connection: close
D/OkHttp: <HTML><HEAD>
D/OkHttp: <TITLE>Invalid URL</TITLE>
D/OkHttp: </HEAD><BODY>
D/OkHttp: <H1>Invalid URL</H1>
D/OkHttp: The requested URL "http&#58;&#47;&#47;&#37;5bNo&#37;20Host&#37;5d&#47;jsc&#47;xp2&#47;fns&#46;vast&#63;", is invalid.<p>
D/OkHttp: Reference&#32;&#35;9&#46;756f87dd&#46;1487483027&#46;1f41287
 D/OkHttp: </BODY></HTML>

Althogth both calls use the same GET , the Retrofit2 call fails with 400. Probably something with the Headers or cookies, but I can't work it out.

I think it is better to enable logging in OkHttp and check that

  1. requested url is correct
  2. received data is correct too.

More info on how to enable OkHttp Loggin could be found here: https://github.com/square/okhttp/tree/master/okhttp-logging-interceptor

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM