miércoles, 17 de agosto de 2011

Custom Tag - Una forma facil de quitarte scriptlets

Una manera limpia de hacer JSP's es quitando todo rastro de scriptlet. Pero puede darse el caso de que sea inevitable. Para esos casos ya vimos las EL Functions y hoy veremos un caso sencillo de custom tag. En tres simples pasos podremos usarlas:

Para el ejemplo haremos un tag sencillo que almacena en el ámbito determinado una variable que permite el acceso a las constantes de una clase de utilidad de constantes.

1. Crear la Clase que implemente alguna de las clase de soporte de Tags existentes dentro de Java EE. La más sencilla es SimpleTagSuport que realizará toda su lógica dentro del método void doTag(). Si el tag va a tener parámetros, estos se crearan como atributos en la clase (se han quitado los getters y setters para aligerar el código pero son necesarios ! ).
public class UsarConstanteTag extends SimpleTagSupport {

    private final static Logger MYLOG = Logger.getLogger(UsarConstanteTag.class);

    private final static String REQUEST = "request";
    private final static String SESSION = "session";
    private final static String APPLICATION = "application";

    private String clase;
    private String variable;
    private String scope;

    private void almacenaEnAmbito(final Object objeto) {
    if (REQUEST.equals(getScope())) {
        getJspContext().setAttribute(getVariable(), objeto, PageContext.REQUEST_SCOPE);
    } else if (SESSION.equals(getScope())) {
        getJspContext().setAttribute(getVariable(), objeto, PageContext.SESSION_SCOPE);
    } else if (APPLICATION.equals(getScope())) {
        getJspContext().setAttribute(getVariable(), objeto, PageContext.APPLICATION_SCOPE);
    } else {
        getJspContext().setAttribute(getVariable(), objeto, PageContext.PAGE_SCOPE);
    }
    }

    /*
     * (non-Javadoc)
     *
     * @see javax.servlet.jsp.tagext.SimpleTagSupport#doTag()
     */
    @SuppressWarnings("rawtypes")
    @Override
    public void doTag() throws JspException, IOException {
    Map constants = null;
    try {
        constants = getClassConstants(getClase());
    } catch (ClassNotFoundException except) {
        MYLOG.error("ConstanteTag: No se ha podido obtener la clase", except);
    } catch (SecurityException except) {
        MYLOG.error("ConstanteTag: Ha ocurrido un securityException en getDeclaredField", except);
    } catch (IllegalArgumentException except) {
        MYLOG.error("ConstanteTag: No se ha encontrado el campo", except);
    } catch (IllegalAccessException except) {
        MYLOG.error("ConstanteTag: No se ha podido acceder al campo", except);
    }
    if (constants != null && !constants.isEmpty()) {
        almacenaEnAmbito(constants);
    }
    }
   
    @SuppressWarnings({ "rawtypes", "unchecked" })
    private Map getClassConstants(final String className) throws ClassNotFoundException, IllegalArgumentException,
        IllegalAccessException {
    Map constants = new HashMap();
    Class clazz = Class.forName(getClase());
    Field fields[] = clazz.getFields();
    for (int i = 0; i < fields.length; i++) {
        Field field = fields[i];
        int modifiers = field.getModifiers();
        if ((modifiers & 8) == 0 || (modifiers & 0x10) == 0) {
        continue;
        }
        Object value = field.get(null);
        if (value != null) {
        constants.put(field.getName(), value);
        }
    }
    return constants;
    }    
2. Crear el TLD  asociado donde indicamos como vamos se realiza la llamada al tag, que clase y que metodo implemente y cuales son sus parámetros de entrada. Este fichero es necesario almacenarlo dentro de la carpeta WEB-INF y será automáticamente reconocido por la aplicación.
3. Realizar el import de la etiqueta y usarla.

No hay comentarios:

Publicar un comentario