Mostrando las entradas con la etiqueta Java. Mostrar todas las entradas
Mostrando las entradas con la etiqueta Java. Mostrar todas las entradas

16 mayo, 2015

Métodos por defecto en Interfaces de Java 8

En Java 8 se ha introducido un nuevo cambio al uso de interfaces, desde esta versión es posible implementar métodos por defecto en una interface.


public interface Herramienta {
 default public void ajustar(){
  System.out.println("Ajustando herramienta desde interface");
 } 
}


public class HerramientaImpl implements Herramienta {
 public void limpiar(){
  System.out.println("Limpiando herramienta");
 }
}


public class TestHerramienta {
 public static void main(String[] args) {
  HerramientaImpl herramientaImpl= new HerramientaImpl();
  herramientaImpl.ajustar();
 }
}
Un problema de ambiguedad se podría producir cuando una clase implementa dos o mas interfaces que tienen metodos por defecto con el mismo nombre:
public interface HerramientaElectrica{
 default public void ajustar(){
  System.out.println("Ajustando herramienta desde HerramientaElectrica ");
 }
}

public interface HerramientaManual {
 default public void ajustar(){
  System.out.println("Ajustando herramienta desde HerramientaManual ");
 }
}

public class HerramientaImpl implements HerramientaElectrica,HerramientaManual {
 
}

La solución al problema se encuentra en definir una implementación al método por defecto:


public class HerramientaImpl implements HerramientaElectrica,HerramientaManual {
 @Override
 public void ajustar() {
 }
}
Para invocar una implementación del método por defecto lo hacemos sobreescribiendo en nuestra clase
public class HerramientaImpl implements HerramientaElectrica,HerramientaManual {
 @Override
 public void ajustar() {
  HerramientaElectrica.super.ajustar();
 }
}

26 octubre, 2013

Hola Mundo con Spring MVC

Tipicamente cuando incursionamos con un nuevo framework o lenguaje de programacion queremos rapidamente hacer funcionar algo, y como estoy dedicando una serie de articulos a Spring Framework, no podia faltar uno dedicado al simple y bien ponderado "Hola Mundo"... La idea es mostrar como construir el Skeleton fundamental para que nuestra aplicacion Spring MVC funcione...
Para realizar este ejemplo como la mayoria de los publicados aqui usaré:
  • Eclipse (Juno) como IDE
  • Maven (plugin de eclipse) para incluir facilmente librerias y dependencias
  • Tomcat 7
  • Spring Framework (en este ejemplo la version 3.01)

Configurando el nuevo proyecto

Lo primero es crear un nuevo proyecto, para esto podemos usar clic derecho la ventana de Package Explorer o bien en Archivo->New->Project y seleccionar Maven Project
Luego seleccionado Maven Project le damos Next, para seleccionar el nombre y la ubicacion del proyecto, en esta oportunidad todos los valores quedan por defecto y ademas debemos seleccionar el checkbox "Create a simple project (skip archetype selection)" para saltarnos la selección de arquetipo puesto que lo crearemos nosotros mismos...
Ahora introducimos informacion de configuracion del proyecto como el grupo, artefacto, version y forma de empaquetamiento, en este caso el Group Id es com.codelious.mimvc, el Artifact Id es MiMVC y en Packaging seleccionamos war, la version queda por defecto...
Luego damos clic en Finish y deberiamos tener nuestro proyecto creado con una estructura basica que incluye los directorios src/main/webapp y tambien se ha creado nuestro archivo pom.xml que nos permitira el facil manejo de dependencias con Maven.
Dentro de nuestro directorio webapp debemos crear manualmente algunos directorios y archivos para que se vea finalmente una estructura como la de la imagen abajo...

Incluyendo dependencias Maven

Ahora debemos incluir algunas dependencias y las librerias de Spring Framework en nuestro archivo pom.xml para que Maven las cargue a nuestro proyecto, editemos el contenido del pom.xml para que quede asi:

