Возникла проблема с Retrofit 2, не знаю, связано ли это с неправильной обработкой ответа сервера или с моим кодом.
ПОЛЕЗНАЯ ИНФОРМАЦИЯ
ApiUtils.getUserAPI(getApplicationContext());
Следующий код находится внутри getUserApi для создания правильного OkHttpClient
public static UserAPI getUserAPI(Context context) {
String baseUrl = context.getString(R.string.base_context);
if (gson == null) {
gson = new GsonBuilder()
.setLenient()
.create();
}
if (okHttpClient == null) {
okHttpClient = new OkHttpClient.Builder()
.connectTimeout(10, TimeUnit.SECONDS)
.writeTimeout(10, TimeUnit.SECONDS)
.readTimeout(10, TimeUnit.SECONDS)
.followRedirects(true)
.followSslRedirects(true)
.addInterceptor(new AddHeadersInterceptor())
.addInterceptor(new ReceivedCookiesInterceptor())
.build();
}
return new Retrofit.Builder().baseUrl(baseUrl).addConverterFactory(GsonConverterFactory.create(gson)).client(okHttpClient).build().create(UserAPI.class);
}
Два перехватчика добавляют несколько заголовков и cookie cookie сеанса ( У меня есть добавленные заголовки для имитации реального вызова
HttpUrl url = chain.request().url();
Request.Builder builder = chain.request().newBuilder();
builder.addHeader("accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
builder.addHeader("accept-language", "it-IT,it;q=0.9,en-US;q=0.8,en;q=0.7,es;q=0.6,fr;q=0.5,ar;q=0.4");
builder.addHeader("content-type", "application/x-www-form-urlencoded");
builder.addHeader("origin", "https://www.XXX.XX");
builder.addHeader("referer", url.toString());
builder.addHeader("User-Agent", USER_AGENT);
List<String> cookies = SessionData.getInstance().getCookies();
if (cookies != null && cookies.size() >= 1)
builder.addHeader("Cookie", cookies.get(0).split(";")[0] + ";");
return chain.proceed(builder.build());
Создание звонка
Call<ResponseBody> login = userAPI.login(user.getUserName(), user.getPassword());
Обработка ответа
login.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
if (response.isSuccessful()) {
try {
Document doc = Jsoup.parse(response.body().string());
if (doc.getElementsByClass("flash flash-error") != null && doc.getElementsByClass("flash flash-error").size() > 0) {
fullScreenOverlay.setVisibility(View.GONE);
Toast.makeText(getContext(), doc.getElementsByClass("flash flash-error").get(0).text(), Toast.LENGTH_LONG).show();
onLoginFail();
} else {
User user = ContentDeserializer.getInstance().parseNewUser(doc);
SessionData.getInstance().setUser(user );
onLoginDone(user );
}
} catch (IOException e) {
Toast.makeText(getContext(), getString(R.string.generic_error), Toast.LENGTH_LONG).show();
fullScreenOverlay.setVisibility(View.GONE);
}
} else {
call.cancel();
Toast.makeText(getContext(), response.errorBody().toString(), Toast.LENGTH_LONG).show();
fullScreenOverlay.setVisibility(View.GONE);
}
}
Поскольку нет общедоступного API для получения кода, мне нужно смоделировать вызов мобильного агента и проанализировать содержимое страницы для получения данных.
ПРОБЛЕМА
Проблема в том, что при медленном соединении (например, я могу воспроизвести принудительное соединение 2G), если
if (response.isSuccessful()) {
возвращает true, когда я анализирую данные в содержимом HTML, я обнаружил некоторый div с
<span class="bt-label__state" data-button-state="submiting"> **Connecting** <span class="bt-icon bt-icon--loader"></span> </span>
Если я переключаюсь на 4G или на рабочее соединение, проблема исчезает
Похоже, что моя страница не загружена, но обновление загружается при загрузке страницы. Проблема в том, что веб-страница дает мне действительные коды ответов (например, 200 или 302 - как видно из инструментов разработчика в chrome), или есть что-то, что я могу сделать?