2016-10-15 4 views
6

retrofit을 사용하여 Reddit 용 Android 클라이언트를 만듭니다. toke를 얻으려면 logcat에서 제대로 작동하지만 로그인 사용자의 정보를 얻으려고 할 때 "404 Not Found"가 표시됩니다. 여기 Android Retrofit2 reddit 404을 찾을 수 없음

D/OkHttp: --> POST https://oauth.reddit.com/api/v1/me http/1.1 
D/OkHttp: Content-Length: 0 
D/OkHttp: Authorization: bearer myToken 
D/OkHttp: User-Agent: MyRedditClient/0.1 by myusername 
D/OkHttp: --> END POST 
D/OkHttp: <-- 404 Not Found https://oauth.reddit.com/api/v1/me (677ms) 

내 코드입니다 :

import java.io.IOException; 

import okhttp3.Interceptor; 
import okhttp3.OkHttpClient; 
import okhttp3.Request; 
import okhttp3.Response; 
import okhttp3.logging.HttpLoggingInterceptor; 
import retrofit2.Retrofit; 
import retrofit2.converter.gson.GsonConverterFactory; 

public class ServiceAuthGenerator { 

    public static final String API_BASE_URL = "https://www.reddit.com/"; 

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

    private static Retrofit.Builder builder = 
      new Retrofit.Builder() 
        .baseUrl(API_BASE_URL) 
        .addConverterFactory(GsonConverterFactory.create()); 

    public static <S> S getTokenService(Class<S> serviceClass) { 
     return getTokenService(serviceClass, null, null); 
    } 

    public static <S> S getTokenService(Class<S> serviceClass, String username, String password) { 
     if (username != null && password != null) { 
      String credentials = username + ":" + password; 
      final String basic = 
        "Basic " + Base64.encodeToString(credentials.getBytes(), Base64.NO_WRAP); 

      httpClient.addInterceptor(new Interceptor() { 
       @Override 
       public Response intercept(Interceptor.Chain chain) throws IOException { 
        Request original = chain.request(); 

        Request.Builder requestBuilder = original.newBuilder() 
          .header("Authorization", basic) 
          .header("Accept", "application/json") 
          .method(original.method(), original.body()); 

        Request request = requestBuilder.build(); 
        return chain.proceed(request); 
       } 
      }); 
     } 

     HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(); 
     interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); 

     OkHttpClient client = httpClient.addInterceptor(interceptor).build(); 
     Retrofit retrofit = builder.client(client).build(); 
     return retrofit.create(serviceClass); 
    } 

} 

import java.io.IOException; 

import okhttp3.Interceptor; 
import okhttp3.OkHttpClient; 
import okhttp3.Request; 
import okhttp3.Response; 
import okhttp3.logging.HttpLoggingInterceptor; 
import retrofit2.Retrofit; 
import retrofit2.converter.gson.GsonConverterFactory; 

public class ServiceInfoGenerator { 

    public static final String API_BASE_URL = "https://oauth.reddit.com/"; 

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

    private static Retrofit.Builder builder = 
      new Retrofit.Builder() 
        .baseUrl(API_BASE_URL) 
        .addConverterFactory(GsonConverterFactory.create()); 

    public static <S> S retrieveInfoService(Class<S> serviceClass) { 
     return retrieveInfoService(serviceClass, null, null); 
    } 

    public static <S> S retrieveInfoService(Class<S> serviceClass, final String authToken, final String username) { 
     if (authToken != null && username != null) { 
      httpClient.addInterceptor(new Interceptor() { 
       @Override 
       public Response intercept(Chain chain) throws IOException { 
        Request original = chain.request(); 

        // Request customization: add request headers 
        Request.Builder requestBuilder = original.newBuilder() 
          .header("Authorization", " bearer "+authToken) 
          .header("User-Agent", "MyRedditClient/0.1 by "+username) 
          .method(original.method(), original.body()); 

        Request request = requestBuilder.build(); 
        return chain.proceed(request); 
       } 
      }); 
     } 

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

     OkHttpClient client = httpClient.addInterceptor(interceptor).build(); 
     try { 
      client.interceptors().add(new UserAgentInterceptor(username)); 
     } catch (Exception e){ 
      Log.i("ServiceInfoGenerator", "retrieveInfoService: "+e.getMessage()); 
     } 
     Retrofit retrofit = builder.client(client).build(); 
     return retrofit.create(serviceClass); 
    } 
} 

import java.util.Map; 

import retrofit2.Call; 
import retrofit2.http.Field; 
import retrofit2.http.FormUrlEncoded; 
import retrofit2.http.GET; 
import retrofit2.http.Headers; 
import retrofit2.http.POST; 
import retrofit2.http.QueryMap; 

public interface MyApiRetrofit { 

    @POST("/api/v1/access_token") 
    @FormUrlEncoded 
    Call<Authorize> accessToken(@Field(("grant_type")) String grantType, @Field(("username")) String username, @Field(("password")) String password); 