<project xmlns="http://maven.apache.org/POM/4.0.0" 
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 <modelVersion>4.0.0</modelVersion>
 <groupId>com.codelious.mimvc</groupId>
 <artifactId>MiMVC</artifactId>
 <version>0.0.1-SNAPSHOT</version>
 <packaging>war</packaging>
 <dependencies>
  <dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-webmvc</artifactId>
   <version>3.0.1.RELEASE</version>
  </dependency>
  <dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-context</artifactId>
   <version>3.0.1.RELEASE</version>
  </dependency>
  <dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-core</artifactId>
   <version>3.0.1.RELEASE</version>
  </dependency>
  <dependency>
   <groupId>commons-logging</groupId>
   <artifactId>commons-logging</artifactId>
   <version>1.1.1</version>
  </dependency>
  <dependency>
   <groupId>javax.servlet</groupId>
   <artifactId>jstl</artifactId>
   <version>1.2</version>
  </dependency>
 </dependencies>
</project> 

Configurando nuestra aplicación

Luego de añadir las dependencias, debemos codificar nuestro archivo web.xml que es el descriptor de despliegue, y ahi debemos incluir las referencias a nuestro Dispatcher Servlet que es basicamente el despachador de solicitudes a controladores.

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns="http://java.sun.com/xml/ns/javaee" 
 xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
 xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
 http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
 id="WebApp_ID" version="3.0">
 
 <display-name>MiMVC</display-name>
 
 <welcome-file-list>
  <welcome-file>index.jsp</welcome-file>
 </welcome-file-list>

 <servlet>
  <servlet-name>despachador</servlet-name>
  <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  <load-on-startup>1</load-on-startup>
 </servlet>
 
 <servlet-mapping>
  <servlet-name>despachador</servlet-name>
  <url-pattern>*.html</url-pattern>
 </servlet-mapping>

</web-app>
Como se puede notar en el web.xml arriba, tenemos un <servlet> y un <servlet-mapping>, el servlet-mapping trabaja direccionando todos los patrones de url que incluyan extension .html a nuestro dispatcher servlet llamado despachador que es de clase org.springframework.web.servlet.DispatcherServlet, por tanto no es coincidencia que hayamos creado un archivo despachador-servlet.xml, ya que spring buscará un archivo con nombre compuesto por el nombre del servlet añadiendo "-servlet.xml" o sea si en el archivo web.xml estamos declarando el dispatcher servlet con <servlet-name>mascotas</servlet-name> entonces se buscará el archivo mascotas-servlet.xml
También tenemos <welcome-file-list> que permite indicar la pagina de entrada a la aplicacion, la que en este caso sera index.jsp

Ahora codificamos el dispatcher servlet llamado despachador-servlet.xml añadiendo bean viewResolver y un component-scan:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
 http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
 http://www.springframework.org/schema/context
 http://www.springframework.org/schema/context/spring-context-3.0.xsd">
 
    <context:component-scan
        base-package="com.codelious.mimvc.controller" />
         
    <bean id="viewResolver"
        class="org.springframework.web.servlet.view.UrlBasedViewResolver">
        <property name="viewClass"
            value="org.springframework.web.servlet.view.JstlView" />
        <property name="prefix" value="/WEB-INF/jsp/" />
        <property name="suffix" value=".jsp" />
    </bean>
    
</beans>
El bean context:component-scan resaltado arriba permitirá escanear automáticamente todos los controladores ubicados en el paquete com.codelious.mimvc.controller, tambien es posible declarar  varios beans por separado que invocan directamente a cada controlador.
El bean viewResolver nos permitirá resolver las vistas de nuestra aplicación cuando las invoquemos desde nuestros controladores y en este caso indica la ubicacion de las vistas.

Codificando la pagina de entrada

Como mencionamos en el archivo de configuracion web.xml declaramos una pagina de entrada a la aplicacion, para esto agreguemos el siguiente codigo a index.jsp
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
 pageEncoding="ISO-8859-1"%>
<!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=ISO-8859-1">
<title>MiMVC</title>
</head>
<body>
 <h1>Bienvenido a MiMVC</h1>
 <p>
  Presiona el link para ver el <a href="saludar.html">saludo</a>
 </p>
</body>
</html>

Creando el controlador

