Tips, Soluciones y Novedades en Tecnología

14/11/2016

Manejando Exception






En java las excepciones son muy importante, y si no la usas correctamente, pues no lo estas aprovechando al máximo.









Vamos a trabajar explicitamente sobre la Clase Exception



El uso basicamente depende del escenario y el grado de control que se requiere utilizar.



Para este tutorial vamos a usar nuestra exception que herede de la Clase Exception



Como recomendacion debemos crear una única clase de exepcion para nuestra aplicacion, en este caso crearemos STExeption



Esta clase debe heredar de Exeption como se indica a continuacion



public class STException extends Exception {

private String code;
private int status;

public STException() {
super();
}

/**
     *
     * @param message
     */
public STException(String message) {
super(message);
}

public STException(int status,String message) {
super(message);
this.status=status;
}

/**
     * Este metodo se inicia cuando se invoca desde las excepciones que lo
     * extienden
     *
     * @param status
     * @param code
     * @param message
     */
public STException(int status, String code, String message) {
super(message);
this.status = status;
this.code = code;
}

/**
     *
     * @param status
     * @param message
     * @param rootCause
     */
public STException(int status, String message, Throwable rootCause) {
super(message, rootCause);
this.status = status;
}

/**
     *
     * @param rootCause
     */
public STException(Throwable rootCause) {
super(rootCause);
}

public STException(String message, Throwable rootCause) {
super(message, rootCause);
}

public String getCode() {
return code;
}

public int getStatus() {
return status;
}

}






Como podemos ver la clase tiene 2 atributos Code y Status, estos atributos almacenan los valores que producen las excepciones Hijos, mas adelante veremos que valores y como utilizarlos.





STException debe ser nuestra clase padre de todas nuestras excepciones que queramos controlar. por ejemplo si queremos tener excepciones de validacion, conversion, base de datos, etc.  esta debe implementar de STException. a continuacion veremos 2 excepciones hijas que implementen de STException.





public class AccessDeniedException extends STException {

public static final int status = 401;

public AccessDeniedException() {
super();
}

/**
     *
     * @param message
     */
public AccessDeniedException(String message) {
super(status, message);
}

public AccessDeniedException(String code, String message) {
super(status, code, message);
}

/**
     *
     * @param message
     * @param rootCause
     */
public AccessDeniedException(String message, Throwable rootCause) {
super(status, message, rootCause);
}

/**
     *
     * @param rootCause
     */
public AccessDeniedException(Throwable rootCause) {
super(rootCause);
}
}



En este caso la excepcion es para validar la autenticación, podemos ver que el atributo status tiene un valor por defecto de 401, este codigo se estableció segun: https://en.wikipedia.org/wiki/List_of_HTTP_status_codes



De esta forma cuando lanzamos la excepcion de Autenticación  ya no tendremos que agregar el codigo para respuesta al navegador.





Otro ejemplo de implementacion es:



public class DatabaseException extends STException {

public static final int status = 500;
public DatabaseException() {
super();
}

/**
     *
     * @param message
     */
public DatabaseException(String message) {
super(status,message);
}
public DatabaseException(String code,String message) {
super(status, code, message);
}

/**
     *
     * @param message
     * @param rootCause
     */
public DatabaseException(String message, Throwable rootCause) {
super(status, message, rootCause);
}

/**
     *
     * @param rootCause
     */
public DatabaseException(Throwable rootCause) {
super(rootCause);
}
}



En este caso se estableció un codigo de 500, para indicar que se ha producido un error en el servidor de base de datos o servidor de aplicaciones, los codigo pueden variar segun el grado de precición de la validación.



Ahora veremos como encapsular nuestra excepcion ya sea el tipo que sea todos tiene un solo tipo de salida que es STException.



 @Override
public void remove(String token, int id) throws STException {
log.debug("add ({},{})", token, id);
UserInfo info = null;
try {
info = SessionManager.getInstance().get(token);
TrainingDAO.getInstance().remove(info, id);
} catch (AccessDeniedException e) {
log.error("remove ({},{})", e.getLocalizedMessage(), e);
throw new AccessDeniedException ("Mensaje de objeto autenticacion");
} catch (HibernateException e) {
log.error("remove ({},{})", e.getLocalizedMessage(), e);
throw new DatabaseException("Mensaje de error en la base de dados");
}
log.debug("add void");
}



Compo podemos ver podemos controlar muchas excepciones pero como respuesta daremos como salida solo a STException, por que todas las demas excepciones heredan de esta.



De este modo nos evitamos colocar todas las excepciones en nuestras interfaces y lo simplificamos con una sola.





Ahora supongamos que debemos dar respuesta a la peticion y devolver en el request, solo tendremos que lanzar este control.



    @POST
@Path("/add/{id}")
public ResponseData add(TrainingPartaker item) throws STException {
try {
TrainingPartaker nwitem = STTrainingPartaker.getInstance().add(null, item);
return STMessage.success(nwitem);
} catch (STException e) {
throw new GenericException(e);
} catch (Exception e) {
throw new GenericException(e);
}
}



Ahora si queremos determinar especificamente que excepcion es la que há lanzado nuestra aplicación, solo base de colocarlo de esta forma y sabremos a que excepcion pertenece.



       @POST
@Path("/add/{id}")
public ResponseData add(TrainingPartaker item) throws STException {
try {
TrainingPartaker nwitem = STTrainingPartaker.getInstance().add(null, item);
return STMessage.success(nwitem);
} catch (AccessDeniedException e) {
throw new GenericException(e);
} catch (DatabaseException e) {
throw new GenericException(e);
} catch (ParseException e) {
throw new GenericException(e);
} catch (ConverterException e) {
throw new GenericException(e);
} catch (Exception e) {
throw new GenericException(e);
}
}







Como podemos ver, las excepciones es recomendable encapsularlas al momento de generarlas y desencapsularlas el momento cuando queremos usarlas, o no desencapsularlas si queremos manejar mensajes de proposito general.





Espero que los ayude a manejar mejor sus excepciones en sus aplicacion.