jueves, 27 de septiembre de 2007

Acceder a una sesión dentro de un Action

Acceder a los contenidos de la sesión desde un Action es una cosa bastante sencilla, para empezar, hay que hacer que el action mismo implemente la interfaz SessionAware e implemente el metodo adecuado.


public class ActionConSession implements SessionAware {
private Map session;

public void execute() {
//Agregamos un nuevo valor a la sesion
session.put("nuevo", valor);

//Eliminar valores de la sesion
session.remove("nuevo");

//Recuperar un valor de la sesion
Object v = session.get("otro");
}

public void setSession(Map session) {
this.session = session;
}
}


Todas las operaciones con la sesion son mas sencillas pues internamente solo se trata de implementar las acciones sobre un mapa, sin embargo, en caso de que sea necesario acceder a las funcionalidades reales del objeto HttpSession podemos realizarlo mediante la interfaz ServletRequestAware.


public class ActionHttpSession implements ServletRequestAware {
private HttpServletRequest request;

public void setServletRequest(HttpServletRequest request) {
this.request = request;
}

public String execute() {
//Pedimos la sesion del request y en caso de no existir la creamos
HttpSession session = request.getSession(true);
}
}


De aqui en adelante puede manipularse la session como normalmente se realizaria sin Struts. En lo personal sugiero usar SessionAware pues es mas sencillo y abstraes las dificultades del proceso de usar una sesión.

lunes, 24 de septiembre de 2007

Inicios de Sesión

El control de acceso sobre Struts puede realizarse de varias maneras, vamos a revisar una de las mas sencillas y que no utiliza ninguna de las especificaciones propias de HTTP para su login.

Struts incluye el concepto de Interceptor, esta es una clase que realiza una acción antes de que el Action propiamente dicho se ejecute, así por ejemplo podemos agregar un Interceptor que se encargue de iniciar una sesión en caso de que esta no exista.

Los Interceptors son entonces "cajas" que envuelven a los actions y hay varios de ellos, pero de momento lo que nos interesa es crear un nuevo Interceptor para validar que nuestros usuarios esten dentro del sistema.

Para empezar vamos a crear un Action que se encarga del inicio de sesión.


public class LoginAction extends ActionSupport implements SessionAware {
private String usuario;
private String password;
private LoginDao dao;

//Getters y Setters omitidos por resumen

public String execute() {
if(!dao.userExists(usuario)) {
addActionError(getText("user.unknown"));
return INPUT;
}

if(!dao.login(usuario, password)) {
addActionError(getText("password.invalid"));
return INPUT;
}

//Una vez logeado ponemos los datos en la sesión
session.put("usuario", dao.getIdUsuario(usuario));
return SUCCESS;
}
}


El action necesita una JSP para mostrar su interfaz y un validador, supongamos que el JSP se llama login.jsp


<%@taglib prefix="s" uri="/struts-tags" %>

<s:actionerror/>
<s:form action="Login">
<s:textfield name="usuario" label="Usuario" />
<s:password name="contrasenia" label="Contraseña" />

<s:submit value="Iniciar Sesión" />
</s:form>


Una vez con ambos elementos partimos de el supuesto de que existe un action llamado Bienvenida que es donde inicia el sitio. Modificamos entonces el struts.xml pata referenciar los actions entre si.



<action name="Bienvenida.action">
<!-- No se que vaya aqui -->
</action>

<action name="Login" class="ClaseLogin">
<!-- Si el login es exitoso se envia al action de Bienvenida -->
<result type="redirect-action">Bienvenida</result>
<!-- Registramos la pagina de login -->
<result name="input">/login.jsp</result>
</action>



Una vez que tenemos estos elementos podemos ingresar a
Login.action
y revisar la pagina recien creada. Sin embargo esta funciona solamente que sea la primera que se muestre... o sea index.jsp, pero generalmente no es asi. Además, si alguna persona teclea la URL directa a un action y no ha iniciado sesión entonces entrara sin problemas. Aqui es donde entra el Interceptor, que tomara cualquier petición al sistema y se asegurara de que el login exista. La clase Interceptor es mas o menos algo asi:


public class LoginInterceptor extends AbstractInterceptor {
private static String HTTP_REQUEST ="com.opensymphony.xwork2.dispatcher.HttpServletRequest";

public String intercept(ActionInvocation ai) {
ActionContext ac = ai.getInvocationContext();
HttpServletRequest request = ac.get(HTTP_REQUEST);
HttpSession session = request.getSession();

String val = session.getAttribute("usuario");
if(val == null || val.trim().length() = 0) {
//Si se esta logeando puede entrar al sitio
if(ai.getAction().getClass() == LoginAction.class)
return ai.invoke();

return "login";
}

//Si llega aqui entonces presuponemos que ya hay un login valido
return ai.invoke();
}
}


Solamente resta registrar el Interceptor dentro del mismo struts.xml para que este cargue en cualquier pagina solicitada.


<!-- Colocamos esto despues de abrir la etiqueta package -->
<interceptors>
<!-- Registramos el nuevo interceptor -->
<interceptor name="loger" class="LoginAction" />

<!-- Creamos una nueva pila de interceptors para adecuarla a nuestro ejemplo -->
<interceptor-stack name="include_session">
<!-- Agregamos un interceptor que crea la session para evitar que esta este vacia -->
<interceptor-ref name="createSession" />
<!-- Posteriormente nuestro recien creado interceptor -->
<interceptor-ref name="loger" />
<!-- Y todos los interceptors que van por default -->
<interceptor-ref name="completeStack" />
</interceptor-stack>
</interceptors>

<!-- Sobreescribimos el stack de interceptors por el que acabamos de definir -->
<default-interceptor-ref name="include_session" />

<!-- Finalmente creamos un GlobalResult para interceptar la falta de login al sitio -->
<global-results>
<result name="login">/login.jsp</result>
</global-results>

lunes, 17 de septiembre de 2007

Material del Curso de Web Development

Resumen del material revisado en las sesiones del curso.

Revisen los requerimientos generales del mismo.

Material.

Actualización:

jueves, 13 de septiembre de 2007

JUnit

JUnit es una libreria Java que permite realizar pruebas de unidad sobre las clases que han sido desarrolladas dentro de un proyecto orientado a objetos. Por medio de JUnit podemos probar parte de la calidad del software que desarrollamos.

Las pruebas que se pueden desarrollar sobre JUnit parten de un sencillo concepto: assert, un assert en una condición que debe cumplirse para considerar que nuestra clase probada funciona de la manera esperada.

Además, los JUnits permiten realizar operaciones complejas dentro de una clase utilizando código Java para las pruebas.

Un UnitTest tiene la siguiente estructura:
  1. 1 método protegido setUp( ) que configura el entorno antes de realizar cualquier prueba.
  2. 1 método protegido tearDown( ) que destruye el entorno de pruebas.
  3. Varios métodos con el nombre test* que son cada una de las pruebas que se van a realizar.
Dentro de cualquiera de estos métodos pueden utilizarse los métodos siguientes:
  1. assertTrue(mensaje, condicion), assertTrue(condicion). Que comprueba que la condicion booleana que se le pasa como parametro sea forzosamente correcta.
  2. assertFalse. Lo mismo pero al reves.
  3. assertEquals(valor, valor), assertEquals(mensaje, valor, valor). Se asegura que los valores pasados como parametro sean iguales.
  4. assertNotEquals( );
  5. assertSame(Objeto, Objeto). Los objetos deben hacer referencia al mismo objeto, es decir, la misma direccion de memoria.
  6. assertNotSame( ).

martes, 11 de septiembre de 2007

JSF's... va...

Los JSF's estan bastante mas avanzados que Struts, creo que si, por lo menos he escuchado bastantes comentarios en Web sobre la extensibilidad de los componentes de JSF, además de que el modelo de transferencia no es tan complicado. Pero:

  1. JSF se centra en los componentes, no en las funciones.
  2. Pesa un buen como tecnología
  3. Los tiempos de respuesta son algo complicados
  4. La mayoria de implementaciones son $$$
  5. El MyFaces es lento
  6. Los componentes o UI de JSF con AJAX dependen de terceros
Regularmente estaria de acuerdo en usar un estandar, pero para ahorrar recursos y librerias extensivas prefiero el Struts...