Vamos a crear un contralador llamado "Saludo" que recibira nuestra solicitud desde la pagina de entrada index.jsp y luego nos direccionará a la vista de saludo, para esto debemos crear en src/main/java el paquete com.codelious.mimvc.controller donde crearemos la clase SaludoController.java y le agregaremos el siguiente codigo:
package com.codelious.mimvc.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class SaludoController {

 @RequestMapping("/saludar")
 public ModelAndView saludar(){
  
  String mensaje = "Hola Mundo Maravilloso";
  return new ModelAndView("saludo", "mensaje", mensaje);
  
 }
}
En el codigo hemos creado un metodo saludar() que devuelve ModelAndView y es el metodo que procesará nuestra solicitud y nos direccionará a la vista deseada, luego hemos puesto un par de anotaciones de Spring, la primera es @Controller e indica que la clase es un controlador, la segunda es @RequestMapping("/saludar") que permite mapear la solicitud desde la url. El metodo saludar() nos retornará un objeto ModelAndView al cual le indicamos la vista que en nuestro caso sera saludo.jsp, luego incluimos un mensaje que estará disponible en nuestra vista para accederlo mediante tags jstl.

Creando la vista

Para nuestra vista crearemos en WEB-INF/jsp el archivo saludo.jsp en el cual agregaremos nuestro codigo:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
 pageEncoding="ISO-8859-1"%>
<!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=ISO-8859-1">
<title>MiMVC</title>
</head>
<body>
 <h1>${mensaje}</h1>
</body>
</html>

Probando la aplicacion

Hecho todo lo anterior deberiamos tener una estructura similar a la siguiente:
y entonces ya podemos probar nuestra aplicación en un navegador web, para eso podemos dar clic derecho sobre la raiz de nuestro proyecto y seleccionar Run As->Run on Server y verlo en la direccion http://localhost:18080/MiMVC/ (reemplazar el puerto 18080 por el que uses)
Si damos clic al link saludo estaremos haciendo la llamada al controlador y este nos devolvera la pagina saludo.jsp
Y esto sería todo, ya tenemos nuestro hola mundo MVC en Spring Framework. Si quieres descargar el proyecto completo puedes hacerlo en github: https://github.com/codelious/MiMVC

20 octubre, 2013

Spring Framework y Vistas XSLT

XSLT es un lenguaje de transformación para XML y es popular como una tecnología de vistas con aplicaciones web. XSLT puede ser una buena elección como una tecnología de vista si tu aplicación naturalmente negocia con XML, o si tu modelo puede ser fácilmente convertido a XML. Este post muestra como producir un documento XML como modelo de datos y tenerlo transformado con XSLT en una aplicación Spring Web MVC.

Este ejemplo es una aplicación trivial de Spring que crea una lista de palabras en el Controlador y las agrega al mapa de modelo. El mapa es retornado junto con el nombre de vista de nuestra vista XSLT. La vista XSLT pondrá la lista de palabras en un documento simple XML listo para la transformación.

La estructura de la aplicacion

Nuestra aplicacion es una aplicacion Simple de Maven y deberá tener una estructura similar a esto:


Usando Maven

Como yo estoy usando Maven para el manejo de las dependencias de la aplicacion, mi archivo pom.xml se ve asi:
<project xmlns="http://maven.apache.org/POM/4.0.0" 
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
            xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
                    http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.codelious.mixslt</groupId>
  <artifactId>MiXSLT</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>war</packaging>
  <dependencies>
   <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>3.0.1.RELEASE</version>
   </dependency>
   <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    <version>3.0.1.RELEASE</version>
   </dependency>
   <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-web</artifactId>
    <version>3.0.1.RELEASE</version>
   </dependency>
   <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>3.0.1.RELEASE</version>
   </dependency>
   <dependency>
    <groupId>jstl</groupId>
    <artifactId>jstl</artifactId>
    <version>1.2</version>
   </dependency>
   <dependency>
    <groupId>commons-logging</groupId>
    <artifactId>commons-logging</artifactId>
    <version>1.1.1</version>
   </dependency>
   <dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>servlet-api</artifactId>
    <version>2.5</version>
   </dependency>
  </dependencies>
</project>

