我想对Restlet Framework和GWT客户端使用异常处理。 Restlet Framework支持本文所述的带注释异常的概念;
http://restlet.com/company/blog/2015/12/21/exception-handling-with-restlet-framework/
在我的项目中,我创建了一个LocationNameException
<!DOCTYPE html>
<html>
<head>
<title>A Text Editor Project</title>
<link rel="stylesheet" type="text/css" href="CSS/style.css">
<link href="https://fonts.googleapis.com/css?family=Roboto:300,400" rel="stylesheet">
<link href="https://fonts.googleapis.com/css?family=Source+Code+Pro" rel="stylesheet">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
</head>
<body>
<div class="text-editor">
<iframe class="text-field" id="text-field" src="about:blank" contenteditable="true">
</iframe>
</div>
</body>
</html>
并在我的ServerResource中使用它;
@Status(value = 409)
public class LocationNameException extends Exception
{
...
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
public LocationNameException(String pMessage, Throwable pCause)
{
super(pMessage, pCause);
}
}
使用界面
@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;
}
这是有效的,如果是异常,则调用返回代码409;
在GWT客户端,onFailure()被调用;
public interface LocationListServerResourceInt
{
...
@Post
LocationDto postLocation(LocationDto pLocationDto) throws LocationNameException;
...
}
但是参数pCaught只包含一个状态码为409的ResourceException。 我的LocationNameException不包含在底层原因堆栈中。 我需要此LocationNameException以进行适当的错误消息处理。
原因是Restlet GWT ClientProxyGenerator生成的ServerResourceProxy LocationListServerResourceProxyImpl;
private class PostLocationCallback implements AsyncCallback<LocationDto>
{
...
@Override
public void onFailure(Throwable pCaught)
{
mCallback.onFailure(pCaught, mLocationDto);
}
}
我想我必须在ClientProxyGenerator中重写Post方法;
LocationNameException存在于响应数据中,因此the Basic approach using the getResponseEntity() method of the ClientResource class should be possible。
这是要走的路吗?或者我可以按照Catching annotated exceptions建议的其他地方捕获LocationNameException异常吗?
由于生成的代码,很难尝试不同的方法。是否有一种简单的方法来绕过自定义类的代码生成器?
答案 0 :(得分:0)
如前所述,ResponseNameException存在于Response数据中。 因此,我们可以像普通实体一样获得它;
...
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()));
答案 1 :(得分:0)
在Jerome Louvel和Thierry Boileau的帮助下,我创建了一个新的ClientProxyGenerator(),支持对GWT客户端的自定义异常;
只需在ServerResourceProxy(ClientProxy)
中指定接口的异常即可和voilà
可以立即在项目中使用此自定义ClientProxyGenerator()。
Download custom ClientProxyGenerator
并将其放在服务器上的包中(例如包com.ludus.server.util)
在GWT模块中,XML将ClientProxyGenerator更改为服务器上的新版本;
您已准备好使用自定义异常,但如果将此扩展程序集成到Restlet框架中会很好。