2017-08-04 52 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()));