Los archivos de configuracion y dispatcher sevlet

El archivo web.xml tiene el siguiente aspecto:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns="http://java.sun.com/xml/ns/javaee" 
 xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
 xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
 http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
 id="WebApp_ID" version="3.0">
 
 <display-name>MiXSLT</display-name>
 
 <welcome-file-list>
  <welcome-file>index.jsp</welcome-file>
 </welcome-file-list>

 <servlet>
  <servlet-name>spring</servlet-name>
  <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  <load-on-startup>1</load-on-startup>
 </servlet>
 
 <servlet-mapping>
  <servlet-name>spring</servlet-name>
  <url-pattern>*.htm</url-pattern>
 </servlet-mapping>

</web-app>
y El archivo spring-servlet.xml que es nuestro despachador de solicitudes sigue asi:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
 xmlns:p="http://www.springframework.org/schema/p"
 xmlns:context="http://www.springframework.org/schema/context"
 xsi:schemaLocation="http://www.springframework.org/schema/beans
      http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
      http://www.springframework.org/schema/context
      http://www.springframework.org/schema/context/spring-context-3.0.xsd">

 <bean id="viewResolver"
  class="org.springframework.web.servlet.view.ResourceBundleViewResolver">
  <property name="order">
   <value>1</value>
  </property>
  <property name="basename" value="views" />
 </bean>
 
 <bean id="xsltViewResolver"
  class="org.springframework.web.servlet.view.xslt.XsltViewResolver">
  <property name="order">
   <value>2</value>
  </property>
  <property name="viewClass"
   value="org.springframework.web.servlet.view.xslt.XsltView" />
  <property name="sourceKey" value="obj" />
  <property name="suffix" value=".xsl" />
  <property name="prefix" value="/WEB-INF/xsl/" />
 </bean>

 <bean id="simpleUrlMapping"
  class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
  <property name="mappings">
   <value>
    /home.htm=homeController
   </value>
  </property>
 </bean>

 <bean id="homeController" class="com.codelious.mixslt.controller.HomeController" /> 
</beans>

Definicion de Beans

Como se ve arriba, la configuracion es estandar para una aplicacion simple de Spring. El archivo de configuracion de dispatcher servlet contiene una referencia a un ViewResolver, URL mappings y un Bean de controlador que encapsula nuestra logica de generacion de palabras:
<bean id="homeController" class="com.codelious.mixslt.controller.HomeController" />

Codigo del Controlador MVC

La logica del controlador es encapsulada en una subclase de AbstractController, con el metodo handler que se define como sigue...
package com.codelious.mixslt.controller;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.AbstractController;

public class HomeController extends AbstractController {

    protected ModelAndView handleRequestInternal(HttpServletRequest request,
        HttpServletResponse response) throws Exception {
  
        Map mapa = new HashMap();
        List listaPalabras = new ArrayList();
  
        listaPalabras.add("Hola");
        listaPalabras.add("Universo");
  
        mapa.put("listaPalabras", listaPalabras);
  
        return new ModelAndView("home", mapa);
    }

}
Hasta aqui no tenemos nada especifico de XSLT. Los datos del modelo han sido creados en la misma forma en que hariamos otra aplicacion Spring MVC. Dependiendo de la configuracion de la aplicacion, esta lista de palabras podria ser renderizada por JSP/JSTL teniendolas agregadas como atributos en la solicitud (request attributes), o podrian ser manipuladas por Velocity agregando el objeto al VelocityContext. Para tener XSLT renderizalos, y por supuesto tienen que ser convertidos en un documento XML de alguna manera. Existen paquetes de software que automaticamente 'DOMifican' los objetos, pero con Spring, tienes completa flexibilidad para crear el DOM desde tu modelo en cualquier forma que quieras. Esto evita el juego exesivo con la transformacion de XML, lo cual es peligroso cuando usamos herramientas para manejar procesos de DOMificacion

Convertir los datos del modelo a XML

