2017-08-04 97 views
0

我想用異常與Restlet框架和GWT的客戶端處理。 Restlet框架支持本文中描述的註釋異常的概念;接收來自Restlet框架自定義異常在GWT客戶

http://restlet.com/company/blog/2015/12/21/exception-handling-with-restlet-framework/

在我的項目我創建了一個LocationNameException

@Status(value = 409) 
public class LocationNameException extends Exception 
{ 
    ... 

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 
    public LocationNameException(String pMessage, Throwable pCause) 
    { 
     super(pMessage, pCause); 
    } 
} 

在我ServerResource使用;

@Override 
    @Transactional(rollbackOn = LocationNameException.class) 
    public LocationDto postLocation(LocationDto pLocationDto) throws LocationNameException 
    { 
     ... 

     Location lLocation = new Location(pLocationDto); 

     try 
     { 
      LocationDao lLocationDao = getLocationDao(); 
      lLocationDao.persist(lLocation); 
     } 
     catch (PersistenceException pPersistenceException) 
     { 
      throw new LocationNameException("Location requires unique Name", pPersistenceException); 
     } 

     ... 

     return lLocationDto; 
    } 

隨着接口

public interface LocationListServerResourceInt 
{ 
    ... 

    @Post 
    LocationDto postLocation(LocationDto pLocationDto) throws LocationNameException; 

    ... 
} 

這工作,在出現異常的情況下,調用返回碼409;

enter image description here

,並在GWT客戶端onFailure處()被調用;

private class PostLocationCallback implements AsyncCallback<LocationDto> 
{ 
    ... 

    @Override 
    public void onFailure(Throwable pCaught) 
    { 
     mCallback.onFailure(pCaught, mLocationDto); 
    } 
} 

但參數pCaught只含有狀態碼409 我LocationNameException不包括在根本原因堆棧ResourceException。 我需要此LocationNameException來處理適當的錯誤消息。

原因是所生成的ServerResourceProxy LocationListServerResourceProxyImpl通過的Restlet GWT ClientProxyGenerator;

public void postLocation(LocationDto param1, final LocationDto> callback) 
{  
    ... 

    public void handle(Request request, Response response) 
    { 
     if (getClientResource().getStatus().isError()) 
     {  
      callback.onFailure(new ResourceException(getClientResource().getStatus())); 
     } 
     else 
     { 

    ... 

} 

我想我必須重寫ClientProxyGenerator中的Post方法;

enter image description here

的LocationNameException存在於響應數據,以便the Basic approach using the getResponseEntity() method of the ClientResource class should be possible

這是要走的路?或者我可以在Catching annotated exceptions建議的地方捕獲LocationNameException異常嗎?

這是真的很難去嘗試的,因爲生成的代碼不同的方法。有沒有一種簡單的方法來繞過自定義類的代碼生成器?

+0

圍繞這個問題,它仍然非常安靜...... Restlet/GWT還活着嗎?任何人都曾在使用Restlet的GWT客戶端中使用服務器異常? –

+0

Hi Roland,對Restlet/GWT中註釋異常的支持尚未開發,但它應該在技術上可行。你認爲你可以貢獻它嗎?很高興在此過程中爲您提供支持。 –

+0

你好傑羅姆,是的,我認爲我可以貢獻它。挑戰不是註釋異常(我可以使用描述的基本方法),而是ClientProxyGenerator(因此GWT編譯器的東西...)。我試圖在我的項目中使用生成的源代碼,但是ServerResourceProxy_TypeSerializer存在問題...您是否有可以使用的工作/編譯ServerResourceProxyImpl/ServerResourceProxy_TypeSerializer示例? –

回答

0

傑羅姆Louvel和Thierry布瓦洛的幫助下,我創建了一個支持向客戶端GWT自定義異常新ClientProxyGenerator();

enter image description here

只要指定從ServerResourceProxy(ClientProxy)接口異常

enter image description here

就萬事大吉了

enter image description here

enter image description here

可以立即在您的項目中使用此自定義ClientProxyGenerator()。

Download custom ClientProxyGenerator

並將其放置在服務器上的一個包(例如包com.ludus.server.util)

enter image description here

在GWT模塊XML改變ClientProxyGenerator到新版本在服務器上;

enter image description here

,你準備好去與你的自定義異常,但它會很好,如果這個擴展將被集成在Restlet框架。

0

如已經提到的LocationNameException存在於響應數據。因此,我們可以像普通實體一樣獲得它;

... 

     public void handle(Request request, Response response) 
     { 
      if (getClientResource().getStatus().isError()) 
      { 
       LocationNameException lLocationNameException = null; 
       boolean serializationError = false; 

       try 
       { 
        if (response.isEntityAvailable()) 
        { 
         if (MediaType.APPLICATION_JAVA_OBJECT_GWT.equals(response.getEntity().getMediaType())) 
         { 
          lLocationNameException = new ObjectRepresentation<LocationNameException>(
            response.getEntity().getText(), 
            (SerializationStreamFactory) MyLocationListServerResourceProxyImpl.this, false) 
            .getObject(); 
         } 
         else 
         { 
          throw new IOException("Can't parse the enclosed LocationNameException."); 
         } 
        } 
       } 
       catch (Throwable e) 
       { 
        serializationError = true; 
        callback.onFailure(new ResourceException(e)); 
       } 

       if (!serializationError) 
       { 
        callback.onFailure(lLocationNameException); 
       } 
      } 
      else 
      { 

... 

ClientProxyGenerator需要知道異常類型(在本例中爲LocationNameException)。因此我們在ClientProxy接口中指定異常;

@Post 
    void postLocation(LocationDto pLocationDto, AsyncCallback<LocationDto> pResult) throws LocationNameException; 

並在ClientProxyGenerator中使用getExceptionTypes()或getGenericExceptionTypes()方法;

Class<?>[] exceptionTypes = method.getExceptionTypes(); 
    java.lang.reflect.Type[] genericExceptionTypes = method.getGenericExceptionTypes(); 

當然,並不是所有的REST方法使用一個自定義異常。當getExceptionTypes()返回一個空列表時,我們只返回良好的舊狀態碼;

callback.onFailure(new ResourceException(getClientResource().getStatus()));