    @POST("/api/v1/me") 
    Call<Authorize> retrieveMyInfo(); 

} 

import android.os.AsyncTask; 
import android.util.Log; 

import com.havistudio.myreddit.api.Authorize; 
import com.havistudio.myreddit.api.MyApiRetrofit; 

import java.io.IOException; 

import retrofit2.Call; 
import retrofit2.Callback; 
import retrofit2.Response; 

public class TestAPITask2 extends AsyncTask<Void, Void, Void> { 

    private static final String TAG = "TestAPITask2"; 
    private String myAccessToken; 
    private String myRefreshToken; 

    @Override 
    protected Void doInBackground(Void... voids) { 

     MyApiRetrofit loginService = ServiceAuthGenerator.getTokenService(MyApiRetrofit.class, "client_id", "client_secret"); 
     Call<Authorize> call = loginService.accessToken("password", "myusername", "mypassword"); 
     call.enqueue(new Callback<Authorize>() { 
      @Override 
      public void onResponse(Call<Authorize> call, Response<Authorize> response) { 
       if (response.isSuccessful()) { 
        // user object available 
        Log.i(TAG, "isSuccessful"); 
        Authorize temp = response.body(); 
        myAccessToken = temp.getAccessToken(); 
        Log.i(TAG, temp.toString()); 

        MyApiRetrofit myInfoService = ServiceInfoGenerator.retrieveInfoService(MyApiRetrofit.class, myAccessToken, "myusername"); 
        Call<Authorize> call2 = myInfoService.retrieveMyInfo(); 
        try { 
         Authorize user = call2.execute().body(); 
        } catch (IOException e) { 
         e.printStackTrace(); 
        } 

       } else { 
        // error response, no access to resource? 
        Log.i(TAG, "error response"); 
       } 
      } 

      @Override 
      public void onFailure(Call<Authorize> call, Throwable t) { 
       // something went completely south (like no internet connection) 
       Log.d(TAG, t.getMessage()); 
      } 
     }); 


     return null; 
    } 


} 

나는이 here의 지침에 따라 오전 여기 내 로그 캣입니다. 내 개조 버전은 다음과 같습니다

compile 'com.squareup.retrofit2:retrofit:2.0.2' 
compile 'com.squareup.retrofit2:converter-gson:2.0.2' 
compile 'com.squareup.okhttp3:logging-interceptor:3.2.0' 

마지막 로그 :베이스의 URL이 될 수있는 가능한 원인

10-15 13:17:41.434 9968-9968 D/OkHttp: --> POST https://oauth.reddit.com/api/v1/me http/1.1 
10-15 13:17:41.434 9968-9968 D/OkHttp: Content-Length: 0 
10-15 13:17:41.434 9968-9968 D/OkHttp: Authorization: bearer tokenToken 
10-15 13:17:41.434 9968-9968 D/OkHttp: User-Agent: MyRedditClient/0.1 by myusername 
10-15 13:17:41.434 9968-9968 D/OkHttp: --> END POST (0-byte body) 
10-15 13:17:41.988 9968-9968 D/OkHttp: <-- 404 Not Found https://oauth.reddit.com/api/v1/me (553ms) 
10-15 13:17:41.988 9968-9968 D/OkHttp: Content-Type: application/json; charset=UTF-8 
10-15 13:17:41.988 9968-9968 D/OkHttp: x-frame-options: SAMEORIGIN 
10-15 13:17:41.988 9968-9968 D/OkHttp: x-content-type-options: nosniff 
10-15 13:17:41.988 9968-9968 D/OkHttp: x-xss-protection: 1; mode=block 
10-15 13:17:41.989 9968-9968 D/OkHttp: expires: -1 
10-15 13:17:41.989 9968-9968 D/OkHttp: cache-control: private, s-maxage=0, max-age=0, must-revalidate, max-age=0, must-revalidate 
10-15 13:17:41.990 9968-9968 D/OkHttp: x-ratelimit-remaining: 598.0 
10-15 13:17:41.990 9968-9968 D/OkHttp: x-ratelimit-used: 2 
10-15 13:17:41.990 9968-9968 D/OkHttp: x-ratelimit-reset: 136 
10-15 13:17:41.990 9968-9968 D/OkHttp: set-cookie: loid=Fsx2GnGYmufCQZ6cfT; Domain=reddit.com; Max-Age=63071999; Path=/; expires=Mon, 15-Oct-2018 10:17:44 GMT; secure 
10-15 13:17:41.991 9968-9968 D/OkHttp: set-cookie: loidcreated=2016-10-15T10%3A17%3A44.173Z; Domain=reddit.com; Max-Age=63071999; Path=/; expires=Mon, 15-Oct-2018 10:17:44 GMT; secure 
10-15 13:17:41.991 9968-9968 D/OkHttp: x-ua-compatible: IE=edge 
10-15 13:17:41.991 9968-9968 D/OkHttp: set-cookie: loid=Q52c9gouzuGGdg7UXW; Domain=reddit.com; Max-Age=63071999; Path=/; expires=Mon, 15-Oct-2018 10:17:44 GMT; secure 
10-15 13:17:41.991 9968-9968 D/OkHttp: set-cookie: loidcreated=2016-10-15T10%3A17%3A44.189Z; Domain=reddit.com; Max-Age=63071999; Path=/; expires=Mon, 15-Oct-2018 10:17:44 GMT; secure 
10-15 13:17:41.991 9968-9968 D/OkHttp: X-Moose: majestic 
10-15 13:17:41.991 9968-9968 D/OkHttp: Content-Length: 38 
10-15 13:17:41.992 9968-9968 D/OkHttp: Accept-Ranges: bytes 
10-15 13:17:41.992 9968-9968 D/OkHttp: Date: Sat, 15 Oct 2016 10:17:44 GMT 
10-15 13:17:41.992 9968-9968 D/OkHttp: Via: 1.1 varnish 
10-15 13:17:41.992 9968-9968 D/OkHttp: Connection: keep-alive 
10-15 13:17:41.992 9968-9968 D/OkHttp: X-Served-By: cache-ams4426-AMS 
10-15 13:17:41.992 9968-9968 D/OkHttp: X-Cache: MISS 
10-15 13:17:41.992 9968-9968 D/OkHttp: X-Cache-Hits: 0 
10-15 13:17:41.992 9968-9968 D/OkHttp: X-Timer: S1476526664.126987,VS0,VE109 
10-15 13:17:41.993 9968-9968 D/OkHttp: Server: snooserv 
10-15 13:17:42.002 9968-9968 D/OkHttp: {"message": "Not Found", "error": 404} 
10-15 13:17:42.002 9968-9968 D/OkHttp: <-- END HTTP (38-byte body) 