Para crear un documento DOM desde nuestra lista de palabras o cualquier otro dato del modelo, debemos extender de la clase org.springframework.web.servlet.view.xslt.AbstractXsltView. Haciendo esto, debemos tambien implementar el metodo abstracto createXsltSource(..). El primer parametro pasado a este metodo es nuestro mapa del modelo. Aqui esta la clase HomePage en nuestra aplicacion:
package com.codelious.mixslt.controller;

import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Source;
import javax.xml.transform.dom.DOMSource;

import org.springframework.web.servlet.view.xslt.AbstractXsltView;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Text;

public class HomePage extends AbstractXsltView {

    protected Source createXsltSource(Map modelo, String nombreRaiz,
        HttpServletRequest request, HttpServletResponse response)
        throws Exception {

        Document documento = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
        Element raiz = documento.createElement(nombreRaiz);

        List palabras = (List) modelo.get("listaPalabras");
        for (Iterator it = palabras.iterator(); it.hasNext();) {
            String palabraSiguiente = (String) it.next();
            Element nodoPalabra = documento.createElement("palabra");
            Text nodoTexto = documento.createTextNode(palabraSiguiente);
            nodoPalabra.appendChild(nodoTexto);
            raiz.appendChild(nodoPalabra);
        }
        return new DOMSource(raiz);
    }
}

Una serie de parametros nombre/valor pueden ser definidos opcionalmente por tu subclase la cual sera agregado al objeto de transformacion. Los nombres de parametro deben coincidir con los definidos en la plantilla XSLT declarados con <xsl:param name="miParametro">valorDefecto</xsl:param><bean id="homeController" class="xslt.HomeController" />. Para especificar los parametros, sobreescribe el metodo getParameters() de la clase AbstractXsltView y retorna un Map de nombre/valor. Si tus parametros necesitan derivar informacion desde la solicitud actual, tu puedes sobreescribir el metodo getParameters(HttpServletRequest request) en su lugar.

Definiendo las propiedades de la vista

El archivo views.properties (o definicion xml equivalente si estas usando un view resolver basado en XML) luce como este para la unica vista de la aplicacion que es 'Mis Primeras Palabras':
home.(class)=com.codelious.mixslt.controller.HomePage 
home.stylesheetLocation=/WEB-INF/xsl/home.xsl
home.root=palabras
Aqui, puedes ver como la vista esta enlazada con la clase HomePage recien escrita la cual maneja el modelo domificacion en la primera propiedad '.class'. La propiedad 'stylesheetLocation' apunta al archivo XSLT el cual manipulara para nosotros la transformacion XML dentro de HTML y la propiedad final '.root' es el nombre que sera usado como la raiz del documento XML. Este obtiene acceso a la clase HomePage de arriba en el segundo parametro para los metodos createXsltSource(..).

Transformacion del documento

Finalmente, tenemos el codigo XSLT usado para transformar el documento de arriba. Como muestra en el archivo 'views.properties', la hoja de estilos es llamada 'home.xslt' y esta ubicada en el directorio 'WEB-INF/xsl'.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="html" omit-xml-declaration="yes" />

    <xsl:template match="/">
        <html>
            <head>
                <title>Hola!</title>
            </head>
            <body>
                <h1>Mis Primeras Palabras</h1>
                <xsl:apply-templates />
            </body>
        </html>
    </xsl:template>

    <xsl:template match="palabra">
        <xsl:value-of select="." />
    </xsl:template>
</xsl:stylesheet>

El archivo index.jsp solamente es la pagina de entrada a la aplicacion y en ella hemos puesto un link a nuestro controlador http://localhost:18080/MiXSLT/home.htm
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
 pageEncoding="ISO-8859-1"%>
<!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=ISO-8859-1">
        <title>MiXSLT</title>
    </head>
    <body>
        <h1>Bienvenido a mi XSLT</h1>
        Prueba la vista XSL en <a href="http://localhost:18080/MiXSLT/home.htm">
                      http://localhost:18080/MiXSLT/home.htm</a>
    </body>
</html>

Solo nos queda probar nuestra aplicacion en un navegador usando la pagina de entrada o bien directamente escribiendo la url http://localhost:18080/MiXSLT/home.htm y deberia verse algo asi:
Puedes descargarte el codigo en github https://github.com/codelious/Spring_XSL_views