salida - propagacion de excepciones en java
Recibe excepciones personalizadas de Restlet Framework en el cliente GWT (2)
Con la ayuda de Jerome Louvel y Thierry Boileau creé un nuevo ClientProxyGenerator () que admite excepciones personalizadas para un cliente GWT;
Solo especifique la excepción de la interfaz en ServerResourceProxy (ClientProxy)
y voilá
Es posible utilizar este ClientProxyGenerator personalizado () en su proyecto de inmediato.
Descargar ClientProxyGenerator personalizado
Y colóquelo en un paquete en el servidor (por ejemplo, paquete com.ludus.server.util)
En el módulo GWT, XML cambia ClientProxyGenerator a la nueva versión en el servidor;
Y está listo para ir con sus excepciones personalizadas, pero sería bueno si esta extensión se integrara en el marco de Restlet.
Quiero utilizar el manejo de excepciones con los clientes de GFT y Restlet Framework. El Marco de Restlet apoya el concepto de excepciones anotadas como se describe en esta publicación;
http://restlet.com/company/blog/2015/12/21/exception-handling-with-restlet-framework/
En mi proyecto, creé una LocationNameException
@Status(value = 409)
public class LocationNameException extends Exception
{
...
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
public LocationNameException(String pMessage, Throwable pCause)
{
super(pMessage, pCause);
}
}
Y use esto en mi 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;
}
Con la interfaz
public interface LocationListServerResourceInt
{
...
@Post
LocationDto postLocation(LocationDto pLocationDto) throws LocationNameException;
...
}
Esto funciona, en el caso de una excepción, la llamada devuelve el código 409;
Y en el lado del cliente de GWT se llama aFailure ();
private class PostLocationCallback implements AsyncCallback<LocationDto>
{
...
@Override
public void onFailure(Throwable pCaught)
{
mCallback.onFailure(pCaught, mLocationDto);
}
}
Pero el parámetro pCaught solo contiene una ResourceException con el código de estado 409. My LocationNameException no se incluye en la pila de causas subyacente. Necesito esta LocationNameException para el manejo adecuado de los mensajes de error.
El motivo es el ServerResourceProxy LocationListServerResourceProxyImpl generado por 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
{
...
}
Creo que tengo que volver a escribir el método Post en ClientProxyGenerator;
La LocationNameException está presente en los datos de respuesta por lo que el enfoque básico que utiliza el método getResponseEntity () de la clase ClientResource debería ser posible .
¿Es este el camino a seguir? ¿O puedo capturar la excepción LocationNameException en otro lugar como sugiere Capturar excepciones anotadas ?
Es realmente difícil probar un enfoque diferente debido al código generado. ¿Hay alguna manera fácil de eludir el generador de código con clases personalizadas?
Como ya se mencionó, LocationNameException está presente en los datos de respuesta. Por lo tanto, podemos obtenerlo, al igual que una entidad normal;
...
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 necesita saber el tipo de excepción (en este caso, LocationNameException). Por lo tanto, especificamos la excepción en la interfaz ClientProxy;
@Post
void postLocation(LocationDto pLocationDto, AsyncCallback<LocationDto> pResult) throws LocationNameException;
Y use getExceptionTypes () o getGenericExceptionTypes () en ClientProxyGenerator;
Class<?>[] exceptionTypes = method.getExceptionTypes();
java.lang.reflect.Type[] genericExceptionTypes = method.getGenericExceptionTypes();
Por supuesto, no todos los métodos REST usan una excepción personalizada. Cuando getExceptionTypes () devuelve una lista vacía, simplemente devolvemos el código de estado anterior;
callback.onFailure(new ResourceException(getClientResource().getStatus()));