2017-02-13 17 views
9

(Edit я добавил небольшой демонстрационный тест)Retrofit2 ответ плохой запрос в то время как с OkHttp работает нормально

Я новичок в Retrofit. Что мне нужно сделать, это получить файл XML с сервера и преобразовать его в POJO. Проблема в том, что все работает отлично со статическими файлами на моем тестовом сервере, но когда я пытаюсь это сделать на реальном сервере, я не могу заставить его работать с Retrofit2, но он работает, когда я просто использую напрямую с OkHttp, поэтому что-то не так с созданным Request, я думаю.

Редактирование: я переключил код на использование преобразователя String на простые вещи, поскольку проблема связана исключительно с ответом.

Вот моя базовая реализация.

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); 

Я добавил два Interceptor для того, чтобы установить headers и 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; 
    } 
} 

А вот тест я делаю, что показывает, как с raw OkHttp все работает как ожидалось, но с retrofit2 это провал:

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; 
    } 

} 

Вот результат:

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

Как было предложено, я добавил Logging-Interceptor для обоих, OkHttp запрос и запрос Retrofit2, вот выход:

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 оба вызова используют одинаковые GET, Retrofit2 вызов завершается неудачно с 400. Возможно, что-то с Headers или куки-файлами, но я не могу это обработать.

+0

Можете ли вы показать полный ответ, который вы получаете, когда сделать запрос с дооснащения? Как было предложено ниже, для этого нужно использовать регистратор-перехватчик. – Divers

+1

Я думаю, что ответ сервера с '400: неправильный запрос', возможно, из-за неправильных заголовков или файлов cookie, которые вы передаете. – Divers

+0

Я знаю, что у меня 400, но с такими же заголовками у меня есть 200 хороших ответов с «OkHttp», так что именно то, что я хочу здесь решить – yshahak

ответ

1

Я думаю, что лучше включить ведение журнала в OkHttp и убедитесь, что

  1. запрошенный URL правильно
  2. полученные данные верны тоже.

Более подробную информацию о том, как включить OkHttp Логгина можно найти здесь: https://github.com/square/okhttp/tree/master/okhttp-logging-interceptor

+0

Первое спасибо. Я на самом деле уже реализовал регистрационный перехватчик, но не нашел того, что помогло мне решить проблему. Тот факт, что тот же самый «url' отлично работал при использовании только с« OkHttp », но не то, что я пробовал с помощью« retrofit », - это то, что я не могу скрыть. – yshahak