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...

domingo, 9 de septiembre de 2007

Patrones. Pocos y de pasadita

Los patrones son soluciones a problemas comunes que podemos encontrar de manera documentada, son las mejores practicas y soluciones a varios problemas que te puedes encontrar en el día a día del desarrollo. Generalmente estos patrones favorecen los objetivos de orientación a objetos y facilitan el trabajo. Existen cientos de ellos, aquí solamente vamos a exponer una introducción a algunos de ellos.

  • Singleton. El singleton es una clase de la que solamente queremos crear una sola instancia, podemos pensar por ejemplo en una clase Presidente de Empresa, de estos solamente debería haber uno por Empresa.
  • Listener. Un listener es una clase que esta atenta a los cambios en alguna instancia de otra clase, podemos pensar en que la clase que reporta los cambios envia avisos a todas las clases interesadas, y estas hacen alguna acción en base a estas notificaciones, de manera similar a alertas sobre eventos.
  • Decorator. Una clase de determinado tipo "envuelve" a otra clase del mismo tipo para poder hacer nuevas funcionalidades que pueden ser eco de las de la clase decorada. Los decoradores sirven en muchos casos para crear objetos "con"por ejemplo Cafe con Leche o Leche con Chocolate, o quizas Cafe con Leche con Chocolate.
  • Delegate. Es una clase de dependencia en la que una clase expone cierta funcionalidad que es realizada por alguna otra clase o instancia, de manera que el usuario final solo accede a una clase de salida.
  • Façade. Los objetos de varias clases se agrupan dentro de una nueva que expone la funcionalidad de todas las clases del grupo dentro de si mismo. Podemos compararlo de manera directa con un control remoto universal, que incluye las funciones de varios controles.
  • Factory. Una clase de objetos que son dificiles de configurar se mantienen con constructores de paquete, mientras que una clase de ese mismo paquete permite crear las instancias de los mismos sin pasar por todos los problemas de configuración.
  • Interceptor. Una clase funciona como un envoltorio de otra, cada que la claseenvuelta va a realizar una operación le notifica a la primera para que esta pueda cambiar partes del proceso que realiza.
  • Iterator. Una clase permite recorrer los elementos de una colección.
  • Abstract Factory. Similar a Factory, pero en este caso se define una clase abstracta que creara los objetos, y es en la implementación concreta donde dichos objetos se crean.
  • Strategy. Una clase abstracta define los pasos de un proceso, y el orden que seguiran, pero son las clases concretas quienes determinan la forma exacta en que el proceso se realiza, generalmente implementando partes del proceso.

Conceptos para Web

Una lista de los conceptos generales para crear aplicaciones en Web y lo que hace falta, primero el Software:
Las tecnologías vamos a revisarlas poco a poco y con calma, por lo pronto por lo menos debería de instalar el JDK, Eclipse y Tomcat. El resto podemos irlo haciendo poco a poco.