답변

0

마침내 내 해결책을 찾았습니다! 잘못된 grant_type으로 전화를 걸었습니다! 나는 그것을 바꾼다, 지금 그것이 일하고있다!

0

하나.

Retrofit 2에 따르면 기본 URL은 '/'로 끝나서는 안됩니다.

기본 URL에서 '/'을 제거하고 시도하십시오.

개조 1.9에서 제대로 작동했습니다.

건배 !!!

+0

"404 찾을 수 없음"오류가 표시되면서 제거되었습니다. – KostasC

+0

라이브러리를 사용하여 요청 로그를 공유하십시오. 'com.squareup.okhttp3 : logging-interceptor : 3.4.1' –

+0

헤더 정보와 함께 요청 및 응답을 제공합니다. 이 라이브러리 호출을 사용하려면 :: HttpLoggingInterceptor logging = new HttpLoggingInterceptor(); // 원하는 로그 수준을 설정하십시오. logging.setLevel (HttpLoggingInterceptor.Level.BODY); okHttpClientBuilder.interceptors(). add (logging); –

0

Retrofit 2.0이 Http Resolve를 사용하여 끝점의 URI 체계를 해결하는 방법 때문에이 http://hello.com과 같은 baseurl을 지정하고 끝점 URL을/world/foo로 지정하면 중단됩니다.

기본 URL http://hello.com/과 끝점 URL 인 world/foo를 사용해야합니다.

/이 차이를 만듭니다.

당신이 나를 알려 주시면 다른 해결 방법을 알려 드리겠습니다. Link

그리고 당신은이 문제를 확인할 수 있습니다 : 귀하의 문제는 동일이 문제로 생각 Link

+0

답장을 보내 주셔서 감사합니다. @ jamil-hasnine-tamim,하지만 이미 시도해 봤습니다! – KostasC

+0

작동하지 않았습니까? @KosrasC –

+0

아니요, 그렇지 않았습니다. 이제 "오류 403, 금지됨"이 표시됩니다. – KostasC

0

@POST("api/v1/me")

제거 첫 번째 문자의 URL에서 개조 2.0 "로 끝나야합니다 base을 필요"/ "때문에이/".. 나는 당신의 코드에서 다른 문제를 발견 할 수 없다. 당신은 어떤 null 값이있는 경우 헤더를 확인 또는 엔드 포인트 /api/v1/me 당신이 GET 요청을 사용해야합니다 자신의 documentation enpoint /api/v1/me에 대한에 따르면 POST 방법

@POST("/api/v1/me") 
Call<Authorize> retrieveMyInfo(); 

인을위한 API 링크를

1

귀하의 API 호출을 다시 확인해야합니다.

@GET("/api/v1/me") 
Call<Authorize> retrieveMyInfo(); 

는 그 솔루션을 테스트하지 않았지만 (파이썬) 문제를 해결 (404), as in another post의 원인이 될 것으로 보인다.

관련 문제