2016-07-01 8 views
0

私は、ResourceDelegateを使用してクライアントとサーバーの間のインターフェイスを共有するgwtpをRESTサービスで使用しています。瞬間、すべてうまく動作します。gwtp + RESTを使用してクライアントサイドで例外を処理する

私はクライアントサイドで例外処理を追加したいと思います。正式なドキュメント、carstoreサンプル、複数の投稿を読んだ後、私はまだフレームワークによって何が行われているのか、何が残っているのか疑問に思っています。だから、

、一瞬のために、サーバ側で、私が春を使用してREST簡単に、私のリソースは次のようになります。 インタフェース:

package ***.shared.rest; 

@Path("books") 
@Produces(MediaType.APPLICATION_JSON) 
@Consumes(MediaType.APPLICATION_JSON)  
public interface BookResources { 

    @GET 
    BookDTO getBook(@PathParam("id") Integer bookId) throws BookKeyDecodingException; 
} 

実装:

package ***.server.rest; 

@Component 
@Transactional(readOnly = true) 
public class BookResourcesImpl implements BookResources { 

    @Autowired 
    private BookService bookService; 

    @Autowired 
    private DtoFactory dtoFactory; 

    @Override 
    public BookDTO getBook(String bookKey) throws BookKeyDecodingException { 
     BookDTO bookDTO = BookKeyUtils.decode(supplementKey); 
     BookModel bookModel = dtoFactory.convertSupplementSuggestionDTO(suggestionDTO);     
     return bookService.getBook(bookDTO.getId());    
    } 
} 

BookKeyDecodingExceptionが入っています***。shared.exceptionパッケージであり、シリアライズ可能です。

クライアント側で

、私のプレゼンターは私resourceDelegateを使用します。

package ***.client.application.book; 

public class BookPresenter { 
    ... 

    private void fetch() { 
     clearSlot(SLOT_BOOK); 
     try { 
      bookDelegate.withCallback(new AsyncCallback<BookDTO>() { 

       @Override 
       public void onFailure(Throwable caught) { 
        // TODO Auto-generated catch block 
        **???** 
       } 

       @Override 
       public void onSuccess(BookDTO result) { 

        for (CahierDTO cahier : result.getPages()) { 
         ... 
        } 

       } 
      }).getBook(bookKey); 
     } catch (BookKeyDecodingException e) { 
      **???** 
     } 
    } 
} 

そして、私はまだ思ったんだけど:

  • それはcatch節に落ちるのでしょうか?
  • onFailure()メソッドには?
  • どれもありませんか?
  • サーバー側でエラー状態と一部の 例外シリアル化を管理するとしますか、これはすべて魔法ですか?今、私は解決策を得たが、私はそれが最高のものだか分からないが、私はそれが誰かを助けるかもしれないと思う...

    私はどの大きな魔法を見つける(多くなかったので

+0

補遺:この構成では、汎用的な例外ではなく、BookKeyDecodingException 1とONFAILURE()メソッドの例外の秋と... –

答えて

0

小さなもの):

  1. 私は、サーバー側で任意の例外を処理し、私はONFAILUREに落ちるとき、私は(、クライアント側では
  2. それをシリアル化)、私はキャッチパラメータを処理しませんがREST応答と私は逆シリアル化します
  3. 例外を含むErrorEventを発生させます。
  4. 例外をそのコンテキスト(@ProxyEventアノテーションを使用)として設定した後で、独自の場所を明らかにするErrorPresenterで処理します。
  5. 私はこのすべてはかなり複雑ですが、今私が働いて、一般的なシステムを持って、エラーのタイトルを取得するために、例外階層を訪問することができ、メッセージや詳細

をビジターパターンを使用して、ビューのコンテンツを作成サーバーとクライアントの間で既知の共有されている例外の王様です。私は、例外階層でのみ、コンテンツを表示するためのエラーコードに依存していません。

詳細

すべての私の例外は、共有パッケージに直列化可能であり、BookExceptionを拡張します。

1.例外サーバ側の処理。

package ***.server.rest; 

@Provider 
@Component 
public class BookExceptionHandler implements ExceptionMapper<BookException> { 

    @Override 
    public Response toResponse(BookException exception) { 
     return Response.serverError().tag(exception.getClass().getName()).entity(exception).build(); 
    } 
} 

例外クラス名は

...ので、私はそれをデシリアライズすることができます専用のタグに記載されています:私はRESTEasyのを使用するので、私は実装しExceptionMapperでき

2.例外クライアント側の処理。そして3火災のErrorEvent

私はRestyGWTを使用するので、私は一般的なMethodCallbackを定義します。

package ***.client.application.error; 

public abstract class ErrorEventDistpacherMethodCallback<DTO> implements MethodCallback<DTO> { 

    @Inject 
    static ResourceFailureErrourEventDispatcher dispatcher; 

    @Override 
    public void onFailure(Method method, Throwable caught) { 
     dispatcher.onFailure(method, caught); 
    } 
} 

Methodオブジェクトが私にRESTレスポンスのヘッダとボディへのアクセスを提供します。ディスパッチャーの難しい部分:例外を逆シリアル化してイベントを発生させたい 良いニュース:RestyGWTには、私が使用できるJsonEncoderDecoderインターフェイスが付属しています。だから、私はそれぞれの例外のためにそれを拡張し、専用のタグにある対応する型にリンクする必要があります。

package **.client.exceptions.technical.codecs; 

public interface BookKeyDecodingExceptionCodec extends ExceptionCodec<BookKeyDecodingException>, JsonEncoderDecoder<BookKeyDecodingException> { 
} 

generic ExceptionCodec<BookKeyDecodingException>が必要なのはなぜですか?私はそれらをMap<String, ExceptionCodec<?>>に入れたいからです。

public class ResourceFailureErrorEventDispatcher implements HasHandlers { 
    private static final Logger LOGGER = Logger.getLogger(ErreurEventDistpacherMethodCallback.class.getSimpleName()); 
    private static final String EXCEPTION_CLASS_PARAM_NAME = "ETag"; 

    private Map<String, ExceptionCodec<?>> mapExceptionCodecByClassName = new HashMap<String, ExceptionCodec<?>>(); 

    private EventBus eventBus; 

    ... 

    public BookException buildException(Method method, Throwable caught) { 
     String className = method.getResponse().getHeader(EXCEPTION_CLASS_PARAM_NAME); 
     String json = method.getResponse().getText(); 

     BookException result = null; 

     if (className == null) { 
      result = new UnexpectedResourceException((Exception) caught);  
      LOGGER.severe("Unexpected technical exception :" + result.getMessage()); 
     } else if (mapExceptionCodecByClassName.containsKey(className)) { 
      result = mapExceptionCodecByClassName.get(className).decode(json); 
     } else { 
      result = new MissingExceptionCodecException(className); 
     } 

     return result; 
    } 

    public void onFailure(Method method, Throwable caught) { 
     if (caught instanceof RequestTimeoutException) { 
      ErrorEvent.fire(this, new NetworkException()); 
     } else { 
      ErrorEvent.fire(this, buildException(method, caught)); 
     } 
    } 

    @Override 
    public void fireEvent(GwtEvent<?> event) { 
     eventBus.fireEventFromSource(event, this); 
    } 
} 

私は、注釈/ジェネレータによってコーデックを管理することができますが一瞬、私はそれで満足しています。 このソリューションに関するご意見やアドバイスがありましたら、お気軽にコメント/お答えください。

関連する問題