2017-03-21 1 views
3

서버에 액세스하기 위해 POST 요청을 사용했으며 서버에서 데이터를 가져 오는 동안 서버에 데이터를 보내지 마십시오.Retrofit + Okhttp.HTTP 504 요청할 수없는 요청 (캐시 된 경우에만)

@POST("Index/getListShopsInfo") Observable<ShopList> getListShopsInfo();

와 나는 내 데이터에 대한 로컬 캐시를 추가 할.

public class CacheInterceptor implements Interceptor { 

    private Context mContext; 

    public CacheInterceptor(Context context) { 
     mContext = context; 
    } 

    @Override 
    public Response intercept(Chain chain) throws IOException { 
     Request request = chain.request(); 
     boolean netAvailable = AppUtils.isNetworkAvailable(mContext); 
     if (netAvailable) { 
      request = request.newBuilder() 
       .cacheControl(CacheControl.FORCE_NETWORK) 
       .build(); 
     } else { 
     request = request.newBuilder() 
      .cacheControl(CacheControl.FORCE_CACHE) 
      .build(); 
     } 
     Response response = chain.proceed(request); 
     if (netAvailable) { 
      response = response.newBuilder() 
       .removeHeader("Pragma") 
       .header("Cache-Control", "public, max-age=" + 60 * 60) 
       .build(); 
     } else { 
      response = response.newBuilder() 
       .removeHeader("Pragma") 
       .header("Cache-Control", "public, only-if-cached, max-stale=" + 7 * 24 * 60 * 60) 
       .build(); 
     } 
     return response; 
    } 
} 


File cacheFile = new File(AppUtils.getDiskCacheDir(getContext()), "responses"); 
Cache cache = new Cache(cacheFile, App.DEFAULT_DIR_CACHE); 
OkHttpClient client = new OkHttpClient().newBuilder() 
    .addInterceptor(new CacheInterceptor(getContext())) 
    .retryOnConnectionFailure(true) 
    .connectTimeout(15, TimeUnit.SECONDS) 
    .cache(cache) 
    .build();` 

mRetrofit = new Retrofit.Builder() 
    .baseUrl(App.LOGINURL) 
    .client(client) 
    .addConverterFactory(GsonConverterFactory.create()) 
    .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) 
    .build(); 

네트워크에 연결되면 서버에 액세스 할 수 있지만 네트워크가 연결되어 있지 않으면 내 게시물이 가로 채기됩니다. 나는 로컬 캐시 경로를 확인하신 후

HTTP 504 시켰음 요청 (전용 경우-캐시) 그리고 내가 내장 된 "응답"폴더가 않습니다 그리고 그것은 잘못된를 기록합니다

enter image description here

그리고 나는 그것을 해결하는 방법을 알고하지 않습니다 거기에 내가 텍스트 형식에서 엽니 다 안들어에서 "저널"라는 이름의 파일은이 비슷하다.

누구든지 나를 도울 수 있기를 바랍니다.

+0

그런데 POST 요청을 GET으로 변경했습니다. 응답 본문의 NULL이며 응답 메시지의 "만족할 수없는 요청 (유일한 경우)"입니다. –

답변

5

나는 그것을 몇일 동안 찾아서 해결책을 찾았습니다.

FIRST.PET 요청을 GET으로 변경하십시오.

@GET("Index/getListShopsInfo") Call<ShopList> getListShopsInfo();

SECOND.Change Inteceptor.

private final Interceptor REWRITE_RESPONSE_INTERCEPTOR = new Interceptor() { 
    @Override 
    public okhttp3.Response intercept(Chain chain) throws IOException { 
     okhttp3.Response originalResponse = chain.proceed(chain.request()); 
     String cacheControl = originalResponse.header("Cache-Control"); 
     if (cacheControl == null || cacheControl.contains("no-store") || cacheControl.contains("no-cache") || 
       cacheControl.contains("must-revalidate") || cacheControl.contains("max-age=0")) { 
      return originalResponse.newBuilder() 
        .removeHeader("Pragma") 
        .header("Cache-Control", "public, max-age=" + 5000) 
        .build(); 
     } else { 
      return originalResponse; 
     } 
    } 
}; 

private final Interceptor REWRITE_RESPONSE_INTERCEPTOR_OFFLINE = new Interceptor() { 
    @Override 
    public okhttp3.Response intercept(Chain chain) throws IOException { 
     Request request = chain.request(); 
     if (!AppUtils.isNetworkAvailable(getContext())) { 
      request = request.newBuilder() 
        .removeHeader("Pragma") 
        .header("Cache-Control", "public, only-if-cached") 
        .build(); 
     } 
     return chain.proceed(request); 
    } 
}; 

THIRD.the okhttpClient.

File cacheFile = new File(AppUtils.getDiskCacheDir(getContext()), "FuckYouSecondDad"); 
    Cache cache = new Cache(cacheFile, App.DEFAULT_DIR_CACHE); 
    OkHttpClient client = new OkHttpClient().newBuilder() 
      .cache(cache) 
      .addNetworkInterceptor(REWRITE_RESPONSE_INTERCEPTOR) 
      .addInterceptor(REWRITE_RESPONSE_INTERCEPTOR_OFFLINE) 
      .build(); 

FORTH.the 개장.

:

enter image description here

그리고 모두의 가장 중요한,이를 추가하는 것을 잊지 마세요 : 인터넷이 연결되어있을 때

mRetrofit = new Retrofit.Builder() 
      .baseUrl(App.LOGINURL) 
      .client(mClient) 
      .addConverterFactory(GsonConverterFactory.create()) 
      .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) 
      .build(); 

지금, 나는 cache.It이 같다 있어요

.removeHeader("Pragma") 

또는 504 오류가 다시 발생합니다.

+0

나는 똑같은 해결책을 따라 왔지만, 여전히 나에게 504 Unsatisfiable Request (캐시의 경우 만) 오류를 준다. 너 내가 뭘하는거야? – user2498079

+0

테스트 컴퓨터에서 파일 관리자를 확인하십시오. 업로드 한 그림과 같은 캐시가 있습니까? –

+0

504는 인터셉터가 로컬 파일에서 캐시를 사용해야하지만 캐시를 찾지 못했음을 의미하는 것으로 알고 있습니다. 폴더를 만들거나 캐시를 가지고 있어야합니다. –

관련 문제