2014-11-02 2 views
0

Я разрабатываю клиент для отдыха с использованием модификации. Остальной сервер использует oauth как аутентификацию. Для этой задачи мне не нужно заботиться о истечении срока действия маркера. Поэтому в основном я сначала делаю запрос на токен, а затем добавляю его ко всем последующим вызовам. На данный момент я использую два класса. Один, чтобы получить токен доступа, а другой - для всего остального. Я думаю, что я хотел бы объединить эти два ... но я не уверен, как это сделать.Решения клиента о решении клиента

Первый класс имеет только один метод, который использует имя пользователя и пароль, а также интерфейс обратной перестройки. Мне нравится простота обратного вызова, но хотелось бы как-то абстрагировать его, чтобы я мог легко перейти от переоснащения к чему-то еще, если понадобится.

public class RequestAccessToken implements IRequestAccessToken { 
    private String username; 
    private String password; 

    private IRestAPI client; 


    public RequestAccessToken() 
    { 
     RestAdapter restAdapter = new RestAdapter.Builder() 
       .setEndpoint(Config.ENDPOINT) 
       .build(); 
     client = restAdapter.create(IRestAPI.class); 
    } 

    @Override 
    public void requestAccessToken(String username, String password, Callback callback) { 
     String grantType = Config.grantType; 
     String clientId = Config.clientId; 
     String clientSecret = Config.clientSecret; 

     client.getAccessToken(grantType, username, password, clientId, clientSecret, callback); 
    } 
} 

Второй класс принимает токен доступа как аргумент конструктора и добавляет его ко всем HTTP-запросам.

public class RestClient implements IRestClient { 
    private static final String TAG = RestClient.class.getSimpleName(); 
    private IRestAPI client; 

    public RestClient(final String accessToken) 
    { 
     RequestInterceptor requestInterceptor = new RequestInterceptor() 
     { 
      @Override 
      public void intercept(RequestFacade request) { 
       request.addHeader("Authorization", "Bearer " + accessToken); 
      } 
     }; 

     RestAdapter restAdapter = new RestAdapter.Builder() 
       .setEndpoint(Config.ENDPOINT) 
       .setRequestInterceptor(requestInterceptor) 
       .build(); 
     client = restAdapter.create(IRestAPI.class); 
    } 

    @Override 
    public List<User> requestUsers() { 
     return client.requestUsers(); 
    } 

    @Override 
    public List<Soemthing> requestSomething() { 
     return client.requestSomething(); 
    } 

    @Override 
    public List<SoemthingElse> requestSomethingElse() { 
     return client.requestSomethingElse(); 
    } 
} 

Мне бы очень понравился ввод и предложения о том, как это сделать лучше и, возможно, объединить два класса. Я думаю, что метод requestAccessToken RequestAccessToken является статическим членом класса RestClient. По крайней мере, это объединило бы два класса. Но я использую фабрику для создания RestClient, и если я объявляю статический метод, который я использую на протяжении всего моего кода, я получаю тугое соединение ... Предложения?

ответ

0

После обсуждения этого в другом месте я придумал следующий код.

public class RestClient implements IRestClient { 
    private static final String TAG = RestClient.class.getSimpleName(); 
    private IRestAPI client; 
    private String username; 
    private String password; 
    private RequestAccessToken requestAccessToken; 
    private Access access; 

    private static RestClient singleton; 

    // TODO: use Dagger 
    public static RestClient getInstance() 
    { 
     if(singleton == null) 
     { 
      singleton = new RestClient(); 
     } 
     return singleton; 
    } 

    /** 
    * Access declared as private to prevent instantiation outside of this class. 
    */ 
    private RestClient() 
    { 
     requestAccessToken = new RequestAccessToken(); 
    } 

    /** 
    * Request an access token. 
    * 
    * @return A string containing the access token 
    */ 
    public String requestAccessToken(String username, String password) 
    { 
     this.username = username; 
     this.password = password; 
     this.access = requestAccessToken.requestAccessToken(username, password); 
     return this.access.getAccess_token(); 
    } 

    /** 
    * Wrapper for {@link #requestAccessToken(String, String) requestAccessToken} 
    * @return 
    */ 
    public String requestAccessToken() 
    { 
     if(username == null || password == null) { 
      throw new IllegalArgumentException("missing user/pass"); 
     } 
     return requestAccessToken(username, password); 
    } 

    /** 
    * Eventually we want to look at Access.getExpires_in() and return weather or not the token is 
    * expired. 
    * 
    * @return value indicating weather or not the token is expired. 
    */ 
    public boolean isAccessTokenExpired() 
    { 
     return false; 
    } 

    /** 
    * Return an instance of a rest client with a valid access token. 
    * @return 
    */ 
    private IRestAPI getClient() 
    { 
     if(access == null) 
     { 
      requestAccessToken(); 
     } 
     if(isAccessTokenExpired()) 
     { 
      // Refresh token 
     } 
     if(client == null) { 
      RequestInterceptor requestInterceptor = new RequestInterceptor() { 
       @Override 
       public void intercept(RequestFacade request) { 
        request.addHeader("Authorization", "Bearer " + access.getAccess_token()); 
       } 
      }; 

      RestAdapter restAdapter = new RestAdapter.Builder() 
        .setEndpoint(Config.ENDPOINT) 
        .setLogLevel(RestAdapter.LogLevel.FULL) 
        .setRequestInterceptor(requestInterceptor) 
        .build(); 
      client = restAdapter.create(IRestAPI.class); 
     } 
     return client; 
    } 

    /** 
    * Login to the api and get a access token. 
    * 
    * @param username 
    * @param password 
    */ 
    @Override 
    public void login(String username, String password) 
    { 
     Log.d(TAG, "login"); 
     requestAccessToken(username, password); 
    } 

    /** 
    * Request a list of organizations. 
    * @return List of Organizations. 
    */ 
    @Override 
    public List<Organization> requestOrganizations() { 
     Log.d(TAG, "requestOrganizations"); 
     // TODO: error handling 
     // TODO: caching... which isn't http 
     return getClient().requestOrganizations(); 
    } 

    // Add more api requests here 

} 
+0

Естественно, этого недостаточно, чтобы посмотреть дату истечения срока действия токена доступа. Класс должен обрабатывать сообщение об ошибке, возвращенное с сервера, в случае, если токен истек ... но это не так. – user672009

Смежные вопросы