<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="es">
		<id>https://dosideas.com/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=201.251.182.130</id>
		<title>Dos Ideas. - Contribuciones del usuario [es]</title>
		<link rel="self" type="application/atom+xml" href="https://dosideas.com/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=201.251.182.130"/>
		<link rel="alternate" type="text/html" href="https://dosideas.com/wiki/Especial:Contribuciones/201.251.182.130"/>
		<updated>2026-06-13T17:55:51Z</updated>
		<subtitle>Contribuciones del usuario</subtitle>
		<generator>MediaWiki 1.28.2</generator>

	<entry>
		<id>https://dosideas.com/wiki/index.php?title=Web_Service_con_Axis_2&amp;diff=6397</id>
		<title>Web Service con Axis 2</title>
		<link rel="alternate" type="text/html" href="https://dosideas.com/wiki/index.php?title=Web_Service_con_Axis_2&amp;diff=6397"/>
				<updated>2011-10-03T19:30:57Z</updated>
		
		<summary type="html">&lt;p&gt;201.251.182.130: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Axis 2 es un framework para el desarrollo y consumo de Webservices en Java, e intenta solucionar algunos temas pendientes de su predecesor Axis 1.&lt;br /&gt;
&lt;br /&gt;
A continuación haremos un proyecto prototipo, partiendo de un WSDL de un servicio sencillo de calculadora.&lt;br /&gt;
&lt;br /&gt;
== Pasos: ==&lt;br /&gt;
&lt;br /&gt;
==== Crear un proyecto Web con Netbeans ====&lt;br /&gt;
Utilizaremos el nombre DosIdeas-Axis2 para el proyecto.&lt;br /&gt;
==== Agregar la librería Axis 2 al proyecto ====&lt;br /&gt;
Como puede ser que no este instalada, deberemos bajarla del sitio Web (http://ws.apache.org/axis2/download/1_4_1/download.cgi). Utilizaremos la versión 1.4.1 que es la última versión compatible con Java 1.4.&lt;br /&gt;
En la versión 1.5 de Axis 2 cambia bastante la forma de construir Web Services, pero no será visto en este tutorial.&lt;br /&gt;
&lt;br /&gt;
El proyecto viene con muchas mas librerías de las que son estrictamente necesarias para el ejemplo. No obstante, para simplificar incorporaremos todas.&lt;br /&gt;
==== Agregar Spring 2.5 o posterior ====&lt;br /&gt;
Si bien no es imprescindible para el funcionamiento, permite una clara separación de la lógica de negocio de la implementación del servicio Web.&lt;br /&gt;
==== Copiar WSDL de ejemplo al proyecto ====&lt;br /&gt;
Para este proyecto, tenemos un WSDL de un servicio Calculadora, que tiene 2 operaciones:&lt;br /&gt;
* dividir (división entera)&lt;br /&gt;
* sumar&lt;br /&gt;
&lt;br /&gt;
La operación dividir necesita 2 parámetros, dividendo y divisor y devuelve 2 valores, cociente y resto. Además debe devolver un mensaje de error en caso que el divisor sea 0.&lt;br /&gt;
&lt;br /&gt;
==== Generar código java a partir de un documento WSDL ====&lt;br /&gt;
Axis 2 viene con un generador de código que ahorra al usuario la construcción de todas clases necesarias para la implementación de WebServices.&lt;br /&gt;
En este caso utilizaremos una tarea Ant para construir dichas clases. En caso de trabajar con Eclipse, también tendremos la posibilidad de utilizar el plugin de Web Services, que viene con la distribución JEE del IDE.&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;property name=&amp;quot;axis2.home&amp;quot; value=&amp;quot;D:/development/axis2-1.4.1&amp;quot; /&amp;gt;&lt;br /&gt;
    &amp;lt;property name=&amp;quot;output.wsdl2java.dir&amp;quot; value=&amp;quot;build/codegen&amp;quot; /&amp;gt;&lt;br /&gt;
    &amp;lt;property name=&amp;quot;src.dir&amp;quot; value=&amp;quot;src/java&amp;quot; /&amp;gt;&lt;br /&gt;
    &amp;lt;!-- No resuelve bien el path local la tarea Ant --&amp;gt;&lt;br /&gt;
    &amp;lt;property name=&amp;quot;wsdl.uri&amp;quot; value=&amp;quot;resources/wsdl/CalculadoraService.wsdl&amp;quot; /&amp;gt;&lt;br /&gt;
    &amp;lt;property name=&amp;quot;services.folder&amp;quot; value=&amp;quot;web/WEB-INF/services&amp;quot; /&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
    &amp;lt;property name=&amp;quot;service.name&amp;quot; value=&amp;quot;CalculadoraService&amp;quot; /&amp;gt;&lt;br /&gt;
    &amp;lt;!-- No resuelve bien el path local la tarea Ant --&amp;gt;&lt;br /&gt;
    &amp;lt;property name=&amp;quot;service.wsdl.uri&amp;quot; value=&amp;quot;resources/wsdl/${service.name}.wsdl&amp;quot; /&amp;gt;&lt;br /&gt;
    &amp;lt;property name=&amp;quot;service.folder&amp;quot; value=&amp;quot;${services.folder}/${service.name}/META-INF&amp;quot; /&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
        &lt;br /&gt;
    &amp;lt;path id=&amp;quot;axis2.classpath&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;fileset dir=&amp;quot;${axis2.home}/lib&amp;quot;&amp;gt; &lt;br /&gt;
            &amp;lt;include name=&amp;quot;**/*.jar&amp;quot; /&amp;gt;&lt;br /&gt;
        &amp;lt;/fileset&amp;gt;&lt;br /&gt;
    &amp;lt;/path&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
    &amp;lt;target name=&amp;quot;run-wsdl2java-server&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;mkdir dir=&amp;quot;${output.wsdl2java.dir}&amp;quot; /&amp;gt;&lt;br /&gt;
        &amp;lt;delete dir=&amp;quot;${output.wsdl2java.dir}&amp;quot; includeemptydirs=&amp;quot;true&amp;quot; /&amp;gt;&lt;br /&gt;
        &amp;amp;lt;java classname=&amp;quot;org.apache.axis2.wsdl.WSDL2Java&amp;quot; fork=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
          &amp;lt;classpath refid=&amp;quot;axis2.classpath&amp;quot;/&amp;gt; &lt;br /&gt;
          &amp;lt;arg value=&amp;quot;-uri&amp;quot;/&amp;gt;&amp;lt;arg file=&amp;quot;${wsdl.uri}&amp;quot;/&amp;gt;&lt;br /&gt;
          &amp;lt;arg value=&amp;quot;-ss&amp;quot;/&amp;gt;&lt;br /&gt;
          &amp;lt;arg value=&amp;quot;-g&amp;quot;/&amp;gt;&lt;br /&gt;
          &amp;lt;arg value=&amp;quot;-sd&amp;quot;/&amp;gt;&lt;br /&gt;
          &amp;lt;arg value=&amp;quot;-o&amp;quot;/&amp;gt;&amp;lt;arg file=&amp;quot;${output.wsdl2java.dir}&amp;quot;/&amp;gt;&lt;br /&gt;
        &amp;amp;lt;/java&amp;gt;&lt;br /&gt;
        &amp;lt;!-- Move the schema folder to classpath--&amp;gt;&lt;br /&gt;
        &amp;lt;copy todir=&amp;quot;${src.dir}&amp;quot; overwrite=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;fileset dir=&amp;quot;${output.wsdl2java.dir}/src&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;include name=&amp;quot;**/*.java&amp;quot;/&amp;gt;&lt;br /&gt;
            &amp;lt;/fileset&amp;gt;&lt;br /&gt;
        &amp;lt;/copy&amp;gt;&lt;br /&gt;
        &amp;lt;mkdir dir=&amp;quot;${service.folder}&amp;quot; /&amp;gt;&lt;br /&gt;
        &amp;lt;delete dir=&amp;quot;${service.folder}&amp;quot; includeemptydirs=&amp;quot;true&amp;quot; /&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
        &amp;lt;mkdir dir=&amp;quot;${service.folder}/service&amp;quot; /&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
        &amp;lt;copy todir=&amp;quot;${service.folder}/service&amp;quot; overwrite=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;fileset dir=&amp;quot;${output.wsdl2java.dir}/resources&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;include name=&amp;quot;**/*&amp;quot;/&amp;gt;&lt;br /&gt;
            &amp;lt;/fileset&amp;gt;&lt;br /&gt;
        &amp;lt;/copy&amp;gt;&lt;br /&gt;
    &amp;lt;/target&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Esta tarea Ant generará todas las clases involucradas en el Web Service y una serie de archivos, incluyendo la clase que contendrá la lógica de negocio, la cual vendrá con implementaciones dummy.&lt;br /&gt;
Luego se copiaran los clases java al directorio de fuentes y por último se copiará el archivo de configuración y el wsdl al directorio de servicio predeterminado de Axis.&lt;br /&gt;
&lt;br /&gt;
==== Implementar lógica de negocio ==== &lt;br /&gt;
De las clases generadas, la única que tendremos que implementar es la que tiene el sufijo Skeleton. En caso que implementaramos la lógica aquí, sería poco reutilizable, por lo que haremos en un paso siguiente una clase con la lógica de negocio y en el Skeleton tan solo invocaremos dicha clase.&lt;br /&gt;
&lt;br /&gt;
    public class CalculadoraServiceSkeleton {&lt;br /&gt;
        &lt;br /&gt;
        protected CalculadoraBo calculadoraBo = null;&lt;br /&gt;
        &lt;br /&gt;
        public CalculadoraBo getCalculadoraBo() {&lt;br /&gt;
            return calculadoraBo;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        public void setCalculadoraBo(CalculadoraBo calculadoraBo) {&lt;br /&gt;
            this.calculadoraBo = calculadoraBo;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        /**&lt;br /&gt;
         * Auto generated method signature&lt;br /&gt;
         * &lt;br /&gt;
         * @param divisionSolicitud&lt;br /&gt;
         * @throws DivisionPorCeroError : &lt;br /&gt;
         */&lt;br /&gt;
        public com.dosideas.www.cursos.calculadora.DivisionRespuesta dividir(&lt;br /&gt;
                com.dosideas.www.cursos.calculadora.DivisionSolicitud divisionSolicitud)&lt;br /&gt;
                throws DivisionPorCeroError {&lt;br /&gt;
            int divisor = divisionSolicitud.getDivisor();&lt;br /&gt;
            int dividendo = divisionSolicitud.getDividendo();&lt;br /&gt;
            try {&lt;br /&gt;
                int cociente = calculadoraBo.divide(dividendo, divisor);&lt;br /&gt;
                int resto = calculadoraBo.modulo(dividendo, divisor);&lt;br /&gt;
                DivisionRespuesta rta = new DivisionRespuesta();&lt;br /&gt;
                rta.setCociente(cociente);&lt;br /&gt;
                rta.setResto(resto);&lt;br /&gt;
                return rta;&lt;br /&gt;
            } catch (ArithmeticException e) {&lt;br /&gt;
                DivisionPorCeroException error = new DivisionPorCeroException();&lt;br /&gt;
                // En caso que no se setee el objeto descripcion, tira un error genérico AxisFault&lt;br /&gt;
                DivisionPorCero div = new DivisionPorCero();&lt;br /&gt;
                // Si no se llenan todos los campos obligatorios, devuelve error 500 de http&lt;br /&gt;
                div.setDivisionPorCero(&amp;quot;Descripcion del error&amp;quot;);&lt;br /&gt;
                error.setFaultMessage(div);&lt;br /&gt;
                throw error;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        /**&lt;br /&gt;
         * Auto generated method signature&lt;br /&gt;
         * &lt;br /&gt;
         * @param sumaSolicitud&lt;br /&gt;
         */&lt;br /&gt;
        public com.dosideas.www.cursos.calculadora.SumaRespuesta sumar(&lt;br /&gt;
                com.dosideas.www.cursos.calculadora.SumaSolicitud sumaSolicitud) {&lt;br /&gt;
            SumaRespuesta rta = new SumaRespuesta();&lt;br /&gt;
            rta.setNumero(calculadoraBo.sum(sumaSolicitud.getNumero1(), sumaSolicitud.getNumero2()));    &lt;br /&gt;
            return rta;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
Se recomienda prestar especial atención al tratamiento de los errores custom.&lt;br /&gt;
Cada error de negocio cuenta con un tipo interno, que contiene la descripción del error. En caso de no llenar dicha descripción, se lanzará un error genérico AxisFault.&lt;br /&gt;
Además hay que tener especial cuidado al llenar dicha descripción. En caso que no se cumpla con el formato, Axis devuelve un error http 500, en vez de un error descriptivo.&lt;br /&gt;
Luego se crea la clase con la lógica de negocio, la cual después se inyectará en la clase Skeleton via Spring&lt;br /&gt;
&lt;br /&gt;
    public class CalculadoraBo {&lt;br /&gt;
        public int sum(int n1, int n2) {&lt;br /&gt;
            return n1 + n2;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        public int divide(int n1, int n2){&lt;br /&gt;
            return n1 / n2;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        public int modulo(int n1, int n2){&lt;br /&gt;
            return n1 % n2;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
==== Configurar descriptores de Spring ====&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;bean id=&amp;quot;applicationContext&amp;quot; &lt;br /&gt;
        class=&amp;quot;org.apache.axis2.extensions.spring.receivers.ApplicationContextHolder&amp;quot; /&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
    &amp;lt;bean id=&amp;quot;calculadoraBo&amp;quot; class=&amp;quot;com.dosideas.business.CalculadoraBo&amp;quot;&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
    &amp;lt;/bean&amp;gt;&lt;br /&gt;
    &amp;lt;bean id=&amp;quot;calculadoraService&amp;quot; class=&amp;quot;com.dosideas.www.cursos.calculadora.CalculadoraServiceSkeleton&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;property name=&amp;quot;calculadoraBo&amp;quot; ref=&amp;quot;calculadoraBo&amp;quot; /&amp;gt;&lt;br /&gt;
    &amp;lt;/bean&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Configurar web.xml ====&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;&lt;br /&gt;
    &amp;lt;web-app version=&amp;quot;2.4&amp;quot; xmlns=&amp;quot;http://java.sun.com/xml/ns/j2ee&amp;quot; &lt;br /&gt;
    xmlns:xsi=&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot; &lt;br /&gt;
    xsi:schemaLocation=&amp;quot;http://java.sun.com/xml/ns/j2ee &lt;br /&gt;
    http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;context-param&amp;gt;&lt;br /&gt;
            &amp;lt;param-name&amp;gt;contextConfigLocation&amp;lt;/param-name&amp;gt;&lt;br /&gt;
            &amp;lt;param-value&amp;gt;/WEB-INF/applicationContext.xml&amp;lt;/param-value&amp;gt;&lt;br /&gt;
        &amp;lt;/context-param&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
        &amp;lt;listener&amp;gt;&lt;br /&gt;
            &amp;lt;listener-class&amp;gt;org.springframework.web.context.ContextLoaderListener&amp;lt;/listener-class&amp;gt;&lt;br /&gt;
        &amp;lt;/listener&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
        &amp;lt;servlet&amp;gt;&lt;br /&gt;
            &amp;lt;display-name&amp;gt;Apache-Axis Servlet&amp;lt;/display-name&amp;gt;&lt;br /&gt;
            &amp;lt;servlet-name&amp;gt;AxisServlet&amp;lt;/servlet-name&amp;gt;&lt;br /&gt;
            &amp;lt;servlet-class&amp;gt;org.apache.axis2.transport.http.AxisServlet&amp;lt;/servlet-class&amp;gt;&lt;br /&gt;
        &amp;lt;/servlet&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
        &amp;lt;servlet-mapping&amp;gt;&lt;br /&gt;
            &amp;lt;servlet-name&amp;gt;AxisServlet&amp;lt;/servlet-name&amp;gt;&lt;br /&gt;
            &amp;lt;url-pattern&amp;gt;/services/*&amp;lt;/url-pattern&amp;gt;&lt;br /&gt;
        &amp;lt;/servlet-mapping&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
        &amp;lt;welcome-file-list&amp;gt;&lt;br /&gt;
            &amp;lt;welcome-file&amp;gt;index.jsp&amp;lt;/welcome-file&amp;gt;&lt;br /&gt;
        &amp;lt;/welcome-file-list&amp;gt;&lt;br /&gt;
    &amp;lt;/web-app&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Modificar services.xml para que use Spring ====&lt;br /&gt;
&lt;br /&gt;
        &amp;lt;parameter name=&amp;quot;ServiceObjectSupplier&amp;quot; locked=&amp;quot;false&amp;quot;&amp;gt;&lt;br /&gt;
        org.apache.axis2.extensions.spring.receivers.SpringAppContextAwareObjectSupplier&amp;lt;/parameter&amp;gt;&lt;br /&gt;
        &amp;lt;parameter name=&amp;quot;SpringBeanName&amp;quot; locked=&amp;quot;false&amp;quot;&amp;gt;calculadoraService&amp;lt;/parameter&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La configuración descrita aquí funciona tanto para Tomcat como para Glassfish.&lt;br /&gt;
En caso que se desee hacer un Web Service para Weblogic o para Websphere, son necesarios algunos pasos adicionales. Se sugiere leer la siguiente nota: [[Web Service con Axis 2 para Weblogic y Websphere]]&lt;br /&gt;
&lt;br /&gt;
==== Sugerencias para la construcción del WSDL ====&lt;br /&gt;
&lt;br /&gt;
* No utilizar las palabras Error o Exception al final de los tipos o de los mensajes Fault. Estas palabras son utilizadas por el generador de código, por lo que luego el código generado será incorrecto.&lt;br /&gt;
* Si se usa la versión 1.4 de Axis 2, no nombrar de la misma forma un mensaje de error que el tipo que contiene. Genera un error extraño en el generador de código, por el que genera 2 excepciones con el nombre del mensaje. Ej: Con el tipo DivisionPorCero, generó DivisionPorCeroException0 y DivisionPorCeroException1.&lt;br /&gt;
&lt;br /&gt;
== Recursos ==&lt;br /&gt;
&lt;br /&gt;
=== WSDL de Calculadora Service ===&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;&lt;br /&gt;
   &amp;lt;wsdl:definitions name=&amp;quot;CalculadoraServiceDefinitions&amp;quot; targetNamespace=&amp;quot;http://www.dosideas.com/cursos/calculadora&amp;quot; xmlns:wsdl=&amp;quot;http://schemas.xmlsoap.org/wsdl/&amp;quot; xmlns:xs=&amp;quot;http://www.w3.org/2001/XMLSchema&amp;quot; xmlns:calc=&amp;quot;http://www.dosideas.com/cursos/calculadora&amp;quot; xmlns:soap=&amp;quot;http://schemas.xmlsoap.org/wsdl/soap/&amp;quot;&amp;gt;&lt;br /&gt;
       &amp;lt;wsdl:types&amp;gt;&lt;br /&gt;
           &amp;lt;xs:schema attributeFormDefault=&amp;quot;unqualified&amp;quot; elementFormDefault=&amp;quot;qualified&amp;quot; targetNamespace=&amp;quot;http://www.dosideas.com/cursos/calculadora&amp;quot;&amp;gt;&lt;br /&gt;
               &amp;lt;xs:element name=&amp;quot;divisionSolicitud&amp;quot;&amp;gt;&lt;br /&gt;
                   &amp;lt;xs:complexType&amp;gt;&lt;br /&gt;
                       &amp;lt;xs:sequence&amp;gt;&lt;br /&gt;
                           &amp;lt;xs:element name=&amp;quot;dividendo&amp;quot; type=&amp;quot;xs:int&amp;quot;/&amp;gt;&lt;br /&gt;
                           &amp;lt;xs:element name=&amp;quot;divisor&amp;quot; type=&amp;quot;xs:int&amp;quot;/&amp;gt;&lt;br /&gt;
                       &amp;lt;/xs:sequence&amp;gt;&lt;br /&gt;
                   &amp;lt;/xs:complexType&amp;gt;&lt;br /&gt;
               &amp;lt;/xs:element&amp;gt;&lt;br /&gt;
               &amp;lt;xs:element name=&amp;quot;divisionRespuesta&amp;quot;&amp;gt;&lt;br /&gt;
                   &amp;lt;xs:complexType&amp;gt;&lt;br /&gt;
                       &amp;lt;xs:sequence&amp;gt;&lt;br /&gt;
                           &amp;lt;xs:element name=&amp;quot;cociente&amp;quot; type=&amp;quot;xs:int&amp;quot;/&amp;gt;&lt;br /&gt;
                           &amp;lt;xs:element name=&amp;quot;resto&amp;quot; type=&amp;quot;xs:int&amp;quot;/&amp;gt;&lt;br /&gt;
                       &amp;lt;/xs:sequence&amp;gt;&lt;br /&gt;
                   &amp;lt;/xs:complexType&amp;gt;&lt;br /&gt;
               &amp;lt;/xs:element&amp;gt;&lt;br /&gt;
               &amp;lt;xs:element name=&amp;quot;divisionPorCero&amp;quot; type=&amp;quot;xs:string&amp;quot;/&amp;gt;&lt;br /&gt;
               &amp;lt;xs:element name=&amp;quot;sumaSolicitud&amp;quot;&amp;gt;&lt;br /&gt;
                   &amp;lt;xs:complexType&amp;gt;&lt;br /&gt;
                       &amp;lt;xs:sequence&amp;gt;&lt;br /&gt;
                           &amp;lt;xs:element name=&amp;quot;numero1&amp;quot; type=&amp;quot;xs:int&amp;quot;/&amp;gt;&lt;br /&gt;
                           &amp;lt;xs:element name=&amp;quot;numero2&amp;quot; type=&amp;quot;xs:int&amp;quot;/&amp;gt;&lt;br /&gt;
                       &amp;lt;/xs:sequence&amp;gt;&lt;br /&gt;
                   &amp;lt;/xs:complexType&amp;gt;&lt;br /&gt;
               &amp;lt;/xs:element&amp;gt;&lt;br /&gt;
               &amp;lt;xs:element name=&amp;quot;sumaRespuesta&amp;quot;&amp;gt;&lt;br /&gt;
                   &amp;lt;xs:complexType&amp;gt;&lt;br /&gt;
                       &amp;lt;xs:sequence&amp;gt;&lt;br /&gt;
                           &amp;lt;xs:element name=&amp;quot;numero&amp;quot; type=&amp;quot;xs:int&amp;quot;/&amp;gt;&lt;br /&gt;
                       &amp;lt;/xs:sequence&amp;gt;&lt;br /&gt;
                   &amp;lt;/xs:complexType&amp;gt;&lt;br /&gt;
               &amp;lt;/xs:element&amp;gt;&lt;br /&gt;
           &amp;lt;/xs:schema&amp;gt;&lt;br /&gt;
       &amp;lt;/wsdl:types&amp;gt;&lt;br /&gt;
       &amp;lt;wsdl:message name=&amp;quot;divisionSolicitud&amp;quot;&amp;gt;&lt;br /&gt;
           &amp;lt;wsdl:part name=&amp;quot;parameters&amp;quot; element=&amp;quot;calc:divisionSolicitud&amp;quot;&amp;gt;&lt;br /&gt;
           &amp;lt;/wsdl:part&amp;gt;&lt;br /&gt;
       &amp;lt;/wsdl:message&amp;gt;&lt;br /&gt;
       &amp;lt;wsdl:message name=&amp;quot;divisionRespuesta&amp;quot;&amp;gt;&lt;br /&gt;
           &amp;lt;wsdl:part name=&amp;quot;parameters&amp;quot; element=&amp;quot;calc:divisionRespuesta&amp;quot;&amp;gt;&lt;br /&gt;
           &amp;lt;/wsdl:part&amp;gt;&lt;br /&gt;
       &amp;lt;/wsdl:message&amp;gt;&lt;br /&gt;
       &amp;lt;wsdl:message name=&amp;quot;divisionPorCero&amp;quot;&amp;gt;&lt;br /&gt;
           &amp;lt;wsdl:part name=&amp;quot;divisionPorCero&amp;quot; element=&amp;quot;calc:divisionPorCero&amp;quot;&amp;gt;&lt;br /&gt;
           &amp;lt;/wsdl:part&amp;gt;&lt;br /&gt;
       &amp;lt;/wsdl:message&amp;gt;&lt;br /&gt;
       &amp;lt;wsdl:message name=&amp;quot;sumarResponse&amp;quot;&amp;gt;&lt;br /&gt;
           &amp;lt;wsdl:part name=&amp;quot;parameters&amp;quot; element=&amp;quot;calc:sumaRespuesta&amp;quot;&amp;gt;&lt;br /&gt;
           &amp;lt;/wsdl:part&amp;gt;&lt;br /&gt;
       &amp;lt;/wsdl:message&amp;gt;&lt;br /&gt;
       &amp;lt;wsdl:message name=&amp;quot;sumarRequest&amp;quot;&amp;gt;&lt;br /&gt;
           &amp;lt;wsdl:part name=&amp;quot;parameters&amp;quot; element=&amp;quot;calc:sumaSolicitud&amp;quot;&amp;gt;&lt;br /&gt;
           &amp;lt;/wsdl:part&amp;gt;&lt;br /&gt;
       &amp;lt;/wsdl:message&amp;gt;&lt;br /&gt;
       &amp;lt;wsdl:portType name=&amp;quot;Calculadora&amp;quot;&amp;gt;&lt;br /&gt;
           &amp;lt;wsdl:operation name=&amp;quot;dividir&amp;quot; parameterOrder=&amp;quot;parameters&amp;quot;&amp;gt;&lt;br /&gt;
               &amp;lt;wsdl:input message=&amp;quot;calc:divisionSolicitud&amp;quot;&amp;gt;&lt;br /&gt;
               &amp;lt;/wsdl:input&amp;gt;&lt;br /&gt;
               &amp;lt;wsdl:output message=&amp;quot;calc:divisionRespuesta&amp;quot;&amp;gt;&lt;br /&gt;
               &amp;lt;/wsdl:output&amp;gt;&lt;br /&gt;
               &amp;lt;wsdl:fault name=&amp;quot;divisionPorCero&amp;quot; message=&amp;quot;calc:divisionPorCero&amp;quot;&amp;gt;&lt;br /&gt;
               &amp;lt;/wsdl:fault&amp;gt;&lt;br /&gt;
           &amp;lt;/wsdl:operation&amp;gt;&lt;br /&gt;
           &amp;lt;wsdl:operation name=&amp;quot;sumar&amp;quot;&amp;gt;&lt;br /&gt;
               &amp;lt;wsdl:input message=&amp;quot;calc:sumarRequest&amp;quot;&amp;gt;&lt;br /&gt;
               &amp;lt;/wsdl:input&amp;gt;&lt;br /&gt;
               &amp;lt;wsdl:output message=&amp;quot;calc:sumarResponse&amp;quot;&amp;gt;&lt;br /&gt;
               &amp;lt;/wsdl:output&amp;gt;&lt;br /&gt;
           &amp;lt;/wsdl:operation&amp;gt;&lt;br /&gt;
       &amp;lt;/wsdl:portType&amp;gt;&lt;br /&gt;
       &amp;lt;wsdl:binding name=&amp;quot;CalculadoraServiceSoapBinding&amp;quot; type=&amp;quot;calc:Calculadora&amp;quot;&amp;gt;&lt;br /&gt;
           &amp;lt;soap:binding style=&amp;quot;document&amp;quot; transport=&amp;quot;http://schemas.xmlsoap.org/soap/http&amp;quot;/&amp;gt;&lt;br /&gt;
           &amp;lt;wsdl:operation name=&amp;quot;dividir&amp;quot;&amp;gt;&lt;br /&gt;
               &amp;lt;soap:operation soapAction=&amp;quot;&amp;quot; style=&amp;quot;document&amp;quot;/&amp;gt;&lt;br /&gt;
               &amp;lt;wsdl:input&amp;gt;&lt;br /&gt;
                   &amp;lt;soap:body parts=&amp;quot;parameters&amp;quot; use=&amp;quot;literal&amp;quot;/&amp;gt;&lt;br /&gt;
               &amp;lt;/wsdl:input&amp;gt;&lt;br /&gt;
               &amp;lt;wsdl:output&amp;gt;&lt;br /&gt;
                   &amp;lt;soap:body parts=&amp;quot;parameters&amp;quot; use=&amp;quot;literal&amp;quot;/&amp;gt;&lt;br /&gt;
               &amp;lt;/wsdl:output&amp;gt;&lt;br /&gt;
               &amp;lt;wsdl:fault name=&amp;quot;divisionPorCero&amp;quot;&amp;gt;&lt;br /&gt;
                   &amp;lt;soap:fault name=&amp;quot;divisionPorCero&amp;quot; use=&amp;quot;literal&amp;quot;/&amp;gt;&lt;br /&gt;
               &amp;lt;/wsdl:fault&amp;gt;&lt;br /&gt;
           &amp;lt;/wsdl:operation&amp;gt;&lt;br /&gt;
           &amp;lt;wsdl:operation name=&amp;quot;sumar&amp;quot;&amp;gt;&lt;br /&gt;
               &amp;lt;soap:operation soapAction=&amp;quot;http://www.dosideas.com/cursos/calculadora/sumar&amp;quot;/&amp;gt;&lt;br /&gt;
               &amp;lt;wsdl:input&amp;gt;&lt;br /&gt;
                   &amp;lt;soap:body use=&amp;quot;literal&amp;quot;/&amp;gt;&lt;br /&gt;
               &amp;lt;/wsdl:input&amp;gt;&lt;br /&gt;
               &amp;lt;wsdl:output&amp;gt;&lt;br /&gt;
                   &amp;lt;soap:body use=&amp;quot;literal&amp;quot;/&amp;gt;&lt;br /&gt;
               &amp;lt;/wsdl:output&amp;gt;&lt;br /&gt;
           &amp;lt;/wsdl:operation&amp;gt;&lt;br /&gt;
       &amp;lt;/wsdl:binding&amp;gt;&lt;br /&gt;
       &amp;lt;wsdl:service name=&amp;quot;CalculadoraService&amp;quot;&amp;gt;&lt;br /&gt;
           &amp;lt;wsdl:port name=&amp;quot;CalculadoraSoapPort&amp;quot; binding=&amp;quot;calc:CalculadoraServiceSoapBinding&amp;quot;&amp;gt;&lt;br /&gt;
               &amp;lt;soap:address location=&amp;quot;http://localhost:8080/Axis2-15/services/CalculadoraService&amp;quot;/&amp;gt;&lt;br /&gt;
           &amp;lt;/wsdl:port&amp;gt;&lt;br /&gt;
       &amp;lt;/wsdl:service&amp;gt;&lt;br /&gt;
   &amp;lt;/wsdl:definitions&amp;gt;&lt;br /&gt;
==Proyectos de ejemplo para descargar==&lt;br /&gt;
Aquí que te podés descargar 2 versiones del proyecto&lt;br /&gt;
&lt;br /&gt;
* [http://www.dosideas.com/descargas/category/8-.html?download=32%3A2-1.4.1-p-1.4 Axis2 1.4.1 para JDK 1.4]&lt;br /&gt;
* [http://www.dosideas.com/descargas/category/8-.html?download=33%3A2-1.5.1-p-5 Axis2 1.5.1 para JDK 5]&lt;br /&gt;
&lt;br /&gt;
==Ver también==&lt;br /&gt;
* [[Web Service]]&lt;br /&gt;
* [[Clientes De Web Service]]&lt;br /&gt;
* [[Cliente Web Service con Ant y Axis2]]&lt;br /&gt;
* [[Web Service con Axis 2 para Weblogic y Websphere]]&lt;br /&gt;
* [[Web Service Con Spring]]&lt;br /&gt;
* [http://ws.apache.org/axis2/ Apache Axis 2]&lt;br /&gt;
&lt;br /&gt;
[[Category:Java]]&lt;br /&gt;
[[Category:Web Service]]&lt;/div&gt;</summary>
		<author><name>201.251.182.130</name></author>	</entry>

	<entry>
		<id>https://dosideas.com/wiki/index.php?title=UML&amp;diff=6366</id>
		<title>UML</title>
		<link rel="alternate" type="text/html" href="https://dosideas.com/wiki/index.php?title=UML&amp;diff=6366"/>
				<updated>2011-09-28T17:37:53Z</updated>
		
		<summary type="html">&lt;p&gt;201.251.182.130: /* Diagramas */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Diseño De Software]]&lt;br /&gt;
Lenguaje Unificado de Modelado (UML, por sus siglas en inglés, Unified Modeling Language) es el lenguaje de modelado de sistemas de software más conocido y utilizado en la actualidad; está respaldado por el OMG (Object Management Group). Es un lenguaje gráfico para visualizar, especificar, construir y documentar un sistema de software. UML ofrece un estándar para describir un &amp;quot;plano&amp;quot; del sistema (modelo), incluyendo aspectos conceptuales tales como procesos de negocios y funciones del sistema, y aspectos concretos como expresiones de lenguajes de programación, esquemas de bases de datos y componentes de software reutilizables.&lt;br /&gt;
&lt;br /&gt;
==Diagramas==&lt;br /&gt;
En UML 2.0 hay 13 tipos diferentes de diagramas.&lt;br /&gt;
&lt;br /&gt;
Los '''Diagramas de Estructura''' enfatizan en los elementos que deben existir en el sistema modelado:&lt;br /&gt;
&lt;br /&gt;
*[[Diagrama de dominio]]&lt;br /&gt;
*[[Diagrama de clases]]&lt;br /&gt;
*[[Diagrama de componentes]]&lt;br /&gt;
*Diagrama de estructura compuesta (UML 2.0)&lt;br /&gt;
*[[Diagrama de despliegue]]&lt;br /&gt;
*Diagrama de paquetes&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Los '''Diagramas de Comportamiento''' enfatizan en lo que debe suceder en el sistema modelado:&lt;br /&gt;
&lt;br /&gt;
*Diagrama de actividades&lt;br /&gt;
*[[Diagrama de casos de uso]]&lt;br /&gt;
*Diagrama de estados&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Los '''Diagramas de Interacción''' son un subtipo de diagramas de comportamiento, que enfatiza sobre el flujo de control y de datos entre los elementos del sistema modelado:&lt;br /&gt;
&lt;br /&gt;
*[[Diagrama de secuencia]]&lt;br /&gt;
*Diagrama de colaboración&lt;br /&gt;
*Diagrama de tiempos (UML 2.0)&lt;br /&gt;
*Diagrama de vista de interacción (UML 2.0)&lt;br /&gt;
&lt;br /&gt;
==Ver también==&lt;br /&gt;
* [[Diseño De Software]]&lt;br /&gt;
* [http://es.wikipedia.org/wiki/Lenguaje_Unificado_de_Modelado UML en la Wikipedia ]&lt;br /&gt;
* [http://case-tools.org/uml.html Listado de herramientas UML]&lt;br /&gt;
* [http://www.uml.org/ Sitio oficial de UML]&lt;/div&gt;</summary>
		<author><name>201.251.182.130</name></author>	</entry>

	<entry>
		<id>https://dosideas.com/wiki/index.php?title=REST_con_Spring&amp;diff=6281</id>
		<title>REST con Spring</title>
		<link rel="alternate" type="text/html" href="https://dosideas.com/wiki/index.php?title=REST_con_Spring&amp;diff=6281"/>
				<updated>2011-09-07T13:36:16Z</updated>
		
		<summary type="html">&lt;p&gt;201.251.182.130: /* Manejo de errores */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Spring Framework]] 3.x trae la posibilidad de crear servicios web REST de manera muy simple. &lt;br /&gt;
&lt;br /&gt;
== Un ejemplo ==&lt;br /&gt;
Vamos a realizar una aplicación que responda a las siguientes URL: &lt;br /&gt;
&lt;br /&gt;
 /persona/todos   : devuelve todas las personas&lt;br /&gt;
 /persona/123     : devuelve la persona cuyo id es 123&lt;br /&gt;
&lt;br /&gt;
Tendremos que seguir 3 pasos:&lt;br /&gt;
# Configurar el servlet de Spring&lt;br /&gt;
# Crear la clase que atenderá y resolverá estas peticiones&lt;br /&gt;
# Configurar Spring&lt;br /&gt;
&lt;br /&gt;
=== El servlet de Spring ===&lt;br /&gt;
Lo primero es configurar el servlet de Spring que se encargará de tomas las peticiones y redireccionarla a las clases correspondientes. La clase que se encarga de esto es ''org.springframework.web.servlet.DispatcherServlet''. Un archivo web.xml de ejemplo sería: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;web-app version=&amp;quot;2.5&amp;quot; xmlns=&amp;quot;http://java.sun.com/xml/ns/javaee&amp;quot; xmlns:xsi=&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot; xsi:schemaLocation=&amp;quot;http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;display-name&amp;gt;json-con-spring-mvc&amp;lt;/display-name&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;filter&amp;gt;&lt;br /&gt;
        &amp;lt;filter-name&amp;gt;characterEncodingFilter&amp;lt;/filter-name&amp;gt;&lt;br /&gt;
        &amp;lt;filter-class&amp;gt;org.springframework.web.filter.CharacterEncodingFilter&amp;lt;/filter-class&amp;gt;&lt;br /&gt;
        &amp;lt;init-param&amp;gt;&lt;br /&gt;
            &amp;lt;param-name&amp;gt;encoding&amp;lt;/param-name&amp;gt;&lt;br /&gt;
            &amp;lt;param-value&amp;gt;UTF-8&amp;lt;/param-value&amp;gt;&lt;br /&gt;
        &amp;lt;/init-param&amp;gt;&lt;br /&gt;
        &amp;lt;init-param&amp;gt;&lt;br /&gt;
            &amp;lt;param-name&amp;gt;forceEncoding&amp;lt;/param-name&amp;gt;&lt;br /&gt;
            &amp;lt;param-value&amp;gt;true&amp;lt;/param-value&amp;gt;&lt;br /&gt;
        &amp;lt;/init-param&amp;gt;&lt;br /&gt;
    &amp;lt;/filter&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;filter-mapping&amp;gt;&lt;br /&gt;
        &amp;lt;filter-name&amp;gt;characterEncodingFilter&amp;lt;/filter-name&amp;gt;&lt;br /&gt;
        &amp;lt;url-pattern&amp;gt;/*&amp;lt;/url-pattern&amp;gt;&lt;br /&gt;
    &amp;lt;/filter-mapping&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;servlet&amp;gt;&lt;br /&gt;
        &amp;lt;servlet-name&amp;gt;Spring MVC Dispatcher Servlet&amp;lt;/servlet-name&amp;gt;&lt;br /&gt;
        &amp;lt;servlet-class&amp;gt;org.springframework.web.servlet.DispatcherServlet&amp;lt;/servlet-class&amp;gt;&lt;br /&gt;
        &amp;lt;init-param&amp;gt;&lt;br /&gt;
            &amp;lt;param-name&amp;gt;contextConfigLocation&amp;lt;/param-name&amp;gt;&lt;br /&gt;
            &amp;lt;param-value&amp;gt;&lt;br /&gt;
			WEB-INF/applicationContext-clasico.xml&lt;br /&gt;
            &amp;lt;/param-value&amp;gt;&lt;br /&gt;
        &amp;lt;/init-param&amp;gt;&lt;br /&gt;
        &amp;lt;load-on-startup&amp;gt;1&amp;lt;/load-on-startup&amp;gt;&lt;br /&gt;
    &amp;lt;/servlet&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;servlet-mapping&amp;gt;&lt;br /&gt;
        &amp;lt;servlet-name&amp;gt;Spring MVC Dispatcher Servlet&amp;lt;/servlet-name&amp;gt;&lt;br /&gt;
        &amp;lt;url-pattern&amp;gt;/app/*&amp;lt;/url-pattern&amp;gt;&lt;br /&gt;
    &amp;lt;/servlet-mapping&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;session-config&amp;gt;&lt;br /&gt;
        &amp;lt;session-timeout&amp;gt;&lt;br /&gt;
            30&lt;br /&gt;
        &amp;lt;/session-timeout&amp;gt;&lt;br /&gt;
    &amp;lt;/session-config&amp;gt;&lt;br /&gt;
    &amp;lt;welcome-file-list&amp;gt;&lt;br /&gt;
        &amp;lt;welcome-file&amp;gt;index.jsp&amp;lt;/welcome-file&amp;gt;&lt;br /&gt;
    &amp;lt;/welcome-file-list&amp;gt;&lt;br /&gt;
&amp;lt;/web-app&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En este ejemplo, el servlet de Spring queda atendiendo todas las URL que empiecen con &amp;quot;/app&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
=== El controller ===&lt;br /&gt;
La clase que toma las peticiones HTTP es una clase Java anotada con @Controller. Esta clase asocia las URL con métodos. Los objetos que devuelven los métodos son luego procesador por conversores, que representan la respuesta de distinta manera (XML, JSON, etc.)&lt;br /&gt;
&lt;br /&gt;
Para esto, creamos una clase de la siguiente forma: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java5&amp;gt;&lt;br /&gt;
package com.dosideas.jsonconspringmvc;&lt;br /&gt;
&lt;br /&gt;
import java.util.ArrayList;&lt;br /&gt;
import java.util.Collection;&lt;br /&gt;
import org.springframework.stereotype.Controller;&lt;br /&gt;
import org.springframework.web.bind.annotation.PathVariable;&lt;br /&gt;
import org.springframework.web.bind.annotation.RequestBody;&lt;br /&gt;
import org.springframework.web.bind.annotation.RequestMapping;&lt;br /&gt;
import org.springframework.web.bind.annotation.ResponseBody;&lt;br /&gt;
&lt;br /&gt;
@Controller&lt;br /&gt;
@RequestMapping(value=&amp;quot;/persona&amp;quot;)&lt;br /&gt;
public class PersonaController {&lt;br /&gt;
&lt;br /&gt;
    @RequestMapping(value=&amp;quot;/{id}&amp;quot;)&lt;br /&gt;
    public @ResponseBody Persona get(@PathVariable Long id) {&lt;br /&gt;
        Persona p = new Persona(&amp;quot;Invasor &amp;quot; + id, &amp;quot;Zim &amp;quot; + id);&lt;br /&gt;
        return p;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    @RequestMapping(value=&amp;quot;/todos&amp;quot;)&lt;br /&gt;
    public @ResponseBody Collection&amp;lt;Persona&amp;gt; getTodos() {&lt;br /&gt;
        Collection&amp;lt;Persona&amp;gt; personas = new ArrayList&amp;lt;Persona&amp;gt;();&lt;br /&gt;
        for (int i = 0; i &amp;lt; 10; i++) {&lt;br /&gt;
            Persona p = new Persona(&amp;quot;Invasor &amp;quot; + i, &amp;quot;Zim&amp;quot; + i);&lt;br /&gt;
            personas.add(p);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        return personas;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
El objeto Persona es un POJO que tiene dos atributos: nombre y apellido. Los tags @RequestMapping se encargan de asociar la clase y cada uno de sus métodos con una URL en particular. &lt;br /&gt;
&lt;br /&gt;
=== La configuración ===&lt;br /&gt;
Lo último que nos queda configurar es Spring con un archivo clásico (el cual es referenciado por el servlet):  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;beans xmlns=&amp;quot;http://www.springframework.org/schema/beans&amp;quot;&lt;br /&gt;
       xmlns:xsi=&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot;&lt;br /&gt;
       xmlns:p=&amp;quot;http://www.springframework.org/schema/p&amp;quot;&lt;br /&gt;
       xmlns:aop=&amp;quot;http://www.springframework.org/schema/aop&amp;quot;&lt;br /&gt;
       xmlns:tx=&amp;quot;http://www.springframework.org/schema/tx&amp;quot;&lt;br /&gt;
       xmlns:context=&amp;quot;http://www.springframework.org/schema/context&amp;quot;&lt;br /&gt;
       xmlns:mvc=&amp;quot;http://www.springframework.org/schema/mvc&amp;quot;&lt;br /&gt;
       xsi:schemaLocation=&amp;quot;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd&lt;br /&gt;
       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd&lt;br /&gt;
       http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd&lt;br /&gt;
       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd&lt;br /&gt;
       http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd&amp;quot;&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
    &amp;lt;context:component-scan base-package=&amp;quot;com.dosideas.jsonconspringmvc&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;mvc:annotation-driven /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/beans&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
El tag ''mvc:annotation-driven'' se encarga de configurar automáticamente para emepezar a recibir y responder peticiones usando los controladores encontrados. &lt;br /&gt;
&lt;br /&gt;
Más aún, la configuración predeterminada se encarga de realizar [http://en.wikipedia.org/wiki/Content_negotiation negociación de contenido]: la respuesta se formatea de acuerdo a las capacidades del cliente. Por ejemplo, si en el classpath tenemos agregado las librerías de Jackson (un parser JSON), se habilitará el soporte JSON correspondiente. Si están agregadas las librerías de JAXB2, se habilitará el soporte XML. &lt;br /&gt;
&lt;br /&gt;
=== Probando ===&lt;br /&gt;
Podemos crear una prueba [[JUnit]] para acceder a nuestro servicio: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java5&amp;gt;&lt;br /&gt;
package com.dosideas.jsonconspringmvc;&lt;br /&gt;
&lt;br /&gt;
import java.io.IOException;&lt;br /&gt;
import org.apache.commons.httpclient.methods.GetMethod;&lt;br /&gt;
import org.apache.commons.httpclient.HttpMethod;&lt;br /&gt;
import org.apache.commons.httpclient.HttpClient;&lt;br /&gt;
import org.junit.Test;&lt;br /&gt;
import static org.junit.Assert.*;&lt;br /&gt;
&lt;br /&gt;
public class HttpTest {&lt;br /&gt;
&lt;br /&gt;
    @Test&lt;br /&gt;
    public void personaTodosJSON() throws IOException {&lt;br /&gt;
        HttpClient httpclient = new HttpClient();&lt;br /&gt;
        HttpMethod method = new GetMethod(&amp;quot;http://localhost:8084/json-con-spring-mvc/app/persona/todos&amp;quot;);&lt;br /&gt;
        method.addRequestHeader(&amp;quot;accept&amp;quot;, &amp;quot;application/json&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        httpclient.executeMethod(method);&lt;br /&gt;
        String resultado = method.getResponseBodyAsString();&lt;br /&gt;
        System.out.println(resultado);&lt;br /&gt;
&lt;br /&gt;
        assertNotNull(resultado);&lt;br /&gt;
        assertTrue(resultado.startsWith(&amp;quot;[{\&amp;quot;&amp;quot;));&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    @Test&lt;br /&gt;
    public void personaPorIdJSON() throws IOException {&lt;br /&gt;
        HttpClient httpclient = new HttpClient();&lt;br /&gt;
        HttpMethod method = new GetMethod(&amp;quot;http://localhost:8084/json-con-spring-mvc/app/persona/34421&amp;quot;);&lt;br /&gt;
        method.addRequestHeader(&amp;quot;accept&amp;quot;, &amp;quot;application/json&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        httpclient.executeMethod(method);&lt;br /&gt;
        String resultado = method.getResponseBodyAsString();&lt;br /&gt;
        System.out.println(resultado);&lt;br /&gt;
&lt;br /&gt;
        assertNotNull(resultado);&lt;br /&gt;
        assertTrue(resultado.startsWith(&amp;quot;{\&amp;quot;&amp;quot;));&lt;br /&gt;
        assertTrue(resultado.contains(&amp;quot;34421&amp;quot;));&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    @Test&lt;br /&gt;
    public void personaPorIdXML() throws IOException {&lt;br /&gt;
        HttpClient httpclient = new HttpClient();&lt;br /&gt;
        HttpMethod method = new GetMethod(&amp;quot;http://localhost:8084/json-con-spring-mvc/app/persona/34421&amp;quot;);&lt;br /&gt;
        method.addRequestHeader(&amp;quot;accept&amp;quot;, &amp;quot;application/xml&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        httpclient.executeMethod(method);&lt;br /&gt;
        String resultado = method.getResponseBodyAsString();&lt;br /&gt;
        System.out.println(resultado);&lt;br /&gt;
&lt;br /&gt;
        assertNotNull(resultado);&lt;br /&gt;
        assertTrue(resultado.startsWith(&amp;quot;&amp;lt;?xml version=\&amp;quot;1.0\&amp;quot;&amp;quot;));&lt;br /&gt;
        assertTrue(resultado.contains(&amp;quot;34421&amp;quot;));&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Manejo de errores ==&lt;br /&gt;
Es posible personalizar las excepciones para que devuelvan códigos de estado HTTP personalizados, usando la anotación @ResponseStatus en la excepción lanzada. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java5&amp;gt;&lt;br /&gt;
@ResponseStatus(value=HttpStatus.NOT_FOUND, reason=&amp;quot;No se encontró el recurso pedido&amp;quot;)&lt;br /&gt;
public class NotFoundException extends RuntimeException { ... }&lt;br /&gt;
&lt;br /&gt;
.....&lt;br /&gt;
&lt;br /&gt;
    @RequestMapping(value=&amp;quot;/id/{id}&amp;quot;)&lt;br /&gt;
    public @ResponseBody Persona findById(@PathVariable long id) {&lt;br /&gt;
       Contact contact = personaService.findById(id);&lt;br /&gt;
       if (contact == null) {&lt;br /&gt;
           throw new NotFoundException();&lt;br /&gt;
       } else {&lt;br /&gt;
           return contact;&lt;br /&gt;
       }&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Otra forma de personalizar las excepciones, es interceptar las excepciones del controller(@Controller) y personalizarla en el mismo controller. &lt;br /&gt;
Para esto debemos crear un método handleException por cada excepción que deseemos personalizar.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java5&amp;gt;&lt;br /&gt;
    @RequestMapping(value=&amp;quot;/id/{id}&amp;quot;)&lt;br /&gt;
    public @ResponseBody Persona findById(@PathVariable long id) {&lt;br /&gt;
       Contact contact = personaService.findById(id);&lt;br /&gt;
       if (contact == null) {&lt;br /&gt;
           throw new NotFoundException();&lt;br /&gt;
       } else {&lt;br /&gt;
           return contact;&lt;br /&gt;
       }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    @ResponseStatus(HttpStatus.NOT_FOUND)&lt;br /&gt;
    @ExceptionHandler(NotFoundException.class)&lt;br /&gt;
    @ResponseBody&lt;br /&gt;
    public Map&amp;lt;String, String&amp;gt; handleException(NotFoundException exception) {&lt;br /&gt;
        return Collections.singletonMap(&amp;quot;message&amp;quot;, &amp;quot;No se encontró el recurso pedido&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y agregar lo siguiente en el applicationContext.xml&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;beans xmlns=&amp;quot;http://www.springframework.org/schema/beans&amp;quot;&lt;br /&gt;
       xmlns:xsi=&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot;&lt;br /&gt;
       xmlns:p=&amp;quot;http://www.springframework.org/schema/p&amp;quot;&lt;br /&gt;
       xmlns:aop=&amp;quot;http://www.springframework.org/schema/aop&amp;quot;&lt;br /&gt;
       xmlns:tx=&amp;quot;http://www.springframework.org/schema/tx&amp;quot;&lt;br /&gt;
       xmlns:context=&amp;quot;http://www.springframework.org/schema/context&amp;quot;&lt;br /&gt;
       xmlns:mvc=&amp;quot;http://www.springframework.org/schema/mvc&amp;quot;&lt;br /&gt;
       xsi:schemaLocation=&amp;quot;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd&lt;br /&gt;
       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd&lt;br /&gt;
       http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd&lt;br /&gt;
       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd&lt;br /&gt;
       http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd&amp;quot;&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
    &amp;lt;context:component-scan base-package=&amp;quot;com.dosideas.jsonconspringmvc&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;mvc:annotation-driven /&amp;gt;&lt;br /&gt;
    &amp;lt;bean class=&amp;quot;org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerExceptionResolver&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;property name=&amp;quot;messageConverters&amp;quot;&amp;gt;&lt;br /&gt;
	    &amp;lt;list&amp;gt;&lt;br /&gt;
	        &amp;lt;bean class=&amp;quot;org.springframework.http.converter.json.MappingJacksonHttpMessageConverter&amp;quot; /&amp;gt;&lt;br /&gt;
	    &amp;lt;/list&amp;gt;&lt;br /&gt;
	&amp;lt;/property&amp;gt;&lt;br /&gt;
    &amp;lt;/bean&amp;gt;&lt;br /&gt;
&amp;lt;/beans&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Al utilizar este interceptor se debe personalizar la excepciones en todos los controladores, caso contrario la excepción no es customizada y retorna un status code 500.&lt;br /&gt;
En caso de que se quiera utilizar los 2 métodos, el de @ResponseStatus y el de @ExceptionHandler, se debe registrar los 2 Handler en el applicationContext con el orden de ejecucion.&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;bean class=&amp;quot;org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerExceptionResolver&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;property name=&amp;quot;order&amp;quot; value=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;
    &amp;lt;property name=&amp;quot;messageConverters&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;list&amp;gt;&lt;br /&gt;
            &amp;lt;bean class=&amp;quot;org.springframework.http.converter.json.MappingJacksonHttpMessageConverter&amp;quot; /&amp;gt;&lt;br /&gt;
       &amp;lt;/list&amp;gt;&lt;br /&gt;
    &amp;lt;/property&amp;gt;&lt;br /&gt;
&amp;lt;/bean&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;bean class=&amp;quot;org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver&amp;quot; &amp;gt;&lt;br /&gt;
    &amp;lt;property name=&amp;quot;order&amp;quot; value=&amp;quot;2&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/bean&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Manejo de la respuesta ==&lt;br /&gt;
La anotación @ResponseStatus puede usarse para personalizar el código HTTP de cualquier respuesta, al ubicarla en el método. &lt;br /&gt;
Por ejemplo, los métodos que devuelven void pueden usar esta anotación para indicar que no hay contenido (es útil si, por ejemplo, se parsea el contenido con algunas librerías como [[JQuery]]).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java5&amp;gt;&lt;br /&gt;
    @RequestMapping(value=&amp;quot;/delete/{id}&amp;quot;)&lt;br /&gt;
    @ResponseStatus(HttpStatus.NO_CONTENT)&lt;br /&gt;
    public void delete(@PathVariable long id) {&lt;br /&gt;
        contactService.delete(id);&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Descargar un proyecto de ejemplo ===&lt;br /&gt;
Les dejamos para [http://www.dosideas.com/descargas/category/2-spring-framework.html?download=41%3Ap descargar un proyecto de ejemplo de REST con Spring MVC] donde tienen todos los fuentes necesarios para abrir y ejecutar el ejemplo de esta página.&lt;br /&gt;
&lt;br /&gt;
== Ver también ==&lt;br /&gt;
* [http://www.dosideas.com/descargas/category/2-spring-framework.html?download=41%3Ap Descargar un proyecto de ejemplo]&lt;br /&gt;
* [http://static.springsource.org/spring/docs/3.0.0.M3/spring-framework-reference/html/ch18.html Creating Restful services - Documentación oficial]&lt;br /&gt;
* [http://www.informit.com/guides/content.aspx?g=java&amp;amp;seqNum=544 Creating Restful web services]&lt;br /&gt;
* [http://www.ibm.com/developerworks/web/library/wa-spring3webserv/index.html?ca=drs- Building RESTful web services using Spring 3]&lt;br /&gt;
* [http://www.adictosaltrabajo.com/tutoriales/tutoriales.php?pagina=springRestJson Spring + REST + JSON = SOAUI]&lt;br /&gt;
* [http://www.jpalace.org/docs/spring/rest.html Sprint REST Tutorial]&lt;/div&gt;</summary>
		<author><name>201.251.182.130</name></author>	</entry>

	<entry>
		<id>https://dosideas.com/wiki/index.php?title=REST_con_Spring&amp;diff=6280</id>
		<title>REST con Spring</title>
		<link rel="alternate" type="text/html" href="https://dosideas.com/wiki/index.php?title=REST_con_Spring&amp;diff=6280"/>
				<updated>2011-09-07T13:35:20Z</updated>
		
		<summary type="html">&lt;p&gt;201.251.182.130: /* Manejo de errores */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Spring Framework]] 3.x trae la posibilidad de crear servicios web REST de manera muy simple. &lt;br /&gt;
&lt;br /&gt;
== Un ejemplo ==&lt;br /&gt;
Vamos a realizar una aplicación que responda a las siguientes URL: &lt;br /&gt;
&lt;br /&gt;
 /persona/todos   : devuelve todas las personas&lt;br /&gt;
 /persona/123     : devuelve la persona cuyo id es 123&lt;br /&gt;
&lt;br /&gt;
Tendremos que seguir 3 pasos:&lt;br /&gt;
# Configurar el servlet de Spring&lt;br /&gt;
# Crear la clase que atenderá y resolverá estas peticiones&lt;br /&gt;
# Configurar Spring&lt;br /&gt;
&lt;br /&gt;
=== El servlet de Spring ===&lt;br /&gt;
Lo primero es configurar el servlet de Spring que se encargará de tomas las peticiones y redireccionarla a las clases correspondientes. La clase que se encarga de esto es ''org.springframework.web.servlet.DispatcherServlet''. Un archivo web.xml de ejemplo sería: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;web-app version=&amp;quot;2.5&amp;quot; xmlns=&amp;quot;http://java.sun.com/xml/ns/javaee&amp;quot; xmlns:xsi=&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot; xsi:schemaLocation=&amp;quot;http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;display-name&amp;gt;json-con-spring-mvc&amp;lt;/display-name&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;filter&amp;gt;&lt;br /&gt;
        &amp;lt;filter-name&amp;gt;characterEncodingFilter&amp;lt;/filter-name&amp;gt;&lt;br /&gt;
        &amp;lt;filter-class&amp;gt;org.springframework.web.filter.CharacterEncodingFilter&amp;lt;/filter-class&amp;gt;&lt;br /&gt;
        &amp;lt;init-param&amp;gt;&lt;br /&gt;
            &amp;lt;param-name&amp;gt;encoding&amp;lt;/param-name&amp;gt;&lt;br /&gt;
            &amp;lt;param-value&amp;gt;UTF-8&amp;lt;/param-value&amp;gt;&lt;br /&gt;
        &amp;lt;/init-param&amp;gt;&lt;br /&gt;
        &amp;lt;init-param&amp;gt;&lt;br /&gt;
            &amp;lt;param-name&amp;gt;forceEncoding&amp;lt;/param-name&amp;gt;&lt;br /&gt;
            &amp;lt;param-value&amp;gt;true&amp;lt;/param-value&amp;gt;&lt;br /&gt;
        &amp;lt;/init-param&amp;gt;&lt;br /&gt;
    &amp;lt;/filter&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;filter-mapping&amp;gt;&lt;br /&gt;
        &amp;lt;filter-name&amp;gt;characterEncodingFilter&amp;lt;/filter-name&amp;gt;&lt;br /&gt;
        &amp;lt;url-pattern&amp;gt;/*&amp;lt;/url-pattern&amp;gt;&lt;br /&gt;
    &amp;lt;/filter-mapping&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;servlet&amp;gt;&lt;br /&gt;
        &amp;lt;servlet-name&amp;gt;Spring MVC Dispatcher Servlet&amp;lt;/servlet-name&amp;gt;&lt;br /&gt;
        &amp;lt;servlet-class&amp;gt;org.springframework.web.servlet.DispatcherServlet&amp;lt;/servlet-class&amp;gt;&lt;br /&gt;
        &amp;lt;init-param&amp;gt;&lt;br /&gt;
            &amp;lt;param-name&amp;gt;contextConfigLocation&amp;lt;/param-name&amp;gt;&lt;br /&gt;
            &amp;lt;param-value&amp;gt;&lt;br /&gt;
			WEB-INF/applicationContext-clasico.xml&lt;br /&gt;
            &amp;lt;/param-value&amp;gt;&lt;br /&gt;
        &amp;lt;/init-param&amp;gt;&lt;br /&gt;
        &amp;lt;load-on-startup&amp;gt;1&amp;lt;/load-on-startup&amp;gt;&lt;br /&gt;
    &amp;lt;/servlet&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;servlet-mapping&amp;gt;&lt;br /&gt;
        &amp;lt;servlet-name&amp;gt;Spring MVC Dispatcher Servlet&amp;lt;/servlet-name&amp;gt;&lt;br /&gt;
        &amp;lt;url-pattern&amp;gt;/app/*&amp;lt;/url-pattern&amp;gt;&lt;br /&gt;
    &amp;lt;/servlet-mapping&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;session-config&amp;gt;&lt;br /&gt;
        &amp;lt;session-timeout&amp;gt;&lt;br /&gt;
            30&lt;br /&gt;
        &amp;lt;/session-timeout&amp;gt;&lt;br /&gt;
    &amp;lt;/session-config&amp;gt;&lt;br /&gt;
    &amp;lt;welcome-file-list&amp;gt;&lt;br /&gt;
        &amp;lt;welcome-file&amp;gt;index.jsp&amp;lt;/welcome-file&amp;gt;&lt;br /&gt;
    &amp;lt;/welcome-file-list&amp;gt;&lt;br /&gt;
&amp;lt;/web-app&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En este ejemplo, el servlet de Spring queda atendiendo todas las URL que empiecen con &amp;quot;/app&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
=== El controller ===&lt;br /&gt;
La clase que toma las peticiones HTTP es una clase Java anotada con @Controller. Esta clase asocia las URL con métodos. Los objetos que devuelven los métodos son luego procesador por conversores, que representan la respuesta de distinta manera (XML, JSON, etc.)&lt;br /&gt;
&lt;br /&gt;
Para esto, creamos una clase de la siguiente forma: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java5&amp;gt;&lt;br /&gt;
package com.dosideas.jsonconspringmvc;&lt;br /&gt;
&lt;br /&gt;
import java.util.ArrayList;&lt;br /&gt;
import java.util.Collection;&lt;br /&gt;
import org.springframework.stereotype.Controller;&lt;br /&gt;
import org.springframework.web.bind.annotation.PathVariable;&lt;br /&gt;
import org.springframework.web.bind.annotation.RequestBody;&lt;br /&gt;
import org.springframework.web.bind.annotation.RequestMapping;&lt;br /&gt;
import org.springframework.web.bind.annotation.ResponseBody;&lt;br /&gt;
&lt;br /&gt;
@Controller&lt;br /&gt;
@RequestMapping(value=&amp;quot;/persona&amp;quot;)&lt;br /&gt;
public class PersonaController {&lt;br /&gt;
&lt;br /&gt;
    @RequestMapping(value=&amp;quot;/{id}&amp;quot;)&lt;br /&gt;
    public @ResponseBody Persona get(@PathVariable Long id) {&lt;br /&gt;
        Persona p = new Persona(&amp;quot;Invasor &amp;quot; + id, &amp;quot;Zim &amp;quot; + id);&lt;br /&gt;
        return p;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    @RequestMapping(value=&amp;quot;/todos&amp;quot;)&lt;br /&gt;
    public @ResponseBody Collection&amp;lt;Persona&amp;gt; getTodos() {&lt;br /&gt;
        Collection&amp;lt;Persona&amp;gt; personas = new ArrayList&amp;lt;Persona&amp;gt;();&lt;br /&gt;
        for (int i = 0; i &amp;lt; 10; i++) {&lt;br /&gt;
            Persona p = new Persona(&amp;quot;Invasor &amp;quot; + i, &amp;quot;Zim&amp;quot; + i);&lt;br /&gt;
            personas.add(p);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        return personas;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
El objeto Persona es un POJO que tiene dos atributos: nombre y apellido. Los tags @RequestMapping se encargan de asociar la clase y cada uno de sus métodos con una URL en particular. &lt;br /&gt;
&lt;br /&gt;
=== La configuración ===&lt;br /&gt;
Lo último que nos queda configurar es Spring con un archivo clásico (el cual es referenciado por el servlet):  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;beans xmlns=&amp;quot;http://www.springframework.org/schema/beans&amp;quot;&lt;br /&gt;
       xmlns:xsi=&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot;&lt;br /&gt;
       xmlns:p=&amp;quot;http://www.springframework.org/schema/p&amp;quot;&lt;br /&gt;
       xmlns:aop=&amp;quot;http://www.springframework.org/schema/aop&amp;quot;&lt;br /&gt;
       xmlns:tx=&amp;quot;http://www.springframework.org/schema/tx&amp;quot;&lt;br /&gt;
       xmlns:context=&amp;quot;http://www.springframework.org/schema/context&amp;quot;&lt;br /&gt;
       xmlns:mvc=&amp;quot;http://www.springframework.org/schema/mvc&amp;quot;&lt;br /&gt;
       xsi:schemaLocation=&amp;quot;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd&lt;br /&gt;
       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd&lt;br /&gt;
       http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd&lt;br /&gt;
       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd&lt;br /&gt;
       http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd&amp;quot;&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
    &amp;lt;context:component-scan base-package=&amp;quot;com.dosideas.jsonconspringmvc&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;mvc:annotation-driven /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/beans&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
El tag ''mvc:annotation-driven'' se encarga de configurar automáticamente para emepezar a recibir y responder peticiones usando los controladores encontrados. &lt;br /&gt;
&lt;br /&gt;
Más aún, la configuración predeterminada se encarga de realizar [http://en.wikipedia.org/wiki/Content_negotiation negociación de contenido]: la respuesta se formatea de acuerdo a las capacidades del cliente. Por ejemplo, si en el classpath tenemos agregado las librerías de Jackson (un parser JSON), se habilitará el soporte JSON correspondiente. Si están agregadas las librerías de JAXB2, se habilitará el soporte XML. &lt;br /&gt;
&lt;br /&gt;
=== Probando ===&lt;br /&gt;
Podemos crear una prueba [[JUnit]] para acceder a nuestro servicio: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java5&amp;gt;&lt;br /&gt;
package com.dosideas.jsonconspringmvc;&lt;br /&gt;
&lt;br /&gt;
import java.io.IOException;&lt;br /&gt;
import org.apache.commons.httpclient.methods.GetMethod;&lt;br /&gt;
import org.apache.commons.httpclient.HttpMethod;&lt;br /&gt;
import org.apache.commons.httpclient.HttpClient;&lt;br /&gt;
import org.junit.Test;&lt;br /&gt;
import static org.junit.Assert.*;&lt;br /&gt;
&lt;br /&gt;
public class HttpTest {&lt;br /&gt;
&lt;br /&gt;
    @Test&lt;br /&gt;
    public void personaTodosJSON() throws IOException {&lt;br /&gt;
        HttpClient httpclient = new HttpClient();&lt;br /&gt;
        HttpMethod method = new GetMethod(&amp;quot;http://localhost:8084/json-con-spring-mvc/app/persona/todos&amp;quot;);&lt;br /&gt;
        method.addRequestHeader(&amp;quot;accept&amp;quot;, &amp;quot;application/json&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        httpclient.executeMethod(method);&lt;br /&gt;
        String resultado = method.getResponseBodyAsString();&lt;br /&gt;
        System.out.println(resultado);&lt;br /&gt;
&lt;br /&gt;
        assertNotNull(resultado);&lt;br /&gt;
        assertTrue(resultado.startsWith(&amp;quot;[{\&amp;quot;&amp;quot;));&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    @Test&lt;br /&gt;
    public void personaPorIdJSON() throws IOException {&lt;br /&gt;
        HttpClient httpclient = new HttpClient();&lt;br /&gt;
        HttpMethod method = new GetMethod(&amp;quot;http://localhost:8084/json-con-spring-mvc/app/persona/34421&amp;quot;);&lt;br /&gt;
        method.addRequestHeader(&amp;quot;accept&amp;quot;, &amp;quot;application/json&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        httpclient.executeMethod(method);&lt;br /&gt;
        String resultado = method.getResponseBodyAsString();&lt;br /&gt;
        System.out.println(resultado);&lt;br /&gt;
&lt;br /&gt;
        assertNotNull(resultado);&lt;br /&gt;
        assertTrue(resultado.startsWith(&amp;quot;{\&amp;quot;&amp;quot;));&lt;br /&gt;
        assertTrue(resultado.contains(&amp;quot;34421&amp;quot;));&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    @Test&lt;br /&gt;
    public void personaPorIdXML() throws IOException {&lt;br /&gt;
        HttpClient httpclient = new HttpClient();&lt;br /&gt;
        HttpMethod method = new GetMethod(&amp;quot;http://localhost:8084/json-con-spring-mvc/app/persona/34421&amp;quot;);&lt;br /&gt;
        method.addRequestHeader(&amp;quot;accept&amp;quot;, &amp;quot;application/xml&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        httpclient.executeMethod(method);&lt;br /&gt;
        String resultado = method.getResponseBodyAsString();&lt;br /&gt;
        System.out.println(resultado);&lt;br /&gt;
&lt;br /&gt;
        assertNotNull(resultado);&lt;br /&gt;
        assertTrue(resultado.startsWith(&amp;quot;&amp;lt;?xml version=\&amp;quot;1.0\&amp;quot;&amp;quot;));&lt;br /&gt;
        assertTrue(resultado.contains(&amp;quot;34421&amp;quot;));&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Manejo de errores ==&lt;br /&gt;
Es posible personalizar las excepciones para que devuelvan códigos de estado HTTP personalizados, usando la anotación @ResponseStatus en la excepción lanzada. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java5&amp;gt;&lt;br /&gt;
@ResponseStatus(value=HttpStatus.NOT_FOUND, reason=&amp;quot;No se encontró el recurso pedido&amp;quot;)&lt;br /&gt;
public class NotFoundException extends RuntimeException { ... }&lt;br /&gt;
&lt;br /&gt;
.....&lt;br /&gt;
&lt;br /&gt;
    @RequestMapping(value=&amp;quot;/id/{id}&amp;quot;)&lt;br /&gt;
    public @ResponseBody Persona findById(@PathVariable long id) {&lt;br /&gt;
       Contact contact = personaService.findById(id);&lt;br /&gt;
       if (contact == null) {&lt;br /&gt;
           throw new NotFoundException();&lt;br /&gt;
       } else {&lt;br /&gt;
           return contact;&lt;br /&gt;
       }&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Otra forma de personalizar las excepciones, es interceptar las excepciones del controller(@Controller) y personalizarla en el mismo controller. &lt;br /&gt;
Para esto debemos crear un método handleException por cada excepción que deseemos personalizar.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java5&amp;gt;&lt;br /&gt;
    @RequestMapping(value=&amp;quot;/id/{id}&amp;quot;)&lt;br /&gt;
    public @ResponseBody Persona findById(@PathVariable long id) {&lt;br /&gt;
       Contact contact = personaService.findById(id);&lt;br /&gt;
       if (contact == null) {&lt;br /&gt;
           throw new NotFoundException();&lt;br /&gt;
       } else {&lt;br /&gt;
           return contact;&lt;br /&gt;
       }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    @ResponseStatus(HttpStatus.NOT_FOUND)&lt;br /&gt;
    @ExceptionHandler(NotFoundException.class)&lt;br /&gt;
    @ResponseBody&lt;br /&gt;
    public Map&amp;lt;String, String&amp;gt; handleException(NotFoundException exception) {&lt;br /&gt;
        return Collections.singletonMap(&amp;quot;message&amp;quot;, &amp;quot;No se encontró el recurso pedido&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y agregar lo siguiente en el applicationContext.xml&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;beans xmlns=&amp;quot;http://www.springframework.org/schema/beans&amp;quot;&lt;br /&gt;
       xmlns:xsi=&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot;&lt;br /&gt;
       xmlns:p=&amp;quot;http://www.springframework.org/schema/p&amp;quot;&lt;br /&gt;
       xmlns:aop=&amp;quot;http://www.springframework.org/schema/aop&amp;quot;&lt;br /&gt;
       xmlns:tx=&amp;quot;http://www.springframework.org/schema/tx&amp;quot;&lt;br /&gt;
       xmlns:context=&amp;quot;http://www.springframework.org/schema/context&amp;quot;&lt;br /&gt;
       xmlns:mvc=&amp;quot;http://www.springframework.org/schema/mvc&amp;quot;&lt;br /&gt;
       xsi:schemaLocation=&amp;quot;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd&lt;br /&gt;
       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd&lt;br /&gt;
       http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd&lt;br /&gt;
       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd&lt;br /&gt;
       http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd&amp;quot;&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
    &amp;lt;context:component-scan base-package=&amp;quot;com.dosideas.jsonconspringmvc&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;mvc:annotation-driven /&amp;gt;&lt;br /&gt;
    &amp;lt;bean class=&amp;quot;org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerExceptionResolver&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;property name=&amp;quot;messageConverters&amp;quot;&amp;gt;&lt;br /&gt;
	    &amp;lt;list&amp;gt;&lt;br /&gt;
	        &amp;lt;bean class=&amp;quot;org.springframework.http.converter.json.MappingJacksonHttpMessageConverter&amp;quot; /&amp;gt;&lt;br /&gt;
	    &amp;lt;/list&amp;gt;&lt;br /&gt;
	&amp;lt;/property&amp;gt;&lt;br /&gt;
    &amp;lt;/bean&amp;gt;&lt;br /&gt;
&amp;lt;/beans&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Al utilizar este interceptor se debe personalizar la excepciones en todos los controladores, caso contrario la excepción no es customizada y retorna un status code 500.&lt;br /&gt;
En caso de que se quiera utilizar los 2 métodos, el de @ResponseStatus y el de @ExceptionHandler, se debe registrar los 2 Handler en el applicationContext con el orden de ejecucion.&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;bean class=&amp;quot;org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerExceptionResolver&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;property name=&amp;quot;order&amp;quot; value=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;
    &amp;lt;property name=&amp;quot;messageConverters&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;list&amp;gt;&lt;br /&gt;
            &amp;lt;bean class=&amp;quot;org.springframework.http.converter.json.MappingJacksonHttpMessageConverter&amp;quot; /&amp;gt;&lt;br /&gt;
       &amp;lt;/list&amp;gt;&lt;br /&gt;
    &amp;lt;/property&amp;gt;&lt;br /&gt;
    &amp;lt;/bean&amp;gt;&lt;br /&gt;
    &amp;lt;bean class=&amp;quot;org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver&amp;quot; &amp;gt;&lt;br /&gt;
    &amp;lt;property name=&amp;quot;order&amp;quot; value=&amp;quot;2&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/bean&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Manejo de la respuesta ==&lt;br /&gt;
La anotación @ResponseStatus puede usarse para personalizar el código HTTP de cualquier respuesta, al ubicarla en el método. &lt;br /&gt;
Por ejemplo, los métodos que devuelven void pueden usar esta anotación para indicar que no hay contenido (es útil si, por ejemplo, se parsea el contenido con algunas librerías como [[JQuery]]).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java5&amp;gt;&lt;br /&gt;
    @RequestMapping(value=&amp;quot;/delete/{id}&amp;quot;)&lt;br /&gt;
    @ResponseStatus(HttpStatus.NO_CONTENT)&lt;br /&gt;
    public void delete(@PathVariable long id) {&lt;br /&gt;
        contactService.delete(id);&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Descargar un proyecto de ejemplo ===&lt;br /&gt;
Les dejamos para [http://www.dosideas.com/descargas/category/2-spring-framework.html?download=41%3Ap descargar un proyecto de ejemplo de REST con Spring MVC] donde tienen todos los fuentes necesarios para abrir y ejecutar el ejemplo de esta página.&lt;br /&gt;
&lt;br /&gt;
== Ver también ==&lt;br /&gt;
* [http://www.dosideas.com/descargas/category/2-spring-framework.html?download=41%3Ap Descargar un proyecto de ejemplo]&lt;br /&gt;
* [http://static.springsource.org/spring/docs/3.0.0.M3/spring-framework-reference/html/ch18.html Creating Restful services - Documentación oficial]&lt;br /&gt;
* [http://www.informit.com/guides/content.aspx?g=java&amp;amp;seqNum=544 Creating Restful web services]&lt;br /&gt;
* [http://www.ibm.com/developerworks/web/library/wa-spring3webserv/index.html?ca=drs- Building RESTful web services using Spring 3]&lt;br /&gt;
* [http://www.adictosaltrabajo.com/tutoriales/tutoriales.php?pagina=springRestJson Spring + REST + JSON = SOAUI]&lt;br /&gt;
* [http://www.jpalace.org/docs/spring/rest.html Sprint REST Tutorial]&lt;/div&gt;</summary>
		<author><name>201.251.182.130</name></author>	</entry>

	<entry>
		<id>https://dosideas.com/wiki/index.php?title=REST_con_Spring&amp;diff=6279</id>
		<title>REST con Spring</title>
		<link rel="alternate" type="text/html" href="https://dosideas.com/wiki/index.php?title=REST_con_Spring&amp;diff=6279"/>
				<updated>2011-09-07T13:34:48Z</updated>
		
		<summary type="html">&lt;p&gt;201.251.182.130: /* Manejo de errores */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Spring Framework]] 3.x trae la posibilidad de crear servicios web REST de manera muy simple. &lt;br /&gt;
&lt;br /&gt;
== Un ejemplo ==&lt;br /&gt;
Vamos a realizar una aplicación que responda a las siguientes URL: &lt;br /&gt;
&lt;br /&gt;
 /persona/todos   : devuelve todas las personas&lt;br /&gt;
 /persona/123     : devuelve la persona cuyo id es 123&lt;br /&gt;
&lt;br /&gt;
Tendremos que seguir 3 pasos:&lt;br /&gt;
# Configurar el servlet de Spring&lt;br /&gt;
# Crear la clase que atenderá y resolverá estas peticiones&lt;br /&gt;
# Configurar Spring&lt;br /&gt;
&lt;br /&gt;
=== El servlet de Spring ===&lt;br /&gt;
Lo primero es configurar el servlet de Spring que se encargará de tomas las peticiones y redireccionarla a las clases correspondientes. La clase que se encarga de esto es ''org.springframework.web.servlet.DispatcherServlet''. Un archivo web.xml de ejemplo sería: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;web-app version=&amp;quot;2.5&amp;quot; xmlns=&amp;quot;http://java.sun.com/xml/ns/javaee&amp;quot; xmlns:xsi=&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot; xsi:schemaLocation=&amp;quot;http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;display-name&amp;gt;json-con-spring-mvc&amp;lt;/display-name&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;filter&amp;gt;&lt;br /&gt;
        &amp;lt;filter-name&amp;gt;characterEncodingFilter&amp;lt;/filter-name&amp;gt;&lt;br /&gt;
        &amp;lt;filter-class&amp;gt;org.springframework.web.filter.CharacterEncodingFilter&amp;lt;/filter-class&amp;gt;&lt;br /&gt;
        &amp;lt;init-param&amp;gt;&lt;br /&gt;
            &amp;lt;param-name&amp;gt;encoding&amp;lt;/param-name&amp;gt;&lt;br /&gt;
            &amp;lt;param-value&amp;gt;UTF-8&amp;lt;/param-value&amp;gt;&lt;br /&gt;
        &amp;lt;/init-param&amp;gt;&lt;br /&gt;
        &amp;lt;init-param&amp;gt;&lt;br /&gt;
            &amp;lt;param-name&amp;gt;forceEncoding&amp;lt;/param-name&amp;gt;&lt;br /&gt;
            &amp;lt;param-value&amp;gt;true&amp;lt;/param-value&amp;gt;&lt;br /&gt;
        &amp;lt;/init-param&amp;gt;&lt;br /&gt;
    &amp;lt;/filter&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;filter-mapping&amp;gt;&lt;br /&gt;
        &amp;lt;filter-name&amp;gt;characterEncodingFilter&amp;lt;/filter-name&amp;gt;&lt;br /&gt;
        &amp;lt;url-pattern&amp;gt;/*&amp;lt;/url-pattern&amp;gt;&lt;br /&gt;
    &amp;lt;/filter-mapping&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;servlet&amp;gt;&lt;br /&gt;
        &amp;lt;servlet-name&amp;gt;Spring MVC Dispatcher Servlet&amp;lt;/servlet-name&amp;gt;&lt;br /&gt;
        &amp;lt;servlet-class&amp;gt;org.springframework.web.servlet.DispatcherServlet&amp;lt;/servlet-class&amp;gt;&lt;br /&gt;
        &amp;lt;init-param&amp;gt;&lt;br /&gt;
            &amp;lt;param-name&amp;gt;contextConfigLocation&amp;lt;/param-name&amp;gt;&lt;br /&gt;
            &amp;lt;param-value&amp;gt;&lt;br /&gt;
			WEB-INF/applicationContext-clasico.xml&lt;br /&gt;
            &amp;lt;/param-value&amp;gt;&lt;br /&gt;
        &amp;lt;/init-param&amp;gt;&lt;br /&gt;
        &amp;lt;load-on-startup&amp;gt;1&amp;lt;/load-on-startup&amp;gt;&lt;br /&gt;
    &amp;lt;/servlet&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;servlet-mapping&amp;gt;&lt;br /&gt;
        &amp;lt;servlet-name&amp;gt;Spring MVC Dispatcher Servlet&amp;lt;/servlet-name&amp;gt;&lt;br /&gt;
        &amp;lt;url-pattern&amp;gt;/app/*&amp;lt;/url-pattern&amp;gt;&lt;br /&gt;
    &amp;lt;/servlet-mapping&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;session-config&amp;gt;&lt;br /&gt;
        &amp;lt;session-timeout&amp;gt;&lt;br /&gt;
            30&lt;br /&gt;
        &amp;lt;/session-timeout&amp;gt;&lt;br /&gt;
    &amp;lt;/session-config&amp;gt;&lt;br /&gt;
    &amp;lt;welcome-file-list&amp;gt;&lt;br /&gt;
        &amp;lt;welcome-file&amp;gt;index.jsp&amp;lt;/welcome-file&amp;gt;&lt;br /&gt;
    &amp;lt;/welcome-file-list&amp;gt;&lt;br /&gt;
&amp;lt;/web-app&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En este ejemplo, el servlet de Spring queda atendiendo todas las URL que empiecen con &amp;quot;/app&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
=== El controller ===&lt;br /&gt;
La clase que toma las peticiones HTTP es una clase Java anotada con @Controller. Esta clase asocia las URL con métodos. Los objetos que devuelven los métodos son luego procesador por conversores, que representan la respuesta de distinta manera (XML, JSON, etc.)&lt;br /&gt;
&lt;br /&gt;
Para esto, creamos una clase de la siguiente forma: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java5&amp;gt;&lt;br /&gt;
package com.dosideas.jsonconspringmvc;&lt;br /&gt;
&lt;br /&gt;
import java.util.ArrayList;&lt;br /&gt;
import java.util.Collection;&lt;br /&gt;
import org.springframework.stereotype.Controller;&lt;br /&gt;
import org.springframework.web.bind.annotation.PathVariable;&lt;br /&gt;
import org.springframework.web.bind.annotation.RequestBody;&lt;br /&gt;
import org.springframework.web.bind.annotation.RequestMapping;&lt;br /&gt;
import org.springframework.web.bind.annotation.ResponseBody;&lt;br /&gt;
&lt;br /&gt;
@Controller&lt;br /&gt;
@RequestMapping(value=&amp;quot;/persona&amp;quot;)&lt;br /&gt;
public class PersonaController {&lt;br /&gt;
&lt;br /&gt;
    @RequestMapping(value=&amp;quot;/{id}&amp;quot;)&lt;br /&gt;
    public @ResponseBody Persona get(@PathVariable Long id) {&lt;br /&gt;
        Persona p = new Persona(&amp;quot;Invasor &amp;quot; + id, &amp;quot;Zim &amp;quot; + id);&lt;br /&gt;
        return p;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    @RequestMapping(value=&amp;quot;/todos&amp;quot;)&lt;br /&gt;
    public @ResponseBody Collection&amp;lt;Persona&amp;gt; getTodos() {&lt;br /&gt;
        Collection&amp;lt;Persona&amp;gt; personas = new ArrayList&amp;lt;Persona&amp;gt;();&lt;br /&gt;
        for (int i = 0; i &amp;lt; 10; i++) {&lt;br /&gt;
            Persona p = new Persona(&amp;quot;Invasor &amp;quot; + i, &amp;quot;Zim&amp;quot; + i);&lt;br /&gt;
            personas.add(p);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        return personas;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
El objeto Persona es un POJO que tiene dos atributos: nombre y apellido. Los tags @RequestMapping se encargan de asociar la clase y cada uno de sus métodos con una URL en particular. &lt;br /&gt;
&lt;br /&gt;
=== La configuración ===&lt;br /&gt;
Lo último que nos queda configurar es Spring con un archivo clásico (el cual es referenciado por el servlet):  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;beans xmlns=&amp;quot;http://www.springframework.org/schema/beans&amp;quot;&lt;br /&gt;
       xmlns:xsi=&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot;&lt;br /&gt;
       xmlns:p=&amp;quot;http://www.springframework.org/schema/p&amp;quot;&lt;br /&gt;
       xmlns:aop=&amp;quot;http://www.springframework.org/schema/aop&amp;quot;&lt;br /&gt;
       xmlns:tx=&amp;quot;http://www.springframework.org/schema/tx&amp;quot;&lt;br /&gt;
       xmlns:context=&amp;quot;http://www.springframework.org/schema/context&amp;quot;&lt;br /&gt;
       xmlns:mvc=&amp;quot;http://www.springframework.org/schema/mvc&amp;quot;&lt;br /&gt;
       xsi:schemaLocation=&amp;quot;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd&lt;br /&gt;
       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd&lt;br /&gt;
       http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd&lt;br /&gt;
       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd&lt;br /&gt;
       http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd&amp;quot;&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
    &amp;lt;context:component-scan base-package=&amp;quot;com.dosideas.jsonconspringmvc&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;mvc:annotation-driven /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/beans&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
El tag ''mvc:annotation-driven'' se encarga de configurar automáticamente para emepezar a recibir y responder peticiones usando los controladores encontrados. &lt;br /&gt;
&lt;br /&gt;
Más aún, la configuración predeterminada se encarga de realizar [http://en.wikipedia.org/wiki/Content_negotiation negociación de contenido]: la respuesta se formatea de acuerdo a las capacidades del cliente. Por ejemplo, si en el classpath tenemos agregado las librerías de Jackson (un parser JSON), se habilitará el soporte JSON correspondiente. Si están agregadas las librerías de JAXB2, se habilitará el soporte XML. &lt;br /&gt;
&lt;br /&gt;
=== Probando ===&lt;br /&gt;
Podemos crear una prueba [[JUnit]] para acceder a nuestro servicio: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java5&amp;gt;&lt;br /&gt;
package com.dosideas.jsonconspringmvc;&lt;br /&gt;
&lt;br /&gt;
import java.io.IOException;&lt;br /&gt;
import org.apache.commons.httpclient.methods.GetMethod;&lt;br /&gt;
import org.apache.commons.httpclient.HttpMethod;&lt;br /&gt;
import org.apache.commons.httpclient.HttpClient;&lt;br /&gt;
import org.junit.Test;&lt;br /&gt;
import static org.junit.Assert.*;&lt;br /&gt;
&lt;br /&gt;
public class HttpTest {&lt;br /&gt;
&lt;br /&gt;
    @Test&lt;br /&gt;
    public void personaTodosJSON() throws IOException {&lt;br /&gt;
        HttpClient httpclient = new HttpClient();&lt;br /&gt;
        HttpMethod method = new GetMethod(&amp;quot;http://localhost:8084/json-con-spring-mvc/app/persona/todos&amp;quot;);&lt;br /&gt;
        method.addRequestHeader(&amp;quot;accept&amp;quot;, &amp;quot;application/json&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        httpclient.executeMethod(method);&lt;br /&gt;
        String resultado = method.getResponseBodyAsString();&lt;br /&gt;
        System.out.println(resultado);&lt;br /&gt;
&lt;br /&gt;
        assertNotNull(resultado);&lt;br /&gt;
        assertTrue(resultado.startsWith(&amp;quot;[{\&amp;quot;&amp;quot;));&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    @Test&lt;br /&gt;
    public void personaPorIdJSON() throws IOException {&lt;br /&gt;
        HttpClient httpclient = new HttpClient();&lt;br /&gt;
        HttpMethod method = new GetMethod(&amp;quot;http://localhost:8084/json-con-spring-mvc/app/persona/34421&amp;quot;);&lt;br /&gt;
        method.addRequestHeader(&amp;quot;accept&amp;quot;, &amp;quot;application/json&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        httpclient.executeMethod(method);&lt;br /&gt;
        String resultado = method.getResponseBodyAsString();&lt;br /&gt;
        System.out.println(resultado);&lt;br /&gt;
&lt;br /&gt;
        assertNotNull(resultado);&lt;br /&gt;
        assertTrue(resultado.startsWith(&amp;quot;{\&amp;quot;&amp;quot;));&lt;br /&gt;
        assertTrue(resultado.contains(&amp;quot;34421&amp;quot;));&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    @Test&lt;br /&gt;
    public void personaPorIdXML() throws IOException {&lt;br /&gt;
        HttpClient httpclient = new HttpClient();&lt;br /&gt;
        HttpMethod method = new GetMethod(&amp;quot;http://localhost:8084/json-con-spring-mvc/app/persona/34421&amp;quot;);&lt;br /&gt;
        method.addRequestHeader(&amp;quot;accept&amp;quot;, &amp;quot;application/xml&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        httpclient.executeMethod(method);&lt;br /&gt;
        String resultado = method.getResponseBodyAsString();&lt;br /&gt;
        System.out.println(resultado);&lt;br /&gt;
&lt;br /&gt;
        assertNotNull(resultado);&lt;br /&gt;
        assertTrue(resultado.startsWith(&amp;quot;&amp;lt;?xml version=\&amp;quot;1.0\&amp;quot;&amp;quot;));&lt;br /&gt;
        assertTrue(resultado.contains(&amp;quot;34421&amp;quot;));&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Manejo de errores ==&lt;br /&gt;
Es posible personalizar las excepciones para que devuelvan códigos de estado HTTP personalizados, usando la anotación @ResponseStatus en la excepción lanzada. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java5&amp;gt;&lt;br /&gt;
@ResponseStatus(value=HttpStatus.NOT_FOUND, reason=&amp;quot;No se encontró el recurso pedido&amp;quot;)&lt;br /&gt;
public class NotFoundException extends RuntimeException { ... }&lt;br /&gt;
&lt;br /&gt;
.....&lt;br /&gt;
&lt;br /&gt;
    @RequestMapping(value=&amp;quot;/id/{id}&amp;quot;)&lt;br /&gt;
    public @ResponseBody Persona findById(@PathVariable long id) {&lt;br /&gt;
       Contact contact = personaService.findById(id);&lt;br /&gt;
       if (contact == null) {&lt;br /&gt;
           throw new NotFoundException();&lt;br /&gt;
       } else {&lt;br /&gt;
           return contact;&lt;br /&gt;
       }&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Otra forma de personalizar las excepciones, es interceptar las excepciones del controller(@Controller) y personalizarla en el mismo controller. &lt;br /&gt;
Para esto debemos crear un método handleException por cada excepción que deseemos personalizar.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java5&amp;gt;&lt;br /&gt;
    @RequestMapping(value=&amp;quot;/id/{id}&amp;quot;)&lt;br /&gt;
    public @ResponseBody Persona findById(@PathVariable long id) {&lt;br /&gt;
       Contact contact = personaService.findById(id);&lt;br /&gt;
       if (contact == null) {&lt;br /&gt;
           throw new NotFoundException();&lt;br /&gt;
       } else {&lt;br /&gt;
           return contact;&lt;br /&gt;
       }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    @ResponseStatus(HttpStatus.NOT_FOUND)&lt;br /&gt;
    @ExceptionHandler(NotFoundException.class)&lt;br /&gt;
    @ResponseBody&lt;br /&gt;
    public Map&amp;lt;String, String&amp;gt; handleException(NotFoundException exception) {&lt;br /&gt;
        return Collections.singletonMap(&amp;quot;message&amp;quot;, &amp;quot;No se encontró el recurso pedido&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y agregar lo siguiente en el applicationContext.xml&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;beans xmlns=&amp;quot;http://www.springframework.org/schema/beans&amp;quot;&lt;br /&gt;
       xmlns:xsi=&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot;&lt;br /&gt;
       xmlns:p=&amp;quot;http://www.springframework.org/schema/p&amp;quot;&lt;br /&gt;
       xmlns:aop=&amp;quot;http://www.springframework.org/schema/aop&amp;quot;&lt;br /&gt;
       xmlns:tx=&amp;quot;http://www.springframework.org/schema/tx&amp;quot;&lt;br /&gt;
       xmlns:context=&amp;quot;http://www.springframework.org/schema/context&amp;quot;&lt;br /&gt;
       xmlns:mvc=&amp;quot;http://www.springframework.org/schema/mvc&amp;quot;&lt;br /&gt;
       xsi:schemaLocation=&amp;quot;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd&lt;br /&gt;
       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd&lt;br /&gt;
       http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd&lt;br /&gt;
       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd&lt;br /&gt;
       http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd&amp;quot;&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
    &amp;lt;context:component-scan base-package=&amp;quot;com.dosideas.jsonconspringmvc&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;mvc:annotation-driven /&amp;gt;&lt;br /&gt;
    &amp;lt;bean class=&amp;quot;org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerExceptionResolver&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;property name=&amp;quot;messageConverters&amp;quot;&amp;gt;&lt;br /&gt;
	    &amp;lt;list&amp;gt;&lt;br /&gt;
	        &amp;lt;bean class=&amp;quot;org.springframework.http.converter.json.MappingJacksonHttpMessageConverter&amp;quot; /&amp;gt;&lt;br /&gt;
	    &amp;lt;/list&amp;gt;&lt;br /&gt;
	&amp;lt;/property&amp;gt;&lt;br /&gt;
    &amp;lt;/bean&amp;gt;&lt;br /&gt;
&amp;lt;/beans&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Al utilizar este interceptor se debe personalizar la excepciones en todos los controladores, caso contrario la excepción no es customizada y retorna un status code 500.&lt;br /&gt;
En caso de que se quiera utilizar los 2 métodos, el de @ResponseStatus y el de @ExceptionHandler, se debe registrar los 2 Handler en el applicationContext con el orden de ejecucion.&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;bean class=&amp;quot;org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerExceptionResolver&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;property name=&amp;quot;order&amp;quot; value=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;
    &amp;lt;property name=&amp;quot;messageConverters&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;list&amp;gt;&lt;br /&gt;
            &amp;lt;bean class=&amp;quot;org.springframework.http.converter.json.MappingJacksonHttpMessageConverter&amp;quot; /&amp;gt;&lt;br /&gt;
       &amp;lt;/list&amp;gt;&lt;br /&gt;
    &amp;lt;/property&amp;gt;&lt;br /&gt;
    &amp;lt;/bean&amp;gt;&lt;br /&gt;
    &amp;lt;bean class=&amp;quot;org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver&amp;quot; &amp;gt;&lt;br /&gt;
    &amp;lt;property name=&amp;quot;order&amp;quot; value=&amp;quot;2&amp;quot;/&amp;gt;&lt;br /&gt;
    &amp;lt;/bean&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Manejo de la respuesta ==&lt;br /&gt;
La anotación @ResponseStatus puede usarse para personalizar el código HTTP de cualquier respuesta, al ubicarla en el método. &lt;br /&gt;
Por ejemplo, los métodos que devuelven void pueden usar esta anotación para indicar que no hay contenido (es útil si, por ejemplo, se parsea el contenido con algunas librerías como [[JQuery]]).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java5&amp;gt;&lt;br /&gt;
    @RequestMapping(value=&amp;quot;/delete/{id}&amp;quot;)&lt;br /&gt;
    @ResponseStatus(HttpStatus.NO_CONTENT)&lt;br /&gt;
    public void delete(@PathVariable long id) {&lt;br /&gt;
        contactService.delete(id);&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Descargar un proyecto de ejemplo ===&lt;br /&gt;
Les dejamos para [http://www.dosideas.com/descargas/category/2-spring-framework.html?download=41%3Ap descargar un proyecto de ejemplo de REST con Spring MVC] donde tienen todos los fuentes necesarios para abrir y ejecutar el ejemplo de esta página.&lt;br /&gt;
&lt;br /&gt;
== Ver también ==&lt;br /&gt;
* [http://www.dosideas.com/descargas/category/2-spring-framework.html?download=41%3Ap Descargar un proyecto de ejemplo]&lt;br /&gt;
* [http://static.springsource.org/spring/docs/3.0.0.M3/spring-framework-reference/html/ch18.html Creating Restful services - Documentación oficial]&lt;br /&gt;
* [http://www.informit.com/guides/content.aspx?g=java&amp;amp;seqNum=544 Creating Restful web services]&lt;br /&gt;
* [http://www.ibm.com/developerworks/web/library/wa-spring3webserv/index.html?ca=drs- Building RESTful web services using Spring 3]&lt;br /&gt;
* [http://www.adictosaltrabajo.com/tutoriales/tutoriales.php?pagina=springRestJson Spring + REST + JSON = SOAUI]&lt;br /&gt;
* [http://www.jpalace.org/docs/spring/rest.html Sprint REST Tutorial]&lt;/div&gt;</summary>
		<author><name>201.251.182.130</name></author>	</entry>

	<entry>
		<id>https://dosideas.com/wiki/index.php?title=REST_con_Spring&amp;diff=6278</id>
		<title>REST con Spring</title>
		<link rel="alternate" type="text/html" href="https://dosideas.com/wiki/index.php?title=REST_con_Spring&amp;diff=6278"/>
				<updated>2011-09-07T13:29:18Z</updated>
		
		<summary type="html">&lt;p&gt;201.251.182.130: /* Manejo de errores */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Spring Framework]] 3.x trae la posibilidad de crear servicios web REST de manera muy simple. &lt;br /&gt;
&lt;br /&gt;
== Un ejemplo ==&lt;br /&gt;
Vamos a realizar una aplicación que responda a las siguientes URL: &lt;br /&gt;
&lt;br /&gt;
 /persona/todos   : devuelve todas las personas&lt;br /&gt;
 /persona/123     : devuelve la persona cuyo id es 123&lt;br /&gt;
&lt;br /&gt;
Tendremos que seguir 3 pasos:&lt;br /&gt;
# Configurar el servlet de Spring&lt;br /&gt;
# Crear la clase que atenderá y resolverá estas peticiones&lt;br /&gt;
# Configurar Spring&lt;br /&gt;
&lt;br /&gt;
=== El servlet de Spring ===&lt;br /&gt;
Lo primero es configurar el servlet de Spring que se encargará de tomas las peticiones y redireccionarla a las clases correspondientes. La clase que se encarga de esto es ''org.springframework.web.servlet.DispatcherServlet''. Un archivo web.xml de ejemplo sería: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;web-app version=&amp;quot;2.5&amp;quot; xmlns=&amp;quot;http://java.sun.com/xml/ns/javaee&amp;quot; xmlns:xsi=&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot; xsi:schemaLocation=&amp;quot;http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;display-name&amp;gt;json-con-spring-mvc&amp;lt;/display-name&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;filter&amp;gt;&lt;br /&gt;
        &amp;lt;filter-name&amp;gt;characterEncodingFilter&amp;lt;/filter-name&amp;gt;&lt;br /&gt;
        &amp;lt;filter-class&amp;gt;org.springframework.web.filter.CharacterEncodingFilter&amp;lt;/filter-class&amp;gt;&lt;br /&gt;
        &amp;lt;init-param&amp;gt;&lt;br /&gt;
            &amp;lt;param-name&amp;gt;encoding&amp;lt;/param-name&amp;gt;&lt;br /&gt;
            &amp;lt;param-value&amp;gt;UTF-8&amp;lt;/param-value&amp;gt;&lt;br /&gt;
        &amp;lt;/init-param&amp;gt;&lt;br /&gt;
        &amp;lt;init-param&amp;gt;&lt;br /&gt;
            &amp;lt;param-name&amp;gt;forceEncoding&amp;lt;/param-name&amp;gt;&lt;br /&gt;
            &amp;lt;param-value&amp;gt;true&amp;lt;/param-value&amp;gt;&lt;br /&gt;
        &amp;lt;/init-param&amp;gt;&lt;br /&gt;
    &amp;lt;/filter&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;filter-mapping&amp;gt;&lt;br /&gt;
        &amp;lt;filter-name&amp;gt;characterEncodingFilter&amp;lt;/filter-name&amp;gt;&lt;br /&gt;
        &amp;lt;url-pattern&amp;gt;/*&amp;lt;/url-pattern&amp;gt;&lt;br /&gt;
    &amp;lt;/filter-mapping&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;servlet&amp;gt;&lt;br /&gt;
        &amp;lt;servlet-name&amp;gt;Spring MVC Dispatcher Servlet&amp;lt;/servlet-name&amp;gt;&lt;br /&gt;
        &amp;lt;servlet-class&amp;gt;org.springframework.web.servlet.DispatcherServlet&amp;lt;/servlet-class&amp;gt;&lt;br /&gt;
        &amp;lt;init-param&amp;gt;&lt;br /&gt;
            &amp;lt;param-name&amp;gt;contextConfigLocation&amp;lt;/param-name&amp;gt;&lt;br /&gt;
            &amp;lt;param-value&amp;gt;&lt;br /&gt;
			WEB-INF/applicationContext-clasico.xml&lt;br /&gt;
            &amp;lt;/param-value&amp;gt;&lt;br /&gt;
        &amp;lt;/init-param&amp;gt;&lt;br /&gt;
        &amp;lt;load-on-startup&amp;gt;1&amp;lt;/load-on-startup&amp;gt;&lt;br /&gt;
    &amp;lt;/servlet&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;servlet-mapping&amp;gt;&lt;br /&gt;
        &amp;lt;servlet-name&amp;gt;Spring MVC Dispatcher Servlet&amp;lt;/servlet-name&amp;gt;&lt;br /&gt;
        &amp;lt;url-pattern&amp;gt;/app/*&amp;lt;/url-pattern&amp;gt;&lt;br /&gt;
    &amp;lt;/servlet-mapping&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;session-config&amp;gt;&lt;br /&gt;
        &amp;lt;session-timeout&amp;gt;&lt;br /&gt;
            30&lt;br /&gt;
        &amp;lt;/session-timeout&amp;gt;&lt;br /&gt;
    &amp;lt;/session-config&amp;gt;&lt;br /&gt;
    &amp;lt;welcome-file-list&amp;gt;&lt;br /&gt;
        &amp;lt;welcome-file&amp;gt;index.jsp&amp;lt;/welcome-file&amp;gt;&lt;br /&gt;
    &amp;lt;/welcome-file-list&amp;gt;&lt;br /&gt;
&amp;lt;/web-app&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En este ejemplo, el servlet de Spring queda atendiendo todas las URL que empiecen con &amp;quot;/app&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
=== El controller ===&lt;br /&gt;
La clase que toma las peticiones HTTP es una clase Java anotada con @Controller. Esta clase asocia las URL con métodos. Los objetos que devuelven los métodos son luego procesador por conversores, que representan la respuesta de distinta manera (XML, JSON, etc.)&lt;br /&gt;
&lt;br /&gt;
Para esto, creamos una clase de la siguiente forma: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java5&amp;gt;&lt;br /&gt;
package com.dosideas.jsonconspringmvc;&lt;br /&gt;
&lt;br /&gt;
import java.util.ArrayList;&lt;br /&gt;
import java.util.Collection;&lt;br /&gt;
import org.springframework.stereotype.Controller;&lt;br /&gt;
import org.springframework.web.bind.annotation.PathVariable;&lt;br /&gt;
import org.springframework.web.bind.annotation.RequestBody;&lt;br /&gt;
import org.springframework.web.bind.annotation.RequestMapping;&lt;br /&gt;
import org.springframework.web.bind.annotation.ResponseBody;&lt;br /&gt;
&lt;br /&gt;
@Controller&lt;br /&gt;
@RequestMapping(value=&amp;quot;/persona&amp;quot;)&lt;br /&gt;
public class PersonaController {&lt;br /&gt;
&lt;br /&gt;
    @RequestMapping(value=&amp;quot;/{id}&amp;quot;)&lt;br /&gt;
    public @ResponseBody Persona get(@PathVariable Long id) {&lt;br /&gt;
        Persona p = new Persona(&amp;quot;Invasor &amp;quot; + id, &amp;quot;Zim &amp;quot; + id);&lt;br /&gt;
        return p;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    @RequestMapping(value=&amp;quot;/todos&amp;quot;)&lt;br /&gt;
    public @ResponseBody Collection&amp;lt;Persona&amp;gt; getTodos() {&lt;br /&gt;
        Collection&amp;lt;Persona&amp;gt; personas = new ArrayList&amp;lt;Persona&amp;gt;();&lt;br /&gt;
        for (int i = 0; i &amp;lt; 10; i++) {&lt;br /&gt;
            Persona p = new Persona(&amp;quot;Invasor &amp;quot; + i, &amp;quot;Zim&amp;quot; + i);&lt;br /&gt;
            personas.add(p);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        return personas;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
El objeto Persona es un POJO que tiene dos atributos: nombre y apellido. Los tags @RequestMapping se encargan de asociar la clase y cada uno de sus métodos con una URL en particular. &lt;br /&gt;
&lt;br /&gt;
=== La configuración ===&lt;br /&gt;
Lo último que nos queda configurar es Spring con un archivo clásico (el cual es referenciado por el servlet):  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;beans xmlns=&amp;quot;http://www.springframework.org/schema/beans&amp;quot;&lt;br /&gt;
       xmlns:xsi=&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot;&lt;br /&gt;
       xmlns:p=&amp;quot;http://www.springframework.org/schema/p&amp;quot;&lt;br /&gt;
       xmlns:aop=&amp;quot;http://www.springframework.org/schema/aop&amp;quot;&lt;br /&gt;
       xmlns:tx=&amp;quot;http://www.springframework.org/schema/tx&amp;quot;&lt;br /&gt;
       xmlns:context=&amp;quot;http://www.springframework.org/schema/context&amp;quot;&lt;br /&gt;
       xmlns:mvc=&amp;quot;http://www.springframework.org/schema/mvc&amp;quot;&lt;br /&gt;
       xsi:schemaLocation=&amp;quot;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd&lt;br /&gt;
       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd&lt;br /&gt;
       http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd&lt;br /&gt;
       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd&lt;br /&gt;
       http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd&amp;quot;&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
    &amp;lt;context:component-scan base-package=&amp;quot;com.dosideas.jsonconspringmvc&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;mvc:annotation-driven /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/beans&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
El tag ''mvc:annotation-driven'' se encarga de configurar automáticamente para emepezar a recibir y responder peticiones usando los controladores encontrados. &lt;br /&gt;
&lt;br /&gt;
Más aún, la configuración predeterminada se encarga de realizar [http://en.wikipedia.org/wiki/Content_negotiation negociación de contenido]: la respuesta se formatea de acuerdo a las capacidades del cliente. Por ejemplo, si en el classpath tenemos agregado las librerías de Jackson (un parser JSON), se habilitará el soporte JSON correspondiente. Si están agregadas las librerías de JAXB2, se habilitará el soporte XML. &lt;br /&gt;
&lt;br /&gt;
=== Probando ===&lt;br /&gt;
Podemos crear una prueba [[JUnit]] para acceder a nuestro servicio: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java5&amp;gt;&lt;br /&gt;
package com.dosideas.jsonconspringmvc;&lt;br /&gt;
&lt;br /&gt;
import java.io.IOException;&lt;br /&gt;
import org.apache.commons.httpclient.methods.GetMethod;&lt;br /&gt;
import org.apache.commons.httpclient.HttpMethod;&lt;br /&gt;
import org.apache.commons.httpclient.HttpClient;&lt;br /&gt;
import org.junit.Test;&lt;br /&gt;
import static org.junit.Assert.*;&lt;br /&gt;
&lt;br /&gt;
public class HttpTest {&lt;br /&gt;
&lt;br /&gt;
    @Test&lt;br /&gt;
    public void personaTodosJSON() throws IOException {&lt;br /&gt;
        HttpClient httpclient = new HttpClient();&lt;br /&gt;
        HttpMethod method = new GetMethod(&amp;quot;http://localhost:8084/json-con-spring-mvc/app/persona/todos&amp;quot;);&lt;br /&gt;
        method.addRequestHeader(&amp;quot;accept&amp;quot;, &amp;quot;application/json&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        httpclient.executeMethod(method);&lt;br /&gt;
        String resultado = method.getResponseBodyAsString();&lt;br /&gt;
        System.out.println(resultado);&lt;br /&gt;
&lt;br /&gt;
        assertNotNull(resultado);&lt;br /&gt;
        assertTrue(resultado.startsWith(&amp;quot;[{\&amp;quot;&amp;quot;));&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    @Test&lt;br /&gt;
    public void personaPorIdJSON() throws IOException {&lt;br /&gt;
        HttpClient httpclient = new HttpClient();&lt;br /&gt;
        HttpMethod method = new GetMethod(&amp;quot;http://localhost:8084/json-con-spring-mvc/app/persona/34421&amp;quot;);&lt;br /&gt;
        method.addRequestHeader(&amp;quot;accept&amp;quot;, &amp;quot;application/json&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        httpclient.executeMethod(method);&lt;br /&gt;
        String resultado = method.getResponseBodyAsString();&lt;br /&gt;
        System.out.println(resultado);&lt;br /&gt;
&lt;br /&gt;
        assertNotNull(resultado);&lt;br /&gt;
        assertTrue(resultado.startsWith(&amp;quot;{\&amp;quot;&amp;quot;));&lt;br /&gt;
        assertTrue(resultado.contains(&amp;quot;34421&amp;quot;));&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    @Test&lt;br /&gt;
    public void personaPorIdXML() throws IOException {&lt;br /&gt;
        HttpClient httpclient = new HttpClient();&lt;br /&gt;
        HttpMethod method = new GetMethod(&amp;quot;http://localhost:8084/json-con-spring-mvc/app/persona/34421&amp;quot;);&lt;br /&gt;
        method.addRequestHeader(&amp;quot;accept&amp;quot;, &amp;quot;application/xml&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        httpclient.executeMethod(method);&lt;br /&gt;
        String resultado = method.getResponseBodyAsString();&lt;br /&gt;
        System.out.println(resultado);&lt;br /&gt;
&lt;br /&gt;
        assertNotNull(resultado);&lt;br /&gt;
        assertTrue(resultado.startsWith(&amp;quot;&amp;lt;?xml version=\&amp;quot;1.0\&amp;quot;&amp;quot;));&lt;br /&gt;
        assertTrue(resultado.contains(&amp;quot;34421&amp;quot;));&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Manejo de errores ==&lt;br /&gt;
Es posible personalizar las excepciones para que devuelvan códigos de estado HTTP personalizados, usando la anotación @ResponseStatus en la excepción lanzada. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java5&amp;gt;&lt;br /&gt;
@ResponseStatus(value=HttpStatus.NOT_FOUND, reason=&amp;quot;No se encontró el recurso pedido&amp;quot;)&lt;br /&gt;
public class NotFoundException extends RuntimeException { ... }&lt;br /&gt;
&lt;br /&gt;
.....&lt;br /&gt;
&lt;br /&gt;
    @RequestMapping(value=&amp;quot;/id/{id}&amp;quot;)&lt;br /&gt;
    public @ResponseBody Persona findById(@PathVariable long id) {&lt;br /&gt;
       Contact contact = personaService.findById(id);&lt;br /&gt;
       if (contact == null) {&lt;br /&gt;
           throw new NotFoundException();&lt;br /&gt;
       } else {&lt;br /&gt;
           return contact;&lt;br /&gt;
       }&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Otra forma de personalizar las excepciones, es interceptar las excepciones del controller(@Controller) y personalizarla en el mismo controller. &lt;br /&gt;
Para esto debemos crear un método handleException por cada excepción que deseemos personalizar.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java5&amp;gt;&lt;br /&gt;
    @RequestMapping(value=&amp;quot;/id/{id}&amp;quot;)&lt;br /&gt;
    public @ResponseBody Persona findById(@PathVariable long id) {&lt;br /&gt;
       Contact contact = personaService.findById(id);&lt;br /&gt;
       if (contact == null) {&lt;br /&gt;
           throw new NotFoundException();&lt;br /&gt;
       } else {&lt;br /&gt;
           return contact;&lt;br /&gt;
       }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    @ResponseStatus(HttpStatus.NOT_FOUND)&lt;br /&gt;
    @ExceptionHandler(NotFoundException.class)&lt;br /&gt;
    @ResponseBody&lt;br /&gt;
    public Map&amp;lt;String, String&amp;gt; handleException(NotFoundException exception) {&lt;br /&gt;
        return Collections.singletonMap(&amp;quot;message&amp;quot;, &amp;quot;No se encontró el recurso pedido&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Y agregar lo siguiente en el applicationContext.xml&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;beans xmlns=&amp;quot;http://www.springframework.org/schema/beans&amp;quot;&lt;br /&gt;
       xmlns:xsi=&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot;&lt;br /&gt;
       xmlns:p=&amp;quot;http://www.springframework.org/schema/p&amp;quot;&lt;br /&gt;
       xmlns:aop=&amp;quot;http://www.springframework.org/schema/aop&amp;quot;&lt;br /&gt;
       xmlns:tx=&amp;quot;http://www.springframework.org/schema/tx&amp;quot;&lt;br /&gt;
       xmlns:context=&amp;quot;http://www.springframework.org/schema/context&amp;quot;&lt;br /&gt;
       xmlns:mvc=&amp;quot;http://www.springframework.org/schema/mvc&amp;quot;&lt;br /&gt;
       xsi:schemaLocation=&amp;quot;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd&lt;br /&gt;
       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd&lt;br /&gt;
       http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd&lt;br /&gt;
       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd&lt;br /&gt;
       http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd&amp;quot;&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
    &amp;lt;context:component-scan base-package=&amp;quot;com.dosideas.jsonconspringmvc&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;mvc:annotation-driven /&amp;gt;&lt;br /&gt;
    &amp;lt;bean class=&amp;quot;org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerExceptionResolver&amp;quot;&amp;gt;&lt;br /&gt;
		&amp;lt;property name=&amp;quot;messageConverters&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;list&amp;gt;&lt;br /&gt;
				&amp;lt;bean class=&amp;quot;org.springframework.http.converter.json.MappingJacksonHttpMessageConverter&amp;quot; /&amp;gt;&lt;br /&gt;
			&amp;lt;/list&amp;gt;&lt;br /&gt;
		&amp;lt;/property&amp;gt;&lt;br /&gt;
    &amp;lt;/bean&amp;gt;&lt;br /&gt;
&amp;lt;/beans&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Al utilizar este interceptor se debe personalizar la excepciones en todos los controladores, caso contrario la excepción no es customizada y retorna un status code 500.&lt;br /&gt;
En caso de que se quiera utilizar los 2 métodos, el de @ResponseStatus y el de @ExceptionHandler, se debe registrar los 2 Handler en el applicationContext con el orden de ejecucion.&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
    &amp;lt;bean class=&amp;quot;org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerExceptionResolver&amp;quot;&amp;gt;&lt;br /&gt;
	    &amp;lt;property name=&amp;quot;order&amp;quot; value=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;
		&amp;lt;property name=&amp;quot;messageConverters&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;list&amp;gt;&lt;br /&gt;
				&amp;lt;bean class=&amp;quot;org.springframework.http.converter.json.MappingJacksonHttpMessageConverter&amp;quot; /&amp;gt;&lt;br /&gt;
			&amp;lt;/list&amp;gt;&lt;br /&gt;
		&amp;lt;/property&amp;gt;&lt;br /&gt;
    &amp;lt;/bean&amp;gt;&lt;br /&gt;
    &amp;lt;bean class=&amp;quot;org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver&amp;quot; &amp;gt;&lt;br /&gt;
        &amp;lt;property name=&amp;quot;order&amp;quot; value=&amp;quot;2&amp;quot;/&amp;gt;&lt;br /&gt;
    &amp;lt;/bean&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Manejo de la respuesta ==&lt;br /&gt;
La anotación @ResponseStatus puede usarse para personalizar el código HTTP de cualquier respuesta, al ubicarla en el método. &lt;br /&gt;
Por ejemplo, los métodos que devuelven void pueden usar esta anotación para indicar que no hay contenido (es útil si, por ejemplo, se parsea el contenido con algunas librerías como [[JQuery]]).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java5&amp;gt;&lt;br /&gt;
    @RequestMapping(value=&amp;quot;/delete/{id}&amp;quot;)&lt;br /&gt;
    @ResponseStatus(HttpStatus.NO_CONTENT)&lt;br /&gt;
    public void delete(@PathVariable long id) {&lt;br /&gt;
        contactService.delete(id);&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Descargar un proyecto de ejemplo ===&lt;br /&gt;
Les dejamos para [http://www.dosideas.com/descargas/category/2-spring-framework.html?download=41%3Ap descargar un proyecto de ejemplo de REST con Spring MVC] donde tienen todos los fuentes necesarios para abrir y ejecutar el ejemplo de esta página.&lt;br /&gt;
&lt;br /&gt;
== Ver también ==&lt;br /&gt;
* [http://www.dosideas.com/descargas/category/2-spring-framework.html?download=41%3Ap Descargar un proyecto de ejemplo]&lt;br /&gt;
* [http://static.springsource.org/spring/docs/3.0.0.M3/spring-framework-reference/html/ch18.html Creating Restful services - Documentación oficial]&lt;br /&gt;
* [http://www.informit.com/guides/content.aspx?g=java&amp;amp;seqNum=544 Creating Restful web services]&lt;br /&gt;
* [http://www.ibm.com/developerworks/web/library/wa-spring3webserv/index.html?ca=drs- Building RESTful web services using Spring 3]&lt;br /&gt;
* [http://www.adictosaltrabajo.com/tutoriales/tutoriales.php?pagina=springRestJson Spring + REST + JSON = SOAUI]&lt;br /&gt;
* [http://www.jpalace.org/docs/spring/rest.html Sprint REST Tutorial]&lt;/div&gt;</summary>
		<author><name>201.251.182.130</name></author>	</entry>

	<entry>
		<id>https://dosideas.com/wiki/index.php?title=REST_con_Spring&amp;diff=6277</id>
		<title>REST con Spring</title>
		<link rel="alternate" type="text/html" href="https://dosideas.com/wiki/index.php?title=REST_con_Spring&amp;diff=6277"/>
				<updated>2011-09-07T13:13:06Z</updated>
		
		<summary type="html">&lt;p&gt;201.251.182.130: /* Manejo de errores */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Spring Framework]] 3.x trae la posibilidad de crear servicios web REST de manera muy simple. &lt;br /&gt;
&lt;br /&gt;
== Un ejemplo ==&lt;br /&gt;
Vamos a realizar una aplicación que responda a las siguientes URL: &lt;br /&gt;
&lt;br /&gt;
 /persona/todos   : devuelve todas las personas&lt;br /&gt;
 /persona/123     : devuelve la persona cuyo id es 123&lt;br /&gt;
&lt;br /&gt;
Tendremos que seguir 3 pasos:&lt;br /&gt;
# Configurar el servlet de Spring&lt;br /&gt;
# Crear la clase que atenderá y resolverá estas peticiones&lt;br /&gt;
# Configurar Spring&lt;br /&gt;
&lt;br /&gt;
=== El servlet de Spring ===&lt;br /&gt;
Lo primero es configurar el servlet de Spring que se encargará de tomas las peticiones y redireccionarla a las clases correspondientes. La clase que se encarga de esto es ''org.springframework.web.servlet.DispatcherServlet''. Un archivo web.xml de ejemplo sería: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;web-app version=&amp;quot;2.5&amp;quot; xmlns=&amp;quot;http://java.sun.com/xml/ns/javaee&amp;quot; xmlns:xsi=&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot; xsi:schemaLocation=&amp;quot;http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;display-name&amp;gt;json-con-spring-mvc&amp;lt;/display-name&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;filter&amp;gt;&lt;br /&gt;
        &amp;lt;filter-name&amp;gt;characterEncodingFilter&amp;lt;/filter-name&amp;gt;&lt;br /&gt;
        &amp;lt;filter-class&amp;gt;org.springframework.web.filter.CharacterEncodingFilter&amp;lt;/filter-class&amp;gt;&lt;br /&gt;
        &amp;lt;init-param&amp;gt;&lt;br /&gt;
            &amp;lt;param-name&amp;gt;encoding&amp;lt;/param-name&amp;gt;&lt;br /&gt;
            &amp;lt;param-value&amp;gt;UTF-8&amp;lt;/param-value&amp;gt;&lt;br /&gt;
        &amp;lt;/init-param&amp;gt;&lt;br /&gt;
        &amp;lt;init-param&amp;gt;&lt;br /&gt;
            &amp;lt;param-name&amp;gt;forceEncoding&amp;lt;/param-name&amp;gt;&lt;br /&gt;
            &amp;lt;param-value&amp;gt;true&amp;lt;/param-value&amp;gt;&lt;br /&gt;
        &amp;lt;/init-param&amp;gt;&lt;br /&gt;
    &amp;lt;/filter&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;filter-mapping&amp;gt;&lt;br /&gt;
        &amp;lt;filter-name&amp;gt;characterEncodingFilter&amp;lt;/filter-name&amp;gt;&lt;br /&gt;
        &amp;lt;url-pattern&amp;gt;/*&amp;lt;/url-pattern&amp;gt;&lt;br /&gt;
    &amp;lt;/filter-mapping&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;servlet&amp;gt;&lt;br /&gt;
        &amp;lt;servlet-name&amp;gt;Spring MVC Dispatcher Servlet&amp;lt;/servlet-name&amp;gt;&lt;br /&gt;
        &amp;lt;servlet-class&amp;gt;org.springframework.web.servlet.DispatcherServlet&amp;lt;/servlet-class&amp;gt;&lt;br /&gt;
        &amp;lt;init-param&amp;gt;&lt;br /&gt;
            &amp;lt;param-name&amp;gt;contextConfigLocation&amp;lt;/param-name&amp;gt;&lt;br /&gt;
            &amp;lt;param-value&amp;gt;&lt;br /&gt;
			WEB-INF/applicationContext-clasico.xml&lt;br /&gt;
            &amp;lt;/param-value&amp;gt;&lt;br /&gt;
        &amp;lt;/init-param&amp;gt;&lt;br /&gt;
        &amp;lt;load-on-startup&amp;gt;1&amp;lt;/load-on-startup&amp;gt;&lt;br /&gt;
    &amp;lt;/servlet&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;servlet-mapping&amp;gt;&lt;br /&gt;
        &amp;lt;servlet-name&amp;gt;Spring MVC Dispatcher Servlet&amp;lt;/servlet-name&amp;gt;&lt;br /&gt;
        &amp;lt;url-pattern&amp;gt;/app/*&amp;lt;/url-pattern&amp;gt;&lt;br /&gt;
    &amp;lt;/servlet-mapping&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;session-config&amp;gt;&lt;br /&gt;
        &amp;lt;session-timeout&amp;gt;&lt;br /&gt;
            30&lt;br /&gt;
        &amp;lt;/session-timeout&amp;gt;&lt;br /&gt;
    &amp;lt;/session-config&amp;gt;&lt;br /&gt;
    &amp;lt;welcome-file-list&amp;gt;&lt;br /&gt;
        &amp;lt;welcome-file&amp;gt;index.jsp&amp;lt;/welcome-file&amp;gt;&lt;br /&gt;
    &amp;lt;/welcome-file-list&amp;gt;&lt;br /&gt;
&amp;lt;/web-app&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En este ejemplo, el servlet de Spring queda atendiendo todas las URL que empiecen con &amp;quot;/app&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
=== El controller ===&lt;br /&gt;
La clase que toma las peticiones HTTP es una clase Java anotada con @Controller. Esta clase asocia las URL con métodos. Los objetos que devuelven los métodos son luego procesador por conversores, que representan la respuesta de distinta manera (XML, JSON, etc.)&lt;br /&gt;
&lt;br /&gt;
Para esto, creamos una clase de la siguiente forma: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java5&amp;gt;&lt;br /&gt;
package com.dosideas.jsonconspringmvc;&lt;br /&gt;
&lt;br /&gt;
import java.util.ArrayList;&lt;br /&gt;
import java.util.Collection;&lt;br /&gt;
import org.springframework.stereotype.Controller;&lt;br /&gt;
import org.springframework.web.bind.annotation.PathVariable;&lt;br /&gt;
import org.springframework.web.bind.annotation.RequestBody;&lt;br /&gt;
import org.springframework.web.bind.annotation.RequestMapping;&lt;br /&gt;
import org.springframework.web.bind.annotation.ResponseBody;&lt;br /&gt;
&lt;br /&gt;
@Controller&lt;br /&gt;
@RequestMapping(value=&amp;quot;/persona&amp;quot;)&lt;br /&gt;
public class PersonaController {&lt;br /&gt;
&lt;br /&gt;
    @RequestMapping(value=&amp;quot;/{id}&amp;quot;)&lt;br /&gt;
    public @ResponseBody Persona get(@PathVariable Long id) {&lt;br /&gt;
        Persona p = new Persona(&amp;quot;Invasor &amp;quot; + id, &amp;quot;Zim &amp;quot; + id);&lt;br /&gt;
        return p;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    @RequestMapping(value=&amp;quot;/todos&amp;quot;)&lt;br /&gt;
    public @ResponseBody Collection&amp;lt;Persona&amp;gt; getTodos() {&lt;br /&gt;
        Collection&amp;lt;Persona&amp;gt; personas = new ArrayList&amp;lt;Persona&amp;gt;();&lt;br /&gt;
        for (int i = 0; i &amp;lt; 10; i++) {&lt;br /&gt;
            Persona p = new Persona(&amp;quot;Invasor &amp;quot; + i, &amp;quot;Zim&amp;quot; + i);&lt;br /&gt;
            personas.add(p);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        return personas;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
El objeto Persona es un POJO que tiene dos atributos: nombre y apellido. Los tags @RequestMapping se encargan de asociar la clase y cada uno de sus métodos con una URL en particular. &lt;br /&gt;
&lt;br /&gt;
=== La configuración ===&lt;br /&gt;
Lo último que nos queda configurar es Spring con un archivo clásico (el cual es referenciado por el servlet):  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;beans xmlns=&amp;quot;http://www.springframework.org/schema/beans&amp;quot;&lt;br /&gt;
       xmlns:xsi=&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot;&lt;br /&gt;
       xmlns:p=&amp;quot;http://www.springframework.org/schema/p&amp;quot;&lt;br /&gt;
       xmlns:aop=&amp;quot;http://www.springframework.org/schema/aop&amp;quot;&lt;br /&gt;
       xmlns:tx=&amp;quot;http://www.springframework.org/schema/tx&amp;quot;&lt;br /&gt;
       xmlns:context=&amp;quot;http://www.springframework.org/schema/context&amp;quot;&lt;br /&gt;
       xmlns:mvc=&amp;quot;http://www.springframework.org/schema/mvc&amp;quot;&lt;br /&gt;
       xsi:schemaLocation=&amp;quot;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd&lt;br /&gt;
       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd&lt;br /&gt;
       http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd&lt;br /&gt;
       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd&lt;br /&gt;
       http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd&amp;quot;&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
    &amp;lt;context:component-scan base-package=&amp;quot;com.dosideas.jsonconspringmvc&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;mvc:annotation-driven /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/beans&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
El tag ''mvc:annotation-driven'' se encarga de configurar automáticamente para emepezar a recibir y responder peticiones usando los controladores encontrados. &lt;br /&gt;
&lt;br /&gt;
Más aún, la configuración predeterminada se encarga de realizar [http://en.wikipedia.org/wiki/Content_negotiation negociación de contenido]: la respuesta se formatea de acuerdo a las capacidades del cliente. Por ejemplo, si en el classpath tenemos agregado las librerías de Jackson (un parser JSON), se habilitará el soporte JSON correspondiente. Si están agregadas las librerías de JAXB2, se habilitará el soporte XML. &lt;br /&gt;
&lt;br /&gt;
=== Probando ===&lt;br /&gt;
Podemos crear una prueba [[JUnit]] para acceder a nuestro servicio: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java5&amp;gt;&lt;br /&gt;
package com.dosideas.jsonconspringmvc;&lt;br /&gt;
&lt;br /&gt;
import java.io.IOException;&lt;br /&gt;
import org.apache.commons.httpclient.methods.GetMethod;&lt;br /&gt;
import org.apache.commons.httpclient.HttpMethod;&lt;br /&gt;
import org.apache.commons.httpclient.HttpClient;&lt;br /&gt;
import org.junit.Test;&lt;br /&gt;
import static org.junit.Assert.*;&lt;br /&gt;
&lt;br /&gt;
public class HttpTest {&lt;br /&gt;
&lt;br /&gt;
    @Test&lt;br /&gt;
    public void personaTodosJSON() throws IOException {&lt;br /&gt;
        HttpClient httpclient = new HttpClient();&lt;br /&gt;
        HttpMethod method = new GetMethod(&amp;quot;http://localhost:8084/json-con-spring-mvc/app/persona/todos&amp;quot;);&lt;br /&gt;
        method.addRequestHeader(&amp;quot;accept&amp;quot;, &amp;quot;application/json&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        httpclient.executeMethod(method);&lt;br /&gt;
        String resultado = method.getResponseBodyAsString();&lt;br /&gt;
        System.out.println(resultado);&lt;br /&gt;
&lt;br /&gt;
        assertNotNull(resultado);&lt;br /&gt;
        assertTrue(resultado.startsWith(&amp;quot;[{\&amp;quot;&amp;quot;));&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    @Test&lt;br /&gt;
    public void personaPorIdJSON() throws IOException {&lt;br /&gt;
        HttpClient httpclient = new HttpClient();&lt;br /&gt;
        HttpMethod method = new GetMethod(&amp;quot;http://localhost:8084/json-con-spring-mvc/app/persona/34421&amp;quot;);&lt;br /&gt;
        method.addRequestHeader(&amp;quot;accept&amp;quot;, &amp;quot;application/json&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        httpclient.executeMethod(method);&lt;br /&gt;
        String resultado = method.getResponseBodyAsString();&lt;br /&gt;
        System.out.println(resultado);&lt;br /&gt;
&lt;br /&gt;
        assertNotNull(resultado);&lt;br /&gt;
        assertTrue(resultado.startsWith(&amp;quot;{\&amp;quot;&amp;quot;));&lt;br /&gt;
        assertTrue(resultado.contains(&amp;quot;34421&amp;quot;));&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    @Test&lt;br /&gt;
    public void personaPorIdXML() throws IOException {&lt;br /&gt;
        HttpClient httpclient = new HttpClient();&lt;br /&gt;
        HttpMethod method = new GetMethod(&amp;quot;http://localhost:8084/json-con-spring-mvc/app/persona/34421&amp;quot;);&lt;br /&gt;
        method.addRequestHeader(&amp;quot;accept&amp;quot;, &amp;quot;application/xml&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        httpclient.executeMethod(method);&lt;br /&gt;
        String resultado = method.getResponseBodyAsString();&lt;br /&gt;
        System.out.println(resultado);&lt;br /&gt;
&lt;br /&gt;
        assertNotNull(resultado);&lt;br /&gt;
        assertTrue(resultado.startsWith(&amp;quot;&amp;lt;?xml version=\&amp;quot;1.0\&amp;quot;&amp;quot;));&lt;br /&gt;
        assertTrue(resultado.contains(&amp;quot;34421&amp;quot;));&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Manejo de errores ==&lt;br /&gt;
Es posible personalizar las excepciones para que devuelvan códigos de estado HTTP personalizados, usando la anotación @ResponseStatus en la excepción lanzada. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java5&amp;gt;&lt;br /&gt;
@ResponseStatus(value=HttpStatus.NOT_FOUND, reason=&amp;quot;No se encontró el recurso pedido&amp;quot;)&lt;br /&gt;
public class NotFoundException extends RuntimeException { ... }&lt;br /&gt;
&lt;br /&gt;
.....&lt;br /&gt;
&lt;br /&gt;
    @RequestMapping(value=&amp;quot;/id/{id}&amp;quot;)&lt;br /&gt;
    public @ResponseBody Persona findById(@PathVariable long id) {&lt;br /&gt;
       Contact contact = personaService.findById(id);&lt;br /&gt;
       if (contact == null) {&lt;br /&gt;
           throw new NotFoundException();&lt;br /&gt;
       } else {&lt;br /&gt;
           return contact;&lt;br /&gt;
       }&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Otra forma de personalizar las excepciones, es interceptar las excepciones del controller(@Controller) y personalizarla en el mismo controller. &lt;br /&gt;
Para esto debemos crear un método handleException por cada excepción que deseemos personalizar.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java5&amp;gt;&lt;br /&gt;
    @RequestMapping(value=&amp;quot;/id/{id}&amp;quot;)&lt;br /&gt;
    public @ResponseBody Persona findById(@PathVariable long id) {&lt;br /&gt;
       Contact contact = personaService.findById(id);&lt;br /&gt;
       if (contact == null) {&lt;br /&gt;
           throw new NotFoundException();&lt;br /&gt;
       } else {&lt;br /&gt;
           return contact;&lt;br /&gt;
       }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    @ResponseStatus(HttpStatus.NOT_FOUND)&lt;br /&gt;
    @ExceptionHandler(NotFoundException.class)&lt;br /&gt;
    @ResponseBody&lt;br /&gt;
    public Map&amp;lt;String, String&amp;gt; handleException(NotFoundException exception) {&lt;br /&gt;
        return Collections.singletonMap(&amp;quot;message&amp;quot;, &amp;quot;No se encontró el recurso pedido&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
Y configurar lo siguiente en el applicationContext.xml&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Manejo de la respuesta ==&lt;br /&gt;
La anotación @ResponseStatus puede usarse para personalizar el código HTTP de cualquier respuesta, al ubicarla en el método. &lt;br /&gt;
Por ejemplo, los métodos que devuelven void pueden usar esta anotación para indicar que no hay contenido (es útil si, por ejemplo, se parsea el contenido con algunas librerías como [[JQuery]]).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java5&amp;gt;&lt;br /&gt;
    @RequestMapping(value=&amp;quot;/delete/{id}&amp;quot;)&lt;br /&gt;
    @ResponseStatus(HttpStatus.NO_CONTENT)&lt;br /&gt;
    public void delete(@PathVariable long id) {&lt;br /&gt;
        contactService.delete(id);&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Descargar un proyecto de ejemplo ===&lt;br /&gt;
Les dejamos para [http://www.dosideas.com/descargas/category/2-spring-framework.html?download=41%3Ap descargar un proyecto de ejemplo de REST con Spring MVC] donde tienen todos los fuentes necesarios para abrir y ejecutar el ejemplo de esta página.&lt;br /&gt;
&lt;br /&gt;
== Ver también ==&lt;br /&gt;
* [http://www.dosideas.com/descargas/category/2-spring-framework.html?download=41%3Ap Descargar un proyecto de ejemplo]&lt;br /&gt;
* [http://static.springsource.org/spring/docs/3.0.0.M3/spring-framework-reference/html/ch18.html Creating Restful services - Documentación oficial]&lt;br /&gt;
* [http://www.informit.com/guides/content.aspx?g=java&amp;amp;seqNum=544 Creating Restful web services]&lt;br /&gt;
* [http://www.ibm.com/developerworks/web/library/wa-spring3webserv/index.html?ca=drs- Building RESTful web services using Spring 3]&lt;br /&gt;
* [http://www.adictosaltrabajo.com/tutoriales/tutoriales.php?pagina=springRestJson Spring + REST + JSON = SOAUI]&lt;br /&gt;
* [http://www.jpalace.org/docs/spring/rest.html Sprint REST Tutorial]&lt;/div&gt;</summary>
		<author><name>201.251.182.130</name></author>	</entry>

	<entry>
		<id>https://dosideas.com/wiki/index.php?title=Mockito&amp;diff=6208</id>
		<title>Mockito</title>
		<link rel="alternate" type="text/html" href="https://dosideas.com/wiki/index.php?title=Mockito&amp;diff=6208"/>
				<updated>2011-09-06T19:22:27Z</updated>
		
		<summary type="html">&lt;p&gt;201.251.182.130: Deshecha la edición 6168 de 211.214.160.38 (disc.)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Mockito es una librería [[Java]] para la creación de [[Mock Object]] muy usados para el testeo unitario en [[Test Driven Development]], basado en [[EasyMock]]. &lt;br /&gt;
&lt;br /&gt;
Mockito fue creado con el objetivo de simplificar y solucionar algunos de los temas antes mencionados. EasyMock y Mockito puede hacer exactamente las mismas cosas, pero Mockito tiene un API más natural y práctico de usar.&lt;br /&gt;
&lt;br /&gt;
==Características principales==&lt;br /&gt;
# Se pueden crear mocks de interfaces y clases concretas.&lt;br /&gt;
# Verificación de invocaciones (cantidad exacta, al menos una vez, órden de invocación, etc.)&lt;br /&gt;
# El stack trace se mantiene limpio, ya que los errores ocurren en los assert que se hagan (y no dentro del método bajo prueba, como en EasyMock).&lt;br /&gt;
# Un API más clara para crear stubs y verificaciones&lt;br /&gt;
&lt;br /&gt;
==Ejemplo de uso==&lt;br /&gt;
&amp;lt;code java&amp;gt;&lt;br /&gt;
import static org.mockito.Mockito.*;&lt;br /&gt;
.....&lt;br /&gt;
//creamos el mock y el stub&lt;br /&gt;
ArrayList instance = mock(ArrayList.class);&lt;br /&gt;
doReturn(&amp;quot;hola mundo&amp;quot;).when(instance).get(0);&lt;br /&gt;
 &lt;br /&gt;
//ejecutamos la lógica a probar&lt;br /&gt;
instance.get(0);     &lt;br /&gt;
 &lt;br /&gt;
//verificamos que se hayan invocado los métodos&lt;br /&gt;
verify(instance).get(0);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Más de una invocación a un mismo método==&lt;br /&gt;
&lt;br /&gt;
Algunas veces necesitamos que un método retorne un valor y que en la segunda invocación retorne nulo o una excepción. Para eso, anidamos los retornos:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code html4strict&amp;gt;&lt;br /&gt;
&lt;br /&gt;
//Retornos para las 2 invocaciones&lt;br /&gt;
doReturn(&amp;quot;algo&amp;quot;).doReturn(null).when(instance).scrollNext();&lt;br /&gt;
&lt;br /&gt;
//ejecutamos la lógica a probar&lt;br /&gt;
instance.unMetodoQueUsaScroll();     &lt;br /&gt;
&lt;br /&gt;
//verificamos que se haya invocado el mismo método dos veces&lt;br /&gt;
verify(instance, times(2)).scrollNext();&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [http://mockito.googlecode.com/svn/branches/1.5/javadoc/org/mockito/Mockito.html Leer más en Mockito API]&lt;br /&gt;
&lt;br /&gt;
==Ejemplos de Mockito junto a PowerMock==&lt;br /&gt;
&lt;br /&gt;
===Invocación a un método estático===&lt;br /&gt;
&lt;br /&gt;
Para mockear métodos estáticos, según el [http://code.google.com/p/mockito/wiki/FAQ FAQ] de mockito, esto no es posible. Pero nombra 2 framewors que pueden resultarnos útil [http://jmockit.dev.java.net/ JMockit] y [http://code.google.com/p/powermock PowerMock]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java&amp;gt;&lt;br /&gt;
@RunWith(PowerMockRunner.class)&lt;br /&gt;
@PrepareForTest(ClaseConMetodosEstaticos.class)&lt;br /&gt;
public class DosIdeasTestCase {&lt;br /&gt;
    @Test&lt;br /&gt;
    public void testMetodo_conInvocacionAMetodosEstaticos() {&lt;br /&gt;
	&lt;br /&gt;
        //PowerMockito mockea los metodos estaticos que se encuentren en la &lt;br /&gt;
        //clase ClaseConMetodosEstaticos&lt;br /&gt;
        PowerMockito.mockStatic(ClaseConMetodosEstaticos.class);&lt;br /&gt;
&lt;br /&gt;
        //Con mockito determinamos el retorno del metodo estatico&lt;br /&gt;
        when(ClaseConMetodosEstaticos.firstStaticMethod(param)).thenReturn(value);&lt;br /&gt;
&lt;br /&gt;
        // ejecucion &lt;br /&gt;
        instance.invocarMetodoEstatico();&lt;br /&gt;
&lt;br /&gt;
        //Por cada metodo estatico que se quiere verificar se debe invocar &lt;br /&gt;
        //a PowerMockito.verifyStatic().&lt;br /&gt;
        PowerMockito.verifyStatic(); &lt;br /&gt;
        ClaseConMetodosEstaticos.secondStaticMethod();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Invocación a un método privado===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java&amp;gt;&lt;br /&gt;
public class PruebaMetodoPrivado {&lt;br /&gt;
&lt;br /&gt;
    public String decirHola(String nombre) {&lt;br /&gt;
        return decirHolaNombre(nombre);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    private String decirHolaNombre(String nombre) {&lt;br /&gt;
        return &amp;quot;Hola &amp;quot;+nombre;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java&amp;gt;&lt;br /&gt;
@RunWith(PowerMockRunner.class)&lt;br /&gt;
@PrepareForTest(PruebaMetodoPrivado.class)&lt;br /&gt;
public class PruebaMetodoPrivadoTest {&lt;br /&gt;
&lt;br /&gt;
   @Spy&lt;br /&gt;
   PruebaMetodoPrivado metodoPrivado = new PruebaMetodoPrivado();&lt;br /&gt;
    &lt;br /&gt;
    @Test&lt;br /&gt;
    public void mockMetodoPrivado() throws Exception {&lt;br /&gt;
&lt;br /&gt;
	Assert.assertEquals(&amp;quot;Hola Juan&amp;quot;, metodoPrivado.decirHola(&amp;quot;Juan&amp;quot;));&lt;br /&gt;
        doReturn(&amp;quot;Chau Juan&amp;quot;).when(metodoPrivado,&amp;quot;decirHolaNombre&amp;quot;,&amp;quot;Juan&amp;quot;);&lt;br /&gt;
        Assert.assertEquals(&amp;quot;Chau Juan&amp;quot;,metodoPrivado.decirHola(&amp;quot;Juan&amp;quot;));&lt;br /&gt;
        verifyPrivate(metodoPrivado,&lt;br /&gt;
                       Mockito.times(2)).invoke(&amp;quot;decirHolaNombre&amp;quot;,&amp;quot;Juan&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Inicialización de atributos estaticos===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java&amp;gt;&lt;br /&gt;
public class PruebaInicializacionEstaticos {&lt;br /&gt;
&lt;br /&gt;
    private static final String atributo = new String(&amp;quot;CHAU&amp;quot;);&lt;br /&gt;
 &lt;br /&gt;
    public String crearObjetoLista() {&lt;br /&gt;
        return atributo;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java&amp;gt;&lt;br /&gt;
@RunWith(PowerMockRunner.class)&lt;br /&gt;
@SuppressStaticInitializationFor(&amp;quot;PruebaInicializacionEstaticos&amp;quot;)&lt;br /&gt;
@PrepareForTest(PruebaInicializacionEstaticos.class)&lt;br /&gt;
public class PruebaMetodoPrivadoTest {&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
   PruebaInicializacionEstaticos pruebaInicializacionEstaticos = &lt;br /&gt;
                                    new PruebaInicializacionEstaticos();&lt;br /&gt;
 &lt;br /&gt;
    @Test&lt;br /&gt;
    public void controlCreacionLista() throws Exception {&lt;br /&gt;
	Assert.assertNull(pruebaInicializacionEstaticos.retornarAtrinbuto());&lt;br /&gt;
        String s = &amp;quot;Hola&amp;quot;;&lt;br /&gt;
        Whitebox.setInternalState(pruebaInicializacionEstaticos.class,&amp;quot;atributo&amp;quot;, s);&lt;br /&gt;
        Assert.assertEquals(s, pruebaInicializacionEstaticos.retornarAtrinbuto());&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Captura creación de objetos===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java&amp;gt;&lt;br /&gt;
public class PruebaCreacionObjeto {&lt;br /&gt;
 &lt;br /&gt;
    public List crearObjetoLista() {&lt;br /&gt;
        return new ArrayList();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java&amp;gt;&lt;br /&gt;
@RunWith(PowerMockRunner.class)&lt;br /&gt;
@PrepareForTest(PruebaCreacionObjeto.class)&lt;br /&gt;
public class PruebaMetodoPrivadoTest {&lt;br /&gt;
 &lt;br /&gt;
   @Spy&lt;br /&gt;
   PruebaCreacionObjeto pruebaCreacionObjeto = new PruebaCreacionObjeto();&lt;br /&gt;
 &lt;br /&gt;
    @Test&lt;br /&gt;
    public void controlCreacionLista() throws Exception {&lt;br /&gt;
        List list = new ArrayList();&lt;br /&gt;
        list.add(&amp;quot;Hola&amp;quot;);&lt;br /&gt;
        whenNew(ArrayList.class).withNoArguments().thenReturn((ArrayList) list);&lt;br /&gt;
        List resultado = pruebaCreacionObjeto.crearObjetoLista();&lt;br /&gt;
        Assert.assertEquals(list, resultado);&lt;br /&gt;
        verifyNew(ArrayList.class);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para mas ejemplos de Mockito junto a PowerMock ver los [http://code.google.com/p/powermock/wiki/MockitoUsage13 ejemplos] provisto por la documentación de PowerMock.&lt;br /&gt;
&lt;br /&gt;
[http://www.dosideas.com/descargas/category/3-testing.html?download=40 Descargar proyecto NetBeans demo de los ejemplos]&lt;br /&gt;
&lt;br /&gt;
===PowerMockito &amp;amp; Cobertura===&lt;br /&gt;
Existe un problema al utilizar PowerMockito con Cobertura (versión 1.8.4), este último no registra la corrida de los test con anotación @PrepareForTest, dando como resultados falta de cobertura.&lt;br /&gt;
Para solucionar este inconveniente solo hay que actualizar la versión de Cobertura.&lt;br /&gt;
&lt;br /&gt;
==Ejemplo de Mockito para mockear appender de log4j==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java&amp;gt;&lt;br /&gt;
//Inicializamos mock.&lt;br /&gt;
Appender mockAppender = mock(AppenderSkeleton.class);&lt;br /&gt;
//Inicializamos logger de la clase bajo test&lt;br /&gt;
Logger log = Logger.getLogger(ClaseATestear.class);&lt;br /&gt;
//Agregamos el mock del appender al logger.&lt;br /&gt;
log.addAppender(mockAppender);&lt;br /&gt;
//Seteamos el nivel de log que nos interesa recuperar.&lt;br /&gt;
log.setLevel(Level.DEBUG);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para poder obtener los log que se produjeron utilizamos la clase ArgumentCaptor de mockito que nos permite, entre otras cosas, capturar los eventos de log.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java&amp;gt;&lt;br /&gt;
ArgumentCaptor loggingEventCaptor = ArgumentCaptor.forClass(LoggingEvent.class);&lt;br /&gt;
&lt;br /&gt;
loggingEventCaptor.capture());&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Una posible forma de obtener un mensaje particular es iterando la lista de mensajes que nos da la clase capturada.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java&amp;gt;&lt;br /&gt;
List&amp;lt;LoggingEvent&amp;gt; loggingEvent = (List&amp;lt;LoggingEvent&amp;gt;) loggingEventCaptor.getAllValues();&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== BDDMockito ==&lt;br /&gt;
BDDMokcito es una clase alternativa que ofrece [[Mockito]] para crear pruebas al estilo [[Behavior Driven Development]] (BDD) (es decir, con bloques dado / cuando / entonces). &lt;br /&gt;
&lt;br /&gt;
El problema es que el API de Mockito usa la palabra &amp;quot;when&amp;quot; y no se integra bien con los comentarios //given //when //then (según BDD, el stubbing forma parte del área //given, y no del //when). &lt;br /&gt;
&lt;br /&gt;
BDDMockito agrega una clase que tiene alias para los métodos de stub, usando given(Object). &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java5&amp;gt;&lt;br /&gt;
 import static org.mockito.BDDMockito.*;&lt;br /&gt;
 &lt;br /&gt;
 Vendedor vendedor = mock(Vendedor.class);&lt;br /&gt;
 Negocio negocio = new Negocio(vendedor);&lt;br /&gt;
 &lt;br /&gt;
 @Test&lt;br /&gt;
 public void comprarPan() throws Exception {&lt;br /&gt;
   //given  &lt;br /&gt;
   given(vendedor.buscarPan()).willReturn(new Pan());&lt;br /&gt;
   &lt;br /&gt;
   //when&lt;br /&gt;
   Compra compra = negocio.comprarPan();&lt;br /&gt;
   &lt;br /&gt;
   //then&lt;br /&gt;
   assertThat(compra, contienePan());&lt;br /&gt;
 } &lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Stubbing con void y excepciones:&lt;br /&gt;
&amp;lt;code java5&amp;gt;&lt;br /&gt;
   //given&lt;br /&gt;
   willThrow(new RuntimeException(&amp;quot;boo&amp;quot;)).given(mock).foo();&lt;br /&gt;
   &lt;br /&gt;
   //when&lt;br /&gt;
   Result result = sistemaBajoPrueba.ejecutar();&lt;br /&gt;
   &lt;br /&gt;
   //then&lt;br /&gt;
   assertEquals(failure, result); &lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Ver también==&lt;br /&gt;
* [[EasyMock]]&lt;br /&gt;
* [[Captura De Parametros]]&lt;br /&gt;
* [[Inyeccion De Mocks De Mockito Con Spring]]&lt;br /&gt;
* [http://www.dosideas.com/descargas/category/3-testing.html?download=11%3Ademo-de-mockito Proyecto de ejemplos con Mockito]&lt;br /&gt;
* [http://www.dosideas.com/java/242-mockito-o-basta-de-easymock.html Introducción a Mockito]&lt;br /&gt;
* [http://mockito.googlecode.com/svn/branches/1.8.0/javadoc/org/mockito/BDDMockito.html Javadoc de BDDMockito]&lt;br /&gt;
&lt;br /&gt;
[[Category:TDD]]&lt;br /&gt;
[[Category:BDD]]&lt;br /&gt;
[[Category:JUnit]]&lt;/div&gt;</summary>
		<author><name>201.251.182.130</name></author>	</entry>

	<entry>
		<id>https://dosideas.com/wiki/index.php?title=Mockito&amp;diff=6207</id>
		<title>Mockito</title>
		<link rel="alternate" type="text/html" href="https://dosideas.com/wiki/index.php?title=Mockito&amp;diff=6207"/>
				<updated>2011-09-06T19:18:34Z</updated>
		
		<summary type="html">&lt;p&gt;201.251.182.130: Deshecha la edición 6179 de 209.0.141.71 (disc.)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Mockito es una librería [[Java]] para la creación de [[Mock Object]] muy usados para el testeo unitario en [[Test Driven Development]], basado en [[EasyMock]]. &lt;br /&gt;
&lt;br /&gt;
Mockito fue creado con el objetivo de simplificar y solucionar algunos de los temas antes mencionados. EasyMock y Mockito puede hacer exactamente las mismas cosas, pero Mockito tiene un API más natural y práctico de usar.&lt;br /&gt;
&lt;br /&gt;
==Características principales==&lt;br /&gt;
# Se pueden crear mocks de interfaces y clases concretas.&lt;br /&gt;
# Verificación de invocaciones (cantidad exacta, al menos una vez, órden de invocación, etc.)&lt;br /&gt;
# El stack trace se mantiene limpio, ya que los errores ocurren en los assert que se hagan (y no dentro del método bajo prueba, como en EasyMock).&lt;br /&gt;
# Un API más clara para crear stubs y verificaciones&lt;br /&gt;
&lt;br /&gt;
==Ejemplo de uso==&lt;br /&gt;
&amp;lt;code java&amp;gt;&lt;br /&gt;
import static org.mockito.Mockito.*;&lt;br /&gt;
.....&lt;br /&gt;
//creamos el mock y el stub&lt;br /&gt;
ArrayList instance = mock(ArrayList.class);&lt;br /&gt;
doReturn(&amp;quot;hola mundo&amp;quot;).when(instance).get(0);&lt;br /&gt;
 &lt;br /&gt;
//ejecutamos la lógica a probar&lt;br /&gt;
instance.get(0);     &lt;br /&gt;
 &lt;br /&gt;
//verificamos que se hayan invocado los métodos&lt;br /&gt;
verify(instance).get(0);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Más de una invocación a un mismo método==&lt;br /&gt;
&lt;br /&gt;
Algunas veces necesitamos que un método retorne un valor y que en la segunda invocación retorne nulo o una excepción. Para eso, anidamos los retornos:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code html4strict&amp;gt;&lt;br /&gt;
&lt;br /&gt;
//Retornos para las 2 invocaciones&lt;br /&gt;
doReturn(&amp;quot;algo&amp;quot;).doReturn(null).when(instance).scrollNext();&lt;br /&gt;
&lt;br /&gt;
//ejecutamos la lógica a probar&lt;br /&gt;
instance.unMetodoQueUsaScroll();     &lt;br /&gt;
&lt;br /&gt;
//verificamos que se haya invocado el mismo método dos veces&lt;br /&gt;
verify(instance, times(2)).scrollNext();&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [http://mockito.googlecode.com/svn/branches/1.5/javadoc/org/mockito/Mockito.html Leer más en Mockito API]&lt;br /&gt;
&lt;br /&gt;
It's spooky how celevr some ppl are. Thanks!&lt;br /&gt;
&lt;br /&gt;
==Ejemplo de Mockito para mockear appender de log4j==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java&amp;gt;&lt;br /&gt;
//Inicializamos mock.&lt;br /&gt;
Appender mockAppender = mock(AppenderSkeleton.class);&lt;br /&gt;
//Inicializamos logger de la clase bajo test&lt;br /&gt;
Logger log = Logger.getLogger(ClaseATestear.class);&lt;br /&gt;
//Agregamos el mock del appender al logger.&lt;br /&gt;
log.addAppender(mockAppender);&lt;br /&gt;
//Seteamos el nivel de log que nos interesa recuperar.&lt;br /&gt;
log.setLevel(Level.DEBUG);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para poder obtener los log que se produjeron utilizamos la clase ArgumentCaptor de mockito que nos permite, entre otras cosas, capturar los eventos de log.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java&amp;gt;&lt;br /&gt;
ArgumentCaptor loggingEventCaptor = ArgumentCaptor.forClass(LoggingEvent.class);&lt;br /&gt;
&lt;br /&gt;
loggingEventCaptor.capture());&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Una posible forma de obtener un mensaje particular es iterando la lista de mensajes que nos da la clase capturada.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java&amp;gt;&lt;br /&gt;
List&amp;lt;LoggingEvent&amp;gt; loggingEvent = (List&amp;lt;LoggingEvent&amp;gt;) loggingEventCaptor.getAllValues();&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== BDDMockito ==&lt;br /&gt;
BDDMokcito es una clase alternativa que ofrece [[Mockito]] para crear pruebas al estilo [[Behavior Driven Development]] (BDD) (es decir, con bloques dado / cuando / entonces). &lt;br /&gt;
&lt;br /&gt;
El problema es que el API de Mockito usa la palabra &amp;quot;when&amp;quot; y no se integra bien con los comentarios //given //when //then (según BDD, el stubbing forma parte del área //given, y no del //when). &lt;br /&gt;
&lt;br /&gt;
BDDMockito agrega una clase que tiene alias para los métodos de stub, usando given(Object). &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java5&amp;gt;&lt;br /&gt;
 import static org.mockito.BDDMockito.*;&lt;br /&gt;
 &lt;br /&gt;
 Vendedor vendedor = mock(Vendedor.class);&lt;br /&gt;
 Negocio negocio = new Negocio(vendedor);&lt;br /&gt;
 &lt;br /&gt;
 @Test&lt;br /&gt;
 public void comprarPan() throws Exception {&lt;br /&gt;
   //given  &lt;br /&gt;
   given(vendedor.buscarPan()).willReturn(new Pan());&lt;br /&gt;
   &lt;br /&gt;
   //when&lt;br /&gt;
   Compra compra = negocio.comprarPan();&lt;br /&gt;
   &lt;br /&gt;
   //then&lt;br /&gt;
   assertThat(compra, contienePan());&lt;br /&gt;
 } &lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Stubbing con void y excepciones:&lt;br /&gt;
&amp;lt;code java5&amp;gt;&lt;br /&gt;
   //given&lt;br /&gt;
   willThrow(new RuntimeException(&amp;quot;boo&amp;quot;)).given(mock).foo();&lt;br /&gt;
   &lt;br /&gt;
   //when&lt;br /&gt;
   Result result = sistemaBajoPrueba.ejecutar();&lt;br /&gt;
   &lt;br /&gt;
   //then&lt;br /&gt;
   assertEquals(failure, result); &lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Ver también==&lt;br /&gt;
* [[EasyMock]]&lt;br /&gt;
* [[Captura De Parametros]]&lt;br /&gt;
* [[Inyeccion De Mocks De Mockito Con Spring]]&lt;br /&gt;
* [http://www.dosideas.com/descargas/category/3-testing.html?download=11%3Ademo-de-mockito Proyecto de ejemplos con Mockito]&lt;br /&gt;
* [http://www.dosideas.com/java/242-mockito-o-basta-de-easymock.html Introducción a Mockito]&lt;br /&gt;
* [http://mockito.googlecode.com/svn/branches/1.8.0/javadoc/org/mockito/BDDMockito.html Javadoc de BDDMockito]&lt;br /&gt;
&lt;br /&gt;
[[Category:TDD]]&lt;br /&gt;
[[Category:BDD]]&lt;br /&gt;
[[Category:JUnit]]&lt;/div&gt;</summary>
		<author><name>201.251.182.130</name></author>	</entry>

	<entry>
		<id>https://dosideas.com/wiki/index.php?title=Google_Guava&amp;diff=6113</id>
		<title>Google Guava</title>
		<link rel="alternate" type="text/html" href="https://dosideas.com/wiki/index.php?title=Google_Guava&amp;diff=6113"/>
				<updated>2011-09-02T17:52:52Z</updated>
		
		<summary type="html">&lt;p&gt;201.251.182.130: /* Ver también */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[http://code.google.com/p/guava-libraries/  Google Guava] es un proyecto de Google que reúne un conjunto de librerías usadas internamente dentro de Google para sus proyectos que emplean Java. El propósito de la librería es simplificar el código empleado para realizar tareas que son comunes dentro de [[Java]] y que no están soportadas por las librerías estándar, de esta manera busca eliminar código propenso a errores.&lt;br /&gt;
&lt;br /&gt;
== Maven ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
&amp;lt;dependency&amp;gt;&lt;br /&gt;
   &amp;lt;groupId&amp;gt;com.google.guava&amp;lt;/groupId&amp;gt;&lt;br /&gt;
   &amp;lt;artifactId&amp;gt;guava&amp;lt;/artifactId&amp;gt;&lt;br /&gt;
   &amp;lt;version&amp;gt;r09&amp;lt;/version&amp;gt;&lt;br /&gt;
&amp;lt;/dependency&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Controlara última versión [http://mvnrepository.com/artifact/com.google.guava/guava aquí].&lt;br /&gt;
&lt;br /&gt;
== Ejemplos ==&lt;br /&gt;
&lt;br /&gt;
===CharMatcher===&lt;br /&gt;
&lt;br /&gt;
Determina verdadero o falso para cualquier carácter java, también ofrece  métodos básicos de tratamiento de texto.&lt;br /&gt;
&lt;br /&gt;
==== and / or ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java&amp;gt;&lt;br /&gt;
String input = &amp;quot;La fecha es : 01/01/2011&amp;quot;;&lt;br /&gt;
CharMatcher charMatcher = CharMatcher.DIGIT.or(CharMatcher.is('/'));&lt;br /&gt;
String output = charMatcher.retainFrom(input);&lt;br /&gt;
System.out.println(output);&lt;br /&gt;
&lt;br /&gt;
// Salida : 01/01/2011&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== negate ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java&amp;gt;&lt;br /&gt;
String input = &amp;quot;MAYUSCULA minuscula&amp;quot;;&lt;br /&gt;
CharMatcher charMatcher = CharMatcher.JAVA_LOWER_CASE.or(CharMatcher.WHITESPACE).negate();&lt;br /&gt;
String output = charMatcher.retainFrom(input);&lt;br /&gt;
System.out.println(output);&lt;br /&gt;
&lt;br /&gt;
// Salida: MAYUSCULA&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== inRange ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java&amp;gt;&lt;br /&gt;
String input = &amp;quot;Solo quedan los numeros 1, 2, 3, 4 que son menores a  5 &amp;quot;;&lt;br /&gt;
CharMatcher charMatcher = CharMatcher.inRange('0', '4').or(CharMatcher.WHITESPACE);&lt;br /&gt;
String output = charMatcher.retainFrom(input);&lt;br /&gt;
System.out.println(output);&lt;br /&gt;
&lt;br /&gt;
// Salida: 1 2 3 4&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Joiner ===&lt;br /&gt;
&lt;br /&gt;
Une fragmentos de texto mediante un separador. también ofrece métodos básicos de tratamiento de texto.&lt;br /&gt;
&lt;br /&gt;
==== join ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java&amp;gt;&lt;br /&gt;
String[] nombres = {&amp;quot;Josefina&amp;quot;, &amp;quot;Nacho&amp;quot;, &amp;quot;Lali&amp;quot;, &amp;quot;Coco&amp;quot;};&lt;br /&gt;
String output = Joiner.on(&amp;quot;, &amp;quot;).join(nombres);&lt;br /&gt;
System.out.println(output);&lt;br /&gt;
&lt;br /&gt;
// Salida: Josefina, Nacho, Lali, Coco&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== skipNulls ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java&amp;gt;&lt;br /&gt;
String[] nombres = {null, &amp;quot;Josefina&amp;quot;, null, &amp;quot;Nacho&amp;quot;, null, &amp;quot;Lali&amp;quot;, null, &amp;quot;Coco&amp;quot;};&lt;br /&gt;
String output = Joiner.on(&amp;quot;, &amp;quot;).skipNulls().join(nombres);&lt;br /&gt;
System.out.println(output);&lt;br /&gt;
&lt;br /&gt;
// Salida: Josefina, Nacho, Lali, Coco&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== useForNull ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java&amp;gt;&lt;br /&gt;
String[] nombres = {null, &amp;quot;Josefina&amp;quot;, null, &amp;quot;Nacho&amp;quot;, null, &amp;quot;Lali&amp;quot;, null, &amp;quot;Coco&amp;quot;};&lt;br /&gt;
String output = Joiner.on(&amp;quot;, &amp;quot;).useForNull(&amp;quot;n/a&amp;quot;).join(nombres);&lt;br /&gt;
System.out.println(output);&lt;br /&gt;
&lt;br /&gt;
// Salida: n/a, Josefina, n/a, Nacho, n/a, Lali, n/a, Coco&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== withKeyValueSeparator ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java&amp;gt;&lt;br /&gt;
Map&amp;lt;Integer, String&amp;gt; map = newHashMap();&lt;br /&gt;
map.put(1, &amp;quot;Josefina&amp;quot;);&lt;br /&gt;
map.put(2, &amp;quot;Nacho&amp;quot;);&lt;br /&gt;
map.put(3, &amp;quot;Lali&amp;quot;);&lt;br /&gt;
String output = Joiner.on(&amp;quot;, &amp;quot;).withKeyValueSeparator(&amp;quot; -&amp;gt; &amp;quot;).join(map);&lt;br /&gt;
System.out.println(output);&lt;br /&gt;
&lt;br /&gt;
// Salida: 1 -&amp;gt; Josefina, 2 -&amp;gt; Nacho, 3 -&amp;gt; Lali&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Splitter ===&lt;br /&gt;
&lt;br /&gt;
Divide cadenas de texto en subcadenas mediante el reconocimiento de un separador (también conocido como delimitador), este se puede definir mediante un carácter, una cadena literal, una expresión regular, un CharMatcher, o mediante el uso de una longitud fija.&lt;br /&gt;
&lt;br /&gt;
==== split ====&lt;br /&gt;
&lt;br /&gt;
Split retorna una instancia de Iterable en lugar de un Array.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java&amp;gt;&lt;br /&gt;
String input = &amp;quot;Josefina|Nacho|Lali&amp;quot;;&lt;br /&gt;
Iterable&amp;lt;String&amp;gt; split = Splitter.on(&amp;quot;|&amp;quot;).split(input);&lt;br /&gt;
List&amp;lt;String&amp;gt; output = newArrayList(split);&lt;br /&gt;
System.out.println(output);&lt;br /&gt;
&lt;br /&gt;
// Salida: [Josefina, Nacho, Lali]&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== fixedLength ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java&amp;gt;&lt;br /&gt;
String input =&amp;quot;Josefina  Nacho     Lali      &amp;quot;;&lt;br /&gt;
Iterable&amp;lt;String&amp;gt; splitted = Splitter.fixedLength(10).trimResults().split(input);&lt;br /&gt;
List&amp;lt;String&amp;gt; output = newArrayList(splitted);&lt;br /&gt;
System.out.println(output);&lt;br /&gt;
&lt;br /&gt;
//Salida: [Josefina, Nacho, Lali]&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== onPattern ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java&amp;gt;&lt;br /&gt;
String input =&amp;quot;Josefina Nacho Lali&amp;quot;;&lt;br /&gt;
Iterable&amp;lt;String&amp;gt; splitted = &lt;br /&gt;
            Splitter.onPattern(&amp;quot;[a-z&amp;amp;&amp;amp;[aeiou]]&amp;quot;).omitEmptyStrings().split(input);&lt;br /&gt;
List&amp;lt;String&amp;gt; output = newArrayList(splitted);&lt;br /&gt;
System.out.println(output);&lt;br /&gt;
&lt;br /&gt;
// Salida: [J, s, f, n,  N, ch,  L, l]&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Collection2 ===&lt;br /&gt;
&lt;br /&gt;
Proporciona métodos estáticos para trabajar con colecciones.&lt;br /&gt;
&lt;br /&gt;
==== filter ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java&amp;gt;&lt;br /&gt;
List&amp;lt;String&amp;gt; input = newArrayList(&amp;quot;Josefina&amp;quot;,&amp;quot;Nacho&amp;quot;,&amp;quot;Lali&amp;quot;);&lt;br /&gt;
Collection&amp;lt;String&amp;gt; output = &lt;br /&gt;
     Collections2.filter(input, new Predicate&amp;lt;String&amp;gt;() {&lt;br /&gt;
&lt;br /&gt;
                public boolean apply(String t) {&lt;br /&gt;
                    if (t.contains(&amp;quot;i&amp;quot;)) {&lt;br /&gt;
                        return true;&lt;br /&gt;
                    }&lt;br /&gt;
                    return false;&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
            &lt;br /&gt;
System.out.println(output);&lt;br /&gt;
&lt;br /&gt;
// Salida: [Josefina, Lali]&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== transform ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java&amp;gt;&lt;br /&gt;
List&amp;lt;String&amp;gt; input = newArrayList(&amp;quot;Josefina&amp;quot;, &amp;quot;Nacho&amp;quot;, &amp;quot;Lali&amp;quot;);&lt;br /&gt;
Collection&amp;lt;String&amp;gt; output = &lt;br /&gt;
     Collections2.transform(input, new Function&amp;lt;String, String&amp;gt;() {&lt;br /&gt;
&lt;br /&gt;
            public String apply(String f) {&lt;br /&gt;
                return f.replaceAll(&amp;quot;fina&amp;quot;,&amp;quot;&amp;quot;);&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
System.out.println(output);&lt;br /&gt;
&lt;br /&gt;
// Salida: [Jose, Nacho, Lali]&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Constraints ===&lt;br /&gt;
&lt;br /&gt;
Restringe la carga de las colecciones medinate limitaciones.&lt;br /&gt;
&lt;br /&gt;
==== constrainedCollection ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java&amp;gt;&lt;br /&gt;
Constraint&amp;lt;String&amp;gt; debeContenerJoL = new Constraint&amp;lt;String&amp;gt;() {&lt;br /&gt;
&lt;br /&gt;
     @Override&lt;br /&gt;
     public String checkElement(String s) {&lt;br /&gt;
       checkNotNull(s);&lt;br /&gt;
       if (!s.contentEquals(&amp;quot;JL&amp;quot;)) {&lt;br /&gt;
         throw new IllegalArgumentException(&amp;quot;No contiene J ni L&amp;quot;);&lt;br /&gt;
       }&lt;br /&gt;
       return s;&lt;br /&gt;
     }&lt;br /&gt;
};&lt;br /&gt;
        &lt;br /&gt;
Collection&amp;lt;String&amp;gt; input = newArrayList(&amp;quot;Josefina&amp;quot;);&lt;br /&gt;
Collection&amp;lt;String&amp;gt; output = constrainedCollection(input, debeContenerJoL);&lt;br /&gt;
output.add(&amp;quot;Nacho&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
// Salida:&lt;br /&gt;
Exception in thread &amp;quot;main&amp;quot; java.lang.IllegalArgumentException: No contiene J ni L&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java&amp;gt;&lt;br /&gt;
Collection&amp;lt;String&amp;gt; input = newArrayList(&amp;quot;Josefina&amp;quot;);&lt;br /&gt;
Collection&amp;lt;String&amp;gt; output = constrainedCollection(input, notNull());&lt;br /&gt;
output.add(null);&lt;br /&gt;
&lt;br /&gt;
// Salida:&lt;br /&gt;
Exception in thread &amp;quot;main&amp;quot; java.lang.NullPointerException&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Ordering ===&lt;br /&gt;
&lt;br /&gt;
Comparador con métodos para soportar funciones comunes.&lt;br /&gt;
&lt;br /&gt;
==== sortedCopy ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java&amp;gt;&lt;br /&gt;
List&amp;lt;String&amp;gt; input = newArrayList(&amp;quot;Josefina&amp;quot;,&amp;quot;Nacho&amp;quot;,&amp;quot;Lali&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
Ordering&amp;lt;String&amp;gt; ordering = Ordering.from(new Comparator&amp;lt; String&amp;gt;() {&lt;br /&gt;
&lt;br /&gt;
        @Override&lt;br /&gt;
        public int compare(String string1, String string2) {&lt;br /&gt;
             return Ints.compare(string1.length(), string2.length());&lt;br /&gt;
                &lt;br /&gt;
        }&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
List&amp;lt;String&amp;gt; output = ordering.sortedCopy(input);&lt;br /&gt;
System.out.println(output);&lt;br /&gt;
&lt;br /&gt;
// Salida: [Lali, Nacho, Josefina]&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Multimap ===&lt;br /&gt;
&lt;br /&gt;
Basicamente es un map en el que se pueden asignar muchos valores a una sola clave.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java&amp;gt;&lt;br /&gt;
Multimap&amp;lt;Integer, String&amp;gt; output = HashMultimap.create();&lt;br /&gt;
        output.put(1, &amp;quot;Josefina&amp;quot;);&lt;br /&gt;
        output.put(2, &amp;quot;nacho&amp;quot;);&lt;br /&gt;
        output.put(3, &amp;quot;Lali&amp;quot;);&lt;br /&gt;
        output.put(1, &amp;quot;Josefina_2&amp;quot;); &lt;br /&gt;
System.out.println(output);&lt;br /&gt;
&lt;br /&gt;
// Salida: {1=[Josefina, Josefina_2], 2=[Bacho], 3=[lali]}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== ImmutableSetMultimap ====&lt;br /&gt;
&lt;br /&gt;
===== inline =====&lt;br /&gt;
&amp;lt;code java&amp;gt;&lt;br /&gt;
Multimap&amp;lt;Integer, String&amp;gt; output = &lt;br /&gt;
ImmutableSetMultimap.of(1, &amp;quot;Josefina&amp;quot;, 2, &amp;quot;Nacho&amp;quot;, 3, &amp;quot;Lali&amp;quot;, 1, &amp;quot;Josefina_2&amp;quot;); &lt;br /&gt;
System.out.println(output);&lt;br /&gt;
&lt;br /&gt;
// Salida: {1=[Josefina, Josefina_2], 2=[Nacho], 3=[Lali]}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== builder =====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java&amp;gt;&lt;br /&gt;
Multimap&amp;lt;Integer, String&amp;gt; output = &lt;br /&gt;
                new ImmutableSetMultimap.Builder&amp;lt;Integer, String&amp;gt;()&lt;br /&gt;
                    .put(1, &amp;quot;Josefina&amp;quot;)&lt;br /&gt;
                    .put(2, &amp;quot;Nacho&amp;quot;)&lt;br /&gt;
                    .put(3, &amp;quot;Lali&amp;quot;)&lt;br /&gt;
                    .put(1, &amp;quot;Josefina_2&amp;quot;)&lt;br /&gt;
                    .build();&lt;br /&gt;
System.out.println(output);&lt;br /&gt;
&lt;br /&gt;
// Salida: {1=[Josefina, Josefina_2], 2=[Bacho], 3=[Lali]}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Tables ===&lt;br /&gt;
&lt;br /&gt;
Es una colección con columnas filas y valores. Permite el traspaso de una tabla a otra.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java&amp;gt;&lt;br /&gt;
Table&amp;lt;Integer, String, String&amp;gt; table = HashBasedTable.create();&lt;br /&gt;
table.put(1, &amp;quot;Hija&amp;quot;, &amp;quot;Josefina&amp;quot;);&lt;br /&gt;
table.put(1, &amp;quot;Sobrino&amp;quot;, &amp;quot;Nacho&amp;quot;);&lt;br /&gt;
table.put(1, &amp;quot;Pareja&amp;quot;, &amp;quot;Lali&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
Table output = Tables.transpose(table);&lt;br /&gt;
&lt;br /&gt;
System.out.println(output);&lt;br /&gt;
        &lt;br /&gt;
// Salida: {Sobrino={1=Nacho}, Hija={1=Josefina}, Pareja={1=Lali}}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== BiMap ===&lt;br /&gt;
&lt;br /&gt;
Es un Map que solo permite valores únicos.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java&amp;gt;&lt;br /&gt;
BiMap&amp;lt;Integer, String&amp;gt; output = HashBiMap.create();&lt;br /&gt;
output.put(1, &amp;quot;Josefina&amp;quot;);&lt;br /&gt;
output.put(2, &amp;quot;Lali&amp;quot;);&lt;br /&gt;
output.put(3, &amp;quot;Josefina&amp;quot;); //IllegalArgumentException&lt;br /&gt;
&lt;br /&gt;
// Salida:&lt;br /&gt;
Exception in thread &amp;quot;main&amp;quot; java.lang.IllegalArgumentException: value already present: Josefina&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Throwables ===&lt;br /&gt;
&lt;br /&gt;
Clase utilitaria que contiene métodos estáticos para el manejo de excepciones. &lt;br /&gt;
&lt;br /&gt;
==== propagate ====&lt;br /&gt;
&lt;br /&gt;
En el caso de que la excepción sea del tipo RuntimeException la lanza, de lo contrario crea una RuntimeException con la excepción recibida y la lanza.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java&amp;gt;&lt;br /&gt;
    try {&lt;br /&gt;
      throw new Exception(&amp;quot;Error !!!&amp;quot;);&lt;br /&gt;
    } catch (Throwable t) {&lt;br /&gt;
      throw Throwables.propagate(t);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
// Salida: &lt;br /&gt;
Exception in thread &amp;quot;main&amp;quot; java.lang.RuntimeException: java.lang.Exception: Error !!!&lt;br /&gt;
	at com.google.common.base.Throwables.propagate(Throwables.java:155)&lt;br /&gt;
	at com.dosideas.guavalibrarydemo.Ejemplo.main(Ejemplo.java:92)&lt;br /&gt;
Caused by: java.lang.Exception: Error !!!&lt;br /&gt;
	at com.dosideas.guavalibrarydemo.Ejemplo.main(Ejemplo.java:90)&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Files ===&lt;br /&gt;
&lt;br /&gt;
Clase con métodos útiles para el manejo de archovs.&lt;br /&gt;
&lt;br /&gt;
==== readLines ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java&amp;gt;&lt;br /&gt;
ClassLoader cla = App.class.getClassLoader();&lt;br /&gt;
File file = new File(cla.getResource(&amp;quot;prueba.txt&amp;quot;).getFile());&lt;br /&gt;
List&amp;lt;String&amp;gt; lines = Files.readLines(file, Charsets.UTF_8);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Ver también==&lt;br /&gt;
* [http://code.google.com/p/dosideas-aplicaciones-modelo/source/browse/#svn Descargar con svn de nuestro proyecto en google-code la aplicación demo de Google Guava]&lt;br /&gt;
* [http://www.javacodegeeks.com/2011/09/google-guava-libraries-essentials.html Google Guava Libraries Essentials]&lt;br /&gt;
* [http://guava-libraries.googlecode.com/svn/tags/release09/javadoc/index.html Google Guava API]&lt;br /&gt;
&lt;br /&gt;
[[Category:Java]]&lt;/div&gt;</summary>
		<author><name>201.251.182.130</name></author>	</entry>

	<entry>
		<id>https://dosideas.com/wiki/index.php?title=Mockito&amp;diff=6094</id>
		<title>Mockito</title>
		<link rel="alternate" type="text/html" href="https://dosideas.com/wiki/index.php?title=Mockito&amp;diff=6094"/>
				<updated>2011-08-23T13:34:14Z</updated>
		
		<summary type="html">&lt;p&gt;201.251.182.130: /* Ejemplo de Mockito para mockear appender de log4j */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Mockito es una librería [[Java]] para la creación de [[Mock Object]] muy usados para el testeo unitario en [[Test Driven Development]], basado en [[EasyMock]]. &lt;br /&gt;
&lt;br /&gt;
Mockito fue creado con el objetivo de simplificar y solucionar algunos de los temas antes mencionados. EasyMock y Mockito puede hacer exactamente las mismas cosas, pero Mockito tiene un API más natural y práctico de usar.&lt;br /&gt;
&lt;br /&gt;
==Características principales==&lt;br /&gt;
# Se pueden crear mocks de interfaces y clases concretas.&lt;br /&gt;
# Verificación de invocaciones (cantidad exacta, al menos una vez, órden de invocación, etc.)&lt;br /&gt;
# El stack trace se mantiene limpio, ya que los errores ocurren en los assert que se hagan (y no dentro del método bajo prueba, como en EasyMock).&lt;br /&gt;
# Un API más clara para crear stubs y verificaciones&lt;br /&gt;
&lt;br /&gt;
==Ejemplo de uso==&lt;br /&gt;
&amp;lt;code java&amp;gt;&lt;br /&gt;
import static org.mockito.Mockito.*;&lt;br /&gt;
.....&lt;br /&gt;
//creamos el mock y el stub&lt;br /&gt;
ArrayList instance = mock(ArrayList.class);&lt;br /&gt;
doReturn(&amp;quot;hola mundo&amp;quot;).when(instance).get(0);&lt;br /&gt;
 &lt;br /&gt;
//ejecutamos la lógica a probar&lt;br /&gt;
instance.get(0);     &lt;br /&gt;
 &lt;br /&gt;
//verificamos que se hayan invocado los métodos&lt;br /&gt;
verify(instance).get(0);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Más de una invocación a un mismo método==&lt;br /&gt;
&lt;br /&gt;
Algunas veces necesitamos que un método retorne un valor y que en la segunda invocación retorne nulo o una excepción. Para eso, anidamos los retornos:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code html4strict&amp;gt;&lt;br /&gt;
&lt;br /&gt;
//Retornos para las 2 invocaciones&lt;br /&gt;
doReturn(&amp;quot;algo&amp;quot;).doReturn(null).when(instance).scrollNext();&lt;br /&gt;
&lt;br /&gt;
//ejecutamos la lógica a probar&lt;br /&gt;
instance.unMetodoQueUsaScroll();     &lt;br /&gt;
&lt;br /&gt;
//verificamos que se haya invocado el mismo método dos veces&lt;br /&gt;
verify(instance, times(2)).scrollNext();&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [http://mockito.googlecode.com/svn/branches/1.5/javadoc/org/mockito/Mockito.html Leer más en Mockito API]&lt;br /&gt;
&lt;br /&gt;
==Ejemplos de Mockito junto a PowerMock==&lt;br /&gt;
&lt;br /&gt;
===Invocación a un método estático===&lt;br /&gt;
&lt;br /&gt;
Para mockear métodos estáticos, según el [http://code.google.com/p/mockito/wiki/FAQ FAQ] de mockito, esto no es posible. Pero nombra 2 framewors que pueden resultarnos útil [http://jmockit.dev.java.net/ JMockit] y [http://code.google.com/p/powermock PowerMock]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java&amp;gt;&lt;br /&gt;
@RunWith(PowerMockRunner.class)&lt;br /&gt;
@PrepareForTest(ClaseConMetodosEstaticos.class)&lt;br /&gt;
public class DosIdeasTestCase {&lt;br /&gt;
    @Test&lt;br /&gt;
    public void testMetodo_conInvocacionAMetodosEstaticos() {&lt;br /&gt;
	&lt;br /&gt;
        //PowerMockito mockea los metodos estaticos que se encuentren en la &lt;br /&gt;
        //clase ClaseConMetodosEstaticos&lt;br /&gt;
        PowerMockito.mockStatic(ClaseConMetodosEstaticos.class);&lt;br /&gt;
&lt;br /&gt;
        //Con mockito determinamos el retorno del metodo estatico&lt;br /&gt;
        when(ClaseConMetodosEstaticos.firstStaticMethod(param)).thenReturn(value);&lt;br /&gt;
&lt;br /&gt;
        // ejecucion &lt;br /&gt;
        instance.invocarMetodoEstatico();&lt;br /&gt;
&lt;br /&gt;
        //Por cada metodo estatico que se quiere verificar se debe invocar &lt;br /&gt;
        //a PowerMockito.verifyStatic().&lt;br /&gt;
        PowerMockito.verifyStatic(); &lt;br /&gt;
        ClaseConMetodosEstaticos.secondStaticMethod();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Invocación a un método privado===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java&amp;gt;&lt;br /&gt;
public class PruebaMetodoPrivado {&lt;br /&gt;
&lt;br /&gt;
    public String decirHola(String nombre) {&lt;br /&gt;
        return decirHolaNombre(nombre);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    private String decirHolaNombre(String nombre) {&lt;br /&gt;
        return &amp;quot;Hola &amp;quot;+nombre;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java&amp;gt;&lt;br /&gt;
@RunWith(PowerMockRunner.class)&lt;br /&gt;
@PrepareForTest(PruebaMetodoPrivado.class)&lt;br /&gt;
public class PruebaMetodoPrivadoTest {&lt;br /&gt;
&lt;br /&gt;
   @Spy&lt;br /&gt;
   PruebaMetodoPrivado metodoPrivado = new PruebaMetodoPrivado();&lt;br /&gt;
    &lt;br /&gt;
    @Test&lt;br /&gt;
    public void mockMetodoPrivado() throws Exception {&lt;br /&gt;
&lt;br /&gt;
	Assert.assertEquals(&amp;quot;Hola Juan&amp;quot;, metodoPrivado.decirHola(&amp;quot;Juan&amp;quot;));&lt;br /&gt;
        doReturn(&amp;quot;Chau Juan&amp;quot;).when(metodoPrivado,&amp;quot;decirHolaNombre&amp;quot;,&amp;quot;Juan&amp;quot;);&lt;br /&gt;
        Assert.assertEquals(&amp;quot;Chau Juan&amp;quot;,metodoPrivado.decirHola(&amp;quot;Juan&amp;quot;));&lt;br /&gt;
        verifyPrivate(metodoPrivado,&lt;br /&gt;
                       Mockito.times(2)).invoke(&amp;quot;decirHolaNombre&amp;quot;,&amp;quot;Juan&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Inicialización de atributos estaticos===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java&amp;gt;&lt;br /&gt;
public class PruebaInicializacionEstaticos {&lt;br /&gt;
&lt;br /&gt;
    private static final String atributo = new String(&amp;quot;CHAU&amp;quot;);&lt;br /&gt;
 &lt;br /&gt;
    public String crearObjetoLista() {&lt;br /&gt;
        return atributo;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java&amp;gt;&lt;br /&gt;
@RunWith(PowerMockRunner.class)&lt;br /&gt;
@SuppressStaticInitializationFor(&amp;quot;PruebaInicializacionEstaticos&amp;quot;)&lt;br /&gt;
@PrepareForTest(PruebaInicializacionEstaticos.class)&lt;br /&gt;
public class PruebaMetodoPrivadoTest {&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
   PruebaInicializacionEstaticos pruebaInicializacionEstaticos = &lt;br /&gt;
                                    new PruebaInicializacionEstaticos();&lt;br /&gt;
 &lt;br /&gt;
    @Test&lt;br /&gt;
    public void controlCreacionLista() throws Exception {&lt;br /&gt;
	Assert.assertNull(pruebaInicializacionEstaticos.retornarAtrinbuto());&lt;br /&gt;
        String s = &amp;quot;Hola&amp;quot;;&lt;br /&gt;
        Whitebox.setInternalState(pruebaInicializacionEstaticos.class,&amp;quot;atributo&amp;quot;, s);&lt;br /&gt;
        Assert.assertEquals(s, pruebaInicializacionEstaticos.retornarAtrinbuto());&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Captura creación de objetos===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java&amp;gt;&lt;br /&gt;
public class PruebaCreacionObjeto {&lt;br /&gt;
 &lt;br /&gt;
    public List crearObjetoLista() {&lt;br /&gt;
        return new ArrayList();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java&amp;gt;&lt;br /&gt;
@RunWith(PowerMockRunner.class)&lt;br /&gt;
@PrepareForTest(PruebaCreacionObjeto.class)&lt;br /&gt;
public class PruebaMetodoPrivadoTest {&lt;br /&gt;
 &lt;br /&gt;
   @Spy&lt;br /&gt;
   PruebaCreacionObjeto pruebaCreacionObjeto = new PruebaCreacionObjeto();&lt;br /&gt;
 &lt;br /&gt;
    @Test&lt;br /&gt;
    public void controlCreacionLista() throws Exception {&lt;br /&gt;
        List list = new ArrayList();&lt;br /&gt;
        list.add(&amp;quot;Hola&amp;quot;);&lt;br /&gt;
        whenNew(ArrayList.class).withNoArguments().thenReturn((ArrayList) list);&lt;br /&gt;
        List resultado = pruebaCreacionObjeto.crearObjetoLista();&lt;br /&gt;
        Assert.assertEquals(list, resultado);&lt;br /&gt;
        verifyNew(ArrayList.class);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para mas ejemplos de Mockito junto a PowerMock ver los [http://code.google.com/p/powermock/wiki/MockitoUsage13 ejemplos] provisto por la documentación de PowerMock.&lt;br /&gt;
&lt;br /&gt;
[http://www.dosideas.com/descargas/category/3-testing.html?download=40 Descargar proyecto NetBeans demo de los ejemplos]&lt;br /&gt;
&lt;br /&gt;
===PowerMockito &amp;amp; Cobertura===&lt;br /&gt;
Existe un problema al utilizar PowerMockito con Cobertura (versión 1.8.4), este último no registra la corrida de los test con anotación @PrepareForTest, dando como resultados falta de cobertura.&lt;br /&gt;
Para solucionar este inconveniente solo hay que actualizar la versión de Cobertura.&lt;br /&gt;
&lt;br /&gt;
==Ejemplo de Mockito para mockear appender de log4j==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java&amp;gt;&lt;br /&gt;
//Inicializamos mock.&lt;br /&gt;
Appender mockAppender = mock(AppenderSkeleton.class);&lt;br /&gt;
//Inicializamos logger de la clase bajo test&lt;br /&gt;
Logger log = Logger.getLogger(ClaseATestear.class);&lt;br /&gt;
//Agregamos el mock del appender al logger.&lt;br /&gt;
log.addAppender(mockAppender);&lt;br /&gt;
//Seteamos el nivel de log que nos interesa recuperar.&lt;br /&gt;
log.setLevel(Level.DEBUG);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para poder obtener los log que se produjeron utilizamos la clase ArgumentCaptor de mockito que nos permite, entre otras cosas, capturar los eventos de log.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java&amp;gt;&lt;br /&gt;
ArgumentCaptor loggingEventCaptor = ArgumentCaptor.forClass(LoggingEvent.class);&lt;br /&gt;
&lt;br /&gt;
loggingEventCaptor.capture());&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Una posible forma de obtener un mensaje particular es iterando la lista de mensajes que nos da la clase capturada.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java&amp;gt;&lt;br /&gt;
List&amp;lt;LoggingEvent&amp;gt; loggingEvent = (List&amp;lt;LoggingEvent&amp;gt;) loggingEventCaptor.getAllValues();&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== BDDMockito ==&lt;br /&gt;
BDDMokcito es una clase alternativa que ofrece [[Mockito]] para crear pruebas al estilo [[Behavior Driven Development]] (BDD) (es decir, con bloques dado / cuando / entonces). &lt;br /&gt;
&lt;br /&gt;
El problema es que el API de Mockito usa la palabra &amp;quot;when&amp;quot; y no se integra bien con los comentarios //given //when //then (según BDD, el stubbing forma parte del área //given, y no del //when). &lt;br /&gt;
&lt;br /&gt;
BDDMockito agrega una clase que tiene alias para los métodos de stub, usando given(Object). &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java5&amp;gt;&lt;br /&gt;
 import static org.mockito.BDDMockito.*;&lt;br /&gt;
 &lt;br /&gt;
 Vendedor vendedor = mock(Vendedor.class);&lt;br /&gt;
 Negocio negocio = new Negocio(vendedor);&lt;br /&gt;
 &lt;br /&gt;
 @Test&lt;br /&gt;
 public void comprarPan() throws Exception {&lt;br /&gt;
   //given  &lt;br /&gt;
   given(vendedor.buscarPan()).willReturn(new Pan());&lt;br /&gt;
   &lt;br /&gt;
   //when&lt;br /&gt;
   Compra compra = negocio.comprarPan();&lt;br /&gt;
   &lt;br /&gt;
   //then&lt;br /&gt;
   assertThat(compra, contienePan());&lt;br /&gt;
 } &lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Stubbing con void y excepciones:&lt;br /&gt;
&amp;lt;code java5&amp;gt;&lt;br /&gt;
   //given&lt;br /&gt;
   willThrow(new RuntimeException(&amp;quot;boo&amp;quot;)).given(mock).foo();&lt;br /&gt;
   &lt;br /&gt;
   //when&lt;br /&gt;
   Result result = sistemaBajoPrueba.ejecutar();&lt;br /&gt;
   &lt;br /&gt;
   //then&lt;br /&gt;
   assertEquals(failure, result); &lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Ver también==&lt;br /&gt;
* [[EasyMock]]&lt;br /&gt;
* [[Captura De Parametros]]&lt;br /&gt;
* [[Inyeccion De Mocks De Mockito Con Spring]]&lt;br /&gt;
* [http://www.dosideas.com/descargas/category/3-testing.html?download=11%3Ademo-de-mockito Proyecto de ejemplos con Mockito]&lt;br /&gt;
* [http://www.dosideas.com/java/242-mockito-o-basta-de-easymock.html Introducción a Mockito]&lt;br /&gt;
* [http://mockito.googlecode.com/svn/branches/1.8.0/javadoc/org/mockito/BDDMockito.html Javadoc de BDDMockito]&lt;br /&gt;
&lt;br /&gt;
[[Category:TDD]]&lt;br /&gt;
[[Category:BDD]]&lt;br /&gt;
[[Category:JUnit]]&lt;/div&gt;</summary>
		<author><name>201.251.182.130</name></author>	</entry>

	<entry>
		<id>https://dosideas.com/wiki/index.php?title=Mockito&amp;diff=6093</id>
		<title>Mockito</title>
		<link rel="alternate" type="text/html" href="https://dosideas.com/wiki/index.php?title=Mockito&amp;diff=6093"/>
				<updated>2011-08-23T13:19:42Z</updated>
		
		<summary type="html">&lt;p&gt;201.251.182.130: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Mockito es una librería [[Java]] para la creación de [[Mock Object]] muy usados para el testeo unitario en [[Test Driven Development]], basado en [[EasyMock]]. &lt;br /&gt;
&lt;br /&gt;
Mockito fue creado con el objetivo de simplificar y solucionar algunos de los temas antes mencionados. EasyMock y Mockito puede hacer exactamente las mismas cosas, pero Mockito tiene un API más natural y práctico de usar.&lt;br /&gt;
&lt;br /&gt;
==Características principales==&lt;br /&gt;
# Se pueden crear mocks de interfaces y clases concretas.&lt;br /&gt;
# Verificación de invocaciones (cantidad exacta, al menos una vez, órden de invocación, etc.)&lt;br /&gt;
# El stack trace se mantiene limpio, ya que los errores ocurren en los assert que se hagan (y no dentro del método bajo prueba, como en EasyMock).&lt;br /&gt;
# Un API más clara para crear stubs y verificaciones&lt;br /&gt;
&lt;br /&gt;
==Ejemplo de uso==&lt;br /&gt;
&amp;lt;code java&amp;gt;&lt;br /&gt;
import static org.mockito.Mockito.*;&lt;br /&gt;
.....&lt;br /&gt;
//creamos el mock y el stub&lt;br /&gt;
ArrayList instance = mock(ArrayList.class);&lt;br /&gt;
doReturn(&amp;quot;hola mundo&amp;quot;).when(instance).get(0);&lt;br /&gt;
 &lt;br /&gt;
//ejecutamos la lógica a probar&lt;br /&gt;
instance.get(0);     &lt;br /&gt;
 &lt;br /&gt;
//verificamos que se hayan invocado los métodos&lt;br /&gt;
verify(instance).get(0);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Más de una invocación a un mismo método==&lt;br /&gt;
&lt;br /&gt;
Algunas veces necesitamos que un método retorne un valor y que en la segunda invocación retorne nulo o una excepción. Para eso, anidamos los retornos:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code html4strict&amp;gt;&lt;br /&gt;
&lt;br /&gt;
//Retornos para las 2 invocaciones&lt;br /&gt;
doReturn(&amp;quot;algo&amp;quot;).doReturn(null).when(instance).scrollNext();&lt;br /&gt;
&lt;br /&gt;
//ejecutamos la lógica a probar&lt;br /&gt;
instance.unMetodoQueUsaScroll();     &lt;br /&gt;
&lt;br /&gt;
//verificamos que se haya invocado el mismo método dos veces&lt;br /&gt;
verify(instance, times(2)).scrollNext();&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [http://mockito.googlecode.com/svn/branches/1.5/javadoc/org/mockito/Mockito.html Leer más en Mockito API]&lt;br /&gt;
&lt;br /&gt;
==Ejemplos de Mockito junto a PowerMock==&lt;br /&gt;
&lt;br /&gt;
===Invocación a un método estático===&lt;br /&gt;
&lt;br /&gt;
Para mockear métodos estáticos, según el [http://code.google.com/p/mockito/wiki/FAQ FAQ] de mockito, esto no es posible. Pero nombra 2 framewors que pueden resultarnos útil [http://jmockit.dev.java.net/ JMockit] y [http://code.google.com/p/powermock PowerMock]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java&amp;gt;&lt;br /&gt;
@RunWith(PowerMockRunner.class)&lt;br /&gt;
@PrepareForTest(ClaseConMetodosEstaticos.class)&lt;br /&gt;
public class DosIdeasTestCase {&lt;br /&gt;
    @Test&lt;br /&gt;
    public void testMetodo_conInvocacionAMetodosEstaticos() {&lt;br /&gt;
	&lt;br /&gt;
        //PowerMockito mockea los metodos estaticos que se encuentren en la &lt;br /&gt;
        //clase ClaseConMetodosEstaticos&lt;br /&gt;
        PowerMockito.mockStatic(ClaseConMetodosEstaticos.class);&lt;br /&gt;
&lt;br /&gt;
        //Con mockito determinamos el retorno del metodo estatico&lt;br /&gt;
        when(ClaseConMetodosEstaticos.firstStaticMethod(param)).thenReturn(value);&lt;br /&gt;
&lt;br /&gt;
        // ejecucion &lt;br /&gt;
        instance.invocarMetodoEstatico();&lt;br /&gt;
&lt;br /&gt;
        //Por cada metodo estatico que se quiere verificar se debe invocar &lt;br /&gt;
        //a PowerMockito.verifyStatic().&lt;br /&gt;
        PowerMockito.verifyStatic(); &lt;br /&gt;
        ClaseConMetodosEstaticos.secondStaticMethod();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Invocación a un método privado===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java&amp;gt;&lt;br /&gt;
public class PruebaMetodoPrivado {&lt;br /&gt;
&lt;br /&gt;
    public String decirHola(String nombre) {&lt;br /&gt;
        return decirHolaNombre(nombre);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    private String decirHolaNombre(String nombre) {&lt;br /&gt;
        return &amp;quot;Hola &amp;quot;+nombre;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java&amp;gt;&lt;br /&gt;
@RunWith(PowerMockRunner.class)&lt;br /&gt;
@PrepareForTest(PruebaMetodoPrivado.class)&lt;br /&gt;
public class PruebaMetodoPrivadoTest {&lt;br /&gt;
&lt;br /&gt;
   @Spy&lt;br /&gt;
   PruebaMetodoPrivado metodoPrivado = new PruebaMetodoPrivado();&lt;br /&gt;
    &lt;br /&gt;
    @Test&lt;br /&gt;
    public void mockMetodoPrivado() throws Exception {&lt;br /&gt;
&lt;br /&gt;
	Assert.assertEquals(&amp;quot;Hola Juan&amp;quot;, metodoPrivado.decirHola(&amp;quot;Juan&amp;quot;));&lt;br /&gt;
        doReturn(&amp;quot;Chau Juan&amp;quot;).when(metodoPrivado,&amp;quot;decirHolaNombre&amp;quot;,&amp;quot;Juan&amp;quot;);&lt;br /&gt;
        Assert.assertEquals(&amp;quot;Chau Juan&amp;quot;,metodoPrivado.decirHola(&amp;quot;Juan&amp;quot;));&lt;br /&gt;
        verifyPrivate(metodoPrivado,&lt;br /&gt;
                       Mockito.times(2)).invoke(&amp;quot;decirHolaNombre&amp;quot;,&amp;quot;Juan&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Inicialización de atributos estaticos===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java&amp;gt;&lt;br /&gt;
public class PruebaInicializacionEstaticos {&lt;br /&gt;
&lt;br /&gt;
    private static final String atributo = new String(&amp;quot;CHAU&amp;quot;);&lt;br /&gt;
 &lt;br /&gt;
    public String crearObjetoLista() {&lt;br /&gt;
        return atributo;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java&amp;gt;&lt;br /&gt;
@RunWith(PowerMockRunner.class)&lt;br /&gt;
@SuppressStaticInitializationFor(&amp;quot;PruebaInicializacionEstaticos&amp;quot;)&lt;br /&gt;
@PrepareForTest(PruebaInicializacionEstaticos.class)&lt;br /&gt;
public class PruebaMetodoPrivadoTest {&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
   PruebaInicializacionEstaticos pruebaInicializacionEstaticos = &lt;br /&gt;
                                    new PruebaInicializacionEstaticos();&lt;br /&gt;
 &lt;br /&gt;
    @Test&lt;br /&gt;
    public void controlCreacionLista() throws Exception {&lt;br /&gt;
	Assert.assertNull(pruebaInicializacionEstaticos.retornarAtrinbuto());&lt;br /&gt;
        String s = &amp;quot;Hola&amp;quot;;&lt;br /&gt;
        Whitebox.setInternalState(pruebaInicializacionEstaticos.class,&amp;quot;atributo&amp;quot;, s);&lt;br /&gt;
        Assert.assertEquals(s, pruebaInicializacionEstaticos.retornarAtrinbuto());&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Captura creación de objetos===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java&amp;gt;&lt;br /&gt;
public class PruebaCreacionObjeto {&lt;br /&gt;
 &lt;br /&gt;
    public List crearObjetoLista() {&lt;br /&gt;
        return new ArrayList();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java&amp;gt;&lt;br /&gt;
@RunWith(PowerMockRunner.class)&lt;br /&gt;
@PrepareForTest(PruebaCreacionObjeto.class)&lt;br /&gt;
public class PruebaMetodoPrivadoTest {&lt;br /&gt;
 &lt;br /&gt;
   @Spy&lt;br /&gt;
   PruebaCreacionObjeto pruebaCreacionObjeto = new PruebaCreacionObjeto();&lt;br /&gt;
 &lt;br /&gt;
    @Test&lt;br /&gt;
    public void controlCreacionLista() throws Exception {&lt;br /&gt;
        List list = new ArrayList();&lt;br /&gt;
        list.add(&amp;quot;Hola&amp;quot;);&lt;br /&gt;
        whenNew(ArrayList.class).withNoArguments().thenReturn((ArrayList) list);&lt;br /&gt;
        List resultado = pruebaCreacionObjeto.crearObjetoLista();&lt;br /&gt;
        Assert.assertEquals(list, resultado);&lt;br /&gt;
        verifyNew(ArrayList.class);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para mas ejemplos de Mockito junto a PowerMock ver los [http://code.google.com/p/powermock/wiki/MockitoUsage13 ejemplos] provisto por la documentación de PowerMock.&lt;br /&gt;
&lt;br /&gt;
[http://www.dosideas.com/descargas/category/3-testing.html?download=40 Descargar proyecto NetBeans demo de los ejemplos]&lt;br /&gt;
&lt;br /&gt;
===PowerMockito &amp;amp; Cobertura===&lt;br /&gt;
Existe un problema al utilizar PowerMockito con Cobertura (versión 1.8.4), este último no registra la corrida de los test con anotación @PrepareForTest, dando como resultados falta de cobertura.&lt;br /&gt;
Para solucionar este inconveniente solo hay que actualizar la versión de Cobertura.&lt;br /&gt;
&lt;br /&gt;
==Ejemplo de Mockito para mockear appender de log4j==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java&amp;gt;&lt;br /&gt;
//Inicializamos mock.&lt;br /&gt;
Appender mockAppender = mock(AppenderSkeleton.class);&lt;br /&gt;
//Inicializamos logger de la clase bajo test&lt;br /&gt;
Logger log = Logger.getLogger(ClaseATestear.class);&lt;br /&gt;
//Agregamos el mock del appender al logger.&lt;br /&gt;
log.addAppender(mockAppender);&lt;br /&gt;
//Seteamos el nivel de log que nos interesa recuperar.&lt;br /&gt;
log.setLevel(Level.DEBUG);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Para poder obtener los log que se producieron utilizamos la clase ArgumentCaptor de mockito que nos permite, entre otras cosas, capturar los eventos de log.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java&amp;gt;&lt;br /&gt;
ArgumentCaptor loggingEventCaptor = ArgumentCaptor.forClass(LoggingEvent.class);&lt;br /&gt;
&lt;br /&gt;
loggingEventCaptor.capture());&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Una posible forma de obtener un mensaje particular es iterando la lista de mensajes que nos da la clase capturada.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java&amp;gt;&lt;br /&gt;
List&amp;lt;LoggingEvent&amp;gt; loggingEvent = (List&amp;lt;LoggingEvent&amp;gt;) loggingEventCaptor.getAllValues();&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== BDDMockito ==&lt;br /&gt;
BDDMokcito es una clase alternativa que ofrece [[Mockito]] para crear pruebas al estilo [[Behavior Driven Development]] (BDD) (es decir, con bloques dado / cuando / entonces). &lt;br /&gt;
&lt;br /&gt;
El problema es que el API de Mockito usa la palabra &amp;quot;when&amp;quot; y no se integra bien con los comentarios //given //when //then (según BDD, el stubbing forma parte del área //given, y no del //when). &lt;br /&gt;
&lt;br /&gt;
BDDMockito agrega una clase que tiene alias para los métodos de stub, usando given(Object). &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java5&amp;gt;&lt;br /&gt;
 import static org.mockito.BDDMockito.*;&lt;br /&gt;
 &lt;br /&gt;
 Vendedor vendedor = mock(Vendedor.class);&lt;br /&gt;
 Negocio negocio = new Negocio(vendedor);&lt;br /&gt;
 &lt;br /&gt;
 @Test&lt;br /&gt;
 public void comprarPan() throws Exception {&lt;br /&gt;
   //given  &lt;br /&gt;
   given(vendedor.buscarPan()).willReturn(new Pan());&lt;br /&gt;
   &lt;br /&gt;
   //when&lt;br /&gt;
   Compra compra = negocio.comprarPan();&lt;br /&gt;
   &lt;br /&gt;
   //then&lt;br /&gt;
   assertThat(compra, contienePan());&lt;br /&gt;
 } &lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Stubbing con void y excepciones:&lt;br /&gt;
&amp;lt;code java5&amp;gt;&lt;br /&gt;
   //given&lt;br /&gt;
   willThrow(new RuntimeException(&amp;quot;boo&amp;quot;)).given(mock).foo();&lt;br /&gt;
   &lt;br /&gt;
   //when&lt;br /&gt;
   Result result = sistemaBajoPrueba.ejecutar();&lt;br /&gt;
   &lt;br /&gt;
   //then&lt;br /&gt;
   assertEquals(failure, result); &lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Ver también==&lt;br /&gt;
* [[EasyMock]]&lt;br /&gt;
* [[Captura De Parametros]]&lt;br /&gt;
* [[Inyeccion De Mocks De Mockito Con Spring]]&lt;br /&gt;
* [http://www.dosideas.com/descargas/category/3-testing.html?download=11%3Ademo-de-mockito Proyecto de ejemplos con Mockito]&lt;br /&gt;
* [http://www.dosideas.com/java/242-mockito-o-basta-de-easymock.html Introducción a Mockito]&lt;br /&gt;
* [http://mockito.googlecode.com/svn/branches/1.8.0/javadoc/org/mockito/BDDMockito.html Javadoc de BDDMockito]&lt;br /&gt;
&lt;br /&gt;
[[Category:TDD]]&lt;br /&gt;
[[Category:BDD]]&lt;br /&gt;
[[Category:JUnit]]&lt;/div&gt;</summary>
		<author><name>201.251.182.130</name></author>	</entry>

	<entry>
		<id>https://dosideas.com/wiki/index.php?title=Oracle_BPM_11g&amp;diff=6048</id>
		<title>Oracle BPM 11g</title>
		<link rel="alternate" type="text/html" href="https://dosideas.com/wiki/index.php?title=Oracle_BPM_11g&amp;diff=6048"/>
				<updated>2011-08-10T14:25:29Z</updated>
		
		<summary type="html">&lt;p&gt;201.251.182.130: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Oracle BPM 11g]] es la una versión de [[Oracle BPM]], que permite instalar aplicaciones basadas en [[BPM]]. &lt;br /&gt;
&lt;br /&gt;
== Instalación ==&lt;br /&gt;
Para instalar Oracle BPM 11g hay que seguir varios pasos e instaladores. Pueden seguir un [http://blog.lebrijo.com/?p=330&amp;amp;language=es paso-a-paso para instalarlo]. &lt;br /&gt;
&lt;br /&gt;
Los pasos simplificados son: &lt;br /&gt;
# Instalar base de datos Oracle Express 10g&lt;br /&gt;
# Ejecutar los siguientes ALTER en el equema: &lt;br /&gt;
  alter system reset sessions scope=spfile sid='*';&lt;br /&gt;
  alter system set processes=200 scope=spfile;&lt;br /&gt;
# Instalar el RCU&lt;br /&gt;
# Descomprimir soa_generic_11.1.1.2.0, y sobre el Disk1 ejecutar bin/setup&lt;br /&gt;
# Descomprimir soa_generic_11.1.1.3.0, y sobre el Disk1 ejectuar bin/setup&lt;br /&gt;
# Sobre el dominio instalado de SOA (Oracle_SOA1) ejecutar Oracle_SOA1\common\bin&amp;gt;config.cmd&lt;br /&gt;
# Instalar JDeveloper 11g.&lt;br /&gt;
# En JDeveloper 11g, ir a las actualizaciones e instalar los componentes SOA y BPM.&lt;br /&gt;
&lt;br /&gt;
== Ver también ==&lt;br /&gt;
* [http://st-curriculum.oracle.com/obe/fmw/obpm/11g/r1/firstProcess/firstprocess_obpm11g.htm Guía para construir una primera aplicación con Oracle BPM 11g]&lt;br /&gt;
* [http://blog.lebrijo.com/?p=330&amp;amp;language=es Instalando Oracle SOA Suite 11g]&lt;br /&gt;
* [http://st-curriculum.oracle.com/obe/jdev/obe11jdev/bulldog/deploysoaapp/deployment.htm Instalación de Oracle SOA y ALTERs necesarios]&lt;br /&gt;
&lt;br /&gt;
[[Category: Oracle]]&lt;/div&gt;</summary>
		<author><name>201.251.182.130</name></author>	</entry>

	<entry>
		<id>https://dosideas.com/wiki/index.php?title=Oracle_BPM_11g&amp;diff=6047</id>
		<title>Oracle BPM 11g</title>
		<link rel="alternate" type="text/html" href="https://dosideas.com/wiki/index.php?title=Oracle_BPM_11g&amp;diff=6047"/>
				<updated>2011-08-10T14:23:52Z</updated>
		
		<summary type="html">&lt;p&gt;201.251.182.130: Página creada con 'Oracle BPM 11g es la una versión de Oracle BPM, que permite instalar aplicaciones basadas en BPM.   == Instalación == Para instalar Oracle BPM 11g hay que seguir v…'&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Oracle BPM 11g]] es la una versión de [[Oracle BPM]], que permite instalar aplicaciones basadas en [[BPM]]. &lt;br /&gt;
&lt;br /&gt;
== Instalación ==&lt;br /&gt;
Para instalar Oracle BPM 11g hay que seguir varios pasos e instaladores. Pueden seguir un [http://blog.lebrijo.com/?p=330&amp;amp;language=es paso-a-paso para instalarlo]. &lt;br /&gt;
&lt;br /&gt;
Los pasos simplificados son: &lt;br /&gt;
# Instalar base de datos Oracle Express 10g&lt;br /&gt;
# Ejecutar los siguientes ALTER en el equema: &lt;br /&gt;
  alter system reset sessions scope=spfile sid='*';&lt;br /&gt;
  alter system set processes=200 scope=spfile;&lt;br /&gt;
# Instalar el RCU&lt;br /&gt;
# Descomprimir soa_generic_11.1.1.2.0, y sobre el Disk1 ejecutar bin/setup&lt;br /&gt;
# Descomprimir soa_generic_11.1.1.3.0, y sobre el Disk1 ejectuar bin/setup&lt;br /&gt;
# Sobre el dominio instalado de SOA (Oracle_SOA1) ejecutar Oracle_SOA1\common\bin&amp;gt;config.cmd&lt;br /&gt;
# Instalar JDeveloper 11g.&lt;br /&gt;
# En JDeveloper 11g, ir a las actualizaciones e instalar los componentes SOA y BPM.&lt;br /&gt;
&lt;br /&gt;
== Ver también ==&lt;br /&gt;
* [http://st-curriculum.oracle.com/obe/fmw/obpm/11g/r1/firstProcess/firstprocess_obpm11g.htm Guía para construir una primera aplicación con Oracle BPM 11g]&lt;br /&gt;
* [http://blog.lebrijo.com/?p=330&amp;amp;language=es Instalando Oracle SOA Suite 11g]&lt;br /&gt;
&lt;br /&gt;
[[Category: Oracle]]&lt;/div&gt;</summary>
		<author><name>201.251.182.130</name></author>	</entry>

	<entry>
		<id>https://dosideas.com/wiki/index.php?title=Oracle_BPM&amp;diff=6046</id>
		<title>Oracle BPM</title>
		<link rel="alternate" type="text/html" href="https://dosideas.com/wiki/index.php?title=Oracle_BPM&amp;diff=6046"/>
				<updated>2011-08-10T14:15:48Z</updated>
		
		<summary type="html">&lt;p&gt;201.251.182.130: /* Ver también */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Image:Bpm.jpg|left]] BPM, acrónimo de Business Process Management, en español Gestión de Procesos de Negocio, se identifica como  uno de los tópicos más escuchados en lo que respecta a tecnologías aplicadas al entorno empresarial. Constituye una filosofía que acompañada de tecnología permite gestionar de forma integral la organización, administrando mejor la carga de trabajo entre las diferentes áreas.&lt;br /&gt;
&lt;br /&gt;
¿ Qué es Oracle BPM ? Es un entorno de ejecución de procesos de negocios de empresas y está compuesto de diferentes aplicaciones y servicios que pueden ser instalados y configurados en diferentes topologías a manejar diferentes escenarios, soportando diferentes usos.&lt;br /&gt;
&lt;br /&gt;
Un entorno BPM es la infraestructura técnica en la cuál se ejecutan procesos de negocio. Definimos entorno BPM como todos los componentes ejecutables (aplicaciones y servicios) que trabajan juntos para permitir la ejecución de procesos de negocio.&lt;br /&gt;
&lt;br /&gt;
=== Infraestructura técnica ===&lt;br /&gt;
&lt;br /&gt;
Algunos componentes deben estar siempre presente para el entorno de ejecución, mientras que otros dependen de la activación de características o requisitos externos. Oracle BPM soporta una variada combinación de estos componentes, que van desde muy sencillos y pequeños a toda la organización. &lt;br /&gt;
&lt;br /&gt;
Los componentes que tienen que estar presentes:&lt;br /&gt;
&lt;br /&gt;
* por lo menos un motor BPM con su correpondiente esquema de base de datos&lt;br /&gt;
* un directorio en el repositorio que contiene el esquema de base de datos&lt;br /&gt;
* la aplicación BPM, vista de usuario final&lt;br /&gt;
* la aplicación BPM, vista administrador&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Los componentes opcionales:&lt;br /&gt;
&lt;br /&gt;
* servidor LDAP&lt;br /&gt;
* más motores BPM&lt;br /&gt;
* un servicio de monitoreo de procesos&lt;br /&gt;
* múltiples áreas de trabajo de BPM&lt;br /&gt;
* clientes JAVA&lt;br /&gt;
&lt;br /&gt;
=== Ejemplos de entornos Oracle BPM ===&lt;br /&gt;
&lt;br /&gt;
Los siguientes gráficos proveen una vista de alto nivel de diferentes partes. Estos gráficos muestran 3 tipos de artefactos: cajas, puntos, y registros. &lt;br /&gt;
&lt;br /&gt;
* Las cajas representan aplicaciones y servicios en el entorno. &lt;br /&gt;
* Los puntos representan los servicios expuestos por las aplicaciones (cajas).&lt;br /&gt;
* Las flechas representan una conexion entre una aplicación y un servicio expuesto por otro.&lt;br /&gt;
&lt;br /&gt;
==== Ejemplo 1: ilustra la arquitectura generada con el wizard de Oracle BPM Enterprise Standalone ====&lt;br /&gt;
&lt;br /&gt;
[[Archivo:BPM-imagen1.JPG]]&lt;br /&gt;
&lt;br /&gt;
==== Ejemplo 2: ilustra la arquitectura generada con el wizard de Oracle BPM Enterprise for WebLogic ====&lt;br /&gt;
&lt;br /&gt;
[[Archivo:BPM-imagen2.JPG]]&lt;br /&gt;
&lt;br /&gt;
==== Ejemplo 3: entorno clusterizado a través de Oracle BPM Enterprise for WebLogic ====&lt;br /&gt;
&lt;br /&gt;
Representea una topología escalable, típicamente usada en instalaciones grandes.&lt;br /&gt;
&lt;br /&gt;
[[Archivo:BPM-imagen3.JPG]]&lt;br /&gt;
&lt;br /&gt;
=== Componentes de un entorno BPM ===&lt;br /&gt;
&lt;br /&gt;
Esta sección enfoca sobre las cajas presentadas en los gráficos de arriba. Las cajas representan la ejecución de aplicaciones como parte del entorno. Consideramos aplicaciones a procesos Java standalone, servidores web y de aplicaciones, aplicaciones web, aplicaciones JEE (EARs), servidores de base de datos, servidores LDAP.&lt;br /&gt;
&lt;br /&gt;
Desde esta perspectiva, los componentes de un entorno BPM se pueden dividir en 3 grupos: BPM Core, BPM Clients y servicios de soporte. Cada entorno BPM contendrá componenetes en cada uno de estos grupos.&lt;br /&gt;
&lt;br /&gt;
=== BPM Core ===&lt;br /&gt;
&lt;br /&gt;
Hay 2 componentes principales: el motor BPM y el servicio de monitoreo de procesos.&lt;br /&gt;
&lt;br /&gt;
==== Motor BPM ====&lt;br /&gt;
&lt;br /&gt;
Es un componente que ejecuta procesos de negocio. El motor BPM es el elemento core de cada entorno BPM desde diferentes puntos de vista:&lt;br /&gt;
&lt;br /&gt;
* desde un punto de vista lógico, es el responsable de crear, almacenar y mover alrededor de instancias de procesos desplegados en él&lt;br /&gt;
* desde un punto de vista de ejecución. un motor BPM es un servicio que ejecuta tareas de procesos que son definidas por procesos de BPM como actividades de procesos. Las ejecuciones pueden ser disparadas externamente por clientes o internamentes en el 'background'&lt;br /&gt;
* desde un punto de vista físico, el motor de BPM toma diferentes formas dependiendo de los productos seleccionados. Es un proceso java standalone en el caso de un enterprise standalone. Es una aplicación JEE en el caso de enterprise para weblogic y websphere&lt;br /&gt;
&lt;br /&gt;
Hay muchos parámetros de configuración con los cuales adaptar el comportamiento de motores BPM, para cosas como hilos, puertos, conexiones  a base de datos. &lt;br /&gt;
&lt;br /&gt;
¿ Dónde definimos el motor BPM ?&lt;br /&gt;
&lt;br /&gt;
Los motores BPM son creados en un directorio BPM. Esto es un repositorio metadata con todas las definiciones, incluyendo motores, organización de procesos y recursos. Cuando un motor comienza a ejecutar, este lee los parámetros del directorio BPM, y los procesos desplegados. Una vez que el motor es creado, este representa la definición lógica. &lt;br /&gt;
&lt;br /&gt;
===== Motor BPM como una aplicación J2EE =====&lt;br /&gt;
&lt;br /&gt;
El motor BPM J2EE ejecuta como una aplicación ear desplegada en un contenedor J2EE (WebLogic o WebSphere). El ear contiene EJBs, MDBs y Servlets que juntos conforman el motor BPM. Un archivo ear debe ser generado desde el proceso BPM administrador para cada motor BPM definido. Este archivo ear está desplegado en un servidor J2EE o cluster. Desplegando en un cluster, muchos servidores ejecutan motores BPM concurrentemente. Algún cluster puede responder el pedido de un proceso desplegado en el motor BPM.&lt;br /&gt;
&lt;br /&gt;
===== Motor BPM como un proceso Java =====&lt;br /&gt;
&lt;br /&gt;
El motor BPM sin dependencias ejectuta como un proceso java que se realiza en segundo plano y no requiere J2EE o contenedor web. Solamente un proceso Java ejecuta el motor, lo que se llama motor activo. Uno o más procesos Java pueden permanecer en modo pausa como soporte. Cuando el motor activo deja de responder uno de los motores pasivos toma el rol de motor activo. El motor BPM sin dependencias tiene sus propios hilos, conexiones, gestión de pedidos, y es altamente configurable.&lt;br /&gt;
&lt;br /&gt;
===== Servicios expuestos del motor BPM =====&lt;br /&gt;
&lt;br /&gt;
El motor de BPM expone varios servicios a través de los cuales puede comunicarse con clientes externos. Estas interfaces contienen operaciones a manipular, consultas, y crean instancias de procesos desplegados en el motor BPM. Estos servicios son representados por los puntos en las figuras de arriba. &lt;br /&gt;
&lt;br /&gt;
===== Motores BPM y procesos de negocio =====&lt;br /&gt;
&lt;br /&gt;
Los procesos de negocio suelen interactuar entre sí, por ejemplo, para dar inicio a un sub-proceso, o notificar a otro proceso de algún evento.&lt;br /&gt;
&lt;br /&gt;
Desde una perspectiva de diseño, dos procesos que interactúan no es necesario que ejecuten en el mismo motor de BPM. El conocimiento y  comunicación entre los motores BPM es manejado automáticamente por el motor. Sin embargo, en algunos casos es necesario configurar la ubicación del motor BPM.&lt;br /&gt;
&lt;br /&gt;
Desde una perspectiva de cliente, diferentes versiones del mismo proceso pueden ser desplegados en diferentes motores. Clientes BPM conectan al directorio BPM, then conocen motores corriendo los procesos que les interesa y conectan a esos motores.&lt;br /&gt;
&lt;br /&gt;
En la mayoria de ambientes BPM el total de procesos de negocio ejecutan en un motor BPM. En algunos casos, es necesario tener muchos motores ejecutando en el mismo ambiente BPM.&lt;br /&gt;
&lt;br /&gt;
¿ Cuántos motores BPM en tu ambiente ?&lt;br /&gt;
&lt;br /&gt;
Motores BPM son desplegados para procesos de negocio. Los procesos pueden ser desplegados en algún motor BPM definido en tu entorno BPM.&lt;br /&gt;
&lt;br /&gt;
Desde el punto de vista de ejecución, un proceso es desplegado en un motor BPM, este no puede ser cambiado a otro, al menos que despliegues una nueva versión del proceso, uno activo y el otro deprecado.&lt;br /&gt;
&lt;br /&gt;
Desde el punto de vista físico, los protocolos de comunicación a ser usado entre los motores BPM dependen de su tipo (independiente o JEE) y si los motores son definidos en el mismo. En el caso de motores JEE, los clientes BPM deben configurarse con las propiedades del motor BPM.&lt;br /&gt;
&lt;br /&gt;
Hay dos posibles casos donde los motores BPM definidos en diferentes directorios BPM interactuan. En el primer caso, tenemos comunicación B2B entre diferentes organizaciones. Y la interacción es limitada a la comunicación interprocesos (IPC).&lt;br /&gt;
&lt;br /&gt;
En el segundo caso, una organización muy grande tiene diferentes directorios BPM para diferentes divisiones o areas funcionales, más claro que centralizar los procesos en un único directorio BPM. En este escenario los usuarios finales deben ver las instancias de procesos ejecutando en motores BPM definidos en diferentes directorios BPM. Esto puede ser archivado por configuración de clientes BPM. El cliente BPM es el que agrega la información desde los motores y presenta una vista unificada al usuario.&lt;br /&gt;
&lt;br /&gt;
==== Servicio de monitoreo de procesos ====&lt;br /&gt;
&lt;br /&gt;
El Servicio de Control de Procesos es responsable de la construcción de la información global de las ejecuciones de instancias de procesos y métricas. &lt;br /&gt;
&lt;br /&gt;
Desde el punto de vista lógico, el servicio busca nuevos eventos de instancias de procesos (creaciones, ejecuciones, terminaciones) que han ocurrido desde la última ejecución y transforma los acontecimientos en filas agregadas al tablero.&lt;br /&gt;
&lt;br /&gt;
Desde el punto de vista del tiempo de ejecución, cada entorno tiene su propia instancia del servicio de monitore de procesos. Cada instancia consulta el esquema de base de datos de tiempo de ejecución de cada motor BPM definido en el directorio BPM en busca de nuevos eventos, que luego serán agregados. &lt;br /&gt;
&lt;br /&gt;
Desde un punto de vista físico, el servicio funciona de forma continua como una JVM independiente en segundo plano, y es independiente del tipo de motor de BPM (Independiente, WebLogic, WebSphere) y si los motores se detienen o se inicia. El servicio no tiene interfaz de usuario y sólo lee los esquemas de base de datos del motor BPM, y escribe en los esquemas de base de datos específicos. Ya que se ejecuta independiente, se conecta a bases de datos utilizando drivers JDBC, haciendo conexiones directas, y no puede utilizar datasources de JEE.&lt;br /&gt;
&lt;br /&gt;
El Servicio de Control de Procesos tiene un propósito muy específico y crítico. Sin esto, no recibe información precisa para mostrar en el tablero de control de los procesos. En algunos casos, cuando el servicio no ha estado funcionando durante mucho tiempo, debe leer y agregar muchos eventos, considerando tiempo y recursos considerables.&lt;br /&gt;
&lt;br /&gt;
=== BPM Clients ===&lt;br /&gt;
&lt;br /&gt;
Los clientes BPM son aplicaciones que interactuan con los procesos de negocio que ejecutan en los motores BPM.&lt;br /&gt;
&lt;br /&gt;
La mayoría de los clientes de BPM se conectan a los motores de BPM a través de los servicios expuestos por el motor. Pero hay otro tipo de cliente BPM: los que interactúan con los procesos de negocio a través de recursos externos, como una cola JMS, un sistema de archivos, o una tabla de base de datos. En este caso es el proceso de negocio en sí - como parte de su definición - la que establece una interacción empujando y tirando de la información a través de estos recursos, la definición de un contrato con la entidad externa para intercambiar información. Desde el punto de vista de que el servicio de motores BPM utiliza el cliente para conectarse, tenemos dos grandes grupos: los clientes PAPI, que utilizan el servicio de proceso interno, y los clientes de servicios Web. &lt;br /&gt;
&lt;br /&gt;
==== Cliente PAPI ====&lt;br /&gt;
&lt;br /&gt;
Es el proceso API y refiere a la API de Java que este cliente usa para interactuar con el motor BPM. PAPI está embebido en muchas aplicaciones web. Realiza funciones críticas desde el punto de vista de usuario final. Está configurado para autenticar y autorizar usuarios finales, encuentra los procesos disponibles en el directorio BPM, conecta a los motores BPM que ejecutan dichos procesos, y retorna información a los usuarios finales. Es la única API de JAVA para la interacción de procesos. &lt;br /&gt;
&lt;br /&gt;
===== Características de ejecución del cliente PAPI =====&lt;br /&gt;
&lt;br /&gt;
PAPI está diseñado para soportar un portal de procesos interactivo. Algunas optimizaciones se realizaron para la perfomance de cliente PAPI, incluyendo cache en memoria de información acerca de procesos. &lt;br /&gt;
&lt;br /&gt;
Un cliente PAPI requiere conectividad al directorio y al motor. &lt;br /&gt;
&lt;br /&gt;
Los clientes PAPI no hablan entre si ni acceden a recursos utilizados por los procesos de negocio.&lt;br /&gt;
&lt;br /&gt;
Los clientes PAPI pueden ejecutarse como procesos independientes de JAVA. Cada uno requiere una copia de la memoria caché y exige mucha memoria.&lt;br /&gt;
&lt;br /&gt;
==== Area de trabajo BPM ====&lt;br /&gt;
&lt;br /&gt;
El &amp;quot;workspace&amp;quot; o area de trabajo BPM es lo más importante en la aplicación de usuario final. El area de trabajo BPM es a los procesos de negocio lo que el Outlook es al mail: la principal aplicación de interacción. El area de trabajo BPM es un cliente PAPI, y tiene funcionalidad adicional que es importante entender. Desde la perspectiva de la topología, es una práctica saludable tener áreas de trabajo BPM siempre disponible. El area de trabajo BPM provee un montón de funcionalidad sobre PAPI: soporte a flujos de pantallas, tableros, diseños de páginas, etc. La aplicación también permite adaptar la interfaz de usuario a través de hojas de estilos y otras configuraciones. Autenticación y SSO (Single Sign On) tienen importantes consideraciones en el área de trabajo de BPM. El área de trabajo BPM puede confiar en el servidor web (Tomcat, Weblogic, etc) para autenticar y conectar a usuarios remotos.&lt;br /&gt;
&lt;br /&gt;
==== Clientes Web Service (WS) ====&lt;br /&gt;
&lt;br /&gt;
Pueden elegirse clientes WS entre dos servicios disponibles: los servicios &amp;quot;Process-WS&amp;quot; expuestos por el motor BPM y la aplicación &amp;quot;PAPI-WS&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
El servicio &amp;quot;Process-WS&amp;quot; expone ciertas actividades del proceso de negocio como operaciones de WS. En particular, puede ser usado para crear nuevas instancias de procesos y enviar notificaciones a las instancias de procesos existentes. Las actividades de los procesos de negocio tienen que ser marcadas explícitamente como expuestas para ser agregadas al servicio. Técnicamente, este servicio es provisto por el mismo motor BPM. Cuando levanta el motor, lee todos los procesos definidos y busca cuales actividades están marcadas. La interfaz expuesta por el servicio es definida por el parámetro las actividades expuestas (creación y espera notificación), entonces la interfaz del servicio está directamente relacionada a la definición de los procesos.&lt;br /&gt;
&lt;br /&gt;
El servicio &amp;quot;PAPI-WS&amp;quot; expone la mayoría de las operaciones de PAPI a través de una interfaz SOA. Este servicio está separado de la aplicación web PAPI-WS. Esta aplicación se despliega como cualquier otra aplicación web, y simula un servicio web alrededor de la funcionalidad PAPI. El servicio &amp;quot;PAPI-WS&amp;quot; es un cliente PAPI porque usa la API. La interfaz expuesta por el servicio es similar a la API, y esta es independiente de los procesos desplegados. PAPI-WS puede interactuar con cualquier proceso desplegado en el entorno.&lt;br /&gt;
&lt;br /&gt;
==== Clientes de administracion ====&lt;br /&gt;
&lt;br /&gt;
Esta categoría incluye el proceso administrador de BPM, la herramienta principal de administración junto con el área de trabajo de BPM y la vista de archivos. Estas aplicaciones web no son usadas para tareas diarias, y son importantes en la configuración y administración del entorno.&lt;br /&gt;
&lt;br /&gt;
El proceso administrador proporciona configuración y administración para la organización, motores, recursos externos, procesos de negocio, y es usado para desplegar procesos de negocio en los motores BPM. Adicionalmente a la configuración técnica de la conexion del directorio BPM, el proceso administrador de BPM también maneja la configuración del resto del entorno.&lt;br /&gt;
&lt;br /&gt;
Desde un punto de vista técnico, el proceso administrador de BPM requiere conectividad al directorio y a motores BPM en orden al monitoreo y control de los mismos (parar, comenzar). El proceso administrador BPM también puede crear el esquema de base de datos requerido por el motor BPM.&lt;br /&gt;
&lt;br /&gt;
La aplicación administradora del área de trabajo de BPM es la responsable de configurar las vistas del área de trabajo (PAPI) y presentar la disponibilidad a los usuarios del área de trabajo. Utilizado por los dueños del negocio o administradores, quienes quieren proporcionar adaptaciones, vistas basadas en roles y presentaciones a usuarios. Por ejemplo, puede proporcionar una vista de seguimiento para los gestores y una cola de trabajo priorizada para los roles no gerenciales.&lt;br /&gt;
&lt;br /&gt;
El visualizador de archivos BPM es una aplicación web que es usada para ver la información archivada de instancias de procesos. Esta información se saca de los motores BPM y se introduce en los archivos de base de datos.&lt;br /&gt;
&lt;br /&gt;
==== Clasificación por tipo de aplicación ====&lt;br /&gt;
&lt;br /&gt;
Hay varios tipos de procesos clientes, incluyendo aplicaciones de usuario final y sistemas backend. Las aplicaciones de usuario final pueden ser parte del producto, por ejemplo, área de trabajo BPM. La mayoría de los entornos tendrá al menos una aplicación de usuario final con la que los usuarios del proceso interctúan con el sitema. La aplicación a ser usada está basada en decisiones de diseño tomadas por el equipo de desrrollo. Estas aplicaciones deben ser comunicadas con el motor BPM en orden a acceder a la información de los procesos e invocar operaciones de los procesos.&lt;br /&gt;
&lt;br /&gt;
¿ Cuántos clientes BPM en tu entorno ?&lt;br /&gt;
&lt;br /&gt;
NO hay restricciones en el número y tipo de clientes BPM trabajando en un entorno BPM. Estas decisiones están basadas en la arquitectura del entorno. La mayoría de los entornos usan áreas de trabajo BPM, mientras que otros pueden optar por construir su propia interfaz de usuario, ya sea a través del PAPI o servicios web. Una tercera opción es escribir los servicios backend que llevan a cabo operaciones específicas en los procesos, como la creación de una instancia cuando llega un mensaje en una cola. Un punto de interés en estos entornos distribuidos es la sincronización de información a través de diferentes componentes. Por ejemplo, si una instancia de proceso está actualizada por una tarea ejecutada en el motor BPM, el estado actualizado de la instancia del proceso debe estar propagado a cualquier cliente PAPI que pueda estar escuchando para actualizaciones. Otro ejemplo es que si un nuevo proceso está desplegado, este debería aparecer inmediatamente en el área de trabajo de BPM y estar disponible para usar. La frecuencia y método de actualización de los diferentes componentes del entorno son consideraciones importantes en los cambios posibles de las propiedades del entorno. &lt;br /&gt;
&lt;br /&gt;
=== Servicios de soporte ===&lt;br /&gt;
&lt;br /&gt;
Un número de servicios de soporte son requeridos para el entorno BPM, incluyendo base de datos, LDAPs y servidores web y J2EE. Los requerimientos de servicio específico dependen de la configuración, topología, y el motor BPM. &lt;br /&gt;
&lt;br /&gt;
==== Base de datos ====&lt;br /&gt;
&lt;br /&gt;
Toda la configuración e información de ejecución se almacena en base de datos. En sistemas de archivos del servidor, se almacenan los archivos de log, cache. La BPM de Oracle requiere un esquema separado de base de datos por cada función específica:&lt;br /&gt;
&lt;br /&gt;
* Requerido por cada directorio BPM: metadata&lt;br /&gt;
* Requerido por cada motor BPM: información de ejecución&lt;br /&gt;
&lt;br /&gt;
===== Conexión a base de datos =====&lt;br /&gt;
&lt;br /&gt;
Hay 2 maneras para que una aplicación BPM pueda obtener conexión a la base de datos: directamente, via los drivers de JDBC o usando datasources de J2EE. Las aplicaciones independientes como el administrador de BPM, el servicio de monitoreo de procesos y el motor independiente siempre usan los drivers JDBC. &lt;br /&gt;
&lt;br /&gt;
==== Servidores de aplicaciones J2EE ====&lt;br /&gt;
&lt;br /&gt;
Los servidores de aplicaciones pueden ser usados como contenedores para motores BPM y/o clientes BPM (área de trabajo BPM, por ejemplo). Cualquier combinación es soportado, asumiendo la configuración correspondiente. Por ejemplo: un área de trabajo BPM corriendo en Weblogic puede ser conectada a un motor BPM independiente. Un cliente java PAPI independiente puede ser conectado a un motor BPM desplegado en Weblogic o WebSphere, motores BPM siempre ejecutan como una aplicación J2EE instalada en un servidor o un clúster.&lt;br /&gt;
&lt;br /&gt;
==== Recursos J2EE usados por el motor BPM ====&lt;br /&gt;
&lt;br /&gt;
Los motores BPM que ejecutan en un servidor de aplicaciones J2EE utilizan datasources para acceder al esquema del directoio y motor. Adicionalmente a estos esquemas requeridos, cada motor BPM requiere dos recursos de mensajeria: una cola y un topic. Estos recursos JMS son necesarios para archivar funcionalidad que el motor BPM independiente puede implementar sin ellos. Los servidores de aplicación no proporcionan un framework para las ejecuciones en segunod plano, entonces las colas JMS son usadas como disparadores de eventos en segundo plano con un MDB. El motor BPM genera un mensaje cuando una tarea tiene que ejecutar. El MDB levanta el mensaje y ejecuta la tarea. El topic JMS se usa para enviar información a los clientes PAPI. Los motores BPM necesitan una forma de propagar los cambios a todos los clientes PAPI, y estos clientes esperan mensajes en estos topicos. El motor BPM coloca un mensaje en el topic cuando hay noticias para publicar, y los clientes leen los mensajes y actualizan la memoria interna. Entonces, el motor BPM es el publicador y los clientes PAPI son los suscriptores.&lt;br /&gt;
&lt;br /&gt;
==== Portal web: centro de integracion web, portal weblogic ====&lt;br /&gt;
&lt;br /&gt;
La BPM de Oracle está integrada con portales en diferentes formas. Algunas aplicaciones web de BPM, área de trabajo BPM particulares, pueden ser navegadas a través del centro de integración web (WCI) o del portal weblogic (WLP). Otra alternatiba es construir portles, usando PAPI. Este último caso no es diferente de cualquiere adaptación de una aplicación PAPI.&lt;br /&gt;
&lt;br /&gt;
Desde el punto de vista físico, el área de trabajo de BPM ejecuta separado de JVM, tipicamente se construye en un servidor Tomcat, y se comunica con WCI remotamente. Para la integración del directorio BPM, la información del WCI es accedida de la misma manera que con cualquier proveedor LDAP.&lt;br /&gt;
&lt;br /&gt;
==== Portal weblogic de integracion (WLP) ====&lt;br /&gt;
&lt;br /&gt;
La integración con este portal se logra mediante la creación de un portal de aplicaciones que incluye un área de trabajo BPM de portlets, además de todas las librerías del cliente PAPI. Esta aplicación se instala en WLP, y de ese modo se incorpora en el portal.&lt;br /&gt;
&lt;br /&gt;
Desde el punto de vista físico, el área de trabajo de BPM del portal de aplicaciones ejecuta sobre el proceso java WLP, de la misma forma que el área de trabajo BPM de las aplicaciones web que ejecutan en Tomcat o Weblogic.&lt;br /&gt;
&lt;br /&gt;
==== LDAPs ====&lt;br /&gt;
&lt;br /&gt;
Son usados como fuente de información de la organización, específicamente usuarios, unidades organizacionales y grupos. Esta integración es muy flexible y configurable.&lt;br /&gt;
&lt;br /&gt;
===== Integración técnica =====&lt;br /&gt;
&lt;br /&gt;
Desde un punto de vista técnico, LDAP se convierte en parte de los metadatos del directorio, por lo que cualquier aplicación que requiere acceso al directorio BPM (por ejemplo, los motores BPM, los clientes PAPI, el proceso administrador). Dado que el acceso a LDAP es de sólo lectura, se utiliza el acceso anónimo. No obstante, puede configurarse la conexión segura y la autenticación. Generalmente, las conexiones LDAP se utilizan a través de un pool para mejorar el rendimiento, y la autenticación se utiliza con usuario/contraseña que proporciona LDAP. Luego, el proceso de autorización se maneja con el esquema de directorio BPM.&lt;br /&gt;
&lt;br /&gt;
===== Integración funcional =====&lt;br /&gt;
&lt;br /&gt;
BPM define usuarios, grupos y unidades de la organización en una estructura única y bien definida. Esto difiere de cómo muchas organizaciones definen los conceptos. Por ejemplo, Oracle BPM definie que un usuario solo puede pertenecer a una unidad de organización, asigna funciones a los usuarios y grupos, mientras que algunas organizaciones podrían asignar funciones a la unidad organizativa. Es importante entender que en todos los casos la estructura LDAP tiene que estar mapeada con el modelo de organización de la BPM. &lt;br /&gt;
&lt;br /&gt;
=== Servicios requeridos por el proceso de negocio ===&lt;br /&gt;
&lt;br /&gt;
Si tus procesos de negocio integran con otros sistemas (web service, colas, etc), estos se convierten en parte de tu entorno BPM y son necesarios para que tus procesos ejecuten. La configuración de estos recursos se realiza sobre todo en el proceso administrador de BPM.&lt;br /&gt;
&lt;br /&gt;
=== Servicios provistos por componentes BPM ===&lt;br /&gt;
&lt;br /&gt;
El proveedor de servicios más importante es el motor BPM. Cada operación instancia de proceso se produce en el motor de BPM y la dispara automáticamente el motor, o externamente un cliente BPM. El principal servicio expuesto por el motor BPM es el servicio de procesos interno. Este servicio es usado por PAPI para interactuar con el motor. Cada cliente PAPI usa este servicio para consultar e invocar instancias del proceso.&lt;br /&gt;
&lt;br /&gt;
==== Servicio de proceso del motor BPM ====&lt;br /&gt;
&lt;br /&gt;
Desde el punto de vista lógico, el servicio de proceso del motor BPM expone una interfaz a través de diferentes protocolos:&lt;br /&gt;
&lt;br /&gt;
* protocolo Java RMI, si es una implementación standalone&lt;br /&gt;
* EJBs, que utilizan el protocolo del servidor de aplicaciones (wl, t3, loop, etc) en las implementaciones en wl y websphere. Los EJBs forman parte de la aplicación ear, que se instala en el servidor de aplicaciones como motor BPM.&lt;br /&gt;
&lt;br /&gt;
Los clientes PAPI ubican automáticamente los motores y seleccionan el protocolo adecuado en función del tipo de motor.&lt;br /&gt;
&lt;br /&gt;
=== Elección de una topología ===&lt;br /&gt;
&lt;br /&gt;
Muchos factores pueden influir la selección de una topología:&lt;br /&gt;
&lt;br /&gt;
* Carga de los procesos de negocio: el número de instancias de proceso, las actividades en el proceso, y personas que interactuan con el proceso&lt;br /&gt;
* Aprovechamiento de infraestructura existente: servidores wl, etc&lt;br /&gt;
* Aprovechamiento de conocimientos existentes: J2EE, Java&lt;br /&gt;
* Políticas institucionales, por ejemplo, separar backend del frontend&lt;br /&gt;
* Confiabilidad, disponibilidad y requisitos de performance&lt;br /&gt;
* Costo&lt;br /&gt;
&lt;br /&gt;
=== Guia para definir una topología ===&lt;br /&gt;
&lt;br /&gt;
Algunas pautas según las capacidades del producto:&lt;br /&gt;
&lt;br /&gt;
* Definir al menos un motor de BPM&lt;br /&gt;
* Los procesos pueden ser desplegados en ninguno de los motores definidos&lt;br /&gt;
* Cada motor de BPM se puede configurar independiente y optimizado para casos de uso específicos&lt;br /&gt;
* Puede haber muchos clientes BPM según se necesiten&lt;br /&gt;
* El área de trabajo de BPM y los clientes PAPI pueden estar en el mismo servidor que el motor de BPM o en otro diferente&lt;br /&gt;
* Los clientes PAPI pueden implementarse en cluster o en granja de servidores&lt;br /&gt;
* Cada cliente PAPI pude configurarse de forma independiente&lt;br /&gt;
* Los clientes PAPI pueden interactuar con cualquiera de los procesos&lt;br /&gt;
* Los motores de BPM, clientes PAPI y todas las aplicaciones de BPM requieren conexión con el directorio BPM&lt;br /&gt;
* El área de trabajo BPM y el motor BPM son aplicaciones que consumen muchos recursos. La decisión de ubicar en el mismo servidor de destino o grupo tiene importantes implicaciones en el rendimiento&lt;br /&gt;
* La comunicación entre el área de trabajo BPM y el motor BPM requiere de una configuración específica, dependiendo de si están en diferentes grupos o dominios. Es más fácil de configurar desplegados en diferentes dominios en lugar de grupos diferentes&lt;br /&gt;
&lt;br /&gt;
=== Requisitos  ===&lt;br /&gt;
&lt;br /&gt;
*&lt;br /&gt;
*&lt;br /&gt;
&lt;br /&gt;
=== Demo  ===&lt;br /&gt;
&lt;br /&gt;
*&lt;br /&gt;
*&lt;br /&gt;
&lt;br /&gt;
=== Problemas y soluciones  ===&lt;br /&gt;
&lt;br /&gt;
*&lt;br /&gt;
&lt;br /&gt;
=== Ver también  ===&lt;br /&gt;
&lt;br /&gt;
* [http://www.oracle.com/technetwork/articles/bpm-environment-explained-097155.html Nota original de entorno BPM explicado]&lt;br /&gt;
* [[BEA Aqualogic BPM 5.7 (Fuego)]]&lt;br /&gt;
* [[Oracle BPM 11g]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Oracle]]&lt;/div&gt;</summary>
		<author><name>201.251.182.130</name></author>	</entry>

	<entry>
		<id>https://dosideas.com/wiki/index.php?title=Servidor_de_Aplicaciones&amp;diff=6045</id>
		<title>Servidor de Aplicaciones</title>
		<link rel="alternate" type="text/html" href="https://dosideas.com/wiki/index.php?title=Servidor_de_Aplicaciones&amp;diff=6045"/>
				<updated>2011-08-10T14:15:07Z</updated>
		
		<summary type="html">&lt;p&gt;201.251.182.130: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Java]]&lt;br /&gt;
Se denomina Servidor de Aplicaciones (Application Server) a un servidor en una red de computadores que ejecuta ciertas aplicaciones&lt;br /&gt;
&lt;br /&gt;
Usualmente se trata de un dispositivo de software que proporciona servicios de aplicación a las computadoras cliente. Un servidor de aplicaciones generalmente gestiona la mayor parte (o la totalidad) de las funciones de lógica de negocio y de acceso a los datos de la aplicación. Los principales beneficios de la aplicación de la tecnología de servidores de aplicación son la centralización y la disminución de la complejidad en el desarrollo de aplicaciones. Si bien el término es aplicable a todas las plataformas de software, hoy en día el término servidor de aplicaciones se ha convertido en sinónimo de la plataforma [[Java EE]] de Sun Microsystems.&lt;br /&gt;
&lt;br /&gt;
Existen diversos Application Servers JEE en el mercado:&lt;br /&gt;
* [[GlassFish]] (software libre)&lt;br /&gt;
* [[JBoss Application Server]] (software libre)&lt;br /&gt;
* IBM [[WebSphere]] (comercial)&lt;br /&gt;
* Oracle [[WebLogic]] (comercial)&lt;br /&gt;
* [[Oracle BPM]] (comercial)&lt;br /&gt;
&lt;br /&gt;
==Ver también==&lt;br /&gt;
* [http://es.wikipedia.org/wiki/Servidor_de_aplicaciones Servidor de aplicaciones en la Wikipedia]&lt;br /&gt;
* [http://www.theserverside.com/tt/articles/article.tss?l=WhatIsAnAppServer What is an application server?]&lt;/div&gt;</summary>
		<author><name>201.251.182.130</name></author>	</entry>

	<entry>
		<id>https://dosideas.com/wiki/index.php?title=HTML&amp;diff=5873</id>
		<title>HTML</title>
		<link rel="alternate" type="text/html" href="https://dosideas.com/wiki/index.php?title=HTML&amp;diff=5873"/>
				<updated>2011-07-08T20:16:18Z</updated>
		
		<summary type="html">&lt;p&gt;201.251.182.130: Página creada con ' * Tablas en HTML'&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
* [[Tablas en HTML]]&lt;/div&gt;</summary>
		<author><name>201.251.182.130</name></author>	</entry>

	<entry>
		<id>https://dosideas.com/wiki/index.php?title=Spring_Integration&amp;diff=5850</id>
		<title>Spring Integration</title>
		<link rel="alternate" type="text/html" href="https://dosideas.com/wiki/index.php?title=Spring_Integration&amp;diff=5850"/>
				<updated>2011-07-07T14:25:25Z</updated>
		
		<summary type="html">&lt;p&gt;201.251.182.130: /* Ver también */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[http://www.springsource.org/spring-integration Spring Integration] es un producto relativamente desconocido del Spring.&lt;br /&gt;
Brinda una extensión a Spring para soportar los [http://www.eaipatterns.com/ Patrones de Integración Corporativos] en pocas palabras es un [http://en.wikipedia.org/wiki/Enterprise_service_bus  ESB] liviano montado sobre el contenedor de Spring e independiente del Servidor de aplicaciones. Permite utilizar mensajería dentro de una aplicación Spring, y se integra con sistemas externos a través de adaptadores. Se basa en el concepto de &amp;quot;mensajes&amp;quot; para intercambiar datos entre distintos componentes.&lt;br /&gt;
&lt;br /&gt;
==Conceptos y componentes básicos==&lt;br /&gt;
&lt;br /&gt;
===Conceptos===&lt;br /&gt;
&lt;br /&gt;
* '''Channel (MessageChannel)''', representa un canal lógico por donde se reciben o se envían mensajes.&lt;br /&gt;
&lt;br /&gt;
* '''Channel-adapter''', representa el adaptador entre el canal lógico y una implementación física de ese canal. &lt;br /&gt;
&lt;br /&gt;
* '''Bridge''', se encarga de redireccionar todos los mensajes del canal de entrada hacia un canal de salida.&lt;br /&gt;
&lt;br /&gt;
* '''Router''', se encarga de redireccionar los mensajes que llegan a un canal de entrada hacia uno o varios canales de salida, dependiendo de ciertas condiciones.&lt;br /&gt;
&lt;br /&gt;
* '''Splitter''', se encarga de separar el contenido de un mensaje en muchos mensajes.&lt;br /&gt;
&lt;br /&gt;
* '''Transformer''', se encarga de transformar el formato del contenido del mensaje.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Componentes===&lt;br /&gt;
&lt;br /&gt;
* '''Message''', esta compuesto por una cabecera (headers) y por un cuerpo (Payload). &lt;br /&gt;
&lt;br /&gt;
* '''MessageChannel''', provee métodos para enviar y recibir. &lt;br /&gt;
&lt;br /&gt;
* '''MessageEndpoint''', Conecta un Handler a un MessageChannel de entrada o/y a uno de salida.&lt;br /&gt;
&lt;br /&gt;
* '''MessageHandler''', interfaz que permite transformer, rutear y en general “tartar” cualquier mensaje de Entrada.&lt;br /&gt;
&lt;br /&gt;
* '''Channel Adapters''', se usan para enviar y recibir mensajes a sistemas externos.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Adaptadores==&lt;br /&gt;
&lt;br /&gt;
* [http://static.springsource.org/spring-integration/docs/2.0.4.RELEASE/reference/htmlsingle/#ip TCP y UDP]&lt;br /&gt;
* [http://static.springsource.org/spring-integration/docs/2.0.4.RELEASE/reference/htmlsingle/#http HTTP]&lt;br /&gt;
* [http://static.springsource.org/spring-integration/docs/2.0.4.RELEASE/reference/htmlsingle/#feed RSS/ATOM]&lt;br /&gt;
* [http://static.springsource.org/spring-integration/docs/2.0.4.RELEASE/reference/htmlsingle/#ws Web Services]&lt;br /&gt;
* [http://static.springsource.org/spring-integration/docs/2.0.4.RELEASE/reference/htmlsingle/#mail Mail (POP3, IMAP, SMTP)]&lt;br /&gt;
* [http://static.springsource.org/spring-integration/docs/2.0.4.RELEASE/reference/htmlsingle/#jms JMS]&lt;br /&gt;
* [http://static.springsource.org/spring-integration/docs/2.0.4.RELEASE/reference/htmlsingle/#jdbc JDBC]&lt;br /&gt;
* [http://static.springsource.org/spring-integration/docs/2.0.4.RELEASE/reference/htmlsingle/#jmx JMX]&lt;br /&gt;
* [http://static.springsource.org/spring-integration/docs/2.0.4.RELEASE/reference/htmlsingle/#rmi RMI]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Taller ==&lt;br /&gt;
&lt;br /&gt;
{{curso|url=http://www.dosideas.com/cursos/course/view.php?id=12|nombre=Introducción a Spring Integration}}&lt;br /&gt;
&lt;br /&gt;
== Ejemplos ==&lt;br /&gt;
&lt;br /&gt;
=== Configuración de canales ===&lt;br /&gt;
[[Spring Integration]] se basa en ''canales'', lugares en donde se consumen o envian mensajes. Estos canales pueden ser colas [[JMS]] u otros medios, como clases propias. La siguiente definición de canales se usa en los ejemplos que siguen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
&amp;lt;integration:channel id=&amp;quot;QueueChanneIn&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;jms:message-driven-channel-adapter connection-factory=&amp;quot;PruebaQueueConnectionFactory&amp;quot; &lt;br /&gt;
destination-name=&amp;quot;jms/Queue-in&amp;quot; destination-resolver=&amp;quot;jmsDestinationResolver&amp;quot; &lt;br /&gt;
channel=&amp;quot;QueueChanneIn&amp;quot; acknowledge=&amp;quot;auto&amp;quot; concurrent-consumers=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;integration:channel id=&amp;quot;QueueChanneOut1&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;jms:outbound-channel-adapter jms-template=&amp;quot;jmsQueueTemplateOut1&amp;quot; channel=&amp;quot;QueueChanneOut1&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;integration:channel id=&amp;quot;QueueChanneOut2&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;jms:outbound-channel-adapter jms-template=&amp;quot;jmsQueueTemplateOut2&amp;quot; channel=&amp;quot;QueueChanneOut2&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===stdout-channel-adapter===&lt;br /&gt;
Podemos consumir un mensaje de una cola y mostrarlo por consola. Para esto es necesario configurar un '''stdout-channel-adapter''', el cual se encargará de procesar los mensajes. Luego, se crea un '''bridge''' que asocia un canal de entrada con este adaptador. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
&amp;lt;stream:stdout-channel-adapter id=&amp;quot;stdout&amp;quot; append-newline=&amp;quot;true&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;integration:bridge id=&amp;quot;echo&amp;quot; input-channel=&amp;quot;QueueChanneIn&amp;quot; output-channel=&amp;quot;stdout&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===recipient-list-router===&lt;br /&gt;
Podemos consumir un mensaje de una cola y enviarlo a una lista fija de canales de destino. En este ejemplo creamos un '''recipient-list-router''', el cual consume mensajes de un canal de entrada y los envia a dos canales de destino distintos. Entonces, cada mensaje que llegue al canal de entrada será derivado a dos canales de destino. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
&amp;lt;integration:recipient-list-router input-channel=&amp;quot;QueueChanneIn&amp;quot; apply-sequence=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;integration:recipient channel=&amp;quot;QueueChanneOut1&amp;quot;/&amp;gt;&lt;br /&gt;
            &amp;lt;integration:recipient channel=&amp;quot;QueueChanneOut2&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/integration:recipient-list-router&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===header-value-router===&lt;br /&gt;
Podemos consumir un mensaje de una cola y enviarlo a una cola especifica dependiendo del valor de un atributo del header del mensaje. De esta manera, configuramos un '''header-value-router''', el cual contiene el canal de entrada y el nombre del atributo del encabezado que se comprobará. Luego, se realiza el mapeo entre los posibles valores de este encabezado y algún canal de destino. Si llega un mensaje que coincida este mapeo, será enviado a ese canal de destino.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
&amp;lt;integration:header-value-router input-channel=&amp;quot;QueueChanneIn&amp;quot; &lt;br /&gt;
header-name=&amp;quot;springintegration_jms_type&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;integration:mapping value=&amp;quot;Out1&amp;quot; channel=&amp;quot;QueueChanneOut1&amp;quot;/&amp;gt;&lt;br /&gt;
        &amp;lt;integration:mapping value=&amp;quot;Out2&amp;quot; channel=&amp;quot;QueueChanneOut2&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/integration:header-value-router&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===router===&lt;br /&gt;
Podemos consumir un mensaje de una cola y enviarlo a una lista de colas de salida utilizando un pojo para determinar a que colas enviarlo. En este ejemplo, creamos un '''router''' que será implementado por la clase &amp;quot;MultiDestino&amp;quot;. Esta clase devuelve una lista de nombres de canales hacia donde se derivará el mensaje.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
&amp;lt;integration:router input-channel=&amp;quot;QueueChanneIn&amp;quot; ref=&amp;quot;multiDestino&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;bean id=&amp;quot;multiDestino&amp;quot; class=&amp;quot;com.dosideas.springintegration.MultiDestino&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java&amp;gt;&lt;br /&gt;
public class MultiDestino {&lt;br /&gt;
&lt;br /&gt;
    @Router&lt;br /&gt;
    public List&amp;lt;String&amp;gt; resolverChannel(GenericMessage message) throws JMSException {&lt;br /&gt;
&lt;br /&gt;
        List&amp;lt;String&amp;gt; list = new ArrayList&amp;lt;String&amp;gt;();&lt;br /&gt;
        if(message.getHeaders().get(&amp;quot;springintegration_jms_type&amp;quot;).equals(&amp;quot;Out1&amp;quot;)) {&lt;br /&gt;
            System.out.println(message.getHeaders().get(&amp;quot;springintegration_jms_type&amp;quot;));&lt;br /&gt;
            list.add(&amp;quot;QueueChanneOut1&amp;quot;);&lt;br /&gt;
            &lt;br /&gt;
        }&lt;br /&gt;
        else if(message.getHeaders().get(&amp;quot;springintegration_jms_type&amp;quot;).equals(&amp;quot;Out2&amp;quot;)) {&lt;br /&gt;
            System.out.println(message.getHeaders().get(&amp;quot;springintegration_jms_type&amp;quot;));&lt;br /&gt;
            list.add(&amp;quot;QueueChanneOut2&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
        else if(message.getHeaders().get(&amp;quot;springintegration_jms_type&amp;quot;).equals(&amp;quot;Multi&amp;quot;)) {&lt;br /&gt;
            System.out.println(message.getHeaders().get(&amp;quot;springintegration_jms_type&amp;quot;));&lt;br /&gt;
            list.add(&amp;quot;QueueChanneOut1&amp;quot;);&lt;br /&gt;
            list.add(&amp;quot;QueueChanneOut2&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        return list;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Ver también==&lt;br /&gt;
* [http://code.google.com/p/dosideas-aplicaciones-modelo/source/browse/#svn Descargar con svn de nuestro proyecto en google-code la aplicación demo de Spring Integration]&lt;br /&gt;
* [http://www.dosideas.com/descargas/category/2-spring-framework.html?download=29%3Ap Descargar un proyecto con varios ejemplos de Spring Integration]&lt;br /&gt;
* [http://static.springsource.org/spring-integration/reference/htmlsingle/spring-integration-reference.html Manual de referencia de Spring Integration]&lt;br /&gt;
&lt;br /&gt;
[[Category:Spring Framework]]&lt;br /&gt;
[[Category:JMS]]&lt;/div&gt;</summary>
		<author><name>201.251.182.130</name></author>	</entry>

	<entry>
		<id>https://dosideas.com/wiki/index.php?title=Spring_Integration&amp;diff=5849</id>
		<title>Spring Integration</title>
		<link rel="alternate" type="text/html" href="https://dosideas.com/wiki/index.php?title=Spring_Integration&amp;diff=5849"/>
				<updated>2011-07-07T14:23:48Z</updated>
		
		<summary type="html">&lt;p&gt;201.251.182.130: /* Ver también */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[http://www.springsource.org/spring-integration Spring Integration] es un producto relativamente desconocido del Spring.&lt;br /&gt;
Brinda una extensión a Spring para soportar los [http://www.eaipatterns.com/ Patrones de Integración Corporativos] en pocas palabras es un [http://en.wikipedia.org/wiki/Enterprise_service_bus  ESB] liviano montado sobre el contenedor de Spring e independiente del Servidor de aplicaciones. Permite utilizar mensajería dentro de una aplicación Spring, y se integra con sistemas externos a través de adaptadores. Se basa en el concepto de &amp;quot;mensajes&amp;quot; para intercambiar datos entre distintos componentes.&lt;br /&gt;
&lt;br /&gt;
==Conceptos y componentes básicos==&lt;br /&gt;
&lt;br /&gt;
===Conceptos===&lt;br /&gt;
&lt;br /&gt;
* '''Channel (MessageChannel)''', representa un canal lógico por donde se reciben o se envían mensajes.&lt;br /&gt;
&lt;br /&gt;
* '''Channel-adapter''', representa el adaptador entre el canal lógico y una implementación física de ese canal. &lt;br /&gt;
&lt;br /&gt;
* '''Bridge''', se encarga de redireccionar todos los mensajes del canal de entrada hacia un canal de salida.&lt;br /&gt;
&lt;br /&gt;
* '''Router''', se encarga de redireccionar los mensajes que llegan a un canal de entrada hacia uno o varios canales de salida, dependiendo de ciertas condiciones.&lt;br /&gt;
&lt;br /&gt;
* '''Splitter''', se encarga de separar el contenido de un mensaje en muchos mensajes.&lt;br /&gt;
&lt;br /&gt;
* '''Transformer''', se encarga de transformar el formato del contenido del mensaje.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Componentes===&lt;br /&gt;
&lt;br /&gt;
* '''Message''', esta compuesto por una cabecera (headers) y por un cuerpo (Payload). &lt;br /&gt;
&lt;br /&gt;
* '''MessageChannel''', provee métodos para enviar y recibir. &lt;br /&gt;
&lt;br /&gt;
* '''MessageEndpoint''', Conecta un Handler a un MessageChannel de entrada o/y a uno de salida.&lt;br /&gt;
&lt;br /&gt;
* '''MessageHandler''', interfaz que permite transformer, rutear y en general “tartar” cualquier mensaje de Entrada.&lt;br /&gt;
&lt;br /&gt;
* '''Channel Adapters''', se usan para enviar y recibir mensajes a sistemas externos.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Adaptadores==&lt;br /&gt;
&lt;br /&gt;
* [http://static.springsource.org/spring-integration/docs/2.0.4.RELEASE/reference/htmlsingle/#ip TCP y UDP]&lt;br /&gt;
* [http://static.springsource.org/spring-integration/docs/2.0.4.RELEASE/reference/htmlsingle/#http HTTP]&lt;br /&gt;
* [http://static.springsource.org/spring-integration/docs/2.0.4.RELEASE/reference/htmlsingle/#feed RSS/ATOM]&lt;br /&gt;
* [http://static.springsource.org/spring-integration/docs/2.0.4.RELEASE/reference/htmlsingle/#ws Web Services]&lt;br /&gt;
* [http://static.springsource.org/spring-integration/docs/2.0.4.RELEASE/reference/htmlsingle/#mail Mail (POP3, IMAP, SMTP)]&lt;br /&gt;
* [http://static.springsource.org/spring-integration/docs/2.0.4.RELEASE/reference/htmlsingle/#jms JMS]&lt;br /&gt;
* [http://static.springsource.org/spring-integration/docs/2.0.4.RELEASE/reference/htmlsingle/#jdbc JDBC]&lt;br /&gt;
* [http://static.springsource.org/spring-integration/docs/2.0.4.RELEASE/reference/htmlsingle/#jmx JMX]&lt;br /&gt;
* [http://static.springsource.org/spring-integration/docs/2.0.4.RELEASE/reference/htmlsingle/#rmi RMI]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Taller ==&lt;br /&gt;
&lt;br /&gt;
{{curso|url=http://www.dosideas.com/cursos/course/view.php?id=12|nombre=Introducción a Spring Integration}}&lt;br /&gt;
&lt;br /&gt;
== Ejemplos ==&lt;br /&gt;
&lt;br /&gt;
=== Configuración de canales ===&lt;br /&gt;
[[Spring Integration]] se basa en ''canales'', lugares en donde se consumen o envian mensajes. Estos canales pueden ser colas [[JMS]] u otros medios, como clases propias. La siguiente definición de canales se usa en los ejemplos que siguen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
&amp;lt;integration:channel id=&amp;quot;QueueChanneIn&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;jms:message-driven-channel-adapter connection-factory=&amp;quot;PruebaQueueConnectionFactory&amp;quot; &lt;br /&gt;
destination-name=&amp;quot;jms/Queue-in&amp;quot; destination-resolver=&amp;quot;jmsDestinationResolver&amp;quot; &lt;br /&gt;
channel=&amp;quot;QueueChanneIn&amp;quot; acknowledge=&amp;quot;auto&amp;quot; concurrent-consumers=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;integration:channel id=&amp;quot;QueueChanneOut1&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;jms:outbound-channel-adapter jms-template=&amp;quot;jmsQueueTemplateOut1&amp;quot; channel=&amp;quot;QueueChanneOut1&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;integration:channel id=&amp;quot;QueueChanneOut2&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;jms:outbound-channel-adapter jms-template=&amp;quot;jmsQueueTemplateOut2&amp;quot; channel=&amp;quot;QueueChanneOut2&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===stdout-channel-adapter===&lt;br /&gt;
Podemos consumir un mensaje de una cola y mostrarlo por consola. Para esto es necesario configurar un '''stdout-channel-adapter''', el cual se encargará de procesar los mensajes. Luego, se crea un '''bridge''' que asocia un canal de entrada con este adaptador. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
&amp;lt;stream:stdout-channel-adapter id=&amp;quot;stdout&amp;quot; append-newline=&amp;quot;true&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;integration:bridge id=&amp;quot;echo&amp;quot; input-channel=&amp;quot;QueueChanneIn&amp;quot; output-channel=&amp;quot;stdout&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===recipient-list-router===&lt;br /&gt;
Podemos consumir un mensaje de una cola y enviarlo a una lista fija de canales de destino. En este ejemplo creamos un '''recipient-list-router''', el cual consume mensajes de un canal de entrada y los envia a dos canales de destino distintos. Entonces, cada mensaje que llegue al canal de entrada será derivado a dos canales de destino. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
&amp;lt;integration:recipient-list-router input-channel=&amp;quot;QueueChanneIn&amp;quot; apply-sequence=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;integration:recipient channel=&amp;quot;QueueChanneOut1&amp;quot;/&amp;gt;&lt;br /&gt;
            &amp;lt;integration:recipient channel=&amp;quot;QueueChanneOut2&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/integration:recipient-list-router&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===header-value-router===&lt;br /&gt;
Podemos consumir un mensaje de una cola y enviarlo a una cola especifica dependiendo del valor de un atributo del header del mensaje. De esta manera, configuramos un '''header-value-router''', el cual contiene el canal de entrada y el nombre del atributo del encabezado que se comprobará. Luego, se realiza el mapeo entre los posibles valores de este encabezado y algún canal de destino. Si llega un mensaje que coincida este mapeo, será enviado a ese canal de destino.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
&amp;lt;integration:header-value-router input-channel=&amp;quot;QueueChanneIn&amp;quot; &lt;br /&gt;
header-name=&amp;quot;springintegration_jms_type&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;integration:mapping value=&amp;quot;Out1&amp;quot; channel=&amp;quot;QueueChanneOut1&amp;quot;/&amp;gt;&lt;br /&gt;
        &amp;lt;integration:mapping value=&amp;quot;Out2&amp;quot; channel=&amp;quot;QueueChanneOut2&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/integration:header-value-router&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===router===&lt;br /&gt;
Podemos consumir un mensaje de una cola y enviarlo a una lista de colas de salida utilizando un pojo para determinar a que colas enviarlo. En este ejemplo, creamos un '''router''' que será implementado por la clase &amp;quot;MultiDestino&amp;quot;. Esta clase devuelve una lista de nombres de canales hacia donde se derivará el mensaje.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
&amp;lt;integration:router input-channel=&amp;quot;QueueChanneIn&amp;quot; ref=&amp;quot;multiDestino&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;bean id=&amp;quot;multiDestino&amp;quot; class=&amp;quot;com.dosideas.springintegration.MultiDestino&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java&amp;gt;&lt;br /&gt;
public class MultiDestino {&lt;br /&gt;
&lt;br /&gt;
    @Router&lt;br /&gt;
    public List&amp;lt;String&amp;gt; resolverChannel(GenericMessage message) throws JMSException {&lt;br /&gt;
&lt;br /&gt;
        List&amp;lt;String&amp;gt; list = new ArrayList&amp;lt;String&amp;gt;();&lt;br /&gt;
        if(message.getHeaders().get(&amp;quot;springintegration_jms_type&amp;quot;).equals(&amp;quot;Out1&amp;quot;)) {&lt;br /&gt;
            System.out.println(message.getHeaders().get(&amp;quot;springintegration_jms_type&amp;quot;));&lt;br /&gt;
            list.add(&amp;quot;QueueChanneOut1&amp;quot;);&lt;br /&gt;
            &lt;br /&gt;
        }&lt;br /&gt;
        else if(message.getHeaders().get(&amp;quot;springintegration_jms_type&amp;quot;).equals(&amp;quot;Out2&amp;quot;)) {&lt;br /&gt;
            System.out.println(message.getHeaders().get(&amp;quot;springintegration_jms_type&amp;quot;));&lt;br /&gt;
            list.add(&amp;quot;QueueChanneOut2&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
        else if(message.getHeaders().get(&amp;quot;springintegration_jms_type&amp;quot;).equals(&amp;quot;Multi&amp;quot;)) {&lt;br /&gt;
            System.out.println(message.getHeaders().get(&amp;quot;springintegration_jms_type&amp;quot;));&lt;br /&gt;
            list.add(&amp;quot;QueueChanneOut1&amp;quot;);&lt;br /&gt;
            list.add(&amp;quot;QueueChanneOut2&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        return list;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Ver también==&lt;br /&gt;
* [http://code.google.com/p/dosideas-aplicaciones-modelo/source/browse/#svn Descarga de nuestro proyecto en google-code la aplicación demo de Spring Integration]&lt;br /&gt;
* [http://www.dosideas.com/descargas/category/2-spring-framework.html?download=29%3Ap Descargar un proyecto con varios ejemplos de Spring Integration]&lt;br /&gt;
* [http://static.springsource.org/spring-integration/reference/htmlsingle/spring-integration-reference.html Manual de referencia de Spring Integration]&lt;br /&gt;
&lt;br /&gt;
[[Category:Spring Framework]]&lt;br /&gt;
[[Category:JMS]]&lt;/div&gt;</summary>
		<author><name>201.251.182.130</name></author>	</entry>

	<entry>
		<id>https://dosideas.com/wiki/index.php?title=Spring_Integration&amp;diff=5848</id>
		<title>Spring Integration</title>
		<link rel="alternate" type="text/html" href="https://dosideas.com/wiki/index.php?title=Spring_Integration&amp;diff=5848"/>
				<updated>2011-07-07T14:23:21Z</updated>
		
		<summary type="html">&lt;p&gt;201.251.182.130: /* Ver también */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[http://www.springsource.org/spring-integration Spring Integration] es un producto relativamente desconocido del Spring.&lt;br /&gt;
Brinda una extensión a Spring para soportar los [http://www.eaipatterns.com/ Patrones de Integración Corporativos] en pocas palabras es un [http://en.wikipedia.org/wiki/Enterprise_service_bus  ESB] liviano montado sobre el contenedor de Spring e independiente del Servidor de aplicaciones. Permite utilizar mensajería dentro de una aplicación Spring, y se integra con sistemas externos a través de adaptadores. Se basa en el concepto de &amp;quot;mensajes&amp;quot; para intercambiar datos entre distintos componentes.&lt;br /&gt;
&lt;br /&gt;
==Conceptos y componentes básicos==&lt;br /&gt;
&lt;br /&gt;
===Conceptos===&lt;br /&gt;
&lt;br /&gt;
* '''Channel (MessageChannel)''', representa un canal lógico por donde se reciben o se envían mensajes.&lt;br /&gt;
&lt;br /&gt;
* '''Channel-adapter''', representa el adaptador entre el canal lógico y una implementación física de ese canal. &lt;br /&gt;
&lt;br /&gt;
* '''Bridge''', se encarga de redireccionar todos los mensajes del canal de entrada hacia un canal de salida.&lt;br /&gt;
&lt;br /&gt;
* '''Router''', se encarga de redireccionar los mensajes que llegan a un canal de entrada hacia uno o varios canales de salida, dependiendo de ciertas condiciones.&lt;br /&gt;
&lt;br /&gt;
* '''Splitter''', se encarga de separar el contenido de un mensaje en muchos mensajes.&lt;br /&gt;
&lt;br /&gt;
* '''Transformer''', se encarga de transformar el formato del contenido del mensaje.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Componentes===&lt;br /&gt;
&lt;br /&gt;
* '''Message''', esta compuesto por una cabecera (headers) y por un cuerpo (Payload). &lt;br /&gt;
&lt;br /&gt;
* '''MessageChannel''', provee métodos para enviar y recibir. &lt;br /&gt;
&lt;br /&gt;
* '''MessageEndpoint''', Conecta un Handler a un MessageChannel de entrada o/y a uno de salida.&lt;br /&gt;
&lt;br /&gt;
* '''MessageHandler''', interfaz que permite transformer, rutear y en general “tartar” cualquier mensaje de Entrada.&lt;br /&gt;
&lt;br /&gt;
* '''Channel Adapters''', se usan para enviar y recibir mensajes a sistemas externos.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Adaptadores==&lt;br /&gt;
&lt;br /&gt;
* [http://static.springsource.org/spring-integration/docs/2.0.4.RELEASE/reference/htmlsingle/#ip TCP y UDP]&lt;br /&gt;
* [http://static.springsource.org/spring-integration/docs/2.0.4.RELEASE/reference/htmlsingle/#http HTTP]&lt;br /&gt;
* [http://static.springsource.org/spring-integration/docs/2.0.4.RELEASE/reference/htmlsingle/#feed RSS/ATOM]&lt;br /&gt;
* [http://static.springsource.org/spring-integration/docs/2.0.4.RELEASE/reference/htmlsingle/#ws Web Services]&lt;br /&gt;
* [http://static.springsource.org/spring-integration/docs/2.0.4.RELEASE/reference/htmlsingle/#mail Mail (POP3, IMAP, SMTP)]&lt;br /&gt;
* [http://static.springsource.org/spring-integration/docs/2.0.4.RELEASE/reference/htmlsingle/#jms JMS]&lt;br /&gt;
* [http://static.springsource.org/spring-integration/docs/2.0.4.RELEASE/reference/htmlsingle/#jdbc JDBC]&lt;br /&gt;
* [http://static.springsource.org/spring-integration/docs/2.0.4.RELEASE/reference/htmlsingle/#jmx JMX]&lt;br /&gt;
* [http://static.springsource.org/spring-integration/docs/2.0.4.RELEASE/reference/htmlsingle/#rmi RMI]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Taller ==&lt;br /&gt;
&lt;br /&gt;
{{curso|url=http://www.dosideas.com/cursos/course/view.php?id=12|nombre=Introducción a Spring Integration}}&lt;br /&gt;
&lt;br /&gt;
== Ejemplos ==&lt;br /&gt;
&lt;br /&gt;
=== Configuración de canales ===&lt;br /&gt;
[[Spring Integration]] se basa en ''canales'', lugares en donde se consumen o envian mensajes. Estos canales pueden ser colas [[JMS]] u otros medios, como clases propias. La siguiente definición de canales se usa en los ejemplos que siguen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
&amp;lt;integration:channel id=&amp;quot;QueueChanneIn&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;jms:message-driven-channel-adapter connection-factory=&amp;quot;PruebaQueueConnectionFactory&amp;quot; &lt;br /&gt;
destination-name=&amp;quot;jms/Queue-in&amp;quot; destination-resolver=&amp;quot;jmsDestinationResolver&amp;quot; &lt;br /&gt;
channel=&amp;quot;QueueChanneIn&amp;quot; acknowledge=&amp;quot;auto&amp;quot; concurrent-consumers=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;integration:channel id=&amp;quot;QueueChanneOut1&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;jms:outbound-channel-adapter jms-template=&amp;quot;jmsQueueTemplateOut1&amp;quot; channel=&amp;quot;QueueChanneOut1&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;integration:channel id=&amp;quot;QueueChanneOut2&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;jms:outbound-channel-adapter jms-template=&amp;quot;jmsQueueTemplateOut2&amp;quot; channel=&amp;quot;QueueChanneOut2&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===stdout-channel-adapter===&lt;br /&gt;
Podemos consumir un mensaje de una cola y mostrarlo por consola. Para esto es necesario configurar un '''stdout-channel-adapter''', el cual se encargará de procesar los mensajes. Luego, se crea un '''bridge''' que asocia un canal de entrada con este adaptador. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
&amp;lt;stream:stdout-channel-adapter id=&amp;quot;stdout&amp;quot; append-newline=&amp;quot;true&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;integration:bridge id=&amp;quot;echo&amp;quot; input-channel=&amp;quot;QueueChanneIn&amp;quot; output-channel=&amp;quot;stdout&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===recipient-list-router===&lt;br /&gt;
Podemos consumir un mensaje de una cola y enviarlo a una lista fija de canales de destino. En este ejemplo creamos un '''recipient-list-router''', el cual consume mensajes de un canal de entrada y los envia a dos canales de destino distintos. Entonces, cada mensaje que llegue al canal de entrada será derivado a dos canales de destino. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
&amp;lt;integration:recipient-list-router input-channel=&amp;quot;QueueChanneIn&amp;quot; apply-sequence=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;integration:recipient channel=&amp;quot;QueueChanneOut1&amp;quot;/&amp;gt;&lt;br /&gt;
            &amp;lt;integration:recipient channel=&amp;quot;QueueChanneOut2&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/integration:recipient-list-router&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===header-value-router===&lt;br /&gt;
Podemos consumir un mensaje de una cola y enviarlo a una cola especifica dependiendo del valor de un atributo del header del mensaje. De esta manera, configuramos un '''header-value-router''', el cual contiene el canal de entrada y el nombre del atributo del encabezado que se comprobará. Luego, se realiza el mapeo entre los posibles valores de este encabezado y algún canal de destino. Si llega un mensaje que coincida este mapeo, será enviado a ese canal de destino.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
&amp;lt;integration:header-value-router input-channel=&amp;quot;QueueChanneIn&amp;quot; &lt;br /&gt;
header-name=&amp;quot;springintegration_jms_type&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;integration:mapping value=&amp;quot;Out1&amp;quot; channel=&amp;quot;QueueChanneOut1&amp;quot;/&amp;gt;&lt;br /&gt;
        &amp;lt;integration:mapping value=&amp;quot;Out2&amp;quot; channel=&amp;quot;QueueChanneOut2&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/integration:header-value-router&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===router===&lt;br /&gt;
Podemos consumir un mensaje de una cola y enviarlo a una lista de colas de salida utilizando un pojo para determinar a que colas enviarlo. En este ejemplo, creamos un '''router''' que será implementado por la clase &amp;quot;MultiDestino&amp;quot;. Esta clase devuelve una lista de nombres de canales hacia donde se derivará el mensaje.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
&amp;lt;integration:router input-channel=&amp;quot;QueueChanneIn&amp;quot; ref=&amp;quot;multiDestino&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;bean id=&amp;quot;multiDestino&amp;quot; class=&amp;quot;com.dosideas.springintegration.MultiDestino&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java&amp;gt;&lt;br /&gt;
public class MultiDestino {&lt;br /&gt;
&lt;br /&gt;
    @Router&lt;br /&gt;
    public List&amp;lt;String&amp;gt; resolverChannel(GenericMessage message) throws JMSException {&lt;br /&gt;
&lt;br /&gt;
        List&amp;lt;String&amp;gt; list = new ArrayList&amp;lt;String&amp;gt;();&lt;br /&gt;
        if(message.getHeaders().get(&amp;quot;springintegration_jms_type&amp;quot;).equals(&amp;quot;Out1&amp;quot;)) {&lt;br /&gt;
            System.out.println(message.getHeaders().get(&amp;quot;springintegration_jms_type&amp;quot;));&lt;br /&gt;
            list.add(&amp;quot;QueueChanneOut1&amp;quot;);&lt;br /&gt;
            &lt;br /&gt;
        }&lt;br /&gt;
        else if(message.getHeaders().get(&amp;quot;springintegration_jms_type&amp;quot;).equals(&amp;quot;Out2&amp;quot;)) {&lt;br /&gt;
            System.out.println(message.getHeaders().get(&amp;quot;springintegration_jms_type&amp;quot;));&lt;br /&gt;
            list.add(&amp;quot;QueueChanneOut2&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
        else if(message.getHeaders().get(&amp;quot;springintegration_jms_type&amp;quot;).equals(&amp;quot;Multi&amp;quot;)) {&lt;br /&gt;
            System.out.println(message.getHeaders().get(&amp;quot;springintegration_jms_type&amp;quot;));&lt;br /&gt;
            list.add(&amp;quot;QueueChanneOut1&amp;quot;);&lt;br /&gt;
            list.add(&amp;quot;QueueChanneOut2&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        return list;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Ver también==&lt;br /&gt;
* [http://code.google.com/p/dosideas-aplicaciones-modelo/source/browse/#svn Descarga de nuestro proyecto en google-code la aplicación demo de Spring Integration]&lt;br /&gt;
* [http://www.dosideas.com/descargas/category/2-spring-framework.html?download=29%3Ap Descargar un proyecto con varios ejemplos de Spring Integration]&lt;br /&gt;
* [http://static.springsource.org/spring-integration/reference/htmlsingle/spring-integration-reference.html Manual de referencia de Spring Integration]&lt;br /&gt;
&lt;br /&gt;
[[Category:Spring Framework]]&lt;br /&gt;
[[Category:JMS]]&lt;br /&gt;
[[Category:JDBC]]&lt;br /&gt;
[[Category:TCP]]&lt;br /&gt;
[[Category:UDP]]&lt;br /&gt;
[[Category:FTP]]&lt;/div&gt;</summary>
		<author><name>201.251.182.130</name></author>	</entry>

	<entry>
		<id>https://dosideas.com/wiki/index.php?title=Spring_Integration&amp;diff=5847</id>
		<title>Spring Integration</title>
		<link rel="alternate" type="text/html" href="https://dosideas.com/wiki/index.php?title=Spring_Integration&amp;diff=5847"/>
				<updated>2011-07-07T14:20:32Z</updated>
		
		<summary type="html">&lt;p&gt;201.251.182.130: /* Ver también */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[http://www.springsource.org/spring-integration Spring Integration] es un producto relativamente desconocido del Spring.&lt;br /&gt;
Brinda una extensión a Spring para soportar los [http://www.eaipatterns.com/ Patrones de Integración Corporativos] en pocas palabras es un [http://en.wikipedia.org/wiki/Enterprise_service_bus  ESB] liviano montado sobre el contenedor de Spring e independiente del Servidor de aplicaciones. Permite utilizar mensajería dentro de una aplicación Spring, y se integra con sistemas externos a través de adaptadores. Se basa en el concepto de &amp;quot;mensajes&amp;quot; para intercambiar datos entre distintos componentes.&lt;br /&gt;
&lt;br /&gt;
==Conceptos y componentes básicos==&lt;br /&gt;
&lt;br /&gt;
===Conceptos===&lt;br /&gt;
&lt;br /&gt;
* '''Channel (MessageChannel)''', representa un canal lógico por donde se reciben o se envían mensajes.&lt;br /&gt;
&lt;br /&gt;
* '''Channel-adapter''', representa el adaptador entre el canal lógico y una implementación física de ese canal. &lt;br /&gt;
&lt;br /&gt;
* '''Bridge''', se encarga de redireccionar todos los mensajes del canal de entrada hacia un canal de salida.&lt;br /&gt;
&lt;br /&gt;
* '''Router''', se encarga de redireccionar los mensajes que llegan a un canal de entrada hacia uno o varios canales de salida, dependiendo de ciertas condiciones.&lt;br /&gt;
&lt;br /&gt;
* '''Splitter''', se encarga de separar el contenido de un mensaje en muchos mensajes.&lt;br /&gt;
&lt;br /&gt;
* '''Transformer''', se encarga de transformar el formato del contenido del mensaje.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Componentes===&lt;br /&gt;
&lt;br /&gt;
* '''Message''', esta compuesto por una cabecera (headers) y por un cuerpo (Payload). &lt;br /&gt;
&lt;br /&gt;
* '''MessageChannel''', provee métodos para enviar y recibir. &lt;br /&gt;
&lt;br /&gt;
* '''MessageEndpoint''', Conecta un Handler a un MessageChannel de entrada o/y a uno de salida.&lt;br /&gt;
&lt;br /&gt;
* '''MessageHandler''', interfaz que permite transformer, rutear y en general “tartar” cualquier mensaje de Entrada.&lt;br /&gt;
&lt;br /&gt;
* '''Channel Adapters''', se usan para enviar y recibir mensajes a sistemas externos.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Adaptadores==&lt;br /&gt;
&lt;br /&gt;
* [http://static.springsource.org/spring-integration/docs/2.0.4.RELEASE/reference/htmlsingle/#ip TCP y UDP]&lt;br /&gt;
* [http://static.springsource.org/spring-integration/docs/2.0.4.RELEASE/reference/htmlsingle/#http HTTP]&lt;br /&gt;
* [http://static.springsource.org/spring-integration/docs/2.0.4.RELEASE/reference/htmlsingle/#feed RSS/ATOM]&lt;br /&gt;
* [http://static.springsource.org/spring-integration/docs/2.0.4.RELEASE/reference/htmlsingle/#ws Web Services]&lt;br /&gt;
* [http://static.springsource.org/spring-integration/docs/2.0.4.RELEASE/reference/htmlsingle/#mail Mail (POP3, IMAP, SMTP)]&lt;br /&gt;
* [http://static.springsource.org/spring-integration/docs/2.0.4.RELEASE/reference/htmlsingle/#jms JMS]&lt;br /&gt;
* [http://static.springsource.org/spring-integration/docs/2.0.4.RELEASE/reference/htmlsingle/#jdbc JDBC]&lt;br /&gt;
* [http://static.springsource.org/spring-integration/docs/2.0.4.RELEASE/reference/htmlsingle/#jmx JMX]&lt;br /&gt;
* [http://static.springsource.org/spring-integration/docs/2.0.4.RELEASE/reference/htmlsingle/#rmi RMI]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Taller ==&lt;br /&gt;
&lt;br /&gt;
{{curso|url=http://www.dosideas.com/cursos/course/view.php?id=12|nombre=Introducción a Spring Integration}}&lt;br /&gt;
&lt;br /&gt;
== Ejemplos ==&lt;br /&gt;
&lt;br /&gt;
=== Configuración de canales ===&lt;br /&gt;
[[Spring Integration]] se basa en ''canales'', lugares en donde se consumen o envian mensajes. Estos canales pueden ser colas [[JMS]] u otros medios, como clases propias. La siguiente definición de canales se usa en los ejemplos que siguen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
&amp;lt;integration:channel id=&amp;quot;QueueChanneIn&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;jms:message-driven-channel-adapter connection-factory=&amp;quot;PruebaQueueConnectionFactory&amp;quot; &lt;br /&gt;
destination-name=&amp;quot;jms/Queue-in&amp;quot; destination-resolver=&amp;quot;jmsDestinationResolver&amp;quot; &lt;br /&gt;
channel=&amp;quot;QueueChanneIn&amp;quot; acknowledge=&amp;quot;auto&amp;quot; concurrent-consumers=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;integration:channel id=&amp;quot;QueueChanneOut1&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;jms:outbound-channel-adapter jms-template=&amp;quot;jmsQueueTemplateOut1&amp;quot; channel=&amp;quot;QueueChanneOut1&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;integration:channel id=&amp;quot;QueueChanneOut2&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;jms:outbound-channel-adapter jms-template=&amp;quot;jmsQueueTemplateOut2&amp;quot; channel=&amp;quot;QueueChanneOut2&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===stdout-channel-adapter===&lt;br /&gt;
Podemos consumir un mensaje de una cola y mostrarlo por consola. Para esto es necesario configurar un '''stdout-channel-adapter''', el cual se encargará de procesar los mensajes. Luego, se crea un '''bridge''' que asocia un canal de entrada con este adaptador. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
&amp;lt;stream:stdout-channel-adapter id=&amp;quot;stdout&amp;quot; append-newline=&amp;quot;true&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;integration:bridge id=&amp;quot;echo&amp;quot; input-channel=&amp;quot;QueueChanneIn&amp;quot; output-channel=&amp;quot;stdout&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===recipient-list-router===&lt;br /&gt;
Podemos consumir un mensaje de una cola y enviarlo a una lista fija de canales de destino. En este ejemplo creamos un '''recipient-list-router''', el cual consume mensajes de un canal de entrada y los envia a dos canales de destino distintos. Entonces, cada mensaje que llegue al canal de entrada será derivado a dos canales de destino. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
&amp;lt;integration:recipient-list-router input-channel=&amp;quot;QueueChanneIn&amp;quot; apply-sequence=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;integration:recipient channel=&amp;quot;QueueChanneOut1&amp;quot;/&amp;gt;&lt;br /&gt;
            &amp;lt;integration:recipient channel=&amp;quot;QueueChanneOut2&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/integration:recipient-list-router&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===header-value-router===&lt;br /&gt;
Podemos consumir un mensaje de una cola y enviarlo a una cola especifica dependiendo del valor de un atributo del header del mensaje. De esta manera, configuramos un '''header-value-router''', el cual contiene el canal de entrada y el nombre del atributo del encabezado que se comprobará. Luego, se realiza el mapeo entre los posibles valores de este encabezado y algún canal de destino. Si llega un mensaje que coincida este mapeo, será enviado a ese canal de destino.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
&amp;lt;integration:header-value-router input-channel=&amp;quot;QueueChanneIn&amp;quot; &lt;br /&gt;
header-name=&amp;quot;springintegration_jms_type&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;integration:mapping value=&amp;quot;Out1&amp;quot; channel=&amp;quot;QueueChanneOut1&amp;quot;/&amp;gt;&lt;br /&gt;
        &amp;lt;integration:mapping value=&amp;quot;Out2&amp;quot; channel=&amp;quot;QueueChanneOut2&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/integration:header-value-router&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===router===&lt;br /&gt;
Podemos consumir un mensaje de una cola y enviarlo a una lista de colas de salida utilizando un pojo para determinar a que colas enviarlo. En este ejemplo, creamos un '''router''' que será implementado por la clase &amp;quot;MultiDestino&amp;quot;. Esta clase devuelve una lista de nombres de canales hacia donde se derivará el mensaje.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
&amp;lt;integration:router input-channel=&amp;quot;QueueChanneIn&amp;quot; ref=&amp;quot;multiDestino&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;bean id=&amp;quot;multiDestino&amp;quot; class=&amp;quot;com.dosideas.springintegration.MultiDestino&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java&amp;gt;&lt;br /&gt;
public class MultiDestino {&lt;br /&gt;
&lt;br /&gt;
    @Router&lt;br /&gt;
    public List&amp;lt;String&amp;gt; resolverChannel(GenericMessage message) throws JMSException {&lt;br /&gt;
&lt;br /&gt;
        List&amp;lt;String&amp;gt; list = new ArrayList&amp;lt;String&amp;gt;();&lt;br /&gt;
        if(message.getHeaders().get(&amp;quot;springintegration_jms_type&amp;quot;).equals(&amp;quot;Out1&amp;quot;)) {&lt;br /&gt;
            System.out.println(message.getHeaders().get(&amp;quot;springintegration_jms_type&amp;quot;));&lt;br /&gt;
            list.add(&amp;quot;QueueChanneOut1&amp;quot;);&lt;br /&gt;
            &lt;br /&gt;
        }&lt;br /&gt;
        else if(message.getHeaders().get(&amp;quot;springintegration_jms_type&amp;quot;).equals(&amp;quot;Out2&amp;quot;)) {&lt;br /&gt;
            System.out.println(message.getHeaders().get(&amp;quot;springintegration_jms_type&amp;quot;));&lt;br /&gt;
            list.add(&amp;quot;QueueChanneOut2&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
        else if(message.getHeaders().get(&amp;quot;springintegration_jms_type&amp;quot;).equals(&amp;quot;Multi&amp;quot;)) {&lt;br /&gt;
            System.out.println(message.getHeaders().get(&amp;quot;springintegration_jms_type&amp;quot;));&lt;br /&gt;
            list.add(&amp;quot;QueueChanneOut1&amp;quot;);&lt;br /&gt;
            list.add(&amp;quot;QueueChanneOut2&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        return list;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Ver también==&lt;br /&gt;
* [https://code.google.com/p/dosideas-aplicaciones-modelo/source/browse/#svn Descarga de nuestro proyecto en google-code la aplicación demo de Spring Integration]&lt;br /&gt;
* [http://www.dosideas.com/descargas/category/2-spring-framework.html?download=29%3Ap Descargar un proyecto con varios ejemplos de Spring Integration]&lt;br /&gt;
* [http://static.springsource.org/spring-integration/reference/htmlsingle/spring-integration-reference.html Manual de referencia de Spring Integration]&lt;br /&gt;
&lt;br /&gt;
[[Category:Spring Framework]]&lt;br /&gt;
[[Category:JMS]]&lt;br /&gt;
[[Category:JDBC]]&lt;br /&gt;
[[Category:TCP]]&lt;br /&gt;
[[Category:UDP]]&lt;br /&gt;
[[Category:FTP]]&lt;/div&gt;</summary>
		<author><name>201.251.182.130</name></author>	</entry>

	<entry>
		<id>https://dosideas.com/wiki/index.php?title=Spring_Integration&amp;diff=5846</id>
		<title>Spring Integration</title>
		<link rel="alternate" type="text/html" href="https://dosideas.com/wiki/index.php?title=Spring_Integration&amp;diff=5846"/>
				<updated>2011-07-07T14:18:54Z</updated>
		
		<summary type="html">&lt;p&gt;201.251.182.130: /* Ver también */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[http://www.springsource.org/spring-integration Spring Integration] es un producto relativamente desconocido del Spring.&lt;br /&gt;
Brinda una extensión a Spring para soportar los [http://www.eaipatterns.com/ Patrones de Integración Corporativos] en pocas palabras es un [http://en.wikipedia.org/wiki/Enterprise_service_bus  ESB] liviano montado sobre el contenedor de Spring e independiente del Servidor de aplicaciones. Permite utilizar mensajería dentro de una aplicación Spring, y se integra con sistemas externos a través de adaptadores. Se basa en el concepto de &amp;quot;mensajes&amp;quot; para intercambiar datos entre distintos componentes.&lt;br /&gt;
&lt;br /&gt;
==Conceptos y componentes básicos==&lt;br /&gt;
&lt;br /&gt;
===Conceptos===&lt;br /&gt;
&lt;br /&gt;
* '''Channel (MessageChannel)''', representa un canal lógico por donde se reciben o se envían mensajes.&lt;br /&gt;
&lt;br /&gt;
* '''Channel-adapter''', representa el adaptador entre el canal lógico y una implementación física de ese canal. &lt;br /&gt;
&lt;br /&gt;
* '''Bridge''', se encarga de redireccionar todos los mensajes del canal de entrada hacia un canal de salida.&lt;br /&gt;
&lt;br /&gt;
* '''Router''', se encarga de redireccionar los mensajes que llegan a un canal de entrada hacia uno o varios canales de salida, dependiendo de ciertas condiciones.&lt;br /&gt;
&lt;br /&gt;
* '''Splitter''', se encarga de separar el contenido de un mensaje en muchos mensajes.&lt;br /&gt;
&lt;br /&gt;
* '''Transformer''', se encarga de transformar el formato del contenido del mensaje.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Componentes===&lt;br /&gt;
&lt;br /&gt;
* '''Message''', esta compuesto por una cabecera (headers) y por un cuerpo (Payload). &lt;br /&gt;
&lt;br /&gt;
* '''MessageChannel''', provee métodos para enviar y recibir. &lt;br /&gt;
&lt;br /&gt;
* '''MessageEndpoint''', Conecta un Handler a un MessageChannel de entrada o/y a uno de salida.&lt;br /&gt;
&lt;br /&gt;
* '''MessageHandler''', interfaz que permite transformer, rutear y en general “tartar” cualquier mensaje de Entrada.&lt;br /&gt;
&lt;br /&gt;
* '''Channel Adapters''', se usan para enviar y recibir mensajes a sistemas externos.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Adaptadores==&lt;br /&gt;
&lt;br /&gt;
* [http://static.springsource.org/spring-integration/docs/2.0.4.RELEASE/reference/htmlsingle/#ip TCP y UDP]&lt;br /&gt;
* [http://static.springsource.org/spring-integration/docs/2.0.4.RELEASE/reference/htmlsingle/#http HTTP]&lt;br /&gt;
* [http://static.springsource.org/spring-integration/docs/2.0.4.RELEASE/reference/htmlsingle/#feed RSS/ATOM]&lt;br /&gt;
* [http://static.springsource.org/spring-integration/docs/2.0.4.RELEASE/reference/htmlsingle/#ws Web Services]&lt;br /&gt;
* [http://static.springsource.org/spring-integration/docs/2.0.4.RELEASE/reference/htmlsingle/#mail Mail (POP3, IMAP, SMTP)]&lt;br /&gt;
* [http://static.springsource.org/spring-integration/docs/2.0.4.RELEASE/reference/htmlsingle/#jms JMS]&lt;br /&gt;
* [http://static.springsource.org/spring-integration/docs/2.0.4.RELEASE/reference/htmlsingle/#jdbc JDBC]&lt;br /&gt;
* [http://static.springsource.org/spring-integration/docs/2.0.4.RELEASE/reference/htmlsingle/#jmx JMX]&lt;br /&gt;
* [http://static.springsource.org/spring-integration/docs/2.0.4.RELEASE/reference/htmlsingle/#rmi RMI]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Taller ==&lt;br /&gt;
&lt;br /&gt;
{{curso|url=http://www.dosideas.com/cursos/course/view.php?id=12|nombre=Introducción a Spring Integration}}&lt;br /&gt;
&lt;br /&gt;
== Ejemplos ==&lt;br /&gt;
&lt;br /&gt;
=== Configuración de canales ===&lt;br /&gt;
[[Spring Integration]] se basa en ''canales'', lugares en donde se consumen o envian mensajes. Estos canales pueden ser colas [[JMS]] u otros medios, como clases propias. La siguiente definición de canales se usa en los ejemplos que siguen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
&amp;lt;integration:channel id=&amp;quot;QueueChanneIn&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;jms:message-driven-channel-adapter connection-factory=&amp;quot;PruebaQueueConnectionFactory&amp;quot; &lt;br /&gt;
destination-name=&amp;quot;jms/Queue-in&amp;quot; destination-resolver=&amp;quot;jmsDestinationResolver&amp;quot; &lt;br /&gt;
channel=&amp;quot;QueueChanneIn&amp;quot; acknowledge=&amp;quot;auto&amp;quot; concurrent-consumers=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;integration:channel id=&amp;quot;QueueChanneOut1&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;jms:outbound-channel-adapter jms-template=&amp;quot;jmsQueueTemplateOut1&amp;quot; channel=&amp;quot;QueueChanneOut1&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;integration:channel id=&amp;quot;QueueChanneOut2&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;jms:outbound-channel-adapter jms-template=&amp;quot;jmsQueueTemplateOut2&amp;quot; channel=&amp;quot;QueueChanneOut2&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===stdout-channel-adapter===&lt;br /&gt;
Podemos consumir un mensaje de una cola y mostrarlo por consola. Para esto es necesario configurar un '''stdout-channel-adapter''', el cual se encargará de procesar los mensajes. Luego, se crea un '''bridge''' que asocia un canal de entrada con este adaptador. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
&amp;lt;stream:stdout-channel-adapter id=&amp;quot;stdout&amp;quot; append-newline=&amp;quot;true&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;integration:bridge id=&amp;quot;echo&amp;quot; input-channel=&amp;quot;QueueChanneIn&amp;quot; output-channel=&amp;quot;stdout&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===recipient-list-router===&lt;br /&gt;
Podemos consumir un mensaje de una cola y enviarlo a una lista fija de canales de destino. En este ejemplo creamos un '''recipient-list-router''', el cual consume mensajes de un canal de entrada y los envia a dos canales de destino distintos. Entonces, cada mensaje que llegue al canal de entrada será derivado a dos canales de destino. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
&amp;lt;integration:recipient-list-router input-channel=&amp;quot;QueueChanneIn&amp;quot; apply-sequence=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;integration:recipient channel=&amp;quot;QueueChanneOut1&amp;quot;/&amp;gt;&lt;br /&gt;
            &amp;lt;integration:recipient channel=&amp;quot;QueueChanneOut2&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/integration:recipient-list-router&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===header-value-router===&lt;br /&gt;
Podemos consumir un mensaje de una cola y enviarlo a una cola especifica dependiendo del valor de un atributo del header del mensaje. De esta manera, configuramos un '''header-value-router''', el cual contiene el canal de entrada y el nombre del atributo del encabezado que se comprobará. Luego, se realiza el mapeo entre los posibles valores de este encabezado y algún canal de destino. Si llega un mensaje que coincida este mapeo, será enviado a ese canal de destino.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
&amp;lt;integration:header-value-router input-channel=&amp;quot;QueueChanneIn&amp;quot; &lt;br /&gt;
header-name=&amp;quot;springintegration_jms_type&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;integration:mapping value=&amp;quot;Out1&amp;quot; channel=&amp;quot;QueueChanneOut1&amp;quot;/&amp;gt;&lt;br /&gt;
        &amp;lt;integration:mapping value=&amp;quot;Out2&amp;quot; channel=&amp;quot;QueueChanneOut2&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/integration:header-value-router&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===router===&lt;br /&gt;
Podemos consumir un mensaje de una cola y enviarlo a una lista de colas de salida utilizando un pojo para determinar a que colas enviarlo. En este ejemplo, creamos un '''router''' que será implementado por la clase &amp;quot;MultiDestino&amp;quot;. Esta clase devuelve una lista de nombres de canales hacia donde se derivará el mensaje.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
&amp;lt;integration:router input-channel=&amp;quot;QueueChanneIn&amp;quot; ref=&amp;quot;multiDestino&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;bean id=&amp;quot;multiDestino&amp;quot; class=&amp;quot;com.dosideas.springintegration.MultiDestino&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java&amp;gt;&lt;br /&gt;
public class MultiDestino {&lt;br /&gt;
&lt;br /&gt;
    @Router&lt;br /&gt;
    public List&amp;lt;String&amp;gt; resolverChannel(GenericMessage message) throws JMSException {&lt;br /&gt;
&lt;br /&gt;
        List&amp;lt;String&amp;gt; list = new ArrayList&amp;lt;String&amp;gt;();&lt;br /&gt;
        if(message.getHeaders().get(&amp;quot;springintegration_jms_type&amp;quot;).equals(&amp;quot;Out1&amp;quot;)) {&lt;br /&gt;
            System.out.println(message.getHeaders().get(&amp;quot;springintegration_jms_type&amp;quot;));&lt;br /&gt;
            list.add(&amp;quot;QueueChanneOut1&amp;quot;);&lt;br /&gt;
            &lt;br /&gt;
        }&lt;br /&gt;
        else if(message.getHeaders().get(&amp;quot;springintegration_jms_type&amp;quot;).equals(&amp;quot;Out2&amp;quot;)) {&lt;br /&gt;
            System.out.println(message.getHeaders().get(&amp;quot;springintegration_jms_type&amp;quot;));&lt;br /&gt;
            list.add(&amp;quot;QueueChanneOut2&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
        else if(message.getHeaders().get(&amp;quot;springintegration_jms_type&amp;quot;).equals(&amp;quot;Multi&amp;quot;)) {&lt;br /&gt;
            System.out.println(message.getHeaders().get(&amp;quot;springintegration_jms_type&amp;quot;));&lt;br /&gt;
            list.add(&amp;quot;QueueChanneOut1&amp;quot;);&lt;br /&gt;
            list.add(&amp;quot;QueueChanneOut2&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        return list;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Ver también==&lt;br /&gt;
* [http://dosideas-aplicaciones-modelo.googlecode.com/svn/spring-integration-demo/trunk Descarga de nuestro proyecto en google-code la aplicación demo de Spring Integration]&lt;br /&gt;
* [http://www.dosideas.com/descargas/category/2-spring-framework.html?download=29%3Ap Descargar un proyecto con varios ejemplos de Spring Integration]&lt;br /&gt;
* [http://static.springsource.org/spring-integration/reference/htmlsingle/spring-integration-reference.html Manual de referencia de Spring Integration]&lt;br /&gt;
&lt;br /&gt;
[[Category:Spring Framework]]&lt;br /&gt;
[[Category:JMS]]&lt;br /&gt;
[[Category:JDBC]]&lt;br /&gt;
[[Category:TCP]]&lt;br /&gt;
[[Category:UDP]]&lt;br /&gt;
[[Category:FTP]]&lt;/div&gt;</summary>
		<author><name>201.251.182.130</name></author>	</entry>

	<entry>
		<id>https://dosideas.com/wiki/index.php?title=Spring_Integration&amp;diff=5845</id>
		<title>Spring Integration</title>
		<link rel="alternate" type="text/html" href="https://dosideas.com/wiki/index.php?title=Spring_Integration&amp;diff=5845"/>
				<updated>2011-07-07T14:17:21Z</updated>
		
		<summary type="html">&lt;p&gt;201.251.182.130: /* Ver también */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[http://www.springsource.org/spring-integration Spring Integration] es un producto relativamente desconocido del Spring.&lt;br /&gt;
Brinda una extensión a Spring para soportar los [http://www.eaipatterns.com/ Patrones de Integración Corporativos] en pocas palabras es un [http://en.wikipedia.org/wiki/Enterprise_service_bus  ESB] liviano montado sobre el contenedor de Spring e independiente del Servidor de aplicaciones. Permite utilizar mensajería dentro de una aplicación Spring, y se integra con sistemas externos a través de adaptadores. Se basa en el concepto de &amp;quot;mensajes&amp;quot; para intercambiar datos entre distintos componentes.&lt;br /&gt;
&lt;br /&gt;
==Conceptos y componentes básicos==&lt;br /&gt;
&lt;br /&gt;
===Conceptos===&lt;br /&gt;
&lt;br /&gt;
* '''Channel (MessageChannel)''', representa un canal lógico por donde se reciben o se envían mensajes.&lt;br /&gt;
&lt;br /&gt;
* '''Channel-adapter''', representa el adaptador entre el canal lógico y una implementación física de ese canal. &lt;br /&gt;
&lt;br /&gt;
* '''Bridge''', se encarga de redireccionar todos los mensajes del canal de entrada hacia un canal de salida.&lt;br /&gt;
&lt;br /&gt;
* '''Router''', se encarga de redireccionar los mensajes que llegan a un canal de entrada hacia uno o varios canales de salida, dependiendo de ciertas condiciones.&lt;br /&gt;
&lt;br /&gt;
* '''Splitter''', se encarga de separar el contenido de un mensaje en muchos mensajes.&lt;br /&gt;
&lt;br /&gt;
* '''Transformer''', se encarga de transformar el formato del contenido del mensaje.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Componentes===&lt;br /&gt;
&lt;br /&gt;
* '''Message''', esta compuesto por una cabecera (headers) y por un cuerpo (Payload). &lt;br /&gt;
&lt;br /&gt;
* '''MessageChannel''', provee métodos para enviar y recibir. &lt;br /&gt;
&lt;br /&gt;
* '''MessageEndpoint''', Conecta un Handler a un MessageChannel de entrada o/y a uno de salida.&lt;br /&gt;
&lt;br /&gt;
* '''MessageHandler''', interfaz que permite transformer, rutear y en general “tartar” cualquier mensaje de Entrada.&lt;br /&gt;
&lt;br /&gt;
* '''Channel Adapters''', se usan para enviar y recibir mensajes a sistemas externos.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Adaptadores==&lt;br /&gt;
&lt;br /&gt;
* [http://static.springsource.org/spring-integration/docs/2.0.4.RELEASE/reference/htmlsingle/#ip TCP y UDP]&lt;br /&gt;
* [http://static.springsource.org/spring-integration/docs/2.0.4.RELEASE/reference/htmlsingle/#http HTTP]&lt;br /&gt;
* [http://static.springsource.org/spring-integration/docs/2.0.4.RELEASE/reference/htmlsingle/#feed RSS/ATOM]&lt;br /&gt;
* [http://static.springsource.org/spring-integration/docs/2.0.4.RELEASE/reference/htmlsingle/#ws Web Services]&lt;br /&gt;
* [http://static.springsource.org/spring-integration/docs/2.0.4.RELEASE/reference/htmlsingle/#mail Mail (POP3, IMAP, SMTP)]&lt;br /&gt;
* [http://static.springsource.org/spring-integration/docs/2.0.4.RELEASE/reference/htmlsingle/#jms JMS]&lt;br /&gt;
* [http://static.springsource.org/spring-integration/docs/2.0.4.RELEASE/reference/htmlsingle/#jdbc JDBC]&lt;br /&gt;
* [http://static.springsource.org/spring-integration/docs/2.0.4.RELEASE/reference/htmlsingle/#jmx JMX]&lt;br /&gt;
* [http://static.springsource.org/spring-integration/docs/2.0.4.RELEASE/reference/htmlsingle/#rmi RMI]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Taller ==&lt;br /&gt;
&lt;br /&gt;
{{curso|url=http://www.dosideas.com/cursos/course/view.php?id=12|nombre=Introducción a Spring Integration}}&lt;br /&gt;
&lt;br /&gt;
== Ejemplos ==&lt;br /&gt;
&lt;br /&gt;
=== Configuración de canales ===&lt;br /&gt;
[[Spring Integration]] se basa en ''canales'', lugares en donde se consumen o envian mensajes. Estos canales pueden ser colas [[JMS]] u otros medios, como clases propias. La siguiente definición de canales se usa en los ejemplos que siguen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
&amp;lt;integration:channel id=&amp;quot;QueueChanneIn&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;jms:message-driven-channel-adapter connection-factory=&amp;quot;PruebaQueueConnectionFactory&amp;quot; &lt;br /&gt;
destination-name=&amp;quot;jms/Queue-in&amp;quot; destination-resolver=&amp;quot;jmsDestinationResolver&amp;quot; &lt;br /&gt;
channel=&amp;quot;QueueChanneIn&amp;quot; acknowledge=&amp;quot;auto&amp;quot; concurrent-consumers=&amp;quot;1&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;integration:channel id=&amp;quot;QueueChanneOut1&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;jms:outbound-channel-adapter jms-template=&amp;quot;jmsQueueTemplateOut1&amp;quot; channel=&amp;quot;QueueChanneOut1&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;integration:channel id=&amp;quot;QueueChanneOut2&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;jms:outbound-channel-adapter jms-template=&amp;quot;jmsQueueTemplateOut2&amp;quot; channel=&amp;quot;QueueChanneOut2&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===stdout-channel-adapter===&lt;br /&gt;
Podemos consumir un mensaje de una cola y mostrarlo por consola. Para esto es necesario configurar un '''stdout-channel-adapter''', el cual se encargará de procesar los mensajes. Luego, se crea un '''bridge''' que asocia un canal de entrada con este adaptador. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
&amp;lt;stream:stdout-channel-adapter id=&amp;quot;stdout&amp;quot; append-newline=&amp;quot;true&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;integration:bridge id=&amp;quot;echo&amp;quot; input-channel=&amp;quot;QueueChanneIn&amp;quot; output-channel=&amp;quot;stdout&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===recipient-list-router===&lt;br /&gt;
Podemos consumir un mensaje de una cola y enviarlo a una lista fija de canales de destino. En este ejemplo creamos un '''recipient-list-router''', el cual consume mensajes de un canal de entrada y los envia a dos canales de destino distintos. Entonces, cada mensaje que llegue al canal de entrada será derivado a dos canales de destino. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
&amp;lt;integration:recipient-list-router input-channel=&amp;quot;QueueChanneIn&amp;quot; apply-sequence=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;integration:recipient channel=&amp;quot;QueueChanneOut1&amp;quot;/&amp;gt;&lt;br /&gt;
            &amp;lt;integration:recipient channel=&amp;quot;QueueChanneOut2&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/integration:recipient-list-router&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===header-value-router===&lt;br /&gt;
Podemos consumir un mensaje de una cola y enviarlo a una cola especifica dependiendo del valor de un atributo del header del mensaje. De esta manera, configuramos un '''header-value-router''', el cual contiene el canal de entrada y el nombre del atributo del encabezado que se comprobará. Luego, se realiza el mapeo entre los posibles valores de este encabezado y algún canal de destino. Si llega un mensaje que coincida este mapeo, será enviado a ese canal de destino.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
&amp;lt;integration:header-value-router input-channel=&amp;quot;QueueChanneIn&amp;quot; &lt;br /&gt;
header-name=&amp;quot;springintegration_jms_type&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;integration:mapping value=&amp;quot;Out1&amp;quot; channel=&amp;quot;QueueChanneOut1&amp;quot;/&amp;gt;&lt;br /&gt;
        &amp;lt;integration:mapping value=&amp;quot;Out2&amp;quot; channel=&amp;quot;QueueChanneOut2&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/integration:header-value-router&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===router===&lt;br /&gt;
Podemos consumir un mensaje de una cola y enviarlo a una lista de colas de salida utilizando un pojo para determinar a que colas enviarlo. En este ejemplo, creamos un '''router''' que será implementado por la clase &amp;quot;MultiDestino&amp;quot;. Esta clase devuelve una lista de nombres de canales hacia donde se derivará el mensaje.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
&amp;lt;integration:router input-channel=&amp;quot;QueueChanneIn&amp;quot; ref=&amp;quot;multiDestino&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;bean id=&amp;quot;multiDestino&amp;quot; class=&amp;quot;com.dosideas.springintegration.MultiDestino&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java&amp;gt;&lt;br /&gt;
public class MultiDestino {&lt;br /&gt;
&lt;br /&gt;
    @Router&lt;br /&gt;
    public List&amp;lt;String&amp;gt; resolverChannel(GenericMessage message) throws JMSException {&lt;br /&gt;
&lt;br /&gt;
        List&amp;lt;String&amp;gt; list = new ArrayList&amp;lt;String&amp;gt;();&lt;br /&gt;
        if(message.getHeaders().get(&amp;quot;springintegration_jms_type&amp;quot;).equals(&amp;quot;Out1&amp;quot;)) {&lt;br /&gt;
            System.out.println(message.getHeaders().get(&amp;quot;springintegration_jms_type&amp;quot;));&lt;br /&gt;
            list.add(&amp;quot;QueueChanneOut1&amp;quot;);&lt;br /&gt;
            &lt;br /&gt;
        }&lt;br /&gt;
        else if(message.getHeaders().get(&amp;quot;springintegration_jms_type&amp;quot;).equals(&amp;quot;Out2&amp;quot;)) {&lt;br /&gt;
            System.out.println(message.getHeaders().get(&amp;quot;springintegration_jms_type&amp;quot;));&lt;br /&gt;
            list.add(&amp;quot;QueueChanneOut2&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
        else if(message.getHeaders().get(&amp;quot;springintegration_jms_type&amp;quot;).equals(&amp;quot;Multi&amp;quot;)) {&lt;br /&gt;
            System.out.println(message.getHeaders().get(&amp;quot;springintegration_jms_type&amp;quot;));&lt;br /&gt;
            list.add(&amp;quot;QueueChanneOut1&amp;quot;);&lt;br /&gt;
            list.add(&amp;quot;QueueChanneOut2&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        return list;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Ver también==&lt;br /&gt;
* [http://dosideas-aplicaciones-modelo.googlecode.com/svn/spring-integration-demo/trunk Descarga con svn nuestra ultima aplicación demo de Spring Integration]&lt;br /&gt;
* [http://www.dosideas.com/descargas/category/2-spring-framework.html?download=29%3Ap Descargar un proyecto con varios ejemplos de Spring Integration]&lt;br /&gt;
* [http://static.springsource.org/spring-integration/reference/htmlsingle/spring-integration-reference.html Manual de referencia de Spring Integration]&lt;br /&gt;
&lt;br /&gt;
[[Category:Spring Framework]]&lt;br /&gt;
[[Category:JMS]]&lt;br /&gt;
[[Category:JDBC]]&lt;br /&gt;
[[Category:TCP]]&lt;br /&gt;
[[Category:UDP]]&lt;br /&gt;
[[Category:FTP]]&lt;/div&gt;</summary>
		<author><name>201.251.182.130</name></author>	</entry>

	<entry>
		<id>https://dosideas.com/wiki/index.php?title=Closures_o_Clausuras_de_Javascript&amp;diff=5794</id>
		<title>Closures o Clausuras de Javascript</title>
		<link rel="alternate" type="text/html" href="https://dosideas.com/wiki/index.php?title=Closures_o_Clausuras_de_Javascript&amp;diff=5794"/>
				<updated>2011-06-28T15:53:06Z</updated>
		
		<summary type="html">&lt;p&gt;201.251.182.130: Página creada con 'Category:JavaScript ==Closures o Clausuras de JavaScript==  El concepto es &amp;quot;clausurar&amp;quot; el contexto en el que se ejecuta una funcion, a esta funcion se la denomina ''Clos…'&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:JavaScript]]&lt;br /&gt;
==Closures o Clausuras de [[JavaScript]]==&lt;br /&gt;
&lt;br /&gt;
El concepto es &amp;quot;clausurar&amp;quot; el contexto en el que se ejecuta una funcion, a esta funcion se la denomina ''Closure''.&lt;br /&gt;
&lt;br /&gt;
===Como funcionan?===&lt;br /&gt;
&lt;br /&gt;
En donde se encuentra una funcion dentro de otra, la funcion interna tiene acceso a las variables de la funcion externa.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
function externa(x) {&lt;br /&gt;
  var variable = 3;&lt;br /&gt;
&lt;br /&gt;
  function interna(y) {&lt;br /&gt;
    alert(x + y + (++variable));&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  interna(10);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
externa(2);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Esto siempre dará un alert de 16, porque ''interna()'' puede acceder a la ''x'' que fue definida como argumento en ''externa()'' y tambien puede acceder a ''variable'' de ''externa()''.&lt;br /&gt;
&lt;br /&gt;
Eso '''NO''' es un ''closure''. Un ''closure'' es cuando se retorna la funcion interna y esta misma cierra sus variables externas antes de salir.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
function externa(x) {&lt;br /&gt;
  var variable = 3;&lt;br /&gt;
&lt;br /&gt;
  return function (y) {&lt;br /&gt;
    alert( x + y + (++variable) );&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
var interna = externa(2); // interna es ahora un closure.&lt;br /&gt;
interna(10);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Tambien retornará un alert de 16, porque ''interna()'' todavia puede referenciar a ''x'' y ''variable'', aunque ya no este directamente dentro del alcance de ''externa()''.&lt;br /&gt;
&lt;br /&gt;
Sin embargo, como ''variable'' todavía esta siendo manejada dentro del closure ''interna()'', va a continuar incrementandose cada vez que ''interna()'' sea llamada, a diferencia del ejemplo anterior.&lt;br /&gt;
&lt;br /&gt;
===Importante cuando trabajamos con Closures===&lt;br /&gt;
&lt;br /&gt;
En el último ejemplo ''x'' es un número literal y como todo literal en javascript, cuando se llame a ''externa()'' el numero ''x'' es copiado en la funcion como argumento.&lt;br /&gt;
&lt;br /&gt;
Por otro lado, javascript siempre utiliza referencias cuando trabaja con Objetos. Por ejemplo, si llamamos a ''externa()'' con un objeto, '''el closure que retornará estará referenciado al objeto original'''.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code javascript&amp;gt;&lt;br /&gt;
function externa(x) {&lt;br /&gt;
  var variable = 3;&lt;br /&gt;
&lt;br /&gt;
  return function (y) {&lt;br /&gt;
    alert(x + y + variable);&lt;br /&gt;
    x.unaProp = x.unaProp ? x.unaProp + 1 : 1;&lt;br /&gt;
    alert(x.unaProp);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
var edad = new Number(2);&lt;br /&gt;
var interna = externa(edad); // interna es una closure referenciando al objeto edad.&lt;br /&gt;
interna(10);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Como es esperado, cada llamada a ''interna()'' incrementará ''x.unaProp''. Lo que puede no ser esperado es que ''x'' está referenciando al mismo objeto que guarda ''edad'', luego de un par de llamadas a ''interna()'' ''edad.unaProp'' valdrá 2.&lt;br /&gt;
&lt;br /&gt;
==Ver también==&lt;br /&gt;
* [http://es.wikipedia.org/wiki/JavaScript JavaScript en la Wikipedia]&lt;br /&gt;
* [http://www.theserverside.com/tt/articles/article.tss?l=OOJavaScriptDemonstrated Conceptos y operaciones básicas]&lt;br /&gt;
&lt;br /&gt;
==Fuente==&lt;br /&gt;
* [http://stackoverflow.com/questions/111102/how-do-javascript-closures-work Stackoverflow: How do JavaScript closures work?]&lt;/div&gt;</summary>
		<author><name>201.251.182.130</name></author>	</entry>

	<entry>
		<id>https://dosideas.com/wiki/index.php?title=JavaScript&amp;diff=5793</id>
		<title>JavaScript</title>
		<link rel="alternate" type="text/html" href="https://dosideas.com/wiki/index.php?title=JavaScript&amp;diff=5793"/>
				<updated>2011-06-28T15:18:21Z</updated>
		
		<summary type="html">&lt;p&gt;201.251.182.130: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:JavaScript]]&lt;br /&gt;
[[JavaScript]] es un lenguaje de programación interpretado, es decir, que no requiere compilación, utilizado principalmente en páginas web, con una sintaxis semejante a la del lenguaje Java y el lenguaje C.&lt;br /&gt;
&lt;br /&gt;
Al igual que [[Java]], [[JavaScript]] es un lenguaje orientado a objetos propiamente dicho, ya que dispone de Herencia, si bien esta se realiza siguiendo el paradigma de programación basada en prototipos, ya que las nuevas clases se generan clonando las clases base (prototipos) y extendiendo su funcionalidad.&lt;br /&gt;
&lt;br /&gt;
Todos los navegadores modernos interpretan el código [[JavaScript]] integrado dentro de las páginas web. Para interactuar con una página web se provee al lenguaje [[JavaScript]] de una implementación del DOM.&lt;br /&gt;
&lt;br /&gt;
[[Closures o Clausuras de Javascript]]&lt;br /&gt;
&lt;br /&gt;
==Frameworks==&lt;br /&gt;
[[JavaScript]] cuenta con infinidad de frameworks y librerias que otorgan diversa funcionalidad. Entre los más conocidos:&lt;br /&gt;
* [[JQuery]], un framework de aplicación base, sumamente extensible.&lt;br /&gt;
* [[Prototype]], un framework de aplicación base que permite definir clases, muy usado.&lt;br /&gt;
* [[Rico]], un framework de componentes de presentación [AJAX].&lt;br /&gt;
* [[Concurrent Thread Javascript]], librería para manejo de hilos.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Ver también==&lt;br /&gt;
* [http://es.wikipedia.org/wiki/JavaScript JavaScript en la Wikipedia]&lt;br /&gt;
* [http://www.theserverside.com/tt/articles/article.tss?l=OOJavaScriptDemonstrated Conceptos y operaciones básicas]&lt;/div&gt;</summary>
		<author><name>201.251.182.130</name></author>	</entry>

	<entry>
		<id>https://dosideas.com/wiki/index.php?title=SoapUI&amp;diff=5778</id>
		<title>SoapUI</title>
		<link rel="alternate" type="text/html" href="https://dosideas.com/wiki/index.php?title=SoapUI&amp;diff=5778"/>
				<updated>2011-05-31T18:13:17Z</updated>
		
		<summary type="html">&lt;p&gt;201.251.182.130: /* Conclusión */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Categoría: Web Service]]&lt;br /&gt;
[[SoapUI]] es una herramienta de [[Software Libre]] gráfica, está basada en [[Java]] y sirve para el testeo de [[Web Service]] y generación de [[Clientes De Web Service]]. &lt;br /&gt;
&lt;br /&gt;
SoapUI permite testear web services de forma facil, ver los resultados. Además, permite facilitar el uso de herramientas comunes para la generación de clientes, como [[Axis]]. &lt;br /&gt;
&lt;br /&gt;
Trabajando con web services, y sin interfase gráfica en la aplicación, esta herramienta nos permite automatizar fácilmente las pruebas funcionales y así asegurar la calidad en nuestros proyectos.&lt;br /&gt;
&lt;br /&gt;
Las pruebas funcionales de los web services podrían usarse para más de un propósito:&lt;br /&gt;
&lt;br /&gt;
*Pruebas unitarias: para validar que cada operación de los servicios funciona como se definió.&lt;br /&gt;
*Prueba de aceptación: para validar que el servicio retorna resultados aceptables según los requerimientos.&lt;br /&gt;
*Pruebas de proceso: para validar que una sucesión de invocaciones del servicio cumple con el proceso de negocio definido.&lt;br /&gt;
*Pruebas de manejo de datos: para validar el comportamiento con las entradas de datos externos al sistema (bases de datos, otros sistemas, uso de otros web services).&lt;br /&gt;
*[http://es.wikipedia.org/wiki/Pruebas_de_regresi%C3%B3n/ Pruebas de regresión]: para validar el comportamiento post cambios.&lt;br /&gt;
&lt;br /&gt;
==Un paso a paso==&lt;br /&gt;
&lt;br /&gt;
1. Tener instalada la última versión bajada de la [http://www.soapui.org/ Web oficial de SoapUI].&lt;br /&gt;
&lt;br /&gt;
2. Crear un nuevo proyecto [[SoapUI]] para el proyecto a probar. Donde configurar la url que contiene el WSDL del proyecto.&lt;br /&gt;
{| width=&amp;quot;80%&amp;quot; align=&amp;quot;center&amp;quot; border=&amp;quot;0&amp;quot;&lt;br /&gt;
 |-&lt;br /&gt;
 | &amp;lt;imagemap&amp;gt;&lt;br /&gt;
Image:SoapUI-Creacion-De-Proyecto.jpg|center|Creacion de un proyecto&lt;br /&gt;
default [[SoapUI]]&lt;br /&gt;
desc none&lt;br /&gt;
&amp;lt;/imagemap&amp;gt; &lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot; style=&amp;quot;font-size:large&amp;quot;&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
 |}&lt;br /&gt;
&lt;br /&gt;
3. Por cada operacion del servicio a probar, crear una peticion. Cada peticion requiere el ingreso de valores para los parámetros definidos. Agregar valores en el XML que nos propone el wizard de la herramienta.&lt;br /&gt;
{| width=&amp;quot;80%&amp;quot; align=&amp;quot;center&amp;quot; border=&amp;quot;0&amp;quot;&lt;br /&gt;
 |-&lt;br /&gt;
 | &amp;lt;imagemap&amp;gt;&lt;br /&gt;
Image:SoapUI-Agregar-Peticion.jpg|center|Agregar Peticion&lt;br /&gt;
default [[SoapUI]]&lt;br /&gt;
desc none&lt;br /&gt;
&amp;lt;/imagemap&amp;gt; &lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot; style=&amp;quot;font-size:large&amp;quot;&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
 |}&lt;br /&gt;
{| width=&amp;quot;80%&amp;quot; align=&amp;quot;center&amp;quot; border=&amp;quot;0&amp;quot;&lt;br /&gt;
 |-&lt;br /&gt;
 | &amp;lt;imagemap&amp;gt;&lt;br /&gt;
Image:SoapUI-Parametros-Peticion.jpg|center|Editar Parametros Peticion&lt;br /&gt;
default [[SoapUI]]&lt;br /&gt;
desc none&lt;br /&gt;
&amp;lt;/imagemap&amp;gt; &lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot; style=&amp;quot;font-size:large&amp;quot;&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
 |}&lt;br /&gt;
&lt;br /&gt;
4. El proyecto se persiste en un script XML, que podemos resguardar en el repositorio en el que tengamos el código fuente del proyecto. Y así todo el equipo podrá hacer crecer la prueba funcional automática del proyecto, y de un modo ágil.&lt;br /&gt;
&lt;br /&gt;
5. Con los pasos dados hasta acá, logramos obtener una prueba funcional del proyecto y su documentación.&lt;br /&gt;
&lt;br /&gt;
6. Esta herramienta maneja el concepto de TestSuite, TestCase, TestStep, como lo manejan [[JUnit]], [[JMeter]], etc. Un TestSuite sirve para contener un número arbitrario de casos de prueba (TestCases) que pueden ejecutarse secuencialmente o en paralelo.  Los TestSteps sirven para ejecutar TestCases secuencialmente.&lt;br /&gt;
Una vez creadas las peticiones, es posible generar una TestSuite y así automatizar las pruebas funcionales, con el valor agregado de tener [[pruebas de regresión]].&lt;br /&gt;
&lt;br /&gt;
{| width=&amp;quot;80%&amp;quot; align=&amp;quot;center&amp;quot; border=&amp;quot;0&amp;quot;&lt;br /&gt;
 |-&lt;br /&gt;
 | &amp;lt;imagemap&amp;gt;&lt;br /&gt;
Image:SoapUI-Agregar-Caso-Prueba.jpg|center|Agregar Peticion a un Caso de Prueba&lt;br /&gt;
default [[SoapUI]]&lt;br /&gt;
desc none&lt;br /&gt;
&amp;lt;/imagemap&amp;gt; &lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot; style=&amp;quot;font-size:large&amp;quot;&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
 |}&lt;br /&gt;
&lt;br /&gt;
7. Por cada TestCase es posible hacer validaciones automáticas de los resultados. Entonces, por cada petición, verificar si la respuesta es un fault, o no lo es, o contiene determinado valor, o no lo contiene. Es una buena práctica, en el manejo de web services, que los errores inesperado del sistema (Runtime Exception) viajen en un tag “fault”. Distinto a una respuesta normal del servicio.&lt;br /&gt;
&lt;br /&gt;
{| width=&amp;quot;80%&amp;quot; align=&amp;quot;center&amp;quot; border=&amp;quot;0&amp;quot;&lt;br /&gt;
 |-&lt;br /&gt;
 | &amp;lt;imagemap&amp;gt;&lt;br /&gt;
Image:SoapUI-Agregar-Aserciones.jpg|center|Agregar una asercion a la respuesta de una peticion&lt;br /&gt;
default [[SoapUI]]&lt;br /&gt;
desc none&lt;br /&gt;
&amp;lt;/imagemap&amp;gt; &lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot; style=&amp;quot;font-size:large&amp;quot;&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
 |}&lt;br /&gt;
&lt;br /&gt;
{| width=&amp;quot;80%&amp;quot; align=&amp;quot;center&amp;quot; border=&amp;quot;0&amp;quot;&lt;br /&gt;
 |-&lt;br /&gt;
 | &amp;lt;imagemap&amp;gt;&lt;br /&gt;
Image:SoapUI-Tipos-Aserciones.jpg|center|Tipos de Aserciones&lt;br /&gt;
default [[SoapUI]]&lt;br /&gt;
desc none&lt;br /&gt;
&amp;lt;/imagemap&amp;gt; &lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot; style=&amp;quot;font-size:large&amp;quot;&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
 |}&lt;br /&gt;
&lt;br /&gt;
{| width=&amp;quot;80%&amp;quot; align=&amp;quot;center&amp;quot; border=&amp;quot;0&amp;quot;&lt;br /&gt;
 |-&lt;br /&gt;
 | &amp;lt;imagemap&amp;gt;&lt;br /&gt;
Image:SoapUI-Asercion-Contenido.jpg|center|Agregar una asercion de contenido&lt;br /&gt;
default [[SoapUI]]&lt;br /&gt;
desc none&lt;br /&gt;
&amp;lt;/imagemap&amp;gt; &lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot; style=&amp;quot;font-size:large&amp;quot;&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
 |}&lt;br /&gt;
&lt;br /&gt;
8. Con las peticiones agregadas a los casos de prueba, se puede realizar una ejecución masiva utilizando la opción Launch TestRunner.&lt;br /&gt;
&lt;br /&gt;
{| width=&amp;quot;80%&amp;quot; align=&amp;quot;center&amp;quot; border=&amp;quot;0&amp;quot;&lt;br /&gt;
 |-&lt;br /&gt;
 | &amp;lt;imagemap&amp;gt;&lt;br /&gt;
Image:SoapUI-Ejecutar-Casos.jpg|center|Configurar y Ejecutar Casos de Prueba&lt;br /&gt;
default [[SoapUI]]&lt;br /&gt;
desc none&lt;br /&gt;
&amp;lt;/imagemap&amp;gt; &lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot; style=&amp;quot;font-size:large&amp;quot;&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
 |}&lt;br /&gt;
&lt;br /&gt;
Mientras se ejecutan los casos de prueba, se pueden visualizar los pasos de ejecución y un resumen global.&lt;br /&gt;
En el directorio físico configurado, se genera un archivo por cada caso de prueba 	con la nomenclatura conteniendo el TestSuite que lo ejecutó, el nombre del caso de 	prueba, y el resultado de la prueba. &lt;br /&gt;
&lt;br /&gt;
==Transferencia de datos entre peticiones==&lt;br /&gt;
&lt;br /&gt;
En un TestSuite podemos tener un TestCase con Steps, donde cada Step puede ser un request de una operación diferente del web service. Y el valor devuelto en un Step puede ser el valor de entrada en el próximo Step. Más en el [http://www.soapui.org/userguide/functional/propertytransfers.html#The_PropertyTransfer_Editor tutorial de soapUI]&lt;br /&gt;
&lt;br /&gt;
{| width=&amp;quot;80%&amp;quot; align=&amp;quot;center&amp;quot; border=&amp;quot;0&amp;quot;&lt;br /&gt;
 |-&lt;br /&gt;
 | &amp;lt;imagemap&amp;gt;&lt;br /&gt;
Image:SoapUI-TestSuite2ConTransfer.jpg|center|Transferencia de datos entre peticiones&lt;br /&gt;
default [[SoapUI]]&lt;br /&gt;
desc none&lt;br /&gt;
&amp;lt;/imagemap&amp;gt; &lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot; style=&amp;quot;font-size:large&amp;quot;&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
 |}&lt;br /&gt;
&lt;br /&gt;
==Conclusión==&lt;br /&gt;
&lt;br /&gt;
*Es fácil y rápido crear, ejecutar y guardar los casos de prueba funcional que quieras. Se pueden adaptar y expandir en cualquier momento.&lt;br /&gt;
*Es fácil hacer aserciones. También con expresiones regulares.&lt;br /&gt;
&lt;br /&gt;
==Algo más==&lt;br /&gt;
&lt;br /&gt;
*Se puede agregar MockService cuando el web service todavía no está listo.&lt;br /&gt;
*Load Tests permite medir performance sobre los tests funcionales creados.&lt;br /&gt;
*Esta nota está basada en una [http://www.soapui.org/userguide/functional/index.html guia] y en un [http://www.soapui.org/movies/sample_project/sample_project.html video] de la [http://www.soapui.org/ página oficial de SoapUI].&lt;br /&gt;
&lt;br /&gt;
== Ver también ==&lt;br /&gt;
* [[Web Service]]&lt;br /&gt;
* [[Clientes De Web Service]]&lt;br /&gt;
* [[SoapUI Con JUnit]]&lt;br /&gt;
* [[Mock de un web service con SoapUI]]&lt;br /&gt;
* [http://www.soapui.org/ Web oficial de SoapUI]&lt;br /&gt;
* [http://www.dosideas.com/foros/5-ascensor-a-ningun-lugar/658-web-service-minimo-para-pruebas-de-desarrollo.html Foro de Ayuda para Simular un Web Service en Desarrollo]&lt;br /&gt;
&lt;br /&gt;
[[Category:Web Service]]&lt;br /&gt;
[[Category:ATDD]]&lt;/div&gt;</summary>
		<author><name>201.251.182.130</name></author>	</entry>

	<entry>
		<id>https://dosideas.com/wiki/index.php?title=SoapUI&amp;diff=5777</id>
		<title>SoapUI</title>
		<link rel="alternate" type="text/html" href="https://dosideas.com/wiki/index.php?title=SoapUI&amp;diff=5777"/>
				<updated>2011-05-31T18:13:05Z</updated>
		
		<summary type="html">&lt;p&gt;201.251.182.130: /* Conclusión */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Categoría: Web Service]]&lt;br /&gt;
[[SoapUI]] es una herramienta de [[Software Libre]] gráfica, está basada en [[Java]] y sirve para el testeo de [[Web Service]] y generación de [[Clientes De Web Service]]. &lt;br /&gt;
&lt;br /&gt;
SoapUI permite testear web services de forma facil, ver los resultados. Además, permite facilitar el uso de herramientas comunes para la generación de clientes, como [[Axis]]. &lt;br /&gt;
&lt;br /&gt;
Trabajando con web services, y sin interfase gráfica en la aplicación, esta herramienta nos permite automatizar fácilmente las pruebas funcionales y así asegurar la calidad en nuestros proyectos.&lt;br /&gt;
&lt;br /&gt;
Las pruebas funcionales de los web services podrían usarse para más de un propósito:&lt;br /&gt;
&lt;br /&gt;
*Pruebas unitarias: para validar que cada operación de los servicios funciona como se definió.&lt;br /&gt;
*Prueba de aceptación: para validar que el servicio retorna resultados aceptables según los requerimientos.&lt;br /&gt;
*Pruebas de proceso: para validar que una sucesión de invocaciones del servicio cumple con el proceso de negocio definido.&lt;br /&gt;
*Pruebas de manejo de datos: para validar el comportamiento con las entradas de datos externos al sistema (bases de datos, otros sistemas, uso de otros web services).&lt;br /&gt;
*[http://es.wikipedia.org/wiki/Pruebas_de_regresi%C3%B3n/ Pruebas de regresión]: para validar el comportamiento post cambios.&lt;br /&gt;
&lt;br /&gt;
==Un paso a paso==&lt;br /&gt;
&lt;br /&gt;
1. Tener instalada la última versión bajada de la [http://www.soapui.org/ Web oficial de SoapUI].&lt;br /&gt;
&lt;br /&gt;
2. Crear un nuevo proyecto [[SoapUI]] para el proyecto a probar. Donde configurar la url que contiene el WSDL del proyecto.&lt;br /&gt;
{| width=&amp;quot;80%&amp;quot; align=&amp;quot;center&amp;quot; border=&amp;quot;0&amp;quot;&lt;br /&gt;
 |-&lt;br /&gt;
 | &amp;lt;imagemap&amp;gt;&lt;br /&gt;
Image:SoapUI-Creacion-De-Proyecto.jpg|center|Creacion de un proyecto&lt;br /&gt;
default [[SoapUI]]&lt;br /&gt;
desc none&lt;br /&gt;
&amp;lt;/imagemap&amp;gt; &lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot; style=&amp;quot;font-size:large&amp;quot;&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
 |}&lt;br /&gt;
&lt;br /&gt;
3. Por cada operacion del servicio a probar, crear una peticion. Cada peticion requiere el ingreso de valores para los parámetros definidos. Agregar valores en el XML que nos propone el wizard de la herramienta.&lt;br /&gt;
{| width=&amp;quot;80%&amp;quot; align=&amp;quot;center&amp;quot; border=&amp;quot;0&amp;quot;&lt;br /&gt;
 |-&lt;br /&gt;
 | &amp;lt;imagemap&amp;gt;&lt;br /&gt;
Image:SoapUI-Agregar-Peticion.jpg|center|Agregar Peticion&lt;br /&gt;
default [[SoapUI]]&lt;br /&gt;
desc none&lt;br /&gt;
&amp;lt;/imagemap&amp;gt; &lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot; style=&amp;quot;font-size:large&amp;quot;&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
 |}&lt;br /&gt;
{| width=&amp;quot;80%&amp;quot; align=&amp;quot;center&amp;quot; border=&amp;quot;0&amp;quot;&lt;br /&gt;
 |-&lt;br /&gt;
 | &amp;lt;imagemap&amp;gt;&lt;br /&gt;
Image:SoapUI-Parametros-Peticion.jpg|center|Editar Parametros Peticion&lt;br /&gt;
default [[SoapUI]]&lt;br /&gt;
desc none&lt;br /&gt;
&amp;lt;/imagemap&amp;gt; &lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot; style=&amp;quot;font-size:large&amp;quot;&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
 |}&lt;br /&gt;
&lt;br /&gt;
4. El proyecto se persiste en un script XML, que podemos resguardar en el repositorio en el que tengamos el código fuente del proyecto. Y así todo el equipo podrá hacer crecer la prueba funcional automática del proyecto, y de un modo ágil.&lt;br /&gt;
&lt;br /&gt;
5. Con los pasos dados hasta acá, logramos obtener una prueba funcional del proyecto y su documentación.&lt;br /&gt;
&lt;br /&gt;
6. Esta herramienta maneja el concepto de TestSuite, TestCase, TestStep, como lo manejan [[JUnit]], [[JMeter]], etc. Un TestSuite sirve para contener un número arbitrario de casos de prueba (TestCases) que pueden ejecutarse secuencialmente o en paralelo.  Los TestSteps sirven para ejecutar TestCases secuencialmente.&lt;br /&gt;
Una vez creadas las peticiones, es posible generar una TestSuite y así automatizar las pruebas funcionales, con el valor agregado de tener [[pruebas de regresión]].&lt;br /&gt;
&lt;br /&gt;
{| width=&amp;quot;80%&amp;quot; align=&amp;quot;center&amp;quot; border=&amp;quot;0&amp;quot;&lt;br /&gt;
 |-&lt;br /&gt;
 | &amp;lt;imagemap&amp;gt;&lt;br /&gt;
Image:SoapUI-Agregar-Caso-Prueba.jpg|center|Agregar Peticion a un Caso de Prueba&lt;br /&gt;
default [[SoapUI]]&lt;br /&gt;
desc none&lt;br /&gt;
&amp;lt;/imagemap&amp;gt; &lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot; style=&amp;quot;font-size:large&amp;quot;&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
 |}&lt;br /&gt;
&lt;br /&gt;
7. Por cada TestCase es posible hacer validaciones automáticas de los resultados. Entonces, por cada petición, verificar si la respuesta es un fault, o no lo es, o contiene determinado valor, o no lo contiene. Es una buena práctica, en el manejo de web services, que los errores inesperado del sistema (Runtime Exception) viajen en un tag “fault”. Distinto a una respuesta normal del servicio.&lt;br /&gt;
&lt;br /&gt;
{| width=&amp;quot;80%&amp;quot; align=&amp;quot;center&amp;quot; border=&amp;quot;0&amp;quot;&lt;br /&gt;
 |-&lt;br /&gt;
 | &amp;lt;imagemap&amp;gt;&lt;br /&gt;
Image:SoapUI-Agregar-Aserciones.jpg|center|Agregar una asercion a la respuesta de una peticion&lt;br /&gt;
default [[SoapUI]]&lt;br /&gt;
desc none&lt;br /&gt;
&amp;lt;/imagemap&amp;gt; &lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot; style=&amp;quot;font-size:large&amp;quot;&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
 |}&lt;br /&gt;
&lt;br /&gt;
{| width=&amp;quot;80%&amp;quot; align=&amp;quot;center&amp;quot; border=&amp;quot;0&amp;quot;&lt;br /&gt;
 |-&lt;br /&gt;
 | &amp;lt;imagemap&amp;gt;&lt;br /&gt;
Image:SoapUI-Tipos-Aserciones.jpg|center|Tipos de Aserciones&lt;br /&gt;
default [[SoapUI]]&lt;br /&gt;
desc none&lt;br /&gt;
&amp;lt;/imagemap&amp;gt; &lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot; style=&amp;quot;font-size:large&amp;quot;&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
 |}&lt;br /&gt;
&lt;br /&gt;
{| width=&amp;quot;80%&amp;quot; align=&amp;quot;center&amp;quot; border=&amp;quot;0&amp;quot;&lt;br /&gt;
 |-&lt;br /&gt;
 | &amp;lt;imagemap&amp;gt;&lt;br /&gt;
Image:SoapUI-Asercion-Contenido.jpg|center|Agregar una asercion de contenido&lt;br /&gt;
default [[SoapUI]]&lt;br /&gt;
desc none&lt;br /&gt;
&amp;lt;/imagemap&amp;gt; &lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot; style=&amp;quot;font-size:large&amp;quot;&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
 |}&lt;br /&gt;
&lt;br /&gt;
8. Con las peticiones agregadas a los casos de prueba, se puede realizar una ejecución masiva utilizando la opción Launch TestRunner.&lt;br /&gt;
&lt;br /&gt;
{| width=&amp;quot;80%&amp;quot; align=&amp;quot;center&amp;quot; border=&amp;quot;0&amp;quot;&lt;br /&gt;
 |-&lt;br /&gt;
 | &amp;lt;imagemap&amp;gt;&lt;br /&gt;
Image:SoapUI-Ejecutar-Casos.jpg|center|Configurar y Ejecutar Casos de Prueba&lt;br /&gt;
default [[SoapUI]]&lt;br /&gt;
desc none&lt;br /&gt;
&amp;lt;/imagemap&amp;gt; &lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot; style=&amp;quot;font-size:large&amp;quot;&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
 |}&lt;br /&gt;
&lt;br /&gt;
Mientras se ejecutan los casos de prueba, se pueden visualizar los pasos de ejecución y un resumen global.&lt;br /&gt;
En el directorio físico configurado, se genera un archivo por cada caso de prueba 	con la nomenclatura conteniendo el TestSuite que lo ejecutó, el nombre del caso de 	prueba, y el resultado de la prueba. &lt;br /&gt;
&lt;br /&gt;
==Transferencia de datos entre peticiones==&lt;br /&gt;
&lt;br /&gt;
En un TestSuite podemos tener un TestCase con Steps, donde cada Step puede ser un request de una operación diferente del web service. Y el valor devuelto en un Step puede ser el valor de entrada en el próximo Step. Más en el [http://www.soapui.org/userguide/functional/propertytransfers.html#The_PropertyTransfer_Editor tutorial de soapUI]&lt;br /&gt;
&lt;br /&gt;
{| width=&amp;quot;80%&amp;quot; align=&amp;quot;center&amp;quot; border=&amp;quot;0&amp;quot;&lt;br /&gt;
 |-&lt;br /&gt;
 | &amp;lt;imagemap&amp;gt;&lt;br /&gt;
Image:SoapUI-TestSuite2ConTransfer.jpg|center|Transferencia de datos entre peticiones&lt;br /&gt;
default [[SoapUI]]&lt;br /&gt;
desc none&lt;br /&gt;
&amp;lt;/imagemap&amp;gt; &lt;br /&gt;
&amp;lt;p align=&amp;quot;center&amp;quot; style=&amp;quot;font-size:large&amp;quot;&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
 |}&lt;br /&gt;
&lt;br /&gt;
==Conclusión==&lt;br /&gt;
&lt;br /&gt;
*Es fácil y rápido crear, ejecutar y guardar los casos de prueba funcional que quieras. Se pueden adaptar y expandir en cualquier momento.&lt;br /&gt;
*Es fácil hacer aserciones. También con expresiones regulares.&lt;br /&gt;
cccc&lt;br /&gt;
&lt;br /&gt;
==Algo más==&lt;br /&gt;
&lt;br /&gt;
*Se puede agregar MockService cuando el web service todavía no está listo.&lt;br /&gt;
*Load Tests permite medir performance sobre los tests funcionales creados.&lt;br /&gt;
*Esta nota está basada en una [http://www.soapui.org/userguide/functional/index.html guia] y en un [http://www.soapui.org/movies/sample_project/sample_project.html video] de la [http://www.soapui.org/ página oficial de SoapUI].&lt;br /&gt;
&lt;br /&gt;
== Ver también ==&lt;br /&gt;
* [[Web Service]]&lt;br /&gt;
* [[Clientes De Web Service]]&lt;br /&gt;
* [[SoapUI Con JUnit]]&lt;br /&gt;
* [[Mock de un web service con SoapUI]]&lt;br /&gt;
* [http://www.soapui.org/ Web oficial de SoapUI]&lt;br /&gt;
* [http://www.dosideas.com/foros/5-ascensor-a-ningun-lugar/658-web-service-minimo-para-pruebas-de-desarrollo.html Foro de Ayuda para Simular un Web Service en Desarrollo]&lt;br /&gt;
&lt;br /&gt;
[[Category:Web Service]]&lt;br /&gt;
[[Category:ATDD]]&lt;/div&gt;</summary>
		<author><name>201.251.182.130</name></author>	</entry>

	<entry>
		<id>https://dosideas.com/wiki/index.php?title=Configuraci%C3%B3n_de_ejecuci%C3%B3n_selectiva_de_tests&amp;diff=5767</id>
		<title>Configuración de ejecución selectiva de tests</title>
		<link rel="alternate" type="text/html" href="https://dosideas.com/wiki/index.php?title=Configuraci%C3%B3n_de_ejecuci%C3%B3n_selectiva_de_tests&amp;diff=5767"/>
				<updated>2011-05-02T18:14:51Z</updated>
		
		<summary type="html">&lt;p&gt;201.251.182.130: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Para poder correr selectivamente los test de integración de nuestras aplicaciones utilizamos la funcionalidad provista por la clase Assume de [[JUnit]]. La clase Assume contiene métodos útiles para afirmar las hipótesis sobre las condiciones en las que los resultados de los test son significativos. Un supuesto negativo no significa que el código está roto, pero si que los resultados de los test no proporciona ninguna información útil. Por defecto [[JUnit]] trata los test con las hipótesis negativas como ignorados.&lt;br /&gt;
&lt;br /&gt;
Para el caso de proyectos creados con [[NetBeans]] compilados con [[Ant]], podemos indicar si queremos o no correr determinados test usando ciertas propiedades.&lt;br /&gt;
&lt;br /&gt;
Propiedad:&lt;br /&gt;
-Dtest-sys-prop.correrIntegracion=NO&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java5&amp;gt;&lt;br /&gt;
&lt;br /&gt;
@BeforeClass&lt;br /&gt;
public static void setUpOnce() throws Throwable {&lt;br /&gt;
        System.out.println(&amp;quot;Se usarán los test de integración [SI/NO]: &amp;quot; + System.getProperty(&amp;quot;correrIntegracion&amp;quot;));&lt;br /&gt;
        Assume.assumeTrue(System.getProperty(&amp;quot;correrIntegracion&amp;quot;) == null&lt;br /&gt;
                ? true : System.getProperty(&amp;quot;correrIntegracion&amp;quot;).matches(&amp;quot;SI&amp;quot;));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Como podemos ver en el ejemplo, por linea de comando se indica la propiedad &amp;quot;test-sys-prop.correrIntegracion&amp;quot;, pero en el test se consulta por la propiedad “correrIntegracion”, esto se debe a que por defecto la tarea [[Ant]] creada por Netbeans para correr los test de [[JUnit]] tiene la propiedad “fork” en true. En esta tarea podemos ver el tag &amp;quot;syspropertyset&amp;quot;, el cual indica que todas las propiedades que tengan el prefijo &amp;quot;test-sys-prop.&amp;quot; se pasen sin este prefijo al proceso iniciado por el fork para ejecutar la clase de test.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
&amp;lt;target name=&amp;quot;-init-macrodef-junit&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;macrodef name=&amp;quot;junit&amp;quot; uri=&amp;quot;http://www.netbeans.org/ns/j2se-project/2&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;attribute name=&amp;quot;includes&amp;quot; default=&amp;quot;**/*Test.java&amp;quot;/&amp;gt;&lt;br /&gt;
        &amp;lt;sequential&amp;gt;&lt;br /&gt;
            &amp;lt;junit showoutput=&amp;quot;true&amp;quot; fork=&amp;quot;true&amp;quot; dir=&amp;quot;${basedir}&amp;quot; failureproperty=&amp;quot;tests.failed&amp;quot; errorproperty=&amp;quot;tests.failed&amp;quot;&amp;gt;&lt;br /&gt;
                .&lt;br /&gt;
		 .&lt;br /&gt;
		 .&lt;br /&gt;
                &amp;lt;syspropertyset&amp;gt;&lt;br /&gt;
                    &amp;lt;propertyref prefix=&amp;quot;test-sys-prop.&amp;quot;/&amp;gt;&lt;br /&gt;
                    &amp;lt;mapper type=&amp;quot;glob&amp;quot; from=&amp;quot;test-sys-prop.*&amp;quot; to=&amp;quot;*&amp;quot;/&amp;gt;&lt;br /&gt;
                &amp;lt;/syspropertyset&amp;gt;&lt;br /&gt;
                .&lt;br /&gt;
		 .&lt;br /&gt;
		 .&lt;br /&gt;
            &amp;lt;/junit&amp;gt;&lt;br /&gt;
	    .&lt;br /&gt;
	    .&lt;br /&gt;
	    .&lt;br /&gt;
        &amp;lt;/sequential&amp;gt;&lt;br /&gt;
    &amp;lt;/macrodef&amp;gt;&lt;br /&gt;
&amp;lt;/target&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;/div&gt;</summary>
		<author><name>201.251.182.130</name></author>	</entry>

	<entry>
		<id>https://dosideas.com/wiki/index.php?title=Configuraci%C3%B3n_de_ejecuci%C3%B3n_selectiva_de_tests&amp;diff=5766</id>
		<title>Configuración de ejecución selectiva de tests</title>
		<link rel="alternate" type="text/html" href="https://dosideas.com/wiki/index.php?title=Configuraci%C3%B3n_de_ejecuci%C3%B3n_selectiva_de_tests&amp;diff=5766"/>
				<updated>2011-05-02T18:14:31Z</updated>
		
		<summary type="html">&lt;p&gt;201.251.182.130: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Para poder correr selectivamente los test de integración de nuestras aplicaciones utilizamos la funcionalidad provista por la clase Assume de [[JUnit]]. La clase Assume contiene métodos útiles para afirmar las hipótesis sobre las condiciones en las que los resultados de los test son significativos. Un supuesto negativo no significa que el código está roto, pero si que los resultados de los test no proporciona ninguna información útil. Por defecto [[JUnit]] trata los test con las hipótesis negativas como ignorados.&lt;br /&gt;
&lt;br /&gt;
Para el caso de proyectos creados con [[NetBeans IDE]] compilados con [[Apache Ant]], podemos indicar si queremos o no correr determinados test usando ciertas propiedades.&lt;br /&gt;
&lt;br /&gt;
Propiedad:&lt;br /&gt;
-Dtest-sys-prop.correrIntegracion=NO&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java5&amp;gt;&lt;br /&gt;
&lt;br /&gt;
@BeforeClass&lt;br /&gt;
public static void setUpOnce() throws Throwable {&lt;br /&gt;
        System.out.println(&amp;quot;Se usarán los test de integración [SI/NO]: &amp;quot; + System.getProperty(&amp;quot;correrIntegracion&amp;quot;));&lt;br /&gt;
        Assume.assumeTrue(System.getProperty(&amp;quot;correrIntegracion&amp;quot;) == null&lt;br /&gt;
                ? true : System.getProperty(&amp;quot;correrIntegracion&amp;quot;).matches(&amp;quot;SI&amp;quot;));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Como podemos ver en el ejemplo, por linea de comando se indica la propiedad &amp;quot;test-sys-prop.correrIntegracion&amp;quot;, pero en el test se consulta por la propiedad “correrIntegracion”, esto se debe a que por defecto la tarea [[Ant]] creada por Netbeans para correr los test de [[JUnit]] tiene la propiedad “fork” en true. En esta tarea podemos ver el tag &amp;quot;syspropertyset&amp;quot;, el cual indica que todas las propiedades que tengan el prefijo &amp;quot;test-sys-prop.&amp;quot; se pasen sin este prefijo al proceso iniciado por el fork para ejecutar la clase de test.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
&amp;lt;target name=&amp;quot;-init-macrodef-junit&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;macrodef name=&amp;quot;junit&amp;quot; uri=&amp;quot;http://www.netbeans.org/ns/j2se-project/2&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;attribute name=&amp;quot;includes&amp;quot; default=&amp;quot;**/*Test.java&amp;quot;/&amp;gt;&lt;br /&gt;
        &amp;lt;sequential&amp;gt;&lt;br /&gt;
            &amp;lt;junit showoutput=&amp;quot;true&amp;quot; fork=&amp;quot;true&amp;quot; dir=&amp;quot;${basedir}&amp;quot; failureproperty=&amp;quot;tests.failed&amp;quot; errorproperty=&amp;quot;tests.failed&amp;quot;&amp;gt;&lt;br /&gt;
                .&lt;br /&gt;
		 .&lt;br /&gt;
		 .&lt;br /&gt;
                &amp;lt;syspropertyset&amp;gt;&lt;br /&gt;
                    &amp;lt;propertyref prefix=&amp;quot;test-sys-prop.&amp;quot;/&amp;gt;&lt;br /&gt;
                    &amp;lt;mapper type=&amp;quot;glob&amp;quot; from=&amp;quot;test-sys-prop.*&amp;quot; to=&amp;quot;*&amp;quot;/&amp;gt;&lt;br /&gt;
                &amp;lt;/syspropertyset&amp;gt;&lt;br /&gt;
                .&lt;br /&gt;
		 .&lt;br /&gt;
		 .&lt;br /&gt;
            &amp;lt;/junit&amp;gt;&lt;br /&gt;
	    .&lt;br /&gt;
	    .&lt;br /&gt;
	    .&lt;br /&gt;
        &amp;lt;/sequential&amp;gt;&lt;br /&gt;
    &amp;lt;/macrodef&amp;gt;&lt;br /&gt;
&amp;lt;/target&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;/div&gt;</summary>
		<author><name>201.251.182.130</name></author>	</entry>

	<entry>
		<id>https://dosideas.com/wiki/index.php?title=Selenium_con_DSL&amp;diff=5753</id>
		<title>Selenium con DSL</title>
		<link rel="alternate" type="text/html" href="https://dosideas.com/wiki/index.php?title=Selenium_con_DSL&amp;diff=5753"/>
				<updated>2011-04-29T12:35:02Z</updated>
		
		<summary type="html">&lt;p&gt;201.251.182.130: /* Ejemplo */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Selenium]] es una herramienta para pruebas de aplicaciones web. Quién tuvo la posibilidad de utilizarla, sabrá lo poderosa que es la herramienta, la cuál tiene diversas funciones para ejecutar con nuestra aplicación web. &lt;br /&gt;
Puede ocurrir, que nuestros test de [[Selenium]] se vayan complejizando a medida que nuestra aplicación crece, por lo que esta es una posible solución, combinando el poder de [[Selenium]] con un enfoque [[DSL]].&lt;br /&gt;
&lt;br /&gt;
== Ejemplo ==&lt;br /&gt;
A continuación mostramos una propuesta de como encarar un test de [[Selenium]]con [[DSL]]. Para el ejemplo, suponemos un sistema de biblioteca, con las siguientes pantallas y su navegación.&lt;br /&gt;
Se puede observar que pare este sistemas planteamos dos roles de usuario, el Bibliotecario y el Socio.&lt;br /&gt;
&lt;br /&gt;
[[Archivo:reservaLibro.jpg]]&lt;br /&gt;
&lt;br /&gt;
=== Creando un test ===&lt;br /&gt;
En el siguiente test, vamos a probar la funcionalidad de la reserva de libro.&lt;br /&gt;
Para escribir el siguiente test, se utilizó una sintaxis acotada y simple con las siguientes reglas:&lt;br /&gt;
&lt;br /&gt;
* '''ir'''''&amp;lt;NombreDeLaPagina&amp;gt;'': Los métodos que comiencen con el prefijo “ir”, nos retorna el nuevo contexto (página).&lt;br /&gt;
* '''verificar'''''&amp;lt;Descripción&amp;gt;'':  Los métodos que comiencen con el prefijo &amp;quot;verificar&amp;quot;, poseen los “assert” para comprobar alguna acción realizada en la página, este método siempre retona la misma página (this).&lt;br /&gt;
* '''ingresarComo'''''&amp;lt;Nombre del Rol&amp;gt;'': Rol con el que se probará el sistema.&lt;br /&gt;
* '''aceptar, cancelar, volver, buscar''': Son nombre de las acciones básica que se realizan en un página y pueden (o nó) devolver otra página.&lt;br /&gt;
* ''&amp;lt;acciones propias de la página&amp;gt;'' : Estos métodos realizan acciones sobre el sistema sin ir a otra página. Ej.: reservar&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== ReservaSeleniumDslTest ====&lt;br /&gt;
&amp;lt;code java&amp;gt;&lt;br /&gt;
package com.test.dsl;&lt;br /&gt;
&lt;br /&gt;
import org.junit.AfterClass;&lt;br /&gt;
import org.junit.Assert;&lt;br /&gt;
import org.junit.BeforeClass;&lt;br /&gt;
import org.junit.Test;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
public class ReservaSeleniumDslTest {&lt;br /&gt;
    &lt;br /&gt;
    @BeforeClass&lt;br /&gt;
    public static void setUpClass() throws Exception {&lt;br /&gt;
        Usuario.inicializar();&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    @AfterClass&lt;br /&gt;
    public static void tearDownClass() throws Exception {&lt;br /&gt;
        Usuario.finalizar();&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    @Test&lt;br /&gt;
    public void comoBibliotecarioQuieroRealizarUnaReserva() {&lt;br /&gt;
        Usuario.ingresaComoBibliotecario()&lt;br /&gt;
        .irReservaDeLibro()&lt;br /&gt;
        .reservar()&lt;br /&gt;
        .aceptar()&lt;br /&gt;
        .verificarReserva()&lt;br /&gt;
        .aceptar()&lt;br /&gt;
        .salir();&lt;br /&gt;
    }    &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
De esta forma, escribimos el test de manera que al leer los métodos a los que se invoca, se entiende paso a paso lo que el test realiza, sin confundirnos con la implementación. Utilizando los patrones &amp;quot;method chaining&amp;quot; ,  &amp;quot;builder&amp;quot;, &amp;quot;Page object&amp;quot; ayuda a realizar una abstracción de la implementación.&lt;br /&gt;
&lt;br /&gt;
A continuación  las implementaciones de las clases utilizadas.&lt;br /&gt;
&lt;br /&gt;
==== Usuario ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java&amp;gt;&lt;br /&gt;
package com.test.dsl;&lt;br /&gt;
&lt;br /&gt;
import org.openqa.selenium.server.SeleniumServer;&lt;br /&gt;
&lt;br /&gt;
import com.test.dsl.pagina.HomeBibliotecario;&lt;br /&gt;
import com.test.dsl.pagina.HomeUsuario;&lt;br /&gt;
import com.thoughtworks.selenium.DefaultSelenium;&lt;br /&gt;
import com.thoughtworks.selenium.Selenium;&lt;br /&gt;
&lt;br /&gt;
public class Usuario {&lt;br /&gt;
&lt;br /&gt;
    public static final String TIEMPO_ESPERA = &amp;quot;90000&amp;quot;;&lt;br /&gt;
    public static final String VELOCIDAD_CERO = &amp;quot;0&amp;quot;;&lt;br /&gt;
    public static final String VELOCIDAD_TEST = &amp;quot;350&amp;quot;;&lt;br /&gt;
    &lt;br /&gt;
    private static SeleniumServer seleniumServer;&lt;br /&gt;
    private static Selenium selenium ;&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
    public static void inicializar() throws Exception {&lt;br /&gt;
        seleniumServer = new SeleniumServer();&lt;br /&gt;
        seleniumServer.start();&lt;br /&gt;
        selenium = new DefaultSelenium(&amp;quot;localhost&amp;quot;, 4444, &amp;quot;*chrome&amp;quot;, &amp;quot;http://localhost:8585/&amp;quot;);&lt;br /&gt;
        selenium.start();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public static void finalizar() {&lt;br /&gt;
        selenium.stop();&lt;br /&gt;
        seleniumServer.stop();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public static HomeBibliotecario ingresaComoBibliotecario() {&lt;br /&gt;
        Usuario.login(&amp;quot;bibliotecario_test&amp;quot;,&amp;quot;123456&amp;quot;);&lt;br /&gt;
        return new HomeBibliotecario(selenium);       &lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    public static HomeUsuario ingresaComoUsuario() {&lt;br /&gt;
        Usuario.login(&amp;quot;usuario_test&amp;quot;,&amp;quot;123456&amp;quot;);&lt;br /&gt;
        return new HomeUsuario(selenium);       &lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    private static void login(String username, String password) {&lt;br /&gt;
        selenium.open(&amp;quot;&amp;quot;);&lt;br /&gt;
        selenium.waitForPageToLoad(TIEMPO_ESPERA);&lt;br /&gt;
        selenium.type(&amp;quot;username&amp;quot;, username);&lt;br /&gt;
        selenium.type(&amp;quot;password&amp;quot;, password);&lt;br /&gt;
        selenium.click(&amp;quot;submitbutton&amp;quot;);&lt;br /&gt;
        selenium.waitForPageToLoad(TIEMPO_ESPERA);&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Esta clase es la que determina con que rol vamos a probar la aplicación.&lt;br /&gt;
El método '''ingresarComoBibliotecario''' instancia y devuelve un objeto de la clase '''HomeBibliotecario''' cuya implementación es:&lt;br /&gt;
&lt;br /&gt;
==== HomeBibliotecario ====&lt;br /&gt;
&amp;lt;code java&amp;gt;&lt;br /&gt;
package com.test.dsl.pagina;&lt;br /&gt;
&lt;br /&gt;
import com.test.dsl.Usuario;&lt;br /&gt;
import com.thoughtworks.selenium.Selenium;&lt;br /&gt;
&lt;br /&gt;
public class HomeBibliotecario {&lt;br /&gt;
    &lt;br /&gt;
    private Selenium selenium;&lt;br /&gt;
&lt;br /&gt;
    public HomeBibliotecario(Selenium selenium) {&lt;br /&gt;
       this.selenium = selenium;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public ReservaDeLibro irReservaDeLibro() {&lt;br /&gt;
        selenium.click(&amp;quot;link=ReservaLibro&amp;quot;);&lt;br /&gt;
        selenium.waitForPageToLoad(Usuario.TIEMPO_ESPERA);&lt;br /&gt;
        return new ReservaDeLibro(selenium);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public void salir() {&lt;br /&gt;
        selenium.click(&amp;quot;link=logout&amp;quot;);        &lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Volvemos a utilizar el patrón builder y el método ingresar denuncia devuelve un objeto de la clase AltaDenuncia. De esta manera, cada clase representa a una pantalla de la aplicación, y expone cada funcionalidad que la misma ofrece. AltaDenuncia sería así:&lt;br /&gt;
Volvemos a utilizar el patrón method chaining y el método '''irReservaDeLibro''' devuelve un objeto de la clase '''ReservaDeLibro'''. De esta manera, cada clase representa a una pantalla de la aplicación (page object), y expone cada funcionalidad que la misma ofrece (acciones que puedo realizar en la página y páginas a la que puedo acceder)&lt;br /&gt;
&lt;br /&gt;
==== ReservaDeLibro ====  &lt;br /&gt;
&amp;lt;code java&amp;gt;&lt;br /&gt;
package com.test.dsl.pagina;&lt;br /&gt;
&lt;br /&gt;
import com.test.dsl.Usuario;&lt;br /&gt;
import com.thoughtworks.selenium.Selenium;&lt;br /&gt;
&lt;br /&gt;
public class ReservaDeLibro {&lt;br /&gt;
&lt;br /&gt;
    private Selenium selenium;&lt;br /&gt;
&lt;br /&gt;
    public ReservaDeLibro(Selenium selenium) {&lt;br /&gt;
       this.selenium = selenium;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public ReservaDeLibro reservar() {&lt;br /&gt;
        selenium.type(&amp;quot;libro&amp;quot;, &amp;quot;El señor de los anillos&amp;quot;);&lt;br /&gt;
        selenium.type(&amp;quot;codSocio&amp;quot;, &amp;quot;0001&amp;quot;);&lt;br /&gt;
        selenium.type(&amp;quot;fechaHasta&amp;quot;, &amp;quot;2011-01-01&amp;quot;);&lt;br /&gt;
        return this;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public ComprobanteDeLibro aceptar() {&lt;br /&gt;
        selenium.click(&amp;quot;submitbutton&amp;quot;);&lt;br /&gt;
        selenium.waitForPageToLoad(Usuario.TIEMPO_ESPERA);&lt;br /&gt;
        return new ComprobanteDeLibro(selenium);&lt;br /&gt;
    }  &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== ComprobanteDeLibro ====  &lt;br /&gt;
&amp;lt;code java&amp;gt;&lt;br /&gt;
package com.test.dsl.pagina;&lt;br /&gt;
&lt;br /&gt;
import org.junit.Assert;&lt;br /&gt;
&lt;br /&gt;
import com.test.dsl.Usuario;&lt;br /&gt;
import com.thoughtworks.selenium.Selenium;&lt;br /&gt;
&lt;br /&gt;
public class ComprobanteDeLibro {&lt;br /&gt;
    private Selenium selenium;&lt;br /&gt;
&lt;br /&gt;
    public ComprobanteDeLibro(Selenium selenium) {&lt;br /&gt;
       this.selenium = selenium;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public ComprobanteDeLibro verificarReserva() {&lt;br /&gt;
        Assert.assertTrue(selenium.isTextPresent(&amp;quot;El señor de los anillos&amp;quot;));&lt;br /&gt;
        Assert.assertTrue(selenium.isTextPresent(&amp;quot;0001&amp;quot;));&lt;br /&gt;
        Assert.assertTrue(selenium.isTextPresent(&amp;quot;2011-01-01&amp;quot;));&lt;br /&gt;
        return this;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    public HomeBibliotecario aceptar() {&lt;br /&gt;
        selenium.click(&amp;quot;submitbutton&amp;quot;);&lt;br /&gt;
        selenium.waitForPageToLoad(Usuario.TIEMPO_ESPERA);&lt;br /&gt;
        return new HomeBibliotecario(selenium);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Tanto el  aceptar (como el cancelar en ReservaDeLibro), devuelven la home del bibliotecario.&lt;br /&gt;
&lt;br /&gt;
== Conclusiones ==&lt;br /&gt;
&lt;br /&gt;
El resultado de hacer los test de esta manera, es la facilidad de escritura y mantenimiento del test en si mismo. A su vez, se podría diseñar las clases a utilizar en el DSL a conveniencia.&lt;/div&gt;</summary>
		<author><name>201.251.182.130</name></author>	</entry>

	<entry>
		<id>https://dosideas.com/wiki/index.php?title=Selenium_con_DSL&amp;diff=5752</id>
		<title>Selenium con DSL</title>
		<link rel="alternate" type="text/html" href="https://dosideas.com/wiki/index.php?title=Selenium_con_DSL&amp;diff=5752"/>
				<updated>2011-04-29T12:30:53Z</updated>
		
		<summary type="html">&lt;p&gt;201.251.182.130: /* Creando un test */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Selenium]] es una herramienta para pruebas de aplicaciones web. Quién tuvo la posibilidad de utilizarla, sabrá lo poderosa que es la herramienta, la cuál tiene diversas funciones para ejecutar con nuestra aplicación web. &lt;br /&gt;
Puede ocurrir, que nuestros test de [[Selenium]] se vayan complejizando a medida que nuestra aplicación crece, por lo que esta es una posible solución, combinando el poder de [[Selenium]] con un enfoque [[DSL]].&lt;br /&gt;
&lt;br /&gt;
== Ejemplo ==&lt;br /&gt;
A continuación mostramos una propuesta de como encarar un test de [[Selenium]]con [[DSL]]. Para el ejemplo, suponemos un sistema de biblioteca, con las siguientes pantallas y su navegación.&lt;br /&gt;
Se puede observar que pare este sistemas planteamos dos roles de usuario, el Bibliotecario y el Socio.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Creando un test ===&lt;br /&gt;
En el siguiente test, vamos a probar la funcionalidad de la reserva de libro.&lt;br /&gt;
Para escribir el siguiente test, se utilizó una sintaxis acotada y simple con las siguientes reglas:&lt;br /&gt;
&lt;br /&gt;
* '''ir'''''&amp;lt;NombreDeLaPagina&amp;gt;'': Los métodos que comiencen con el prefijo “ir”, nos retorna el nuevo contexto (página).&lt;br /&gt;
* '''verificar'''''&amp;lt;Descripción&amp;gt;'':  Los métodos que comiencen con el prefijo &amp;quot;verificar&amp;quot;, poseen los “assert” para comprobar alguna acción realizada en la página, este método siempre retona la misma página (this).&lt;br /&gt;
* '''ingresarComo'''''&amp;lt;Nombre del Rol&amp;gt;'': Rol con el que se probará el sistema.&lt;br /&gt;
* '''aceptar, cancelar, volver, buscar''': Son nombre de las acciones básica que se realizan en un página y pueden (o nó) devolver otra página.&lt;br /&gt;
* ''&amp;lt;acciones propias de la página&amp;gt;'' : Estos métodos realizan acciones sobre el sistema sin ir a otra página. Ej.: reservar&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== ReservaSeleniumDslTest ====&lt;br /&gt;
&amp;lt;code java&amp;gt;&lt;br /&gt;
package com.test.dsl;&lt;br /&gt;
&lt;br /&gt;
import org.junit.AfterClass;&lt;br /&gt;
import org.junit.Assert;&lt;br /&gt;
import org.junit.BeforeClass;&lt;br /&gt;
import org.junit.Test;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
public class ReservaSeleniumDslTest {&lt;br /&gt;
    &lt;br /&gt;
    @BeforeClass&lt;br /&gt;
    public static void setUpClass() throws Exception {&lt;br /&gt;
        Usuario.inicializar();&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    @AfterClass&lt;br /&gt;
    public static void tearDownClass() throws Exception {&lt;br /&gt;
        Usuario.finalizar();&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    @Test&lt;br /&gt;
    public void comoBibliotecarioQuieroRealizarUnaReserva() {&lt;br /&gt;
        Usuario.ingresaComoBibliotecario()&lt;br /&gt;
        .irReservaDeLibro()&lt;br /&gt;
        .reservar()&lt;br /&gt;
        .aceptar()&lt;br /&gt;
        .verificarReserva()&lt;br /&gt;
        .aceptar()&lt;br /&gt;
        .salir();&lt;br /&gt;
    }    &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
De esta forma, escribimos el test de manera que al leer los métodos a los que se invoca, se entiende paso a paso lo que el test realiza, sin confundirnos con la implementación. Utilizando los patrones &amp;quot;method chaining&amp;quot; ,  &amp;quot;builder&amp;quot;, &amp;quot;Page object&amp;quot; ayuda a realizar una abstracción de la implementación.&lt;br /&gt;
&lt;br /&gt;
A continuación  las implementaciones de las clases utilizadas.&lt;br /&gt;
&lt;br /&gt;
==== Usuario ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java&amp;gt;&lt;br /&gt;
package com.test.dsl;&lt;br /&gt;
&lt;br /&gt;
import org.openqa.selenium.server.SeleniumServer;&lt;br /&gt;
&lt;br /&gt;
import com.test.dsl.pagina.HomeBibliotecario;&lt;br /&gt;
import com.test.dsl.pagina.HomeUsuario;&lt;br /&gt;
import com.thoughtworks.selenium.DefaultSelenium;&lt;br /&gt;
import com.thoughtworks.selenium.Selenium;&lt;br /&gt;
&lt;br /&gt;
public class Usuario {&lt;br /&gt;
&lt;br /&gt;
    public static final String TIEMPO_ESPERA = &amp;quot;90000&amp;quot;;&lt;br /&gt;
    public static final String VELOCIDAD_CERO = &amp;quot;0&amp;quot;;&lt;br /&gt;
    public static final String VELOCIDAD_TEST = &amp;quot;350&amp;quot;;&lt;br /&gt;
    &lt;br /&gt;
    private static SeleniumServer seleniumServer;&lt;br /&gt;
    private static Selenium selenium ;&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
    public static void inicializar() throws Exception {&lt;br /&gt;
        seleniumServer = new SeleniumServer();&lt;br /&gt;
        seleniumServer.start();&lt;br /&gt;
        selenium = new DefaultSelenium(&amp;quot;localhost&amp;quot;, 4444, &amp;quot;*chrome&amp;quot;, &amp;quot;http://localhost:8585/&amp;quot;);&lt;br /&gt;
        selenium.start();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public static void finalizar() {&lt;br /&gt;
        selenium.stop();&lt;br /&gt;
        seleniumServer.stop();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public static HomeBibliotecario ingresaComoBibliotecario() {&lt;br /&gt;
        Usuario.login(&amp;quot;bibliotecario_test&amp;quot;,&amp;quot;123456&amp;quot;);&lt;br /&gt;
        return new HomeBibliotecario(selenium);       &lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    public static HomeUsuario ingresaComoUsuario() {&lt;br /&gt;
        Usuario.login(&amp;quot;usuario_test&amp;quot;,&amp;quot;123456&amp;quot;);&lt;br /&gt;
        return new HomeUsuario(selenium);       &lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    private static void login(String username, String password) {&lt;br /&gt;
        selenium.open(&amp;quot;&amp;quot;);&lt;br /&gt;
        selenium.waitForPageToLoad(TIEMPO_ESPERA);&lt;br /&gt;
        selenium.type(&amp;quot;username&amp;quot;, username);&lt;br /&gt;
        selenium.type(&amp;quot;password&amp;quot;, password);&lt;br /&gt;
        selenium.click(&amp;quot;submitbutton&amp;quot;);&lt;br /&gt;
        selenium.waitForPageToLoad(TIEMPO_ESPERA);&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Esta clase es la que determina con que rol vamos a probar la aplicación.&lt;br /&gt;
El método '''ingresarComoBibliotecario''' instancia y devuelve un objeto de la clase '''HomeBibliotecario''' cuya implementación es:&lt;br /&gt;
&lt;br /&gt;
==== HomeBibliotecario ====&lt;br /&gt;
&amp;lt;code java&amp;gt;&lt;br /&gt;
package com.test.dsl.pagina;&lt;br /&gt;
&lt;br /&gt;
import com.test.dsl.Usuario;&lt;br /&gt;
import com.thoughtworks.selenium.Selenium;&lt;br /&gt;
&lt;br /&gt;
public class HomeBibliotecario {&lt;br /&gt;
    &lt;br /&gt;
    private Selenium selenium;&lt;br /&gt;
&lt;br /&gt;
    public HomeBibliotecario(Selenium selenium) {&lt;br /&gt;
       this.selenium = selenium;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public ReservaDeLibro irReservaDeLibro() {&lt;br /&gt;
        selenium.click(&amp;quot;link=ReservaLibro&amp;quot;);&lt;br /&gt;
        selenium.waitForPageToLoad(Usuario.TIEMPO_ESPERA);&lt;br /&gt;
        return new ReservaDeLibro(selenium);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public void salir() {&lt;br /&gt;
        selenium.click(&amp;quot;link=logout&amp;quot;);        &lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Volvemos a utilizar el patrón builder y el método ingresar denuncia devuelve un objeto de la clase AltaDenuncia. De esta manera, cada clase representa a una pantalla de la aplicación, y expone cada funcionalidad que la misma ofrece. AltaDenuncia sería así:&lt;br /&gt;
Volvemos a utilizar el patrón method chaining y el método '''irReservaDeLibro''' devuelve un objeto de la clase '''ReservaDeLibro'''. De esta manera, cada clase representa a una pantalla de la aplicación (page object), y expone cada funcionalidad que la misma ofrece (acciones que puedo realizar en la página y páginas a la que puedo acceder)&lt;br /&gt;
&lt;br /&gt;
==== ReservaDeLibro ====  &lt;br /&gt;
&amp;lt;code java&amp;gt;&lt;br /&gt;
package com.test.dsl.pagina;&lt;br /&gt;
&lt;br /&gt;
import com.test.dsl.Usuario;&lt;br /&gt;
import com.thoughtworks.selenium.Selenium;&lt;br /&gt;
&lt;br /&gt;
public class ReservaDeLibro {&lt;br /&gt;
&lt;br /&gt;
    private Selenium selenium;&lt;br /&gt;
&lt;br /&gt;
    public ReservaDeLibro(Selenium selenium) {&lt;br /&gt;
       this.selenium = selenium;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public ReservaDeLibro reservar() {&lt;br /&gt;
        selenium.type(&amp;quot;libro&amp;quot;, &amp;quot;El señor de los anillos&amp;quot;);&lt;br /&gt;
        selenium.type(&amp;quot;codSocio&amp;quot;, &amp;quot;0001&amp;quot;);&lt;br /&gt;
        selenium.type(&amp;quot;fechaHasta&amp;quot;, &amp;quot;2011-01-01&amp;quot;);&lt;br /&gt;
        return this;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public ComprobanteDeLibro aceptar() {&lt;br /&gt;
        selenium.click(&amp;quot;submitbutton&amp;quot;);&lt;br /&gt;
        selenium.waitForPageToLoad(Usuario.TIEMPO_ESPERA);&lt;br /&gt;
        return new ComprobanteDeLibro(selenium);&lt;br /&gt;
    }  &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== ComprobanteDeLibro ====  &lt;br /&gt;
&amp;lt;code java&amp;gt;&lt;br /&gt;
package com.test.dsl.pagina;&lt;br /&gt;
&lt;br /&gt;
import org.junit.Assert;&lt;br /&gt;
&lt;br /&gt;
import com.test.dsl.Usuario;&lt;br /&gt;
import com.thoughtworks.selenium.Selenium;&lt;br /&gt;
&lt;br /&gt;
public class ComprobanteDeLibro {&lt;br /&gt;
    private Selenium selenium;&lt;br /&gt;
&lt;br /&gt;
    public ComprobanteDeLibro(Selenium selenium) {&lt;br /&gt;
       this.selenium = selenium;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public ComprobanteDeLibro verificarReserva() {&lt;br /&gt;
        Assert.assertTrue(selenium.isTextPresent(&amp;quot;El señor de los anillos&amp;quot;));&lt;br /&gt;
        Assert.assertTrue(selenium.isTextPresent(&amp;quot;0001&amp;quot;));&lt;br /&gt;
        Assert.assertTrue(selenium.isTextPresent(&amp;quot;2011-01-01&amp;quot;));&lt;br /&gt;
        return this;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    public HomeBibliotecario aceptar() {&lt;br /&gt;
        selenium.click(&amp;quot;submitbutton&amp;quot;);&lt;br /&gt;
        selenium.waitForPageToLoad(Usuario.TIEMPO_ESPERA);&lt;br /&gt;
        return new HomeBibliotecario(selenium);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Tanto el  aceptar (como el cancelar en ReservaDeLibro), devuelven la home del bibliotecario.&lt;br /&gt;
&lt;br /&gt;
== Conclusiones ==&lt;br /&gt;
&lt;br /&gt;
El resultado de hacer los test de esta manera, es la facilidad de escritura y mantenimiento del test en si mismo. A su vez, se podría diseñar las clases a utilizar en el DSL a conveniencia.&lt;/div&gt;</summary>
		<author><name>201.251.182.130</name></author>	</entry>

	<entry>
		<id>https://dosideas.com/wiki/index.php?title=Selenium_con_DSL&amp;diff=5751</id>
		<title>Selenium con DSL</title>
		<link rel="alternate" type="text/html" href="https://dosideas.com/wiki/index.php?title=Selenium_con_DSL&amp;diff=5751"/>
				<updated>2011-04-29T12:30:03Z</updated>
		
		<summary type="html">&lt;p&gt;201.251.182.130: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Selenium]] es una herramienta para pruebas de aplicaciones web. Quién tuvo la posibilidad de utilizarla, sabrá lo poderosa que es la herramienta, la cuál tiene diversas funciones para ejecutar con nuestra aplicación web. &lt;br /&gt;
Puede ocurrir, que nuestros test de [[Selenium]] se vayan complejizando a medida que nuestra aplicación crece, por lo que esta es una posible solución, combinando el poder de [[Selenium]] con un enfoque [[DSL]].&lt;br /&gt;
&lt;br /&gt;
== Ejemplo ==&lt;br /&gt;
A continuación mostramos una propuesta de como encarar un test de [[Selenium]]con [[DSL]]. Para el ejemplo, suponemos un sistema de biblioteca, con las siguientes pantallas y su navegación.&lt;br /&gt;
Se puede observar que pare este sistemas planteamos dos roles de usuario, el Bibliotecario y el Socio.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Creando un test ===&lt;br /&gt;
En el siguiente test, vamos a probar la funcionalidad de la reserva de libro.&lt;br /&gt;
Para escribir el siguiente test, se utilizó una sintaxis acotada y simple con las siguientes reglas:&lt;br /&gt;
&lt;br /&gt;
* '''ir'''''&amp;lt;NombreDeLaPagina&amp;gt;'': Los métodos que comiencen con el prefijo “ir”, nos retorna el nuevo contexto (página).&lt;br /&gt;
* '''verificar'''''&amp;lt;Descripción&amp;gt;'':  Los métodos que comiencen con el prefijo &amp;quot;verificar&amp;quot;, poseen los “assert” para comprobar alguna acción realizada en la página, este método siempre retona la misma página (this).&lt;br /&gt;
* '''ingresarComo'''''&amp;lt;Nombre del Rol&amp;gt;'': Rol con el que se probará el sistema en la prueba.&lt;br /&gt;
* '''aceptar, cancelar, volver, buscar''': Son nombre de las acciones básica que se realizan en un página y pueden (o nó) devolver otra página.&lt;br /&gt;
* ''&amp;lt;acciones propias de la página&amp;gt;'' : Estos métodos realizan acciones sobre el sistema sin ir a otra página. Ej.: reservar&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== ReservaSeleniumDslTest ====&lt;br /&gt;
&amp;lt;code java&amp;gt;&lt;br /&gt;
package com.test.dsl;&lt;br /&gt;
&lt;br /&gt;
import org.junit.AfterClass;&lt;br /&gt;
import org.junit.Assert;&lt;br /&gt;
import org.junit.BeforeClass;&lt;br /&gt;
import org.junit.Test;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
public class ReservaSeleniumDslTest {&lt;br /&gt;
    &lt;br /&gt;
    @BeforeClass&lt;br /&gt;
    public static void setUpClass() throws Exception {&lt;br /&gt;
        Usuario.inicializar();&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    @AfterClass&lt;br /&gt;
    public static void tearDownClass() throws Exception {&lt;br /&gt;
        Usuario.finalizar();&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    @Test&lt;br /&gt;
    public void comoBibliotecarioQuieroRealizarUnaReserva() {&lt;br /&gt;
        Usuario.ingresaComoBibliotecario()&lt;br /&gt;
        .irReservaDeLibro()&lt;br /&gt;
        .reservar()&lt;br /&gt;
        .aceptar()&lt;br /&gt;
        .verificarReserva()&lt;br /&gt;
        .aceptar()&lt;br /&gt;
        .salir();&lt;br /&gt;
    }    &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
De esta forma, escribimos el test de manera que al leer los métodos a los que se invoca, se entiende paso a paso lo que el test realiza, sin confundirnos con la implementación. Utilizando los patrones &amp;quot;method chaining&amp;quot; ,  &amp;quot;builder&amp;quot;, &amp;quot;Page object&amp;quot; ayuda a realizar una abstracción de la implementación.&lt;br /&gt;
&lt;br /&gt;
A continuación  las implementaciones de las clases utilizadas.&lt;br /&gt;
&lt;br /&gt;
==== Usuario ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java&amp;gt;&lt;br /&gt;
package com.test.dsl;&lt;br /&gt;
&lt;br /&gt;
import org.openqa.selenium.server.SeleniumServer;&lt;br /&gt;
&lt;br /&gt;
import com.test.dsl.pagina.HomeBibliotecario;&lt;br /&gt;
import com.test.dsl.pagina.HomeUsuario;&lt;br /&gt;
import com.thoughtworks.selenium.DefaultSelenium;&lt;br /&gt;
import com.thoughtworks.selenium.Selenium;&lt;br /&gt;
&lt;br /&gt;
public class Usuario {&lt;br /&gt;
&lt;br /&gt;
    public static final String TIEMPO_ESPERA = &amp;quot;90000&amp;quot;;&lt;br /&gt;
    public static final String VELOCIDAD_CERO = &amp;quot;0&amp;quot;;&lt;br /&gt;
    public static final String VELOCIDAD_TEST = &amp;quot;350&amp;quot;;&lt;br /&gt;
    &lt;br /&gt;
    private static SeleniumServer seleniumServer;&lt;br /&gt;
    private static Selenium selenium ;&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
    public static void inicializar() throws Exception {&lt;br /&gt;
        seleniumServer = new SeleniumServer();&lt;br /&gt;
        seleniumServer.start();&lt;br /&gt;
        selenium = new DefaultSelenium(&amp;quot;localhost&amp;quot;, 4444, &amp;quot;*chrome&amp;quot;, &amp;quot;http://localhost:8585/&amp;quot;);&lt;br /&gt;
        selenium.start();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public static void finalizar() {&lt;br /&gt;
        selenium.stop();&lt;br /&gt;
        seleniumServer.stop();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public static HomeBibliotecario ingresaComoBibliotecario() {&lt;br /&gt;
        Usuario.login(&amp;quot;bibliotecario_test&amp;quot;,&amp;quot;123456&amp;quot;);&lt;br /&gt;
        return new HomeBibliotecario(selenium);       &lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    public static HomeUsuario ingresaComoUsuario() {&lt;br /&gt;
        Usuario.login(&amp;quot;usuario_test&amp;quot;,&amp;quot;123456&amp;quot;);&lt;br /&gt;
        return new HomeUsuario(selenium);       &lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    private static void login(String username, String password) {&lt;br /&gt;
        selenium.open(&amp;quot;&amp;quot;);&lt;br /&gt;
        selenium.waitForPageToLoad(TIEMPO_ESPERA);&lt;br /&gt;
        selenium.type(&amp;quot;username&amp;quot;, username);&lt;br /&gt;
        selenium.type(&amp;quot;password&amp;quot;, password);&lt;br /&gt;
        selenium.click(&amp;quot;submitbutton&amp;quot;);&lt;br /&gt;
        selenium.waitForPageToLoad(TIEMPO_ESPERA);&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Esta clase es la que determina con que rol vamos a probar la aplicación.&lt;br /&gt;
El método '''ingresarComoBibliotecario''' instancia y devuelve un objeto de la clase '''HomeBibliotecario''' cuya implementación es:&lt;br /&gt;
&lt;br /&gt;
==== HomeBibliotecario ====&lt;br /&gt;
&amp;lt;code java&amp;gt;&lt;br /&gt;
package com.test.dsl.pagina;&lt;br /&gt;
&lt;br /&gt;
import com.test.dsl.Usuario;&lt;br /&gt;
import com.thoughtworks.selenium.Selenium;&lt;br /&gt;
&lt;br /&gt;
public class HomeBibliotecario {&lt;br /&gt;
    &lt;br /&gt;
    private Selenium selenium;&lt;br /&gt;
&lt;br /&gt;
    public HomeBibliotecario(Selenium selenium) {&lt;br /&gt;
       this.selenium = selenium;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public ReservaDeLibro irReservaDeLibro() {&lt;br /&gt;
        selenium.click(&amp;quot;link=ReservaLibro&amp;quot;);&lt;br /&gt;
        selenium.waitForPageToLoad(Usuario.TIEMPO_ESPERA);&lt;br /&gt;
        return new ReservaDeLibro(selenium);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public void salir() {&lt;br /&gt;
        selenium.click(&amp;quot;link=logout&amp;quot;);        &lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Volvemos a utilizar el patrón builder y el método ingresar denuncia devuelve un objeto de la clase AltaDenuncia. De esta manera, cada clase representa a una pantalla de la aplicación, y expone cada funcionalidad que la misma ofrece. AltaDenuncia sería así:&lt;br /&gt;
Volvemos a utilizar el patrón method chaining y el método '''irReservaDeLibro''' devuelve un objeto de la clase '''ReservaDeLibro'''. De esta manera, cada clase representa a una pantalla de la aplicación (page object), y expone cada funcionalidad que la misma ofrece (acciones que puedo realizar en la página y páginas a la que puedo acceder)&lt;br /&gt;
&lt;br /&gt;
==== ReservaDeLibro ====  &lt;br /&gt;
&amp;lt;code java&amp;gt;&lt;br /&gt;
package com.test.dsl.pagina;&lt;br /&gt;
&lt;br /&gt;
import com.test.dsl.Usuario;&lt;br /&gt;
import com.thoughtworks.selenium.Selenium;&lt;br /&gt;
&lt;br /&gt;
public class ReservaDeLibro {&lt;br /&gt;
&lt;br /&gt;
    private Selenium selenium;&lt;br /&gt;
&lt;br /&gt;
    public ReservaDeLibro(Selenium selenium) {&lt;br /&gt;
       this.selenium = selenium;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public ReservaDeLibro reservar() {&lt;br /&gt;
        selenium.type(&amp;quot;libro&amp;quot;, &amp;quot;El señor de los anillos&amp;quot;);&lt;br /&gt;
        selenium.type(&amp;quot;codSocio&amp;quot;, &amp;quot;0001&amp;quot;);&lt;br /&gt;
        selenium.type(&amp;quot;fechaHasta&amp;quot;, &amp;quot;2011-01-01&amp;quot;);&lt;br /&gt;
        return this;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public ComprobanteDeLibro aceptar() {&lt;br /&gt;
        selenium.click(&amp;quot;submitbutton&amp;quot;);&lt;br /&gt;
        selenium.waitForPageToLoad(Usuario.TIEMPO_ESPERA);&lt;br /&gt;
        return new ComprobanteDeLibro(selenium);&lt;br /&gt;
    }  &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== ComprobanteDeLibro ====  &lt;br /&gt;
&amp;lt;code java&amp;gt;&lt;br /&gt;
package com.test.dsl.pagina;&lt;br /&gt;
&lt;br /&gt;
import org.junit.Assert;&lt;br /&gt;
&lt;br /&gt;
import com.test.dsl.Usuario;&lt;br /&gt;
import com.thoughtworks.selenium.Selenium;&lt;br /&gt;
&lt;br /&gt;
public class ComprobanteDeLibro {&lt;br /&gt;
    private Selenium selenium;&lt;br /&gt;
&lt;br /&gt;
    public ComprobanteDeLibro(Selenium selenium) {&lt;br /&gt;
       this.selenium = selenium;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public ComprobanteDeLibro verificarReserva() {&lt;br /&gt;
        Assert.assertTrue(selenium.isTextPresent(&amp;quot;El señor de los anillos&amp;quot;));&lt;br /&gt;
        Assert.assertTrue(selenium.isTextPresent(&amp;quot;0001&amp;quot;));&lt;br /&gt;
        Assert.assertTrue(selenium.isTextPresent(&amp;quot;2011-01-01&amp;quot;));&lt;br /&gt;
        return this;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    public HomeBibliotecario aceptar() {&lt;br /&gt;
        selenium.click(&amp;quot;submitbutton&amp;quot;);&lt;br /&gt;
        selenium.waitForPageToLoad(Usuario.TIEMPO_ESPERA);&lt;br /&gt;
        return new HomeBibliotecario(selenium);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Tanto el  aceptar (como el cancelar en ReservaDeLibro), devuelven la home del bibliotecario. &lt;br /&gt;
&lt;br /&gt;
== Conclusiones ==&lt;br /&gt;
&lt;br /&gt;
El resultado de hacer los test de esta manera, es la facilidad de escritura y mantenimiento del test en si mismo. A su vez, se podría diseñar las clases a utilizar en el DSL a conveniencia.&lt;/div&gt;</summary>
		<author><name>201.251.182.130</name></author>	</entry>

	<entry>
		<id>https://dosideas.com/wiki/index.php?title=BEA_Aqualogic_BPM_5.7_(Fuego)&amp;diff=5687</id>
		<title>BEA Aqualogic BPM 5.7 (Fuego)</title>
		<link rel="alternate" type="text/html" href="https://dosideas.com/wiki/index.php?title=BEA_Aqualogic_BPM_5.7_(Fuego)&amp;diff=5687"/>
				<updated>2011-01-25T13:03:10Z</updated>
		
		<summary type="html">&lt;p&gt;201.251.182.130: /* Segundo paso */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===Comunicando con Base de Datos con PBL (Process Business Language)===&lt;br /&gt;
&lt;br /&gt;
Para ejecutar comandos SQL en Aqualogic BPM 5.7 hay que seguir los siguientes pasos: &lt;br /&gt;
&lt;br /&gt;
====Primer paso====&lt;br /&gt;
&lt;br /&gt;
Se debe crear nuevo &amp;quot;External Resource&amp;quot;, haciendo click derecho en el directorio del proyecto &amp;quot;External Resources&amp;quot;, del tipo &amp;quot;SQL Database&amp;quot;. Los campos se deben completar con la información de la base de datos que queremos consultar y con un nombre significativo.&lt;br /&gt;
&lt;br /&gt;
====Segundo paso====&lt;br /&gt;
 &lt;br /&gt;
Se debe crear un nuevo &amp;quot;BPM Object&amp;quot;, haciendo click derecho sobre el modulo deseado en el directorio de &amp;quot;Catalog&amp;quot;, y luego crear un método en nuestro objeto, haciendo click derecho sobre el objeto y seleccionando la opción &amp;quot;New Method&amp;quot;. Ahora se debe editar el nuevo método, expandiendo el objeto bpm y haciendo doble click sobre el nombre del método creado. Ahora podemos editarlo e incluir el código necesario para comunicarnos con la BD a través de una clase propia de Fuego, un ejemplo de implementación puede ser el siguiente: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java&amp;gt;&lt;br /&gt;
String queryAEjecutar =&amp;quot;SELECT campo1, campo2, campo3 FROM nombreTabla WHERE nombreColumna in (?,?)&amp;quot;; &lt;br /&gt;
&lt;br /&gt;
String nombreDeLaBDCreada = &amp;quot;NombreBD&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
String[] arrayDeParametros = {&amp;quot;valor1&amp;quot;, &amp;quot;valor2&amp;quot;};&lt;br /&gt;
&lt;br /&gt;
Iterator &amp;lt;Any[Any]&amp;gt; iterator = DynamicSQL.executeQuery(sentence : queryAEjecutar, implname : nombreDeLaBDCreada, inParameters : arrayDeParametros);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Como se puede observar, el resultado de realizar la consulta va a ser un iterador, que luego puede ser recorrido con un &amp;quot;foreach&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java&amp;gt;&lt;br /&gt;
foreach (e in iterator) {&lt;br /&gt;
&lt;br /&gt;
   logMessage(&amp;quot;campo1: &amp;quot;+e[&amp;quot;campo1&amp;quot;], severity : INFO);&lt;br /&gt;
&lt;br /&gt;
   logMessage(&amp;quot;campo2: &amp;quot;+e[&amp;quot;campo2&amp;quot;], severity : INFO);&lt;br /&gt;
&lt;br /&gt;
   logMessage(&amp;quot;campo3: &amp;quot;+e[&amp;quot;campo3&amp;quot;], severity : INFO);&lt;br /&gt;
&lt;br /&gt;
   logMessage(&amp;quot;nombreColumna: &amp;quot;+e[&amp;quot;nombreColumna&amp;quot;], severity : INFO);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Versionando con CVS ===&lt;br /&gt;
El producto Aqualogic BPM 5.7 incluye un cliente de CVS que permite agregar, remover, actualizar en un repositorio CVS.&lt;br /&gt;
&lt;br /&gt;
==== Configurar el cliente CVS ====&lt;br /&gt;
* Levantar el Studio BPM.&lt;br /&gt;
* File -&amp;gt; Preference -&amp;gt;Default Version Control&lt;br /&gt;
** Version Control Manger: CVS&lt;br /&gt;
** Host: host del servidor CVS&lt;br /&gt;
** User Name: usuario del CVS&lt;br /&gt;
** User Password: password del usuario CVS&lt;br /&gt;
** path: ruta dentro del repositorio donde se guardará el proyecto.&lt;br /&gt;
&lt;br /&gt;
==== Subir el proyecto al CVS ====&lt;br /&gt;
* Levantar el Studio BPM.&lt;br /&gt;
* Abrir el proyecto a versionar.&lt;br /&gt;
* File -&amp;gt; Project Preference -&amp;gt; Project Version Control.&lt;br /&gt;
** Version Control Manager: CVS (nos carga la información ingresada en el punto anterior).&lt;br /&gt;
* File -&amp;gt; VCS -&amp;gt; Store project in repository&lt;br /&gt;
** Path: directorio en el que se creará el proyecto en el repositorio.&lt;br /&gt;
** Si es la primera vez que se sube un proyecto de Aqualogic BPM, pedirá que se ingrese la ruta del directorio donde se creará el &amp;quot;common catalog&amp;quot;&lt;br /&gt;
*** Common catalog: Es un catalogo de componente, el cual puede ser compartido por otros proyectos de Aqualogic BPM.&lt;br /&gt;
En el repositorio quedarán creados 2 directorios, el del proyecto y el del common catalog, ademas se crearán 2 alias en el CVS que apuntan al proyecto y al common catalog.&lt;br /&gt;
&lt;br /&gt;
==== Obtener el proyecto del CVS ====&lt;br /&gt;
* Levantar el Studio BPM.&lt;br /&gt;
* File -&amp;gt; Project Preference -&amp;gt; Project Version Control.&lt;br /&gt;
* File -&amp;gt; Import -&amp;gt; Project -&amp;gt; from Repository.&lt;br /&gt;
** Version Control Manager: CVS&lt;br /&gt;
** En la siguiente pantalla, seleccionar el proyecto del repositorio.&lt;br /&gt;
&lt;br /&gt;
==== Trabajar con proyectos versionados ====&lt;br /&gt;
Aqualogic BPM 5.7, posee una política restrictiva de edición para los proyecto versionados.&lt;br /&gt;
La política, consiste en que todo el proyecto se encuentra en modo lectura y solo un usuario puede editar un determinado archivo versionado (Ej.: un proceso).&lt;br /&gt;
===== Editar un procesos =====&lt;br /&gt;
* Seleccionar el proceso a editar.&lt;br /&gt;
* Menú contextual -&amp;gt; VCS -&amp;gt; edit.&lt;br /&gt;
Esto habilita al usuario a modificar el proceso. En caso de que exitiera otro usuario modificando el proceso nos aparecerá un mensaje de error.&lt;br /&gt;
&lt;br /&gt;
===== Grabar los cambios realizados en un proceso =====&lt;br /&gt;
* Seleccionar el proceso que se esta editando.&lt;br /&gt;
* Menú contextual -&amp;gt; VCS -&amp;gt; commit.&lt;br /&gt;
Este paso es importante, debido a que si se libera la edición del proceso sin realizar el commit se perderán los cambios.&lt;br /&gt;
&lt;br /&gt;
===== Liberar la edición del proceso =====&lt;br /&gt;
* Seleccionar el proceso que se esta editando.&lt;br /&gt;
* Menú contextual -&amp;gt; VCS -&amp;gt; unedit.&lt;br /&gt;
&lt;br /&gt;
=== Ver también  ===&lt;br /&gt;
* [[Oracle BPM]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Oracle]]&lt;/div&gt;</summary>
		<author><name>201.251.182.130</name></author>	</entry>

	<entry>
		<id>https://dosideas.com/wiki/index.php?title=BEA_Aqualogic_BPM_5.7_(Fuego)&amp;diff=5686</id>
		<title>BEA Aqualogic BPM 5.7 (Fuego)</title>
		<link rel="alternate" type="text/html" href="https://dosideas.com/wiki/index.php?title=BEA_Aqualogic_BPM_5.7_(Fuego)&amp;diff=5686"/>
				<updated>2011-01-24T18:45:43Z</updated>
		
		<summary type="html">&lt;p&gt;201.251.182.130: /* Versionando con CVS */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===Comunicando con Base de Datos con PBL (Process Business Language)===&lt;br /&gt;
&lt;br /&gt;
Para ejecutar comandos SQL en Aqualogic BPM 5.7 hay que seguir los siguientes pasos: &lt;br /&gt;
&lt;br /&gt;
====Primer paso====&lt;br /&gt;
&lt;br /&gt;
Se debe crear nuevo &amp;quot;External Resource&amp;quot;, haciendo click derecho en el directorio del proyecto &amp;quot;External Resources&amp;quot;, del tipo &amp;quot;SQL Database&amp;quot;. Los campos se deben completar con la información de la base de datos que queremos consultar y con un nombre significativo.&lt;br /&gt;
&lt;br /&gt;
====Segundo paso====&lt;br /&gt;
 &lt;br /&gt;
Se debe crear un nuevo &amp;quot;BPM Object&amp;quot;, haciendo click derecho sobre el modulo deseado en el directorio de &amp;quot;Catalog&amp;quot;, y luego crear un método en nuestro objeto, haciendo click derecho sobre el objeto y seleccionando la opción &amp;quot;New Method&amp;quot;. Ahora se debe editar el nuevo método, expandiendo el objeto bpm y haciendo doble click sobre el nombre del método creado. Ahora podemos editarlo e incluir el código necesario para comunicarnos con la BD a través de una clase propia de Fuego, un ejemplo de implementación puede ser el siguiente: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java&amp;gt;&lt;br /&gt;
String queryAEjecutar =&amp;quot;SELECT campo1, campo2, campo3 FROM nombreTabla WHERE nombreColumna in (?,?)&amp;quot;; &lt;br /&gt;
&lt;br /&gt;
String nombreDeLaBDCreada = &amp;quot;NombreBD&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
String[] arrayDeParametros = {&amp;quot;valor1&amp;quot;, &amp;quot;valor2&amp;quot;};&lt;br /&gt;
&lt;br /&gt;
Iterator iterator = DynamicSQL.executeQuery(sentence : queryAEjecutar, implname : nombreDeLaBDCreada, inParameters : arrayDeParametros);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Como se puede observar, el resultado de realizar la consulta va a ser un iterador, que luego puede ser recorrido con un &amp;quot;foreach&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java&amp;gt;&lt;br /&gt;
foreach (e in iterator) {&lt;br /&gt;
&lt;br /&gt;
   logMessage(&amp;quot;campo1: &amp;quot;+e[&amp;quot;campo1&amp;quot;], severity : INFO);&lt;br /&gt;
&lt;br /&gt;
   logMessage(&amp;quot;campo2: &amp;quot;+e[&amp;quot;campo2&amp;quot;], severity : INFO);&lt;br /&gt;
&lt;br /&gt;
   logMessage(&amp;quot;campo3: &amp;quot;+e[&amp;quot;campo3&amp;quot;], severity : INFO);&lt;br /&gt;
&lt;br /&gt;
   logMessage(&amp;quot;nombreColumna: &amp;quot;+e[&amp;quot;nombreColumna&amp;quot;], severity : INFO);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Versionando con CVS ===&lt;br /&gt;
El producto Aqualogic BPM 5.7 incluye un cliente de CVS que permite agregar, remover, actualizar en un repositorio CVS.&lt;br /&gt;
&lt;br /&gt;
==== Configurar el cliente CVS ====&lt;br /&gt;
* Levantar el Studio BPM.&lt;br /&gt;
* File -&amp;gt; Preference -&amp;gt;Default Version Control&lt;br /&gt;
** Version Control Manger: CVS&lt;br /&gt;
** Host: host del servidor CVS&lt;br /&gt;
** User Name: usuario del CVS&lt;br /&gt;
** User Password: password del usuario CVS&lt;br /&gt;
** path: ruta dentro del repositorio donde se guardará el proyecto.&lt;br /&gt;
&lt;br /&gt;
==== Subir el proyecto al CVS ====&lt;br /&gt;
* Levantar el Studio BPM.&lt;br /&gt;
* Abrir el proyecto a versionar.&lt;br /&gt;
* File -&amp;gt; Project Preference -&amp;gt; Project Version Control.&lt;br /&gt;
** Version Control Manager: CVS (nos carga la información ingresada en el punto anterior).&lt;br /&gt;
* File -&amp;gt; VCS -&amp;gt; Store project in repository&lt;br /&gt;
** Path: directorio en el que se creará el proyecto en el repositorio.&lt;br /&gt;
** Si es la primera vez que se sube un proyecto de Aqualogic BPM, pedirá que se ingrese la ruta del directorio donde se creará el &amp;quot;common catalog&amp;quot;&lt;br /&gt;
*** Common catalog: Es un catalogo de componente, el cual puede ser compartido por otros proyectos de Aqualogic BPM.&lt;br /&gt;
En el repositorio quedarán creados 2 directorios, el del proyecto y el del common catalog, ademas se crearán 2 alias en el CVS que apuntan al proyecto y al common catalog.&lt;br /&gt;
&lt;br /&gt;
==== Obtener el proyecto del CVS ====&lt;br /&gt;
* Levantar el Studio BPM.&lt;br /&gt;
* File -&amp;gt; Project Preference -&amp;gt; Project Version Control.&lt;br /&gt;
* File -&amp;gt; Import -&amp;gt; Project -&amp;gt; from Repository.&lt;br /&gt;
** Version Control Manager: CVS&lt;br /&gt;
** En la siguiente pantalla, seleccionar el proyecto del repositorio.&lt;br /&gt;
&lt;br /&gt;
==== Trabajar con proyectos versionados ====&lt;br /&gt;
Aqualogic BPM 5.7, posee una política restrictiva de edición para los proyecto versionados.&lt;br /&gt;
La política, consiste en que todo el proyecto se encuentra en modo lectura y solo un usuario puede editar un determinado archivo versionado (Ej.: un proceso).&lt;br /&gt;
===== Editar un procesos =====&lt;br /&gt;
* Seleccionar el proceso a editar.&lt;br /&gt;
* Menú contextual -&amp;gt; VCS -&amp;gt; edit.&lt;br /&gt;
Esto habilita al usuario a modificar el proceso. En caso de que exitiera otro usuario modificando el proceso nos aparecerá un mensaje de error.&lt;br /&gt;
&lt;br /&gt;
===== Grabar los cambios realizados en un proceso =====&lt;br /&gt;
* Seleccionar el proceso que se esta editando.&lt;br /&gt;
* Menú contextual -&amp;gt; VCS -&amp;gt; commit.&lt;br /&gt;
Este paso es importante, debido a que si se libera la edición del proceso sin realizar el commit se perderán los cambios.&lt;br /&gt;
&lt;br /&gt;
===== Liberar la edición del proceso =====&lt;br /&gt;
* Seleccionar el proceso que se esta editando.&lt;br /&gt;
* Menú contextual -&amp;gt; VCS -&amp;gt; unedit.&lt;br /&gt;
&lt;br /&gt;
=== Ver también  ===&lt;br /&gt;
* [[Oracle BPM]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Oracle]]&lt;/div&gt;</summary>
		<author><name>201.251.182.130</name></author>	</entry>

	<entry>
		<id>https://dosideas.com/wiki/index.php?title=BEA_Aqualogic_BPM_5.7_(Fuego)&amp;diff=5685</id>
		<title>BEA Aqualogic BPM 5.7 (Fuego)</title>
		<link rel="alternate" type="text/html" href="https://dosideas.com/wiki/index.php?title=BEA_Aqualogic_BPM_5.7_(Fuego)&amp;diff=5685"/>
				<updated>2011-01-24T18:25:48Z</updated>
		
		<summary type="html">&lt;p&gt;201.251.182.130: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===Comunicando con Base de Datos con PBL (Process Business Language)===&lt;br /&gt;
&lt;br /&gt;
Para ejecutar comandos SQL en Aqualogic BPM 5.7 hay que seguir los siguientes pasos: &lt;br /&gt;
&lt;br /&gt;
====Primer paso====&lt;br /&gt;
&lt;br /&gt;
Se debe crear nuevo &amp;quot;External Resource&amp;quot;, haciendo click derecho en el directorio del proyecto &amp;quot;External Resources&amp;quot;, del tipo &amp;quot;SQL Database&amp;quot;. Los campos se deben completar con la información de la base de datos que queremos consultar y con un nombre significativo.&lt;br /&gt;
&lt;br /&gt;
====Segundo paso====&lt;br /&gt;
 &lt;br /&gt;
Se debe crear un nuevo &amp;quot;BPM Object&amp;quot;, haciendo click derecho sobre el modulo deseado en el directorio de &amp;quot;Catalog&amp;quot;, y luego crear un método en nuestro objeto, haciendo click derecho sobre el objeto y seleccionando la opción &amp;quot;New Method&amp;quot;. Ahora se debe editar el nuevo método, expandiendo el objeto bpm y haciendo doble click sobre el nombre del método creado. Ahora podemos editarlo e incluir el código necesario para comunicarnos con la BD a través de una clase propia de Fuego, un ejemplo de implementación puede ser el siguiente: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java&amp;gt;&lt;br /&gt;
String queryAEjecutar =&amp;quot;SELECT campo1, campo2, campo3 FROM nombreTabla WHERE nombreColumna in (?,?)&amp;quot;; &lt;br /&gt;
&lt;br /&gt;
String nombreDeLaBDCreada = &amp;quot;NombreBD&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
String[] arrayDeParametros = {&amp;quot;valor1&amp;quot;, &amp;quot;valor2&amp;quot;};&lt;br /&gt;
&lt;br /&gt;
Iterator iterator = DynamicSQL.executeQuery(sentence : queryAEjecutar, implname : nombreDeLaBDCreada, inParameters : arrayDeParametros);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Como se puede observar, el resultado de realizar la consulta va a ser un iterador, que luego puede ser recorrido con un &amp;quot;foreach&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java&amp;gt;&lt;br /&gt;
foreach (e in iterator) {&lt;br /&gt;
&lt;br /&gt;
   logMessage(&amp;quot;campo1: &amp;quot;+e[&amp;quot;campo1&amp;quot;], severity : INFO);&lt;br /&gt;
&lt;br /&gt;
   logMessage(&amp;quot;campo2: &amp;quot;+e[&amp;quot;campo2&amp;quot;], severity : INFO);&lt;br /&gt;
&lt;br /&gt;
   logMessage(&amp;quot;campo3: &amp;quot;+e[&amp;quot;campo3&amp;quot;], severity : INFO);&lt;br /&gt;
&lt;br /&gt;
   logMessage(&amp;quot;nombreColumna: &amp;quot;+e[&amp;quot;nombreColumna&amp;quot;], severity : INFO);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Versionando con CVS ===&lt;br /&gt;
El producto Aqualogic BPM 5.7 incluye un cliente de CVS que permite agregar, remover, actulizar en un repositorio cvs.&lt;br /&gt;
&lt;br /&gt;
==== Configurar el cliente CVS ====&lt;br /&gt;
* Levantar el Studio BPM.&lt;br /&gt;
* File -&amp;gt; Preference -&amp;gt;Default Version Control&lt;br /&gt;
** Version Control Manger: CVS&lt;br /&gt;
** Host: host del servidor CVS&lt;br /&gt;
** User Name: usuario del CVS&lt;br /&gt;
** User Password: password del usuario CVS&lt;br /&gt;
** path: ruta dentro del repositorio donde se guardará el proyecto.&lt;br /&gt;
&lt;br /&gt;
==== Subir el proyecto al CVS ====&lt;br /&gt;
* Levantar el Studio BPM.&lt;br /&gt;
* Abrir el proyecto a versionar.&lt;br /&gt;
* File -&amp;gt; Project Preference -&amp;gt; Project Version Control.&lt;br /&gt;
** Version Control Manager: CVS (nos carga la información ingresada en el punto anterior).&lt;br /&gt;
* File -&amp;gt; VCS -&amp;gt; Store project in repository&lt;br /&gt;
** Path: directorio en el que se creará el proyecto en el repositorio.&lt;br /&gt;
** Si es la primera vez que se sube un proyecto de Aqualogic BPM, pedirá que se ingrese la ruta del directorio donde se creará el &amp;quot;common catalog&amp;quot;&lt;br /&gt;
*** Common catalog: Es un catalogo de componente, el cual puede ser compartido por otros proyectos de Aqualogic BPM.&lt;br /&gt;
En el repositorio quedarán creados 2 directorios, el del proyecto y el del common catalog, ademas se crearán 2 alias en el CVS que apuntan al proyecto y al common catalog.&lt;br /&gt;
&lt;br /&gt;
==== Obtener el proyecto del CVS ====&lt;br /&gt;
* Levantar el Studio BPM.&lt;br /&gt;
* File -&amp;gt; Project Preference -&amp;gt; Project Version Control.&lt;br /&gt;
* File -&amp;gt; Import -&amp;gt; Project -&amp;gt; from Repository.&lt;br /&gt;
** Version Control Manager: CVS&lt;br /&gt;
** En la siguiente pantalla, seleccionar el proyecto del repositorio.&lt;br /&gt;
&lt;br /&gt;
==== Trabajar con proyectos versionados ====&lt;br /&gt;
Aqualogic BPM 5.7, posee una política restrictiva de edición para los proyecto versionados.&lt;br /&gt;
La política, consiste en que todo el proyecto se encuentra en modo lectura y solo un usuario puede editar un determinado archivo versionado (Ej.: un proceso).&lt;br /&gt;
===== Editar un procesos =====&lt;br /&gt;
* Seleccionar el proceso a editar.&lt;br /&gt;
* Menú contextual -&amp;gt; VCS -&amp;gt; edit.&lt;br /&gt;
Esto habilita al usuario a modificar el proceso. En caso de que exitiera otro usuario modificando el proceso nos aparecerá un mensaje de error.&lt;br /&gt;
&lt;br /&gt;
===== Grabar los cambios realizados en un proceso =====&lt;br /&gt;
* Seleccionar el proceso que se esta editando.&lt;br /&gt;
* Menú contextual -&amp;gt; VCS -&amp;gt; commit.&lt;br /&gt;
Este paso es importante, debido a que si se libera la edición del proceso sin realizar el commit se perderán los cambios.&lt;br /&gt;
&lt;br /&gt;
===== Liberar la edición del proceso =====&lt;br /&gt;
* Seleccionar el proceso que se esta editando.&lt;br /&gt;
* Menú contextual -&amp;gt; VCS -&amp;gt; unedit.&lt;br /&gt;
&lt;br /&gt;
=== Ver también  ===&lt;br /&gt;
* [[Oracle BPM]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Oracle]]&lt;/div&gt;</summary>
		<author><name>201.251.182.130</name></author>	</entry>

	<entry>
		<id>https://dosideas.com/wiki/index.php?title=BEA_Aqualogic_BPM_5.7_(Fuego)&amp;diff=5677</id>
		<title>BEA Aqualogic BPM 5.7 (Fuego)</title>
		<link rel="alternate" type="text/html" href="https://dosideas.com/wiki/index.php?title=BEA_Aqualogic_BPM_5.7_(Fuego)&amp;diff=5677"/>
				<updated>2011-01-24T12:31:45Z</updated>
		
		<summary type="html">&lt;p&gt;201.251.182.130: /* Segundo paso */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===Comunicando con Base de Datos con PBL (Process Business Language)===&lt;br /&gt;
&lt;br /&gt;
Para ejecutar comandos SQL en Aqualogic BPM 5.7 hay que seguir los siguientes pasos: &lt;br /&gt;
&lt;br /&gt;
====Primer paso====&lt;br /&gt;
&lt;br /&gt;
Se debe crear nuevo &amp;quot;External Resource&amp;quot;, haciendo click derecho en el directorio del proyecto &amp;quot;External Resources&amp;quot;, del tipo &amp;quot;SQL Database&amp;quot;. Los campos se deben completar con la información de la base de datos que queremos consultar y con un nombre significativo.&lt;br /&gt;
&lt;br /&gt;
====Segundo paso====&lt;br /&gt;
 &lt;br /&gt;
Se debe crear un nuevo &amp;quot;BPM Object&amp;quot;, haciendo click derecho sobre el modulo deseado en el directorio de &amp;quot;Catalog&amp;quot;, y luego crear un método en nuestro objeto, haciendo click derecho sobre el objeto y seleccionando la opción &amp;quot;New Method&amp;quot;. Ahora se debe editar el nuevo método, expandiendo el objeto bpm y haciendo doble click sobre el nombre del método creado. Ahora podemos editarlo e incluir el código necesario para comunicarnos con la BD a través de una clase propia de Fuego, un ejemplo de implementación puede ser el siguiente: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java&amp;gt;&lt;br /&gt;
String queryAEjecutar =&amp;quot;SELECT campo1, campo2, campo3 FROM nombreTabla WHERE nombreColumna in (?,?)&amp;quot;; &lt;br /&gt;
&lt;br /&gt;
String nombreDeLaBDCreada = &amp;quot;NombreBD&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
String[] arrayDeParametros = {&amp;quot;valor1&amp;quot;, &amp;quot;valor2&amp;quot;};&lt;br /&gt;
&lt;br /&gt;
Iterator iterator = DynamicSQL.executeQuery(sentence : queryAEjecutar, implname : nombreDeLaBDCreada, inParameters : arrayDeParametros);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Como se puede observar, el resultado de realizar la consulta va a ser un iterador, que luego puede ser recorrido con un &amp;quot;foreach&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java&amp;gt;&lt;br /&gt;
foreach (e in iterator) {&lt;br /&gt;
&lt;br /&gt;
   logMessage(&amp;quot;campo1: &amp;quot;+e[&amp;quot;campo1&amp;quot;], severity : INFO);&lt;br /&gt;
&lt;br /&gt;
   logMessage(&amp;quot;campo2: &amp;quot;+e[&amp;quot;campo2&amp;quot;], severity : INFO);&lt;br /&gt;
&lt;br /&gt;
   logMessage(&amp;quot;campo3: &amp;quot;+e[&amp;quot;campo3&amp;quot;], severity : INFO);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Ver también  ===&lt;br /&gt;
* [[Oracle BPM]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Oracle]]&lt;/div&gt;</summary>
		<author><name>201.251.182.130</name></author>	</entry>

	<entry>
		<id>https://dosideas.com/wiki/index.php?title=BEA_Aqualogic_BPM_5.7_(Fuego)&amp;diff=5676</id>
		<title>BEA Aqualogic BPM 5.7 (Fuego)</title>
		<link rel="alternate" type="text/html" href="https://dosideas.com/wiki/index.php?title=BEA_Aqualogic_BPM_5.7_(Fuego)&amp;diff=5676"/>
				<updated>2011-01-24T12:17:01Z</updated>
		
		<summary type="html">&lt;p&gt;201.251.182.130: /* Segundo paso */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===Comunicando con Base de Datos con PBL (Process Business Language)===&lt;br /&gt;
&lt;br /&gt;
Para ejecutar comandos SQL en Aqualogic BPM 5.7 hay que seguir los siguientes pasos: &lt;br /&gt;
&lt;br /&gt;
====Primer paso====&lt;br /&gt;
&lt;br /&gt;
Se debe crear nuevo &amp;quot;External Resource&amp;quot;, haciendo click derecho en el directorio del proyecto &amp;quot;External Resources&amp;quot;, del tipo &amp;quot;SQL Database&amp;quot;. Los campos se deben completar con la información de la base de datos que queremos consultar y con un nombre significativo.&lt;br /&gt;
&lt;br /&gt;
====Segundo paso====&lt;br /&gt;
 &lt;br /&gt;
Se debe crear un nuevo &amp;quot;BPM Object&amp;quot;, haciendo click derecho sobre el modulo deseado en el directorio de &amp;quot;Catalog&amp;quot;, y luego crear un método en nuestro objeto, haciendo click derecho sobre el objeto y seleccionando la opción &amp;quot;New Method&amp;quot;. Ahora se debe editar el nuevo método, expandiendo el objeto bpm y haciendo doble click sobre el nombre del método creado. Ahora podemos editarlo e incluir el código necesario para comunicarnos con la BD a través de una clase propia de Fuego, un ejemplo de implementación puede ser el siguiente: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java&amp;gt;&lt;br /&gt;
String queryAEjecutar =&amp;quot;SELECT campo1, campo2, campo3 FROM nombreTabla WHERE nombreColumna in (?,?)&amp;quot;; &lt;br /&gt;
&lt;br /&gt;
String nombreDeLaBDCreada = &amp;quot;NombreBD&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
String[] arrayDeParametros = {&amp;quot;valor1&amp;quot;, &amp;quot;valor2&amp;quot;};&lt;br /&gt;
&lt;br /&gt;
Iterator iterator = DynamicSQL.executeQuery(sentence : queryAEjecutar, implname : nombreDeLaBDCreada, inParameters : arrayDeParametros);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Como se puede observar, el resultado de realizar la consulta va a ser un iterador, que luego puede ser recorrido con un &amp;quot;foreach&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java&amp;gt;&lt;br /&gt;
foreach (e in iterator) {&lt;br /&gt;
   logMessage(&amp;quot;campo1: &amp;quot;+e[&amp;quot;campo1&amp;quot;], severity : INFO);&lt;br /&gt;
   logMessage(&amp;quot;campo2: &amp;quot;+e[&amp;quot;campo2&amp;quot;], severity : INFO);&lt;br /&gt;
   logMessage(&amp;quot;campo3: &amp;quot;+e[&amp;quot;campo3&amp;quot;], severity : INFO);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Ver también  ===&lt;br /&gt;
* [[Oracle BPM]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Oracle]]&lt;/div&gt;</summary>
		<author><name>201.251.182.130</name></author>	</entry>

	<entry>
		<id>https://dosideas.com/wiki/index.php?title=BEA_Aqualogic_BPM_5.7_(Fuego)&amp;diff=5675</id>
		<title>BEA Aqualogic BPM 5.7 (Fuego)</title>
		<link rel="alternate" type="text/html" href="https://dosideas.com/wiki/index.php?title=BEA_Aqualogic_BPM_5.7_(Fuego)&amp;diff=5675"/>
				<updated>2011-01-24T12:10:27Z</updated>
		
		<summary type="html">&lt;p&gt;201.251.182.130: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===Comunicando con Base de Datos con PBL (Process Business Language)===&lt;br /&gt;
&lt;br /&gt;
Para ejecutar comandos SQL en Aqualogic BPM 5.7 hay que seguir los siguientes pasos: &lt;br /&gt;
&lt;br /&gt;
====Primer paso====&lt;br /&gt;
&lt;br /&gt;
Se debe crear nuevo &amp;quot;External Resource&amp;quot;, haciendo click derecho en el directorio del proyecto &amp;quot;External Resources&amp;quot;, del tipo &amp;quot;SQL Database&amp;quot;. Los campos se deben completar con la información de la base de datos que queremos consultar y con un nombre significativo.&lt;br /&gt;
&lt;br /&gt;
====Segundo paso====&lt;br /&gt;
 &lt;br /&gt;
Se debe crear un nuevo &amp;quot;BPM Object&amp;quot;, haciendo click derecho sobre el modulo deseado en el directorio de &amp;quot;Catalog&amp;quot;, y luego crear un método en nuestro objeto, haciendo click derecho sobre el objeto y seleccionando la opción &amp;quot;New Method&amp;quot;. Ahora se debe editar el nuevo método, expandiendo el objeto bpm y haciendo doble click sobre el nombre del método creado. Ahora podemos editarlo e incluir el código necesario para comunicarnos con la BD a través de una clase propia de Fuego, un ejemplo de implementación puede ser el siguiente: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java&amp;gt;&lt;br /&gt;
String queryAEjecutar =&amp;quot;SELECT * FROM nombreTabla WHERE nombreColumna in (?,?)&amp;quot;; &lt;br /&gt;
&lt;br /&gt;
String nombreDeLaBDCreada = &amp;quot;NombreBD&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
String[] arrayDeParametros = {&amp;quot;valor1&amp;quot;, &amp;quot;valor2&amp;quot;};&lt;br /&gt;
&lt;br /&gt;
Iterator iterator = DynamicSQL.executeQuery(sentence : queryAEjecutar, implname : nombreDeLaBDCreada, inParameters : arrayDeParametros);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Como se puede observar, el resultado de realizar la consulta va a ser un iterador, que luego puede ser recorrido con un &amp;quot;foreach&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
=== Ver también  ===&lt;br /&gt;
* [[Oracle BPM]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Oracle]]&lt;/div&gt;</summary>
		<author><name>201.251.182.130</name></author>	</entry>

	<entry>
		<id>https://dosideas.com/wiki/index.php?title=BEA_Aqualogic_BPM_5.7_(Fuego)&amp;diff=5674</id>
		<title>BEA Aqualogic BPM 5.7 (Fuego)</title>
		<link rel="alternate" type="text/html" href="https://dosideas.com/wiki/index.php?title=BEA_Aqualogic_BPM_5.7_(Fuego)&amp;diff=5674"/>
				<updated>2011-01-21T19:27:24Z</updated>
		
		<summary type="html">&lt;p&gt;201.251.182.130: /* Segundo paso */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===Comunicando con Base de Datos con PBL (Process Business Language)===&lt;br /&gt;
&lt;br /&gt;
Para ejecutar comandos SQL en Aqualogic BPM 5.7 hay que seguir los siguientes pasos: &lt;br /&gt;
&lt;br /&gt;
====Primer paso====&lt;br /&gt;
&lt;br /&gt;
Se debe crear nuevo &amp;quot;External Resource&amp;quot;, haciendo click derecho en el directorio del proyecto &amp;quot;External Resources&amp;quot;, del tipo &amp;quot;SQL Database&amp;quot;. Los campos se deben completar con la información de la base de datos que queremos consultar y con un nombre significativo.&lt;br /&gt;
&lt;br /&gt;
====Segundo paso====&lt;br /&gt;
 &lt;br /&gt;
Se debe crear un nuevo &amp;quot;BPM Object&amp;quot;, haciendo click derecho sobre el modulo deseado en el directorio de &amp;quot;Catalog&amp;quot;, y luego crear un método en nuestro objeto, haciendo click derecho sobre el objeto y seleccionando la opción &amp;quot;New Method&amp;quot;. Ahora se debe editar el nuevo método, expandiendo el objeto bpm y haciendo doble click sobre el nombre del método creado. Ahora podemos editarlo e incluir el código necesario para comunicarnos con la BD a través de una clase propia de Fuego, un ejemplo de implementación puede ser el siguiente: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java&amp;gt;&lt;br /&gt;
String queryAEjecutar =&amp;quot;SELECT * FROM nombreTabla WHERE nombreColumna in (?,?)&amp;quot;; &lt;br /&gt;
&lt;br /&gt;
String nombreDeLaBDCreada = &amp;quot;NombreBD&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
String[] arrayDeParametros = {&amp;quot;valor1&amp;quot;, &amp;quot;valor2&amp;quot;};&lt;br /&gt;
&lt;br /&gt;
Iterator iterator = DynamicSQL.executeQuery(sentence : queryAEjecutar, implname : nombreDeLaBDCreada, inParameters : arrayDeParametros);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Como se puede observar, el resultado de realizar la consulta va a ser un iterador, que luego puede ser recorrido con un &amp;quot;foreach&amp;quot;.&lt;/div&gt;</summary>
		<author><name>201.251.182.130</name></author>	</entry>

	<entry>
		<id>https://dosideas.com/wiki/index.php?title=BEA_Aqualogic_BPM_5.7_(Fuego)&amp;diff=5672</id>
		<title>BEA Aqualogic BPM 5.7 (Fuego)</title>
		<link rel="alternate" type="text/html" href="https://dosideas.com/wiki/index.php?title=BEA_Aqualogic_BPM_5.7_(Fuego)&amp;diff=5672"/>
				<updated>2011-01-21T19:02:59Z</updated>
		
		<summary type="html">&lt;p&gt;201.251.182.130: /* Comunicando con Base de Datos con PBL (Process Business Language) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===Comunicando con Base de Datos con PBL (Process Business Language)===&lt;br /&gt;
&lt;br /&gt;
Para executar comandos SQL en Aqualogic BPM 5.7 hay que seguir los siguientes pasos: &lt;br /&gt;
&lt;br /&gt;
====Primer paso====&lt;br /&gt;
&lt;br /&gt;
Se debe crear nuevo &amp;quot;External Resource&amp;quot;, haciendo click derecho en el directorio del proyecto &amp;quot;External Resources&amp;quot;, del tipo &amp;quot;SQL Database&amp;quot;. Los campos se deben completar con la información de la base de datos que queremos consultar y con un nombre significativo.&lt;br /&gt;
&lt;br /&gt;
====Segundo paso====&lt;br /&gt;
 &lt;br /&gt;
Se debe crear un nuevo &amp;quot;BPM Object&amp;quot;, haciendo click derecho sobre del modulo deseado en el directorio de &amp;quot;Catalog&amp;quot;, y luego crear un método en nuestro método, haciendo click derecho sobre el objeto y seleccionando la opción &amp;quot;New Method&amp;quot;. Ahora se debe editar el nuevo método, expandiendo el objeto bpm y haciendo doble click sobre el nombre del método creado. Ahora podemos editarlo e incluir el código necesario para comunicarnos con la BD a través de una clase propia de Fuego, un ejemplo de implementación puede ser el siguiente: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java&amp;gt;&lt;br /&gt;
String queryAEjecutar =&amp;quot;SELECT * FROM nombreTabla WHERE nombreColumna in (?,?)&amp;quot;; &lt;br /&gt;
&lt;br /&gt;
String nombreDeLaBDCreada = &amp;quot;NombreBD&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
String[] arrayDeParametros = {&amp;quot;valor1&amp;quot;, &amp;quot;valor2&amp;quot;};&lt;br /&gt;
&lt;br /&gt;
Iterator iterator = DynamicSQL.executeQuery(sentence : queryAEjecutar, implname : nombreDeLaBDCreada, inParameters : arrayDeParametros);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Como se puede obserbar, el resultado de realizar la consulta va a ser un iterador, que luego puede ser recorrido con un &amp;quot;foreach&amp;quot;.&lt;/div&gt;</summary>
		<author><name>201.251.182.130</name></author>	</entry>

	<entry>
		<id>https://dosideas.com/wiki/index.php?title=BEA_Aqualogic_BPM_5.7_(Fuego)&amp;diff=5671</id>
		<title>BEA Aqualogic BPM 5.7 (Fuego)</title>
		<link rel="alternate" type="text/html" href="https://dosideas.com/wiki/index.php?title=BEA_Aqualogic_BPM_5.7_(Fuego)&amp;diff=5671"/>
				<updated>2011-01-21T19:00:02Z</updated>
		
		<summary type="html">&lt;p&gt;201.251.182.130: /* Comunicando con Base de Datos con PBL (Process Business Language) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===Comunicando con Base de Datos con PBL (Process Business Language)===&lt;br /&gt;
&lt;br /&gt;
Para executar comandos SQL en Aqualogic BPM 5.7 hay que seguir los siguientes pasos: &lt;br /&gt;
&lt;br /&gt;
Primer paso: Se debe crear nuevo &amp;quot;External Resource&amp;quot;, haciendo click derecho en el directorio del proyecto &amp;quot;External Resources&amp;quot;, del tipo &amp;quot;SQL Database&amp;quot;. Los campos se deben completar con la información de la base de datos que queremos consultar y con un nombre significativo. &lt;br /&gt;
&lt;br /&gt;
Segundo paso: Se debe crear un nuevo &amp;quot;BPM Object&amp;quot;, haciendo click derecho sobre del modulo deseado en el directorio de &amp;quot;Catalog&amp;quot;, y luego crear un método en nuestro método, haciendo click derecho sobre el objeto y seleccionando la opción &amp;quot;New Method&amp;quot;. Ahora se debe editar el nuevo método, expandiendo el objeto bpm y haciendo doble click sobre el nombre del método creado. Ahora podemos editarlo e incluir el código necesario para comunicarnos con la BD a través de una clase propia de Fuego, un ejemplo de implementación puede ser el siguiente: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java&amp;gt;&lt;br /&gt;
String queryAEjecutar =&amp;quot;SELECT * FROM nombreTabla WHERE nombreColumna in (?,?)&amp;quot;; &lt;br /&gt;
&lt;br /&gt;
String nombreDeLaBDCreada = &amp;quot;NombreBD&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
String[] arrayDeParametros = {&amp;quot;valor1&amp;quot;, &amp;quot;valor2&amp;quot;};&lt;br /&gt;
&lt;br /&gt;
Iterator iterator = DynamicSQL.executeQuery(sentence : queryAEjecutar, implname : nombreDeLaBDCreada, inParameters : arrayDeParametros);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Como se puede obserbar, el resultado de realizar la consulta va a ser un iterador, que luego puede ser recorrido con un &amp;quot;foreach&amp;quot;.&lt;/div&gt;</summary>
		<author><name>201.251.182.130</name></author>	</entry>

	<entry>
		<id>https://dosideas.com/wiki/index.php?title=BEA_Aqualogic_BPM_5.7_(Fuego)&amp;diff=5670</id>
		<title>BEA Aqualogic BPM 5.7 (Fuego)</title>
		<link rel="alternate" type="text/html" href="https://dosideas.com/wiki/index.php?title=BEA_Aqualogic_BPM_5.7_(Fuego)&amp;diff=5670"/>
				<updated>2011-01-21T18:59:45Z</updated>
		
		<summary type="html">&lt;p&gt;201.251.182.130: /* Comunicando con Base de Datos con PBL (Process Business Language) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Comunicando con Base de Datos con PBL (Process Business Language)=&lt;br /&gt;
&lt;br /&gt;
Para executar comandos SQL en Aqualogic BPM 5.7 hay que seguir los siguientes pasos: &lt;br /&gt;
&lt;br /&gt;
Primer paso: Se debe crear nuevo &amp;quot;External Resource&amp;quot;, haciendo click derecho en el directorio del proyecto &amp;quot;External Resources&amp;quot;, del tipo &amp;quot;SQL Database&amp;quot;. Los campos se deben completar con la información de la base de datos que queremos consultar y con un nombre significativo. &lt;br /&gt;
&lt;br /&gt;
Segundo paso: Se debe crear un nuevo &amp;quot;BPM Object&amp;quot;, haciendo click derecho sobre del modulo deseado en el directorio de &amp;quot;Catalog&amp;quot;, y luego crear un método en nuestro método, haciendo click derecho sobre el objeto y seleccionando la opción &amp;quot;New Method&amp;quot;. Ahora se debe editar el nuevo método, expandiendo el objeto bpm y haciendo doble click sobre el nombre del método creado. Ahora podemos editarlo e incluir el código necesario para comunicarnos con la BD a través de una clase propia de Fuego, un ejemplo de implementación puede ser el siguiente: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java&amp;gt;&lt;br /&gt;
String queryAEjecutar =&amp;quot;SELECT * FROM nombreTabla WHERE nombreColumna in (?,?)&amp;quot;; &lt;br /&gt;
&lt;br /&gt;
String nombreDeLaBDCreada = &amp;quot;NombreBD&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
String[] arrayDeParametros = {&amp;quot;valor1&amp;quot;, &amp;quot;valor2&amp;quot;};&lt;br /&gt;
&lt;br /&gt;
Iterator iterator = DynamicSQL.executeQuery(sentence : queryAEjecutar, implname : nombreDeLaBDCreada, inParameters : arrayDeParametros);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Como se puede obserbar, el resultado de realizar la consulta va a ser un iterador, que luego puede ser recorrido con un &amp;quot;foreach&amp;quot;.&lt;/div&gt;</summary>
		<author><name>201.251.182.130</name></author>	</entry>

	<entry>
		<id>https://dosideas.com/wiki/index.php?title=BEA_Aqualogic_BPM_5.7_(Fuego)&amp;diff=5669</id>
		<title>BEA Aqualogic BPM 5.7 (Fuego)</title>
		<link rel="alternate" type="text/html" href="https://dosideas.com/wiki/index.php?title=BEA_Aqualogic_BPM_5.7_(Fuego)&amp;diff=5669"/>
				<updated>2011-01-21T18:59:24Z</updated>
		
		<summary type="html">&lt;p&gt;201.251.182.130: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Comunicando con Base de Datos con PBL (Process Business Language)  ==&lt;br /&gt;
&lt;br /&gt;
Para executar comandos SQL en Aqualogic BPM 5.7 hay que seguir los siguientes pasos: &lt;br /&gt;
&lt;br /&gt;
Primer paso: Se debe crear nuevo &amp;quot;External Resource&amp;quot;, haciendo click derecho en el directorio del proyecto &amp;quot;External Resources&amp;quot;, del tipo &amp;quot;SQL Database&amp;quot;. Los campos se deben completar con la información de la base de datos que queremos consultar y con un nombre significativo. &lt;br /&gt;
&lt;br /&gt;
Segundo paso: Se debe crear un nuevo &amp;quot;BPM Object&amp;quot;, haciendo click derecho sobre del modulo deseado en el directorio de &amp;quot;Catalog&amp;quot;, y luego crear un método en nuestro método, haciendo click derecho sobre el objeto y seleccionando la opción &amp;quot;New Method&amp;quot;. Ahora se debe editar el nuevo método, expandiendo el objeto bpm y haciendo doble click sobre el nombre del método creado. Ahora podemos editarlo e incluir el código necesario para comunicarnos con la BD a través de una clase propia de Fuego, un ejemplo de implementación puede ser el siguiente: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code java&amp;gt;&lt;br /&gt;
String queryAEjecutar =&amp;quot;SELECT * FROM nombreTabla WHERE nombreColumna in (?,?)&amp;quot;; &lt;br /&gt;
&lt;br /&gt;
String nombreDeLaBDCreada = &amp;quot;NombreBD&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
String[] arrayDeParametros = {&amp;quot;valor1&amp;quot;, &amp;quot;valor2&amp;quot;};&lt;br /&gt;
&lt;br /&gt;
Iterator iterator = DynamicSQL.executeQuery(sentence : queryAEjecutar, implname : nombreDeLaBDCreada, inParameters : arrayDeParametros);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Como se puede obserbar, el resultado de realizar la consulta va a ser un iterador, que luego puede ser recorrido con un &amp;quot;foreach&amp;quot;.&lt;/div&gt;</summary>
		<author><name>201.251.182.130</name></author>	</entry>

	<entry>
		<id>https://dosideas.com/wiki/index.php?title=BEA_Aqualogic_BPM_5.7_(Fuego)&amp;diff=5668</id>
		<title>BEA Aqualogic BPM 5.7 (Fuego)</title>
		<link rel="alternate" type="text/html" href="https://dosideas.com/wiki/index.php?title=BEA_Aqualogic_BPM_5.7_(Fuego)&amp;diff=5668"/>
				<updated>2011-01-21T18:54:07Z</updated>
		
		<summary type="html">&lt;p&gt;201.251.182.130: Página creada con '== Comunicando con Base de Datos con PBL (Process Business Language)  ==  Para executar comandos SQL en Aqualogic BPM 5.7 hay que seguir los siguientes pasos:   Primer paso: Se …'&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Comunicando con Base de Datos con PBL (Process Business Language)  ==&lt;br /&gt;
&lt;br /&gt;
Para executar comandos SQL en Aqualogic BPM 5.7 hay que seguir los siguientes pasos: &lt;br /&gt;
&lt;br /&gt;
Primer paso: Se debe crear nuevo &amp;quot;External Resource&amp;quot;, haciendo click derecho en el directorio del proyecto &amp;quot;External Resources&amp;quot;, del tipo &amp;quot;SQL Database&amp;quot;. Los campos se deben completar con la información de la base de datos que queremos consultar y con un nombre significativo. &lt;br /&gt;
&lt;br /&gt;
Segundo paso: Se debe crear un nuevo &amp;quot;BPM Object&amp;quot;, haciendo click derecho sobre del modulo deseado en el directorio de &amp;quot;Catalog&amp;quot;, y luego crear un método en nuestro método, haciendo click derecho sobre el objeto y seleccionando la opción &amp;quot;New Method&amp;quot;. Ahora se debe editar el nuevo método, expandiendo el objeto bpm y haciendo doble click sobre el nombre del método creado. Ahora podemos editarlo e incluir el código necesario para comunicarnos con la BD a través de una clase propia de Fuego, un ejemplo de implementación puede ser el siguiente:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;amp;lt;code&amp;amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
String queryAEjecutar =&amp;amp;nbsp;&amp;quot;SELECT * FROM nombreTabla WHERE nombreColumna in (?, ?);&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
String nombreDeLaBDCreada =&amp;amp;nbsp;&amp;quot;NombreBD&amp;quot;;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
String[] arrayDeParametros = {&amp;quot;valor1&amp;quot;, &amp;quot;valor2&amp;quot;};&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Iterator iterator =&amp;amp;nbsp;DynamicSQL.executeQuery(sentence : queryAEjecutar, implname : nombreDeLaBDCreada, inParameters : arrayDeParametros)&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;amp;lt;/code&amp;amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>201.251.182.130</name></author>	</entry>

	<entry>
		<id>https://dosideas.com/wiki/index.php?title=Spring_Roo&amp;diff=5635</id>
		<title>Spring Roo</title>
		<link rel="alternate" type="text/html" href="https://dosideas.com/wiki/index.php?title=Spring_Roo&amp;diff=5635"/>
				<updated>2010-12-22T14:48:40Z</updated>
		
		<summary type="html">&lt;p&gt;201.251.182.130: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Spring Roo]] es una herramienta RAD extensible para [[Java]] basada en [[Spring Framework]]. Basicamente es un generador de código avanzado, que se utiliza desde la linea de comandos invocando sentencias.&lt;br /&gt;
&lt;br /&gt;
La idea detrás de [[Spring Roo]] es incrementar la productividad del desarrollador [[Java]] sin comprometer la integridad estructural o la flexibilidad de la solución. No contiene un componente Runtime. Esto es muy importante, no solo porque no ata la solución al framework, sino porque no genera overhead. Se puede eliminar facilmente.&lt;br /&gt;
&lt;br /&gt;
Está construido con una serie de plugins (al estilo de [[Maven]]). Fue diseñado pensando en la usabilidad. Los comandos son contextuales; tiene los comandos &amp;quot;hint&amp;quot; y &amp;quot;help&amp;quot; para consultar el uso rápidamente y la tecla TAB para autocompletar. &lt;br /&gt;
&lt;br /&gt;
Está basado en scripts, por lo que en caso que se cometer un error, se puede hacer rollback. Todos los comandos escritos se van guardando automáticamente (log.roo).&lt;br /&gt;
&lt;br /&gt;
== Características ==&lt;br /&gt;
* Permite desarrollar una aplicación Web en minutos. Genera un war. Construye dos capas: la de persistencia y la de presentación. Para agregar la capa de negocio, se pueden agregar las clases manualmente a los controladores generados con Roo.&lt;br /&gt;
* Permite generar un modelo de datos complejo, incluyendo validaciones.&lt;br /&gt;
* La aplicación Web es RESTful y tiene soporte para internacionalización en varios idiomas.&lt;br /&gt;
* Tiene soporte de seguridad out-of-the-box.&lt;br /&gt;
* La presentación usa [[Dojo]] (incorporar otro, por ejemplo [[JQuery]], se hace a mano y es costoso).&lt;br /&gt;
&lt;br /&gt;
=== Generación de código ===&lt;br /&gt;
Es un generador de código ''hibrido'', utilizando generación activa y pasiva.&lt;br /&gt;
&lt;br /&gt;
Utiliza generación pasiva para generación de archivos java y xml. &lt;br /&gt;
Utiliza generación activa para la metadata con la ayuda de los tags @Roo* y modifica gradualmente .aj y los jsp.&lt;br /&gt;
&lt;br /&gt;
Sincroniza los cambios entre Roo y las modificaciones realizadas al código (roundtrip).&lt;br /&gt;
&lt;br /&gt;
[[Spring Roo]] no interviene en runtime, solo lo hace en tiempo de desarrollo. Una vez creado el proyecto con Spring Roo, podría eliminarse y seguir trabajando con un [[IDE]].&lt;br /&gt;
&lt;br /&gt;
=== Librerías/Frameworks que usa ===&lt;br /&gt;
&lt;br /&gt;
* [[Java]]&lt;br /&gt;
* [[AspectJ]]&lt;br /&gt;
* [[Eclipse]]&lt;br /&gt;
* Java Persistence API:  [[Hibernate]], [[OpenJPA]], [[EclipseLink]]&lt;br /&gt;
* [[Java Server Pages]]&lt;br /&gt;
* [[JUnit]]&lt;br /&gt;
* [[Log4J]]&lt;br /&gt;
* [[Maven]]&lt;br /&gt;
* [[Selenium]]&lt;br /&gt;
* [[Spring Framework]]&lt;br /&gt;
* [[Spring MVC]]&lt;br /&gt;
* [[Spring Security]]&lt;br /&gt;
* [[Spring Web Flow]]&lt;br /&gt;
&lt;br /&gt;
== Requisitos ==&lt;br /&gt;
&lt;br /&gt;
Tener instalado Java y Maven, las últimas versiones estables.&lt;br /&gt;
&lt;br /&gt;
== Configuración ==&lt;br /&gt;
Descargar la última versión de Roo del sitio oficial.&lt;br /&gt;
Descomprimir en una carpeta en el disco local. Ej: c:\roo-1.2&lt;br /&gt;
Incluir la carpeta con los ejecutables dentro de la variable de entorno PATH. Ej.: c:\roo-1.2\bin&lt;br /&gt;
&lt;br /&gt;
== Uso ==&lt;br /&gt;
Para la ejecución de comandos podemos utilizar:&lt;br /&gt;
* el shell de roo mediante linea de comando&lt;br /&gt;
* el shell que viene embebido en el [[SpringSource Tool Suite]] &lt;br /&gt;
* o el [[IDE]] que utilizás habitualmente, por ejemplo [[Eclipse]]. En este caso deberías instalar el plugin para trabajar con aspectos y maven.&lt;br /&gt;
&lt;br /&gt;
Para empezar a usar los comandos Roo mediante el shell, crear una carpeta e invocar a [[Spring Roo]]&lt;br /&gt;
Ej.:&lt;br /&gt;
&lt;br /&gt;
  mkdir helloworld&lt;br /&gt;
  cd helloworld&lt;br /&gt;
  roo&lt;br /&gt;
&lt;br /&gt;
Al hacer eso se iniciará la interfaz y desplegará el siguiente mensaje:&lt;br /&gt;
&lt;br /&gt;
     / __ \/ __ \/ __ \&lt;br /&gt;
    / /_/ / / / / / / /&lt;br /&gt;
   / _, _/ /_/ / /_/ /&lt;br /&gt;
  /_/ |_|\____/\____/    1.0.2.RELEASE [rev 638]&lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  Welcome to Spring Roo. For assistance press TAB or type &amp;quot;hint&amp;quot; then hit ENTER.&lt;br /&gt;
  roo&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La tecla TAB despliega las opciones:&lt;br /&gt;
&lt;br /&gt;
  */            /*            //            ;             addon         date          development   exit          help          hint&lt;br /&gt;
  metadata      poll          project       quit          reference     script        system        version&lt;br /&gt;
  roo&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
La sentencia help lista todos los comandos con descripciones breves.&lt;br /&gt;
&lt;br /&gt;
== Pasos para crear una aplicación mínima ==&lt;br /&gt;
&lt;br /&gt;
*Crear el proyecto&lt;br /&gt;
*Elegir el framework de persistencia&lt;br /&gt;
*Crear el modelo de dominio&lt;br /&gt;
*Generar de la capa de presentación&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
En detalle podés verlo en [[Roo: Pasos para crear una aplicación mínima]].&lt;br /&gt;
&lt;br /&gt;
== Manejo de propiedades ==&lt;br /&gt;
&lt;br /&gt;
Roo genera archivos de propiedades dentro del proyecto, por ejemplo: database.properties. &lt;br /&gt;
Dichos archivos pueden ser modificados automáticamente por los comandos de roo. Se debe tener en cuenta entonces que al ejecutar un comando que impacte valores  configurados manualmente, será necesario volver a configurarlos. &lt;br /&gt;
Las claves definidas manualmente por el usuario no son alteradas por ningún comando de roo.&lt;br /&gt;
&lt;br /&gt;
== Maven ==&lt;br /&gt;
&lt;br /&gt;
Desde Roo se pueden ejecutar varias tareas de Maven sin tener que salir del entorno.&lt;br /&gt;
Por ejemplo:&lt;br /&gt;
* 'perform tests' equivale a 'mvn test'&lt;br /&gt;
* 'perform eclipse' equivale a 'mvn eclipse:eclipse'&lt;br /&gt;
&lt;br /&gt;
== Seguridad ==&lt;br /&gt;
&lt;br /&gt;
El módulo de seguridad que viene predeterminado necesita unos pequeños cambios de configuración. De forma predeterminada viene configurado un path segurizado que no corresponde con la aplicación en desarrollo.&lt;br /&gt;
Se invoca mediante la sentencia:&lt;br /&gt;
&lt;br /&gt;
  security setup&lt;br /&gt;
&lt;br /&gt;
== Ejecutar un script ==&lt;br /&gt;
&lt;br /&gt;
Todo lo que se va ejecutando por consola, se va grabando en un archivo de log (log.roo).&lt;br /&gt;
Es posible re-ejecutar las acciones, copiando el archivo con otro nombre y utilizando la sentencia 'script &amp;lt;nombre de archivo&amp;gt;'&lt;br /&gt;
Ej.:&lt;br /&gt;
&lt;br /&gt;
  roo&amp;gt;script helloworld.roo&lt;br /&gt;
&lt;br /&gt;
== Ejemplos ==&lt;br /&gt;
&lt;br /&gt;
Necesitamos tener correctamente instaladas las siguientes versiones (verificar la configuración de las variables de entorno PATH y JAVA_HOME):&lt;br /&gt;
&lt;br /&gt;
* JDK 1.6 UPDATE 21&lt;br /&gt;
* Spring Roo 1.0.2&lt;br /&gt;
* Apache Maven 2.2.1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Para poder ejecutar los siguientes ejemplos: &lt;br /&gt;
&lt;br /&gt;
* [[Ejemplo de script con Spring Roo]]&lt;br /&gt;
* [[Ejemplo de proyecto web ABM con Spring Roo]]&lt;br /&gt;
* [[Ejemplo de proyecto web ABM con SpringSource Tool Suite]]&lt;br /&gt;
&lt;br /&gt;
== Personalizacion de la capa de persistencia ==&lt;br /&gt;
&lt;br /&gt;
En [[Capa de Persistencia de Spring Roo]] veremos algunas características de uso con [[Oracle]].&lt;br /&gt;
&lt;br /&gt;
== Personalizacion de la capa de presentación ==&lt;br /&gt;
&lt;br /&gt;
En [[Capa de Presentación de Spring Roo]] veremos como cambiar la apariencia de las pantallas web.&lt;br /&gt;
&lt;br /&gt;
== Uso de mensajeria ==&lt;br /&gt;
&lt;br /&gt;
En [[JMS con Spring Roo]] veremos como incorporar tareas asincrónicas a la aplicación.&lt;br /&gt;
&lt;br /&gt;
== Uso de servicios web con Rest ==&lt;br /&gt;
&lt;br /&gt;
En [[Restful con Spring Roo]] veremos como incorporar servicios web sencillos a la aplicación, con la tecnología [http://www.dosideas.com/noticias/java/314-introduccion-a-los-servicios-web-restful.html Rest].&lt;br /&gt;
&lt;br /&gt;
== Creación de Add On ==&lt;br /&gt;
&lt;br /&gt;
Podemos incorporar nuevos comandos de Spring Roo, creando un Add On nuevo.&lt;br /&gt;
&lt;br /&gt;
* [https://fisheye.springsource.org/browse/spring-roo Listado de addons existentes]&lt;br /&gt;
* [http://www.slideshare.net/desmax74/spring-roo-internals-javaday-iv Arquitectura de Spring Roo]&lt;br /&gt;
* [http://abaddon-gtz.blogspot.com/2010/04/un-sencillo-add-on-de-spring-roo.html Un sencillo Add On de Spring Roo]&lt;br /&gt;
&lt;br /&gt;
== Problemas y soluciones ==&lt;br /&gt;
* [[Problemas frecuentes con Spring Roo]]&lt;br /&gt;
&lt;br /&gt;
== Para que es ideal ==&lt;br /&gt;
&lt;br /&gt;
* Hacer backends de Administración (ABMs/CRUDs con interfaz Web)&lt;br /&gt;
&lt;br /&gt;
== Lo que le falta ==&lt;br /&gt;
&lt;br /&gt;
* La posibilidad de importar modelos de datos,ya sea desde la base de datos o bien  de un archivo de configuración Hibernate. (próximamente disponible en la versión 1.1.0)&lt;br /&gt;
&lt;br /&gt;
== Ver también ==&lt;br /&gt;
* [[SpringSource Tool Suite]]&lt;br /&gt;
* [http://www.springsource.org/roo/ Web oficial de Spring Roo]&lt;br /&gt;
* [http://static.springsource.org/spring-roo/reference/html-single/index.html Manual de referencia]&lt;br /&gt;
* [http://www.infoq.com/presentations/Introducing-Spring-Roo Presentación hecha por el creador]&lt;br /&gt;
* [https://admin.na3.acrobat.com/_a204547676/p38684494/?launcher=false&amp;amp;fcsContent=true&amp;amp;pbMode=normal Curso de Spring Roo on-line]&lt;br /&gt;
* [http://blog.springsource.com/2009/05/27/roo-part-2/ Ejemplo con buscador dinámico]&lt;br /&gt;
* [http://stsmedia.net/introducing-spring-roo-part-2-security-jms-email-support/ Ejemplo con Jms y envío de mails]&lt;br /&gt;
&lt;br /&gt;
[[Category: Spring Framework]]&lt;/div&gt;</summary>
		<author><name>201.251.182.130</name></author>	</entry>

	<entry>
		<id>https://dosideas.com/wiki/index.php?title=Ant&amp;diff=5629</id>
		<title>Ant</title>
		<link rel="alternate" type="text/html" href="https://dosideas.com/wiki/index.php?title=Ant&amp;diff=5629"/>
				<updated>2010-12-14T13:58:31Z</updated>
		
		<summary type="html">&lt;p&gt;201.251.182.130: /* Ver también */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Ant]] es una herramienta de build de [[Software Libre]] especializada en construir proyectos Java. [[Ant]] utiliza archivos XML para expresar las instrucciones de ejecución de build. Ella posee una gran variedad de tareas que permiten la realización de actividades como generación de pruebas unitarias, publicación de información, entre otras. &lt;br /&gt;
&lt;br /&gt;
Algunos ejemplos de tareas pueden ser: &lt;br /&gt;
&lt;br /&gt;
*Prepare -&amp;amp;gt; Realiza la creación de directorios que contendrán los ejecutables. &lt;br /&gt;
*Compile -&amp;amp;gt; Compila el código fuente del producto. &lt;br /&gt;
*Instrument -&amp;amp;gt; Instrumenta el código para permitir la generación de información de cobertura de código. &lt;br /&gt;
*Compile-test -&amp;amp;gt; Compila el código de pruebas unitarias automatizadas. &lt;br /&gt;
*Test -&amp;amp;gt; Ejecuta la batería de pruebas unitarias automatizadas, genera la información en HTML de las pruebas ejecutadas con éxito y con falla y genera la información en HTMl de la cobertura de código. &lt;br /&gt;
*[[PMD]] -&amp;amp;gt; Ejecuta la generación de información de análisis estática de código. &lt;br /&gt;
*Javadoc -&amp;amp;gt; Ejecuta la generación de documentación de las clases en base a los comentarios en el código fuente. &lt;br /&gt;
*Run -&amp;amp;gt; Ejecuta el software. &lt;br /&gt;
*Clean -&amp;amp;gt; Realiza la limpieza de los directorios que contienen los ejecutables. &lt;br /&gt;
*Jar -&amp;amp;gt; Realiza el empaquetado del software para que pueda se utilizado en producción.&lt;br /&gt;
&lt;br /&gt;
El script de build puede ser ejecutado de diversas maneras y con múltiples opciones. En el caso de línea de comando, por ejemplo &amp;quot;ant test pmd javadoc jar&amp;quot;, todas las secciones del archivo XML serán ejecutadas. &lt;br /&gt;
&lt;br /&gt;
Ant puede ser utilizado para realizar la implantación de una aplicación JEE Web en producción. Un ejemplo de una sección que haría eso sería el siguiente: &amp;lt;code xml=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;target name=&amp;quot;deploy&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;deploy url=&amp;quot;${tomcat.manager.url}&amp;quot;&lt;br /&gt;
    username=&amp;quot;${tomcat.manager.username}&amp;quot;&lt;br /&gt;
    password=&amp;quot;${tomcat.manager.password}&amp;quot;&lt;br /&gt;
    path=&amp;quot;/${webap.name}&amp;quot;&lt;br /&gt;
    war=&amp;quot;file:${warfile.path}&amp;quot; /&amp;gt;&lt;br /&gt;
  &amp;lt;/target&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
== Condicionales con ant  ==&lt;br /&gt;
&lt;br /&gt;
A continuación se muestra una forma de simular los típicos condicionales &amp;quot;if - then - else&amp;quot; con tags de Ant. El ejemplo muestra como realizar diferentes acciones según el contenido de un parámetro. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;project name=&amp;quot;Condicional&amp;quot; default=&amp;quot;if&amp;quot; basedir=&amp;quot;.&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;target name=&amp;quot;if&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;condition property=&amp;quot;condition&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;equals arg1=&amp;quot;${param}&amp;quot; arg2=&amp;quot;VALOR1&amp;quot; /&amp;gt;&lt;br /&gt;
        &amp;lt;/condition&amp;gt;&lt;br /&gt;
        &amp;lt;antcall target=&amp;quot;then&amp;quot;/&amp;gt;&lt;br /&gt;
        &amp;lt;antcall target=&amp;quot;else&amp;quot;/&amp;gt;&lt;br /&gt;
    &amp;lt;/target&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;target name=&amp;quot;then&amp;quot; if=&amp;quot;condition&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;echo&amp;gt;El parámetro fue VALOR1&amp;lt;/echo&amp;gt;&lt;br /&gt;
    &amp;lt;/target&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;target name=&amp;quot;else&amp;quot; unless=&amp;quot;condition&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;condition property=&amp;quot;conditionElse&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;equals arg1=&amp;quot;${param}&amp;quot; arg2=&amp;quot;VALOR2&amp;quot; /&amp;gt;&lt;br /&gt;
        &amp;lt;/condition&amp;gt;&lt;br /&gt;
        &amp;lt;antcall target=&amp;quot;thenElse&amp;quot;/&amp;gt;&lt;br /&gt;
        &amp;lt;antcall target=&amp;quot;elseElse&amp;quot;/&amp;gt;&lt;br /&gt;
    &amp;lt;/target&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;target name=&amp;quot;thenElse&amp;quot; if=&amp;quot;conditionElse&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;echo&amp;gt;El parámetro fue VALOR2&amp;lt;/echo&amp;gt;&lt;br /&gt;
    &amp;lt;/target&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;target name=&amp;quot;elseElse&amp;quot; unless=&amp;quot;conditionElse&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;fail message=&amp;quot;Parametro desconocido&amp;quot;&amp;gt;&amp;lt;/fail&amp;gt;&lt;br /&gt;
    &amp;lt;/target&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
&amp;lt;/project&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
El tag '''condition'''&amp;amp;nbsp;setea una properties de acuerdo a la condición que contiene.&amp;amp;nbsp;Si la condición tiene valor '''true''', el valor de la propertie es seteado en '''true '''por default (tambien se puede especificar que valor asignarle a la propertie con el atributo '''value'''). De otra manera la propertie no es seteada.&amp;amp;nbsp;Existe un [http://ant.apache.org/manual/Tasks/conditions.html listado de condiciones] permitidas para el tag. &lt;br /&gt;
&lt;br /&gt;
Luego utilizando los atributos del tag target&amp;amp;nbsp;: '''if '''y '''unless '''podemos simular un flujo de condicionales:&lt;br /&gt;
&lt;br /&gt;
*El atributo '''if '''permite que se ejecute el target solo si el valor de la variable que se le pasa es '''true'''. &lt;br /&gt;
*El atributo '''unless '''se comporta de la manera contraria: solo permite la ejecución del target si el valor de la variable no es true.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
== Profiling de las tareas Ant ==&lt;br /&gt;
'''Nota:''' Requiere una versión 1.8 o superior.&lt;br /&gt;
&lt;br /&gt;
En caso de que se quiera obtener los tiempo de ejecución de cada tarea ant (clean, report, etc) basta con definir el parámetro logger con el valor ''org.apache.tools.ant.listener.ProfileLogger''. [http://ant.apache.org/manual/listeners.html Para más información]&lt;br /&gt;
&lt;br /&gt;
Por ejemplo si queremos saber los tiempos para la siguiente tarea:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;gt; ant clean compile test javadoc &lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
con el profiling quedaría:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;gt; ant -logger org.apache.tools.ant.listener.ProfileLogger clean compile test javadoc report&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
dando como resultado:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
Target clean: started Tue Dec 14 17:15:40 PKT 2010&lt;br /&gt;
...&lt;br /&gt;
Target clean: finishedTue Dec 14 17:15:40 PKT 2010 (0ms)&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Ver también  ==&lt;br /&gt;
&lt;br /&gt;
*[[Automatizacion De Build]] &lt;br /&gt;
*[[Maven]] &lt;br /&gt;
*[http://ant.apache.org/ Web oficial de Ant] &lt;br /&gt;
*[http://ant.apache.org/manual/Tasks/condition.html Documentación de tag Condition] &lt;br /&gt;
*[http://ant.apache.org/manual/listeners.html Documentación de Listeners &amp;amp; Loggers]&lt;br /&gt;
*[http://www.dosideas.com/java/391-automatizacion-de-despliegues-ino-mas-dolores-de-cabeza.html Patrones para la automatización de despliegues]&lt;br /&gt;
&lt;br /&gt;
[[Category:Java]]&lt;/div&gt;</summary>
		<author><name>201.251.182.130</name></author>	</entry>

	<entry>
		<id>https://dosideas.com/wiki/index.php?title=Ant&amp;diff=5628</id>
		<title>Ant</title>
		<link rel="alternate" type="text/html" href="https://dosideas.com/wiki/index.php?title=Ant&amp;diff=5628"/>
				<updated>2010-12-14T13:43:07Z</updated>
		
		<summary type="html">&lt;p&gt;201.251.182.130: /* Profiling de las tareas Ant */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Ant]] es una herramienta de build de [[Software Libre]] especializada en construir proyectos Java. [[Ant]] utiliza archivos XML para expresar las instrucciones de ejecución de build. Ella posee una gran variedad de tareas que permiten la realización de actividades como generación de pruebas unitarias, publicación de información, entre otras. &lt;br /&gt;
&lt;br /&gt;
Algunos ejemplos de tareas pueden ser: &lt;br /&gt;
&lt;br /&gt;
*Prepare -&amp;amp;gt; Realiza la creación de directorios que contendrán los ejecutables. &lt;br /&gt;
*Compile -&amp;amp;gt; Compila el código fuente del producto. &lt;br /&gt;
*Instrument -&amp;amp;gt; Instrumenta el código para permitir la generación de información de cobertura de código. &lt;br /&gt;
*Compile-test -&amp;amp;gt; Compila el código de pruebas unitarias automatizadas. &lt;br /&gt;
*Test -&amp;amp;gt; Ejecuta la batería de pruebas unitarias automatizadas, genera la información en HTML de las pruebas ejecutadas con éxito y con falla y genera la información en HTMl de la cobertura de código. &lt;br /&gt;
*[[PMD]] -&amp;amp;gt; Ejecuta la generación de información de análisis estática de código. &lt;br /&gt;
*Javadoc -&amp;amp;gt; Ejecuta la generación de documentación de las clases en base a los comentarios en el código fuente. &lt;br /&gt;
*Run -&amp;amp;gt; Ejecuta el software. &lt;br /&gt;
*Clean -&amp;amp;gt; Realiza la limpieza de los directorios que contienen los ejecutables. &lt;br /&gt;
*Jar -&amp;amp;gt; Realiza el empaquetado del software para que pueda se utilizado en producción.&lt;br /&gt;
&lt;br /&gt;
El script de build puede ser ejecutado de diversas maneras y con múltiples opciones. En el caso de línea de comando, por ejemplo &amp;quot;ant test pmd javadoc jar&amp;quot;, todas las secciones del archivo XML serán ejecutadas. &lt;br /&gt;
&lt;br /&gt;
Ant puede ser utilizado para realizar la implantación de una aplicación JEE Web en producción. Un ejemplo de una sección que haría eso sería el siguiente: &amp;lt;code xml=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;target name=&amp;quot;deploy&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;deploy url=&amp;quot;${tomcat.manager.url}&amp;quot;&lt;br /&gt;
    username=&amp;quot;${tomcat.manager.username}&amp;quot;&lt;br /&gt;
    password=&amp;quot;${tomcat.manager.password}&amp;quot;&lt;br /&gt;
    path=&amp;quot;/${webap.name}&amp;quot;&lt;br /&gt;
    war=&amp;quot;file:${warfile.path}&amp;quot; /&amp;gt;&lt;br /&gt;
  &amp;lt;/target&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
== Condicionales con ant  ==&lt;br /&gt;
&lt;br /&gt;
A continuación se muestra una forma de simular los típicos condicionales &amp;quot;if - then - else&amp;quot; con tags de Ant. El ejemplo muestra como realizar diferentes acciones según el contenido de un parámetro. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;project name=&amp;quot;Condicional&amp;quot; default=&amp;quot;if&amp;quot; basedir=&amp;quot;.&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;target name=&amp;quot;if&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;condition property=&amp;quot;condition&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;equals arg1=&amp;quot;${param}&amp;quot; arg2=&amp;quot;VALOR1&amp;quot; /&amp;gt;&lt;br /&gt;
        &amp;lt;/condition&amp;gt;&lt;br /&gt;
        &amp;lt;antcall target=&amp;quot;then&amp;quot;/&amp;gt;&lt;br /&gt;
        &amp;lt;antcall target=&amp;quot;else&amp;quot;/&amp;gt;&lt;br /&gt;
    &amp;lt;/target&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;target name=&amp;quot;then&amp;quot; if=&amp;quot;condition&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;echo&amp;gt;El parámetro fue VALOR1&amp;lt;/echo&amp;gt;&lt;br /&gt;
    &amp;lt;/target&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;target name=&amp;quot;else&amp;quot; unless=&amp;quot;condition&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;condition property=&amp;quot;conditionElse&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;equals arg1=&amp;quot;${param}&amp;quot; arg2=&amp;quot;VALOR2&amp;quot; /&amp;gt;&lt;br /&gt;
        &amp;lt;/condition&amp;gt;&lt;br /&gt;
        &amp;lt;antcall target=&amp;quot;thenElse&amp;quot;/&amp;gt;&lt;br /&gt;
        &amp;lt;antcall target=&amp;quot;elseElse&amp;quot;/&amp;gt;&lt;br /&gt;
    &amp;lt;/target&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;target name=&amp;quot;thenElse&amp;quot; if=&amp;quot;conditionElse&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;echo&amp;gt;El parámetro fue VALOR2&amp;lt;/echo&amp;gt;&lt;br /&gt;
    &amp;lt;/target&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;target name=&amp;quot;elseElse&amp;quot; unless=&amp;quot;conditionElse&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;fail message=&amp;quot;Parametro desconocido&amp;quot;&amp;gt;&amp;lt;/fail&amp;gt;&lt;br /&gt;
    &amp;lt;/target&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
&amp;lt;/project&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
El tag '''condition'''&amp;amp;nbsp;setea una properties de acuerdo a la condición que contiene.&amp;amp;nbsp;Si la condición tiene valor '''true''', el valor de la propertie es seteado en '''true '''por default (tambien se puede especificar que valor asignarle a la propertie con el atributo '''value'''). De otra manera la propertie no es seteada.&amp;amp;nbsp;Existe un [http://ant.apache.org/manual/Tasks/conditions.html listado de condiciones] permitidas para el tag. &lt;br /&gt;
&lt;br /&gt;
Luego utilizando los atributos del tag target&amp;amp;nbsp;: '''if '''y '''unless '''podemos simular un flujo de condicionales:&lt;br /&gt;
&lt;br /&gt;
*El atributo '''if '''permite que se ejecute el target solo si el valor de la variable que se le pasa es '''true'''. &lt;br /&gt;
*El atributo '''unless '''se comporta de la manera contraria: solo permite la ejecución del target si el valor de la variable no es true.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
== Profiling de las tareas Ant ==&lt;br /&gt;
'''Nota:''' Requiere una versión 1.8 o superior.&lt;br /&gt;
&lt;br /&gt;
En caso de que se quiera obtener los tiempo de ejecución de cada tarea ant (clean, report, etc) basta con definir el parámetro logger con el valor ''org.apache.tools.ant.listener.ProfileLogger''. [http://ant.apache.org/manual/listeners.html Para más información]&lt;br /&gt;
&lt;br /&gt;
Por ejemplo si queremos saber los tiempos para la siguiente tarea:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;gt; ant clean compile test javadoc &lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
con el profiling quedaría:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;gt; ant -logger org.apache.tools.ant.listener.ProfileLogger clean compile test javadoc report&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
dando como resultado:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
Target clean: started Tue Dec 14 17:15:40 PKT 2010&lt;br /&gt;
...&lt;br /&gt;
Target clean: finishedTue Dec 14 17:15:40 PKT 2010 (0ms)&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Ver también  ==&lt;br /&gt;
&lt;br /&gt;
*[[Automatizacion De Build]] &lt;br /&gt;
*[[Maven]] &lt;br /&gt;
*[http://ant.apache.org/ Web oficial de Ant] &lt;br /&gt;
*[http://ant.apache.org/manual/Tasks/condition.html Documentación de tag Condition] &lt;br /&gt;
*[http://www.dosideas.com/java/391-automatizacion-de-despliegues-ino-mas-dolores-de-cabeza.html Patrones para la automatización de despliegues]&lt;br /&gt;
&lt;br /&gt;
[[Category:Java]]&lt;/div&gt;</summary>
		<author><name>201.251.182.130</name></author>	</entry>

	<entry>
		<id>https://dosideas.com/wiki/index.php?title=Ant&amp;diff=5627</id>
		<title>Ant</title>
		<link rel="alternate" type="text/html" href="https://dosideas.com/wiki/index.php?title=Ant&amp;diff=5627"/>
				<updated>2010-12-14T13:36:40Z</updated>
		
		<summary type="html">&lt;p&gt;201.251.182.130: /* Profiling de las tareas Ant */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Ant]] es una herramienta de build de [[Software Libre]] especializada en construir proyectos Java. [[Ant]] utiliza archivos XML para expresar las instrucciones de ejecución de build. Ella posee una gran variedad de tareas que permiten la realización de actividades como generación de pruebas unitarias, publicación de información, entre otras. &lt;br /&gt;
&lt;br /&gt;
Algunos ejemplos de tareas pueden ser: &lt;br /&gt;
&lt;br /&gt;
*Prepare -&amp;amp;gt; Realiza la creación de directorios que contendrán los ejecutables. &lt;br /&gt;
*Compile -&amp;amp;gt; Compila el código fuente del producto. &lt;br /&gt;
*Instrument -&amp;amp;gt; Instrumenta el código para permitir la generación de información de cobertura de código. &lt;br /&gt;
*Compile-test -&amp;amp;gt; Compila el código de pruebas unitarias automatizadas. &lt;br /&gt;
*Test -&amp;amp;gt; Ejecuta la batería de pruebas unitarias automatizadas, genera la información en HTML de las pruebas ejecutadas con éxito y con falla y genera la información en HTMl de la cobertura de código. &lt;br /&gt;
*[[PMD]] -&amp;amp;gt; Ejecuta la generación de información de análisis estática de código. &lt;br /&gt;
*Javadoc -&amp;amp;gt; Ejecuta la generación de documentación de las clases en base a los comentarios en el código fuente. &lt;br /&gt;
*Run -&amp;amp;gt; Ejecuta el software. &lt;br /&gt;
*Clean -&amp;amp;gt; Realiza la limpieza de los directorios que contienen los ejecutables. &lt;br /&gt;
*Jar -&amp;amp;gt; Realiza el empaquetado del software para que pueda se utilizado en producción.&lt;br /&gt;
&lt;br /&gt;
El script de build puede ser ejecutado de diversas maneras y con múltiples opciones. En el caso de línea de comando, por ejemplo &amp;quot;ant test pmd javadoc jar&amp;quot;, todas las secciones del archivo XML serán ejecutadas. &lt;br /&gt;
&lt;br /&gt;
Ant puede ser utilizado para realizar la implantación de una aplicación JEE Web en producción. Un ejemplo de una sección que haría eso sería el siguiente: &amp;lt;code xml=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;target name=&amp;quot;deploy&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;deploy url=&amp;quot;${tomcat.manager.url}&amp;quot;&lt;br /&gt;
    username=&amp;quot;${tomcat.manager.username}&amp;quot;&lt;br /&gt;
    password=&amp;quot;${tomcat.manager.password}&amp;quot;&lt;br /&gt;
    path=&amp;quot;/${webap.name}&amp;quot;&lt;br /&gt;
    war=&amp;quot;file:${warfile.path}&amp;quot; /&amp;gt;&lt;br /&gt;
  &amp;lt;/target&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
== Condicionales con ant  ==&lt;br /&gt;
&lt;br /&gt;
A continuación se muestra una forma de simular los típicos condicionales &amp;quot;if - then - else&amp;quot; con tags de Ant. El ejemplo muestra como realizar diferentes acciones según el contenido de un parámetro. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;project name=&amp;quot;Condicional&amp;quot; default=&amp;quot;if&amp;quot; basedir=&amp;quot;.&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;target name=&amp;quot;if&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;condition property=&amp;quot;condition&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;equals arg1=&amp;quot;${param}&amp;quot; arg2=&amp;quot;VALOR1&amp;quot; /&amp;gt;&lt;br /&gt;
        &amp;lt;/condition&amp;gt;&lt;br /&gt;
        &amp;lt;antcall target=&amp;quot;then&amp;quot;/&amp;gt;&lt;br /&gt;
        &amp;lt;antcall target=&amp;quot;else&amp;quot;/&amp;gt;&lt;br /&gt;
    &amp;lt;/target&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;target name=&amp;quot;then&amp;quot; if=&amp;quot;condition&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;echo&amp;gt;El parámetro fue VALOR1&amp;lt;/echo&amp;gt;&lt;br /&gt;
    &amp;lt;/target&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;target name=&amp;quot;else&amp;quot; unless=&amp;quot;condition&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;condition property=&amp;quot;conditionElse&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;equals arg1=&amp;quot;${param}&amp;quot; arg2=&amp;quot;VALOR2&amp;quot; /&amp;gt;&lt;br /&gt;
        &amp;lt;/condition&amp;gt;&lt;br /&gt;
        &amp;lt;antcall target=&amp;quot;thenElse&amp;quot;/&amp;gt;&lt;br /&gt;
        &amp;lt;antcall target=&amp;quot;elseElse&amp;quot;/&amp;gt;&lt;br /&gt;
    &amp;lt;/target&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;target name=&amp;quot;thenElse&amp;quot; if=&amp;quot;conditionElse&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;echo&amp;gt;El parámetro fue VALOR2&amp;lt;/echo&amp;gt;&lt;br /&gt;
    &amp;lt;/target&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;target name=&amp;quot;elseElse&amp;quot; unless=&amp;quot;conditionElse&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;fail message=&amp;quot;Parametro desconocido&amp;quot;&amp;gt;&amp;lt;/fail&amp;gt;&lt;br /&gt;
    &amp;lt;/target&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
&amp;lt;/project&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
El tag '''condition'''&amp;amp;nbsp;setea una properties de acuerdo a la condición que contiene.&amp;amp;nbsp;Si la condición tiene valor '''true''', el valor de la propertie es seteado en '''true '''por default (tambien se puede especificar que valor asignarle a la propertie con el atributo '''value'''). De otra manera la propertie no es seteada.&amp;amp;nbsp;Existe un [http://ant.apache.org/manual/Tasks/conditions.html listado de condiciones] permitidas para el tag. &lt;br /&gt;
&lt;br /&gt;
Luego utilizando los atributos del tag target&amp;amp;nbsp;: '''if '''y '''unless '''podemos simular un flujo de condicionales:&lt;br /&gt;
&lt;br /&gt;
*El atributo '''if '''permite que se ejecute el target solo si el valor de la variable que se le pasa es '''true'''. &lt;br /&gt;
*El atributo '''unless '''se comporta de la manera contraria: solo permite la ejecución del target si el valor de la variable no es true.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
== Profiling de las tareas Ant ==&lt;br /&gt;
'''Nota:''' Requiere una versión 1.8 o superior.&lt;br /&gt;
&lt;br /&gt;
En caso de que se quiera obtener los tiempo de ejecución de cada tarea ant (clean, report, etc) basta con definir el parámetro logger con el valor ''org.apache.tools.ant.listener.ProfileLogger''&lt;br /&gt;
&lt;br /&gt;
Por ejemplo si para la tarea:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;gt; ant clean compile test javadoc &lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
con el profiling quedaría:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;gt; ant -logger org.apache.tools.ant.listener.ProfileLogger clean compile test javadoc report&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Ver también  ==&lt;br /&gt;
&lt;br /&gt;
*[[Automatizacion De Build]] &lt;br /&gt;
*[[Maven]] &lt;br /&gt;
*[http://ant.apache.org/ Web oficial de Ant] &lt;br /&gt;
*[http://ant.apache.org/manual/Tasks/condition.html Documentación de tag Condition] &lt;br /&gt;
*[http://www.dosideas.com/java/391-automatizacion-de-despliegues-ino-mas-dolores-de-cabeza.html Patrones para la automatización de despliegues]&lt;br /&gt;
&lt;br /&gt;
[[Category:Java]]&lt;/div&gt;</summary>
		<author><name>201.251.182.130</name></author>	</entry>

	<entry>
		<id>https://dosideas.com/wiki/index.php?title=Lista_De_Impedimentos&amp;diff=5619</id>
		<title>Lista De Impedimentos</title>
		<link rel="alternate" type="text/html" href="https://dosideas.com/wiki/index.php?title=Lista_De_Impedimentos&amp;diff=5619"/>
				<updated>2010-12-02T18:59:24Z</updated>
		
		<summary type="html">&lt;p&gt;201.251.182.130: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Scrum]]&lt;br /&gt;
Se considera un Impedimento a cualquier cosa alrededor de un proyecto [[Scrum]] que interfiera con la productividad o calidad del mismo.&lt;br /&gt;
&lt;br /&gt;
Es responsabilidad del [[Scrum Master]] eliminar cualquier impedimento que le impida al equipo producir código de calidad productiva. La Lista de Impedimentos es un grupo de tareas que el [[Scrum Master]] usa para el seguimiento de los impedimientos que necesitan ser resueltos.&lt;br /&gt;
&lt;br /&gt;
== Seguimiento de un impedimento ==&lt;br /&gt;
Durante cada [[Reunion Diaria De Scrum]] el [[Scrum Master]] informará el estado del impedimento y de no haber sido resuelto irá asentando el paso de los días en el registro del impedimento.&lt;br /&gt;
&lt;br /&gt;
Una vez resuelto, el Scrum Master podrá tachar el impedimento de la lista. El Impedimento seguirá pegado en el afiche, y servirá para analizar al finalizar el Sprint.&lt;br /&gt;
&lt;br /&gt;
Un impedimento que tarda mucho en resolverse seguramente producirá un impacto negativo en los tiempos de una historia. Lo mismo ocurrirá si un Sprint sufre un número excesivo de impedimentos.&lt;br /&gt;
&lt;br /&gt;
En ambos casos es problable que el equipo no logre cumplir con el compromiso asumido, y contará con un detalle visible de las dificultades que tuvieron.&lt;br /&gt;
&lt;br /&gt;
== Ejemplo ==&lt;br /&gt;
Supongamos un impedimento con un &amp;quot;Servicio de morosidad&amp;quot;, el cual el equipo debe utilizar para completar alguna historia del Sprint (el servicio es externo al Sprint, y no es responsabilidad del equipo). Durante una Reunion Diaria De Scrum algún integrante puede mencionar que dicho servicio no está funcionado. El Scrum Master entonces creará una nota adhesiva con el impedimento, y la ubicará en la sección correspondiente en el afiche del Sprint.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;0&amp;quot; valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|  [[image:Impedimento-servicio-de-morosidad.jpg|frame|El Scrum Master escribe la nota adhesiva y lo pega en el afiche del Sprint]]&lt;br /&gt;
|| [[image:Impedimento-servicio-de-morosidad-2.jpg|frame|2 días y sigue el impedimento sin resolverse]]&lt;br /&gt;
|-&lt;br /&gt;
|  [[image:Impedimento-servicio-de-morosidad-5.jpg|frame|5 días sin resolución]]&lt;br /&gt;
|| [[image:Impedimento-servicio-de-morosidad-resuelto.jpg|frame|Luego de 7 días el impedimento quedó solucionado]] &lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>201.251.182.130</name></author>	</entry>

	<entry>
		<id>https://dosideas.com/wiki/index.php?title=Struts&amp;diff=5604</id>
		<title>Struts</title>
		<link rel="alternate" type="text/html" href="https://dosideas.com/wiki/index.php?title=Struts&amp;diff=5604"/>
				<updated>2010-11-19T17:59:44Z</updated>
		
		<summary type="html">&lt;p&gt;201.251.182.130: /* Previniendo la cache del navegador en Struts&amp;amp;nbsp; */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Previniendo la cache del navegador en Struts&amp;amp;nbsp;  ==&lt;br /&gt;
&lt;br /&gt;
Muchas veces, la utilización por parte del usuario de un sitio del &amp;quot;Volver&amp;quot; del navegador puede ocasionarnos problemas. Para prevenir esto, se suele utilizar el siguiente código html: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;meta http-equiv=&amp;quot;Expires&amp;quot; content=&amp;quot;Tue, 01 Jan 2000 12:12:12 GMT&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;meta http-equiv=&amp;quot;Pragma&amp;quot; content=&amp;quot;no-cache&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Esto funciona inconsistentemente en Internet Explorer. A continuación, una alternativa para que funcione con Struts:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
  &amp;lt;%&lt;br /&gt;
  response.setHeader(&amp;quot;Cache-Control&amp;quot;,&amp;quot;no-cache&amp;quot;);&lt;br /&gt;
  response.setHeader(&amp;quot;Pragma&amp;quot;,&amp;quot;no-cache&amp;quot;);&lt;br /&gt;
  response.setDateHeader (&amp;quot;Expires&amp;quot;, 0);&lt;br /&gt;
  %&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Con esto, Internet Explorer soporta el cache. &lt;br /&gt;
&lt;br /&gt;
Sin embargo, al parecer, Firefox 3 tiene problemas con el no-cache. Si se necesita contemplar también este explorador, el código es el siguiente:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;lt;%&lt;br /&gt;
  response.setHeader(&amp;quot;Cache-Control&amp;quot;,&amp;quot;no-store&amp;quot;);&lt;br /&gt;
  response.setHeader(&amp;quot;Pragma&amp;quot;,&amp;quot;no-cache&amp;quot;);&lt;br /&gt;
  response.setDateHeader (&amp;quot;Expires&amp;quot;, 0);&lt;br /&gt;
  %&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== saveToken y isTokenValid ==&lt;br /&gt;
&lt;br /&gt;
El método saveToken() de la clase Action de Struts, es utilizado para evitar submits duplicados. Para hacer este checkeo, struts tiene el método saveToken() para setear el token, y isTokenValid() para validarlo del lado receptor.&lt;br /&gt;
&lt;br /&gt;
== Ver también ==&lt;br /&gt;
* [[Struts, AJAX y Global Exceptions]]&lt;br /&gt;
* [http://lab.artlung.com/anti-cache/ Fuente]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Struts]]&lt;/div&gt;</summary>
		<author><name>201.251.182.130</name></author>	</entry>

	</feed>