2014-11-01 2 views
4

다음과 같은 클래스에서 Retrofit 코드를 래핑했습니다. 그것이 게시하는 코드에서 명확하지 않다면 OAuth로 편안한 서비스와 상호 작용합니다.개조 오류 처리

오류 처리를 수행하는 좋은 방법은 무엇입니까? REST 서버는 json 형식으로 오류 메시지를 리턴합니다. 내 수업에서 몇 가지 예외를 던져서 그 메시지에 대해 행동하고 싶습니다. 나는 아래와 같은 것을하려고 노력하고있다. 그러나이 좋은 디자인입니까? 믹싱 콜백과 예외 던지는 것이 좋은 생각입니까? 더 좋은 방법이 있습니까?

아래의 접근 방식을 통해 사용자 정의 예외 내에서 i18l 메시지를 가져와 사용자에게 토스트 할 수 있습니다.

public class RestClient implements IRestClient { 
    private IRestAPI api; 

    /** 
    * 
    * @param accessToken 
    */ 
    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(); 
     api = restAdapter.create(IRestAPI.class); 
    } 

    @Override 
    public void requestSomething(final Callback callback) { 
     api.getSomething(new Callback<Something>() { 
      @Override 
      public void success(Something something, Response response) { 
       callback.success(something, response); 
      } 

      @Override 
      public void failure(RetrofitError error) { 
       if(error.getMessage().getId().euqals(ACCESS_TOKEN_EXPIRED)) 
       { 
        throw new AccessTokenExpired(); 
       } 
       else if(error.getMessage().getId().euqals(USER_NOT_FOUND)) 
       { 
        throw new UsernamePasswordNotFound(); 
       } 
       else // something else happened... 
       { 
        throw error; 
       } 
      } 
     }); 
    } 

    @Override 
    public void deleteSomething(final Callback callback) { 
     api.deleteSomething(new Callback<Something>() { 
      @Override 
      public void success(Something something, Response response) { 
       callback.success(something, response); 
      } 

      @Override 
      public void failure(RetrofitError error) { 
       if(error.getMessage().getId().euqals(SOMETHING_NOT_FOUND)) 
       { 
        ... 
        ... 
        Different exceptions 
       } 
       ... 
      } 
     }); 
    } 

} 

당연히 나는 성공 메소드로 내 자신 만의 콜백 인터페이스를 만들어야 할 것입니다.

+1

RestAdfit Builder에서 항상 Retrofit의 ErrorHandler를 사용할 수 있습니다. http://square.github.io/retrofit/javadoc/retrofit/ErrorHandler.html – daentech

답변

8

당신이 RestAdapter를 빌드 할 때, 당신은 사용자 정의 예외에게 매핑하는 error handler를 제공 할 수 있습니다, 그것은 아무것도에 Callback<T>에서 failure에 대한 호출 4XX/5XX를 무시합니다.

public class Scratch { 
    public static void main(String[] args) { 
     Endpoints e = new RestAdapter.Builder() 
       .setEndpoint("http://google.com") 
       .setLogLevel(RestAdapter.LogLevel.FULL) 
       .setErrorHandler(new ErrorHandler() { 
        @Override 
        public Throwable handleError(RetrofitError cause) { 
         switch (cause.getResponse().getStatus()) { 
          case 400: 
           /* Handle the expected body format */ 
           cause.getBody(); 
           throw new RuntimeException("Bad Request"); 
          default: 
           /* Things and stuff */ 
           throw new RuntimeException(""); 
         } 
        } 
       }) 
       .build() 
       .create(Endpoints.class); 

     e.getGoogle(new Callback<Response>() { 
      @Override 
      public void success(Response response, Response response2) { 
       System.out.println("Got it"); 
      } 

      @Override 
      public void failure(RetrofitError error) { 
       System.err.println("This won't ever be seen due to the error handler."); 
      } 
     }); 
    } 

    private static interface Endpoints { 
     @GET("/foo/bar") 
     void getGoogle(Callback<Response> callback); 
    } 
} 

편집 : 정말 인위적인 예를 들어 그러나, 당신은 잠재적으로 당신이 시작하는 Callback 인터페이스를 사용 싶어 왜 큰 이유를 희생하고, 이렇게함으로써. 이것이 일반적인 사용 인 경우 동기화 호출을 사용하고 객체 유형을 반환하는 것이 더 적합 할 수 있습니다. 나는 당신의 사용이 그것이 필요하다고 말하는 것을 완전히 알지 못하지만, 그것이 더 적절할 것처럼 보입니다.

+0

그래,하지만 다른 방법에 대해 다른 예외를 원해 ... 아니면 적어도 내가 할 것 같아. 나는이 접근법에 대해 완전히 확신하지 못한다. createSomething 메서드가 있다고 가정 해보십시오. 그러면 AlreadyExistsException이 throw 될 수 있습니다. deleteSomething 메서드가 있으면 SomethingNotFoundException이 발생합니다 ... 이해가 되니? – user672009

+0

나는 정말로 당신이 적어도이 수준이 아니라고 생각하지 않습니다. 여러분이 소비하는 HTTP 서비스는 표준 오류 코드를 사용해야합니다 (또는 요청이 실패한 이유를 알려주는 표준을 가지고 있어야합니다). 따라서 답안의'switch' 예제에서 여러분의 주석을 템플릿으로 사용하면'ConflictException'에'409', 예외 코드로'NotFoundException'에'404'를 매핑 할 것입니다. 4xx/5xx를 제공하는 무언가를 호출 할 때 - 그것이 무엇인지에 관계없이 표준 예외가 다시 발생합니다. – nerdwaller

+0

부여 된, 부정적인 측면은 당신이 비동기 호출의 좋은 성격을 다른 코드로 던져서 희생시키는 것입니다. 만약 당신이 이것을 공통적 인 것으로 생각한다면 - 아마도'Callback' 인터페이스를 사용하면 귀하의 사용에 대한 잘못된 접근. – nerdwaller