Asumo que ya sabes lo que es MVC, y esa clase de cosas.
Con NetBeans 6.9, te viene instalada la version 3.0 de Spting MVC.
Pre-condiciones para entender esto:
Saber que es MVC: http://es.wikipedia.org/wiki/Modelo_Vista_Controlador
Tener instalado Netbeans 6.9,yo use la version full full desde linux.
Haberlo instalado con un Tomcat (ya que Glassfish me tiraba error con domain.xml).
Saber programar en java.
Tener nociones basicas sobre HTML.
Que es un bean, con este video de un profe de mi facu basta: http://www.youtube.com/watch?v=vFlTYRleZpU
Glosario:
POJO: Una clase java de toda la vida, son clases comunes y corrientes creadas por uno, que no depende de ningun framework en particular.
Logica de negocio: Lo que REALMENTE hace el programa, sin importar la base de datos que use, ni tampoco la forma de visualizar los datos.
Nombre string: Hablando mal, digamos que Spring tiene un hashmap
Sigamos:
1 - Creamos un proyecto web nuevo.
Esto es:
File->New proyect->Java web->Web application.
Next.... hasta que aparezca Server: Apache tomcat 6.0.20
Next... habilitar Spring web MVC. Hibernate para futuros "tutoriales".
2 - Creamos las clases:
Concepto:
Las clases se dividen (por ahora) en tres grupos:
Los beans para la comunicacion vista-control
Los controladores.
Los servicios.
El controlador maneja las vistas, los modelos y los servicios.
El bean es un POJO que contiene la información a mostrar en la Vista. Solo tiene getters&setters (generalmente).
Los servicios, supuestamente contienen la "logica de negocio". Suele
¿Como es el flujo que nos interesa?
Un usuario accede a nuestra web. En algun lugar que veremos luego, le decimos "si quiere acceder a "pantallaLogin.htm", debe llamar al controlador "LoginController".
LoginController le dice al framework "bueno, muestro la vista X".
Cuando haces un Submit desde la web (con algun form html), el controlador (LoginController) RECIBE la respuesta de la pagina web. ¿Se acuerdan del POJO? Bueno, el controlador recibe ESE BEAN, realiza acciones con el servicio asignado, y retorna una nueva web...
Probablemente no hayas entendido nada, asique mejor vamos a-los-palos.
/fin concepto.
Practica:
2.1 - Crear el Bean POJO.
Antes de hacer cualquier cosa, tenemos que tener en claro QUE datos el usuario debe ingresar al sistema: Que datos nos interesa obtener (como desarolladores) desde la pagina web.
Esto es un Login, asique nos interesan Nombre de usuario y Password.
Entonces, creamos una clase java. En este ejemplo, la crearemos en el package BeanVistaControl (porque me gusta asi :P). La clase, la llamaremos Usuario.
package BeanVistaControl;
/**
*
* @author segfault
*/
public class Usuario {
private String usr;
private String pwd;
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
public String getUsr() {
return usr;
}
public void setUsr(String usr) {
this.usr = usr;
}
}
2.2 - Crear un servicio:
¿Que hace que nuestra aplicacion sirva?
Realmente no importa si usamos una pagina web, un formulario Swing, o un sistema de voz. Esos son detalles. Nuestra aplicacion sirve, por su logica de negocios.
Ahora, dijimos que nuestra aplicacion iba a ser un login, asique creamos una clase java, a la que llamaremos "loguearUsuario" (*), en un package "Servicios".
A mi por lo menos, me gusta que los Servicios obtengan directamente el Bean POJO del punto anterior (asi el Controlador solo se encarga de unir componentes y no tener lógica), pero no es obligatorio, ni tampoco se si es una buena practica.
package Servicios;
import BeanVistaControl.Usuario;
public class loguearUsuario {
public String login(Usuario usr)
{
if (usr.getUsr().equals("pablo"))
return "usuario valido! :D";
return "cualquiera mandaste";
}
}
2.3 - Creamos el Controlador.
NOTA: Despues de esto, empiezan los xmls feos...
Creamos un Simple Controller, esto es:
File -> New file -> Spring framework -> Simple Form Controller.
Nombre de clase: LoginController (porque quiero, esto no es Ruby on rails!).
Package: controladores
Adentro, meter en el constructor esto:
public LoginController() {
//Initialize controller properties here or
//in the Web Application Context
// CommandClass es el bean POJO vista-controlador!
setCommandClass(Usuario.class);
// Aca al BEAN le ponemos un nombre STRING que querramos
// (si, puede llamarse "aslñknsdfkaj", pero despues vas a tener que recordarlo
setCommandName("beanUsuario");
// setFormView establece la VISTA COMUN cuando se invoque a este
// controlador. En nuestro caso, es una pantalla de login.
//
// NOTA: Las vistas tienen un nombre de archivo (ponele, pepe.jsp),
// pero a Spring le interesa el Nombre String (ver el glosario arriba).
// Luego en algun xml, le diremos que "pantallaLogin" es TAL archivo jsp.
setFormView("pantallaLogin");
// Aca decidimos cual va a ser la "vista siguiente", luego de que se toque el botón Submit.
// Lo elegimos, mediante el Nombre String de la vista (que todavia no creamos)
setSuccessView("pantallaPrincipal");
}
Ahora, creamos el SERVICIO (logica de negocio) de la siguiente forma:
public loguearUsuario loguearUsuario;
public loguearUsuario getLoguearUsuario() {
return loguearUsuario;
}
// Creo que este no es necesario :P
public void setLoguearUsuario(loguearUsuario miLoguearUsuario) {
this.loguearUsuario = miLoguearUsuario;
}
Después, establecemos la "logica del controlador".
ESTO SUCEDE una vez que se haya tocado el boton "Submit"!!!!
LUEGO de ejecutarse ModelAndView, el framework MUESTA el jsp de "sucessView" que pusimos previamente (en el constructor de esta clase).
@Override
protected ModelAndView onSubmit(Object command) throws Exception {
// Recordar que, cuando se toca el boton onSubmit,
// el framework llena el bean POJO, con los datos que el usuario
// INGRESO a la pagina web. Aca es cuando lo casteamos :P
Usuario name = (Usuario)command;
// Aca obtengo la vista de Sucess :P
ModelAndView mv = new ModelAndView(getSuccessView());
// Aca le digo a la vista de Sucess "Che, te envio este objeto para que lo muestres" Recordar esto como el punto (*1)
// RECORDAR que loguearUsuario retornaba un String, el cual decia si habia sido un login exitoso o no. ESE STRING en la vista lo llamaremos como "mensajeLogin".
mv.addObject("mensajeLogin", loguearUsuario.login(name));
//aca ya termino todo :P.
return mv;
}
Y ya nos olvidamos de clases JAVA por el dia de hoy :P
3.0 - Creacion de Vistas.
En este caso, tenemos dos:
- La pantalla de Login, con dos campos text para usuario & password, mas un boton de "login".
- La pantalla de "entraste!" o "la pifiaste".
Empecemos por el mas facil: Entraste o La pifiaste.
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<%@taglib uri="http://www.springframework.org/tags" prefix="spring" %>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Hello</title>
</head>
<body>
<h1>${mensajeLogin}</h1>
</body>
</html>
FIJARSE que esto no tiene ninguna lógica de negocio:
SOLO mostramos lo que recibimos en el punto (*1) dicho anteriormente,
mediante su "Nombre String", que era 'mensajeLogin' !!!!!!!!!!!!!!
Ahora, vamos con la PantallaLogin, que es un toque mas complicada :P
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@taglib uri="http://www.springframework.org/tags" prefix="spring" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>JSP Page</title>
</head>
<body>
<spring:nestedPath path="beanUsuario">
<form action="" method="post">
Name:
<spring:bind path="usr">
<input type="text" name="${status.expression}" value="${status.value}">
</spring:bind>
<spring:bind path="pwd">
<input type="text" name="${status.expression}" value="${status.value}">
</spring:bind>
<input type="submit" value="OK">
</form>
</spring:nestedPath>
</body>
</html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Hello</title>
</head>
<body>
<h1>${mensajeLogin}</h1>
</body>
</html>
Ahora preguntaran: QUE GOMA ES spring:nestedPath path="beanUsuario" ???
Bueno, digamos que luego al BEAN POJO Vista-Control, le vamos a poner un "Nombre String", al que llamaremos "beanUsuario". Todo esto es vía configuración XML... ¿Ya no lo empiezan a odiar un poco?
Bueno, en "path" ponemos el nombre string del Bean.
Y luego, le decimos "che, asocia este input text, con este otro campo del Bean".
spring:bind path="usr" se asocia con el primer Input text
spring:bind path="pwd" se asocia con el segundo Input text.
usr y pwd es accedido vía getters y setters, así que si NO los creaste, NO va a funcionar (igual, si copypasteaste mi ejemplo, todo funcionará OK).
Y ahora.... EMPIEZAN LOS XMLs FEOS!!!
4.0 - Episodio 4: El ataque de las configuraciones.
La configuracion esta dada por dos archivos (por ahora):
application-context.xml
Asocia los servicios con un nombre string. En realidad, también se usa para todo lo que sea Modelado de datos (Hibernate...), pero como no accedemos a una BD por ahora, usamos esto :P.
Antes de que cierre el tag "/beans", escribimos:
<bean name="loguearUsuario" class="Servicios.loguearUsuario" />
Aca asociamos la clase Servicios.loguearUsuario , con el nombre string
"loguearUsuario" (si, no tuve mucha imaginación :P).
dispatcher-servlet.xml
Aca colocamos los Controles.
Lo importante de un control de este tipo es:
- Saber su "Nombre String" (en este caso, lo llamare loginController, osea, con minuscula).
- Saber que servicio utiliza (why? I don't know).
- Decirle por que web entra (url). En este caso, pondremos "miLogin.htm".
¿Como haremos esto?
Busquen una linea en la que diga: property names="mappings" y dentro de "props", escriban:
<prop key="miLogin.htm">loginController</prop>
Aca asociamos la URL a el loginController.
Ahora, asociemos la clase LoginController, con el nombre string loginController (letra L en minuscula :P)
Antes de que cierre el ultimo tag beans (osea, la ultima linea), coloquen:
<bean name = "loginController" class="controladores.LoginController" p:loguearUsuario-ref="loguearUsuario"/>
Aca asociamos el nombre string, y el servicio con el control.
Y ahora DENLE RUN! E intenten meterse a la web cuya url termine en "miLogin.htm"
en mi caso, es "http://localhost:8084/WebFront/miLogin.htm" :P
Si no funciona, avisen :P
6 comentarios:
Hola: solo queria felicitarte por compartir esta informacion sobre Sprint, yo me estoy comenzando en este framework y me hizo de mucha ayuda ver tu trabajo. me preguntaba si me puedes pasar tu proyecto solo para respaldarla jajaja... este es mi correo
omar1204@gmail.com
Excelente me salvaste la vida! muy bien explicado gracias.
Una pregunta en esta parte del codigo if (usr.getUsr().equals("pablo"))
return "usuario valido! :D";
return "cualquiera mandaste";
por ejm como seria si deseo que salga el nombre del usuario
return "usuario valido" + (nombre de usuario);
como obtengo o como hago la referencia para que me muestre el nombre del usuario?
Buenisimo el tutorial, hace ya un tiempo que empece con spring pero si hubiera encontrado este blog me habria ahorrado un buen rato.
Tengo una duda con respecto a los nombres de controladores, es necesario que se componga de 2 palabras? es decir NombreController? o se pueden usar varias palabras NombreLargoController? porque lo he intentado y no me responde
Hola: la información me parece super buena, pues todo esta bien explicado. Lo que no se porque no me funciona, al parecer no están llegando los datos cuando introduzco user y pass... Ya lo he revisado varias veces y nada...
Te agradecería mucho si me facilitaras el proyecto original, para comparar y ver que estoy haciendo mal... Mi correo mmsilva@uci.cu
Grcias de ante mano... :D
Marthika No te puede funcionar porque el ejemplo es una patata (sí, siento ser tan tajante, pero lo es). Mal explicado, nada fundamentado y poco cuidado. Las llaves se abren de una manera a veces, y de otra en otros casos, los nombres de las variables reaprovechados hasta la saciedad de forma que no se sabe lo que es cada cosa. También faltan los import, no explica donde meter los jsp, si van en algún sitio especial (en Netbeans es importante saberlo) y lo de las mayúsculas/minúsculas en los paquetes, pues más de lo mismo. Se nota el "cuidado" que le ha puesto al hacer esto que en el .jsp publicado haya 2 etiquetas
Búscate un tutorial en castellano en javaHispano, que seguramente te facilite más la vida. No desperdicies tu vida en código que te confundirá más que ayudarte.
Publicar un comentario en la entrada