<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:creativeCommons="http://backend.userland.com/creativeCommonsRssModule" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0"><channel><title>Apuntes de Java</title><link>http://www.apuntesdejava.com/</link><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/ApuntesDeJava" /><description>&lt;p&gt;¡Todas las semanas un nuevo apunte! &lt;br&gt;
Si Dios (y el trabajo) lo permiten &lt;code&gt;:)&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;
&lt;strong&gt;Visita &lt;a href="http://kenai.com/projects/apuntes"&gt;http://kenai.com/projects/apuntes&lt;/a&gt;&lt;/strong&gt;&lt;br&gt;
LinkedIn: &lt;a href="http://www.linkedin.com/groups/Apuntes-Java-4095645?gid=4095645&amp;amp;trk=hb_side_g"&gt;Apuntes de Java&lt;/a&gt;</description><language>en</language><managingEditor>noreply@blogger.com (Diego Silva)</managingEditor><lastBuildDate>Wed, 01 Feb 2012 10:16:18 PST</lastBuildDate><generator>Blogger</generator><atom:id xmlns:atom="http://www.w3.org/2005/Atom">tag:blogger.com,1999:blog-8553642737291298841</atom:id><openSearch:totalResults xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/">257</openSearch:totalResults><openSearch:startIndex xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/">1</openSearch:startIndex><openSearch:itemsPerPage xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/">25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/ApuntesDeJava" /><feedburner:info uri="apuntesdejava" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><creativeCommons:license>http://creativecommons.org/licenses/by-nc-sa/2.0/</creativeCommons:license><image><link>http://apuntesdejava.com</link><url>http://lh4.ggpht.com/_BQk94ojgkDY/S-r2lg63tQI/AAAAAAAAC7Y/rDZjHcQ-d3M/logo-apuntesjavab.png</url><title>ApuntesDeJava.com</title></image><feedburner:emailServiceId>ApuntesDeJava</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><item><title>Un par de regalos para finalizar el año: Plugins para NetBeans</title><link>http://feedproxy.google.com/~r/ApuntesDeJava/~3/OO2jfpJEiUA/un-par-de-regalos-para-finalizar-el-ano.html</link><category>plugins</category><category>tips</category><category>netbeans 7.0</category><category>netbeans</category><author>noreply@blogger.com (Diego Silva)</author><pubDate>Thu, 29 Dec 2011 10:20:00 PST</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-8553642737291298841.post-5210570521090499526</guid><description>&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://1.bp.blogspot.com/-K5dHKujY2HA/Tvytu9JF9VI/AAAAAAAAAGc/us5dRA6-zAE/s1600/plugin.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/-K5dHKujY2HA/Tvytu9JF9VI/AAAAAAAAAGc/us5dRA6-zAE/s1600/plugin.png" /&gt;&lt;/a&gt;&lt;/div&gt;
Antes de finalizar este año - que personalmente me sucedieron varias cosas entre buenas y malas - quiero dejaros un par de enlaces de plugins para que lo anexen a su NetBeans 7.x y con ello tendrán un editor de XSLT y de otros plugins.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;Considerar los siguientes enlaces&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://deadlock.netbeans.org/hudson/job/nbms-and-javadoc/lastStableBuild/artifact/nbbuild/nbms/updates.xml.gz"&gt;http://deadlock.netbeans.org/hudson/job/nbms-and-javadoc/lastStableBuild/artifact/nbbuild/nbms/updates.xml.gz&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://deadlock.netbeans.org/hudson/job/xml/lastSuccessfulBuild/artifact/build/updates/updates.xml"&gt;http://deadlock.netbeans.org/hudson/job/xml/lastSuccessfulBuild/artifact/build/updates/updates.xml&lt;/a&gt; &lt;br /&gt;
&lt;br /&gt;
Ambos se deben agregar en la ventana Tools &amp;gt; Plugins y en la ficha "Settings". Una vez agregado, se mostrarán los plugins adicionales en la ficha "Available plugins".&lt;br /&gt;
&lt;br /&gt;
El primer enlace contiene varios plugins interesantes, entre los que mencioné en un anterior post: &lt;a href="http://www.apuntesdejava.com/2009/10/plugins-curiosos-para-netbeans-68.html" target="_blank"&gt;Plugins curiosos para NetBeans 6.8 &lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
El segundo contiene el editor de XSLT mencionado en el post: &lt;a href="http://www.apuntesdejava.com/2009/06/un-editor-de-xml-schema-gratuito.html" target="_blank"&gt;Un editor de XML Schema gratuito... NetBeans &lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Que el nuevo año les sea para bien :)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8553642737291298841-5210570521090499526?l=www.apuntesdejava.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/DJhZF-X3rLU_KcusdrdI4Vf5oAY/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/DJhZF-X3rLU_KcusdrdI4Vf5oAY/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/DJhZF-X3rLU_KcusdrdI4Vf5oAY/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/DJhZF-X3rLU_KcusdrdI4Vf5oAY/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/ApuntesDeJava?a=OO2jfpJEiUA:e0SAS_ZfjjQ:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ApuntesDeJava?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ApuntesDeJava?a=OO2jfpJEiUA:e0SAS_ZfjjQ:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ApuntesDeJava?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ApuntesDeJava?a=OO2jfpJEiUA:e0SAS_ZfjjQ:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ApuntesDeJava?i=OO2jfpJEiUA:e0SAS_ZfjjQ:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ApuntesDeJava/~4/OO2jfpJEiUA" height="1" width="1"/&gt;</description><atom:updated xmlns:atom="http://www.w3.org/2005/Atom">2011-12-29T13:20:09.532-05:00</atom:updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/-K5dHKujY2HA/Tvytu9JF9VI/AAAAAAAAAGc/us5dRA6-zAE/s72-c/plugin.png" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.apuntesdejava.com/2011/12/un-par-de-regalos-para-finalizar-el-ano.html</feedburner:origLink></item><item><title>AOP con Java EE 6</title><link>http://feedproxy.google.com/~r/ApuntesDeJava/~3/SGuifZUNddE/aop-con-java-ee-6.html</link><category>java</category><category>java ee</category><category>netbeans 7.0</category><category>netbeans</category><category>java ee 6</category><category>aop</category><author>noreply@blogger.com (Diego Silva)</author><pubDate>Mon, 26 Sep 2011 05:00:00 PDT</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-8553642737291298841.post-8696555616974813009</guid><description>&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://2.bp.blogspot.com/-CTmi8-2n6Lc/Tnpp4EcY0-I/AAAAAAAAAFo/6zKKcMtyVzE/s1600/banner-aop.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/-CTmi8-2n6Lc/Tnpp4EcY0-I/AAAAAAAAAFo/6zKKcMtyVzE/s1600/banner-aop.png" /&gt;&lt;/a&gt;&lt;/div&gt;
En un anterior &lt;a href="http://www.apuntesdejava.com/2008/06/aop-programacion-orientada-aspectos-con.html"&gt;Post&lt;/a&gt; hablé sobre &lt;a href="http://es.wikipedia.org/wiki/Programaci%C3%B3n_orientada_a_aspectos"&gt;AOP&lt;/a&gt; usando &lt;a href="http://www.springsource.org/"&gt;Spring&lt;/a&gt;. Es un post algo antiguo, y me había basado de un &lt;a href="http://www.javaranch.com/journal/2008/04/Journal200804.jsp#a2"&gt;artículo publicado&lt;/a&gt; en &lt;a href="http://www.javaranch.com/"&gt;JavaRanch&lt;/a&gt;. &lt;br /&gt;
&lt;br /&gt;
Esa vez fue usando el famoso Framework Spring, pero esta vez mencionaré como funciona el AOP desde Java EE6. Creo que ya existía desde la versión EE 5, pero no importa, aquí lo mencionamos para el deleite de todos.&lt;br /&gt;
&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;A diferencia del Spring, es que este AOP funciona desde un contenedor Java EE, y sobretodo, en un EJB. En Spring funciona desde cualquier aplicación que tenga la biblioteca Spring.&lt;br /&gt;
&lt;br /&gt;
Así que, para que funcione nuestro ejemplo, debemos crear un módulo EJB.. pero esta vez - a diferencia de otros tutoriales - crearemos una Aplicación Enterprise (EA) con un módulo EJB y WAR. El EA se llama aop-ea, y los módulos se llaman aop-ejb y aop-war respectivamente.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://2.bp.blogspot.com/-FupxM6ghHs8/Tnpu_bRN1JI/AAAAAAAAAFw/dWpZ3WN_NDs/s1600/aop-01.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/-FupxM6ghHs8/Tnpu_bRN1JI/AAAAAAAAAFw/dWpZ3WN_NDs/s1600/aop-01.png" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
Luego, en nuestro módulo EJB crearemos una clase común y silvestre llamada &lt;code&gt;MonitoreoInterceptor&lt;/code&gt; y tendrá el siguiente contenido:&lt;br /&gt;
&lt;pre class="brush:java"&gt;package com.apuntesdejava.aop.ejb.interceptor;

import java.lang.reflect.Method;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.interceptor.AroundInvoke;
import javax.interceptor.InvocationContext;

public class MonitoreoInterceptor {
    static final Logger LOGGER=Logger.getLogger(MonitoreoInterceptor.class.getName()); //para mostrar el log
    
    @AroundInvoke //Define un método interceptor que se interpondrá en los métodos del EJB
    public Object seguimientoMetodo(InvocationContext invocationContext) throws Exception{
        Object objetoInterceptado=invocationContext.getTarget();
        Method metodoInterceptado=invocationContext.getMethod();
        // para mostrar el metodo que se va a ejecutar
        LOGGER.log(Level.INFO, "Ejecutando m\u00e9todo: {0}.{1}()", 
                new Object[]{objetoInterceptado.getClass().getName(), metodoInterceptado.getName()});
        
        Object o=invocationContext.proceed(); //hacemos ejecutar el método, o si hay otro interceptor, le damos la posta
        // la variable devuelta es el resultado del método, o NULL si es un método VOID
        
        LOGGER.log(Level.INFO, "Saliendo del m\u00e9todo: {0}.{1}()", 
                new Object[]{objetoInterceptado.getClass().getName(), metodoInterceptado.getName()});
        
        LOGGER.log(Level.INFO, "EL m\u00e9todo devuelve el valor: {0}", o);
        
        return o; //que continue la secuencia
    }
    
}

&lt;/pre&gt;
Solo aquí hemos definido el interceptor. Ahora, crearemos un EJB en el móduglo EJB con un par de métodos y lo interceptamos con la clase que acabamos de crear.
&lt;br /&gt;
&lt;pre class="brush:java"&gt;package com.apuntesdejava.aop.ejb.facade;

import com.apuntesdejava.aop.ejb.domain.Persona;
import com.apuntesdejava.aop.ejb.interceptor.MonitoreoInterceptor;
import java.util.ArrayList;
import java.util.List;
import javax.ejb.Stateless;
import javax.interceptor.Interceptors;


@Stateless
public class PersonaFacade {

    private static List&amp;lt;Persona&amp;gt; personas = new ArrayList&amp;lt;Persona&amp;gt;();

    @Interceptors({MonitoreoInterceptor.class}) //le colocamos un conjunto de interceptores
    public void nuevo(Persona p) { //el método es uno común y corriente.
        personas.add(p);
    }

    @Interceptors({MonitoreoInterceptor.class})// tambien le colocamos un conjunto de interceptores
    public List&amp;lt;Persona&amp;gt; lista() { //este método devuelve algo
        return personas;
    }
}

&lt;/pre&gt;
Y desde un Servlet llamamos al EJB como si fuera cualquier EJB común.&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;&lt;span class="Apple-style-span" style="color: #674ea7;"&gt;Uno de los grandes beneficios es que no necesitaremos que heredar código para hacer algo repetitivo&lt;/span&gt;&lt;/strong&gt;, ni repetir el código en todo lugar donde se necesite. Por ejemplo, si queremos monitorear el acceso a ciertas partes de la lógica de negocio, lo colocamos en el Interceptor, y si queremos cambiar la manera cómo vamos a manejar el monitereo, pues claro.. cambiamos solo un interceptor.

&lt;br /&gt;
&lt;pre class="brush:java"&gt;//...
@WebServlet(name = "ListaServlet", urlPatterns = {"/ListaServlet"})
public class ListaServlet extends HttpServlet {

    @EJB
    private PersonaFacade personaFacade;

    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        List&amp;lt;Persona&amp;gt; lista = personaFacade.lista();
        request.setAttribute("lista", lista);
        RequestDispatcher rd = request.getRequestDispatcher("/lista.jsp");
        rd.forward(request, response);
    }

//...&lt;/pre&gt;
Además, también podemos ejecutarlo desde un Cliente EJB... Con algunas consideraciones en el EJB, tenemos el siguiente código para el cliente EJB:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush:java"&gt;//...
public class Main {

    @EJB
    private static PersonaFacadeRemote personaFacade;

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        Persona p1 = new Persona(1, "Ana");
        Persona p2 = new Persona(1, "Bernardo");
        Persona p3 = new Persona(1, "Carl");
        personaFacade.nuevo(p1);
        personaFacade.nuevo(p2);
        personaFacade.nuevo(p3);
    }
}

&lt;/pre&gt;
&lt;br /&gt;
El resultado en el Servidor es el siguiente..&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://4.bp.blogspot.com/-LL74hAgGZyE/TnqABQNRXQI/AAAAAAAAAF0/xiM1czHYcB0/s1600/aop-02.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/-LL74hAgGZyE/TnqABQNRXQI/AAAAAAAAAF0/xiM1czHYcB0/s1600/aop-02.png" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
Y listo!.. ya estoy monitoreando los métodos!!&lt;br /&gt;
&lt;br /&gt;
Este post &amp;nbsp;no pretendió ser un tutorial de &amp;nbsp;EJB, por lo que me he saltado muchas cosas. El objetivo de este post es solo mostrar como funciona el AOP. Para la creación de un EJB con cliente lo veremos en otro artículo.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
El código fuente de este post, incluyendo el cliente de EJB se puede descargar desde aquí:&amp;nbsp;&lt;a href="http://kenai.com/projects/apuntes/downloads/download/AOP/aop-ea.tar.gz"&gt;http://kenai.com/projects/apuntes/downloads/download/AOP/aop-ea.tar.gz&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Más información sobre los Interceptors, aquí, en la documentación de Java EE 6:&amp;nbsp;&lt;a href="http://download.oracle.com/javaee/6/tutorial/doc/gkeed.html"&gt;http://download.oracle.com/javaee/6/tutorial/doc/gkeed.html&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8553642737291298841-8696555616974813009?l=www.apuntesdejava.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/gF_k9WdHWMbhJh7j7uH9uww0RbE/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/gF_k9WdHWMbhJh7j7uH9uww0RbE/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/gF_k9WdHWMbhJh7j7uH9uww0RbE/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/gF_k9WdHWMbhJh7j7uH9uww0RbE/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/ApuntesDeJava?a=SGuifZUNddE:_GU57Q7LpOM:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ApuntesDeJava?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ApuntesDeJava?a=SGuifZUNddE:_GU57Q7LpOM:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ApuntesDeJava?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ApuntesDeJava?a=SGuifZUNddE:_GU57Q7LpOM:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ApuntesDeJava?i=SGuifZUNddE:_GU57Q7LpOM:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ApuntesDeJava/~4/SGuifZUNddE" height="1" width="1"/&gt;</description><atom:updated xmlns:atom="http://www.w3.org/2005/Atom">2011-09-26T07:00:15.276-05:00</atom:updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/-CTmi8-2n6Lc/Tnpp4EcY0-I/AAAAAAAAAFo/6zKKcMtyVzE/s72-c/banner-aop.png" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.apuntesdejava.com/2011/09/aop-con-java-ee-6.html</feedburner:origLink></item><item><title>Premios Open Source 2011</title><link>http://feedproxy.google.com/~r/ApuntesDeJava/~3/uoYiqhCdnrs/premios-open-source-2011.html</link><author>noreply@blogger.com (Diego Silva)</author><pubDate>Wed, 21 Sep 2011 08:17:00 PDT</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-8553642737291298841.post-5985561723078948493</guid><description>&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://www.packtpub.com/sites/default/files/Packt_OS-AWARDS-2011_0.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" height="191" src="http://www.packtpub.com/sites/default/files/Packt_OS-AWARDS-2011_0.png" width="200" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;a href="http://www.packtpub.com/"&gt;PACKT&lt;/a&gt; anuncia la entrega de premios "Open Source 2011" en el que se presentan los mejores productos OpenSource de la comunidad.&lt;br /&gt;
&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;Los nominados a esta premiación son los siguientes:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.packtpub.com/open-source-awards-home/vote-open-source-cms"&gt;&lt;b&gt;Open Source CMS&lt;/b&gt;&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;Drupal&lt;/li&gt;
&lt;li&gt;Joomla!&lt;/li&gt;
&lt;li&gt;mojoPortal&lt;/li&gt;
&lt;li&gt;Plone&lt;/li&gt;
&lt;li&gt;SilverStripe&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.packtpub.com/open-source-awards-home/vote-open-source-mobile-toolkits-and-libraries"&gt;&lt;b&gt;Open Source Mobile Toolkits and Libraries&lt;/b&gt;&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;FoneMonkey&lt;/li&gt;
&lt;li&gt;jQuery Mobile &lt;/li&gt;
&lt;li&gt;Min3D&lt;/li&gt;
&lt;li&gt;PhoneGap&lt;/li&gt;
&lt;li&gt;Sencha Touch&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.packtpub.com/open-source-awards-home/vote-most-promising-open-source-project"&gt;&lt;b&gt;Most Promising Open Source Project&lt;/b&gt;&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;Chamilo&lt;/li&gt;
&lt;li&gt;FLOW3&lt;/li&gt;
&lt;li&gt;ImpressPages&lt;/li&gt;
&lt;li&gt;Nette Framework&lt;/li&gt;
&lt;li&gt;Seo Panel&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.packtpub.com/open-source-awards-home/vote-open-source-business-application"&gt;&lt;b&gt;Open Source Business Applications&lt;/b&gt;&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;Magento&lt;/li&gt;
&lt;li&gt;nopCommerce&lt;/li&gt;
&lt;li&gt;OpenCart&lt;/li&gt;
&lt;li&gt;PrestaShop&lt;/li&gt;
&lt;li&gt;SugarcCRM&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.packtpub.com/open-source-awards-home/vote-open-source-javascript-libraries"&gt;&lt;b&gt;Open Source JavaScript Libraries&lt;/b&gt;&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;Dojo Toolkit&lt;/li&gt;
&lt;li&gt;jQuery&lt;/li&gt;
&lt;li&gt;RaphaelJS&lt;/li&gt;
&lt;li&gt;Sencha (ExtJS)&lt;/li&gt;
&lt;li&gt;YUI Library&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.packtpub.com/open-source-awards-home/vote-open-source-multimedia-software"&gt;&lt;b&gt;Open Source Multimedia Software&lt;/b&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;Airtime&lt;/li&gt;
&lt;li&gt;Blender&lt;/li&gt;
&lt;li&gt;GIMP&lt;/li&gt;
&lt;li&gt;Inkscape&lt;/li&gt;
&lt;li&gt;Krita&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="color: #cc0000; font-size: large;"&gt;¡¡Voten por sus favoritos!!&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Para conocer más sobre este evento, visiten:&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;a href="http://www.packtpub.com/open-source-awards-home"&gt;http://www.packtpub.com/open-source-awards-home&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Yo ya tengo mis favoritos.. veamos quien es el ganador.&lt;/div&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8553642737291298841-5985561723078948493?l=www.apuntesdejava.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/yS1dnJf-DX2z4FiPz5uWUGy7ONA/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/yS1dnJf-DX2z4FiPz5uWUGy7ONA/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/yS1dnJf-DX2z4FiPz5uWUGy7ONA/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/yS1dnJf-DX2z4FiPz5uWUGy7ONA/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/ApuntesDeJava?a=uoYiqhCdnrs:CNeFf6-KSBQ:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ApuntesDeJava?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ApuntesDeJava?a=uoYiqhCdnrs:CNeFf6-KSBQ:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ApuntesDeJava?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ApuntesDeJava?a=uoYiqhCdnrs:CNeFf6-KSBQ:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ApuntesDeJava?i=uoYiqhCdnrs:CNeFf6-KSBQ:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ApuntesDeJava/~4/uoYiqhCdnrs" height="1" width="1"/&gt;</description><atom:updated xmlns:atom="http://www.w3.org/2005/Atom">2011-09-21T10:17:49.456-05:00</atom:updated><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.apuntesdejava.com/2011/09/premios-open-source-2011.html</feedburner:origLink></item><item><title>Libro: Java EE 6 Development with NetBeans 7</title><link>http://feedproxy.google.com/~r/ApuntesDeJava/~3/gSw_W4bqVw8/libro-java-ee-6-development-with.html</link><category>comentarios</category><category>libros</category><category>java ee</category><category>netbeans 7.0</category><category>netbeans</category><category>java ee 6</category><author>noreply@blogger.com (Diego Silva)</author><pubDate>Tue, 20 Sep 2011 07:45:00 PDT</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-8553642737291298841.post-2212812101401064838</guid><description>&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://www.packtpub.com/sites/default/files/imagecache/productview/2701_Java%20EE6%20.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" src="https://www.packtpub.com/sites/default/files/imagecache/productview/2701_Java%20EE6%20.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;
La gente de &lt;a href="http://packtpub.com/"&gt;PacktPub.com&lt;/a&gt; la noble tarea de revisar un libro que habla sobre Java EE 6 con NetBeans 7:&amp;nbsp;&lt;span class="Apple-style-span" style="background-color: white; font-family: 'Helvetica neue', Helvetica, Arial, Verdana, sans-serif; font-size: 12px; line-height: 18px;"&gt;&lt;a href="http://www.packtpub.com/java-ee-6-development-with-netbeans-7/book"&gt;Java EE 6 Development with NetBeans 7&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Acabo de leerlo y aquí van mis comentarios.&lt;br /&gt;
&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;Conozco gente que desea aprender a hacer aplicaciones profesionales utilizando Java EE 6, bajo plataforma Web, JMS, WebService, base de datos, etc. Esta gente conoce el lenguaje Java pero no sabe por donde empezar. En las bibliotecas y librerías no he visto algún libro que hablara de toda la tecnología Java EE 6 utilizando un IDE como este.&lt;br /&gt;
&lt;br /&gt;
Es un libro práctico de leer, orientado a programadores y desarrolladores que conocen el lenguaje Java. Envuelve varios puntos importantes de cada tecnología de Java EE 6. Los tutoriales gratuitos y manuales que se encuentran en la red no cubren ni exponen toda la potencia de Java EE 6. El autor de este libro sí lo hace, de manera ordenada, concisa, directa.&lt;br /&gt;
&lt;br /&gt;
Hubiera sido de mejor utilidad si se expusiera el desarrollo de un tema concreto, y ver como el NetBeans resuelve el problema utilizando el Java EE 6. Pudo haber mostrado el desarrollo de una solución de eCommerce basado desde Servlets / JSP y como se puede mejorar hasta tener RESTful. Aunque, pensándolo bien, ya escaparía el alcance de este libro, ya que su objetivo principal es mostrar todo lo que puede hacer con NetBeans.&lt;br /&gt;
&lt;br /&gt;
El NetBeans es la estrella de este libro, ya que permite realizar &amp;nbsp;tareas complejas utilizando pocos clics: Pruebas de servicios web, creación de páginas JSF, creación de manejadores de JPA, etc. Lo más sorprendente son los capítulos dedicados a EJB y CDI, ya que explican como hacer cliente en EJB, y cómo utilizar el AOP en Java EE 6.&lt;br /&gt;
&lt;br /&gt;
Algo que no me dejó de buen gusto, es que hay partes (muy pocas) que son tomadas de una versión anterior de NetBeans. Quizás el autor, por la prisa, no pudo diferenciar imágenes y código de su anterior publicación (&lt;span class="Apple-style-span" style="background-color: white; font-family: 'Helvetica neue', Helvetica, Arial, Verdana, sans-serif; font-size: 12px; line-height: 18px;"&gt;&lt;a href="http://www.packtpub.com/java-ee5-development-with-netbeans-6/book"&gt;Java EE 5 Development with NetBeans 6&lt;/a&gt;&lt;/span&gt;). Esto puede confundir al lector porque pudiera esperar el mismo resultado en su IDE tal como &amp;nbsp;aparece en el libro. Pero esto no afecta en la exposición de las tecnologías de Java EE 6. Pero son partes muy pequeñas y no muy relevantes. Creo que soy muy exigente en este punto.&lt;br /&gt;
&lt;br /&gt;
Recomiendo este libro para los desarrolladores Java que quieran entrar en el mundo de Java EE 6. No es la Biblia de Java EE 6, ya que esta tecnología es bastante extensa y no habría libro que cubra profundamente todos los aspectos de Java EE 6, pero da una clara y completa visión de lo que se puede hacer con ella, y qué más, utilizando un gran IDE como es NetBeans.&lt;br /&gt;
&lt;br /&gt;
Aquí les dejo una muestra del capítulo 4, sobre la creación de JSF: &lt;a href="http://www.packtpub.com/sites/default/files/2701OS-Chapter-4-Developing-Web-Applications-using-JavaServer-Faces-2.0.pdf?utm_source=packtpub&amp;amp;utm_medium=free&amp;amp;utm_campaign=pdf"&gt;Chapter 4 Developing-Web Applications using JavaServer Faces 2.0&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Para más información del Libro, ver:&amp;nbsp;&lt;a href="http://www.packtpub.com/java-ee-6-development-with-netbeans-7/book"&gt;http://www.packtpub.com/java-ee-6-development-with-netbeans-7/book&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8553642737291298841-2212812101401064838?l=www.apuntesdejava.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/YO_snHS3gFsoHmw5OC-Xz99T42U/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/YO_snHS3gFsoHmw5OC-Xz99T42U/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/YO_snHS3gFsoHmw5OC-Xz99T42U/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/YO_snHS3gFsoHmw5OC-Xz99T42U/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/ApuntesDeJava?a=gSw_W4bqVw8:b8OMQcHE_OQ:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ApuntesDeJava?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ApuntesDeJava?a=gSw_W4bqVw8:b8OMQcHE_OQ:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ApuntesDeJava?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ApuntesDeJava?a=gSw_W4bqVw8:b8OMQcHE_OQ:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ApuntesDeJava?i=gSw_W4bqVw8:b8OMQcHE_OQ:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ApuntesDeJava/~4/gSw_W4bqVw8" height="1" width="1"/&gt;</description><atom:updated xmlns:atom="http://www.w3.org/2005/Atom">2011-09-20T09:45:42.503-05:00</atom:updated><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.apuntesdejava.com/2011/09/libro-java-ee-6-development-with.html</feedburner:origLink></item><item><title>Probando RESTful con Poster</title><link>http://feedproxy.google.com/~r/ApuntesDeJava/~3/FLMJ-bAa-fA/probando-restful-con-poster.html</link><category>restful</category><category>glassfish v3</category><category>firefox</category><category>ejb</category><category>ajax</category><category>netbeans</category><category>ejb 3.1</category><category>webservices</category><author>noreply@blogger.com (Diego Silva)</author><pubDate>Tue, 13 Sep 2011 15:36:00 PDT</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-8553642737291298841.post-4816120806514303707</guid><description>&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://2.bp.blogspot.com/-s32W4b68fF4/TPmvEVoBOcI/AAAAAAAAACE/Pdb-CjNqGw8/s1600/rest-ful-webservice-baner.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/-s32W4b68fF4/TPmvEVoBOcI/AAAAAAAAACE/Pdb-CjNqGw8/s1600/rest-ful-webservice-baner.png" /&gt;&lt;/a&gt;&lt;/div&gt;
Seguimos con RESTful en Java!&lt;br /&gt;
Ya luego comentaré qué pasó conmigo y por qué no estuve enviando contenido a mi blog.
&lt;br /&gt;
Hasta el momento hemos visto casi de manera abstracta el funcionamiento de &lt;a href="http://en.wikipedia.org/wiki/Representational_State_Transfer"&gt;RESTful&lt;/a&gt;&amp;nbsp;usando &lt;a href="http://jersey.java.net/"&gt;Jersey&lt;/a&gt; desde &lt;a href="http://netbeans.org/"&gt;NetBeans&lt;/a&gt;.&lt;br /&gt;
&lt;div style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;
&lt;/div&gt;
Ahora veremos como probar todo un &lt;a href="http://es.wikipedia.org/wiki/CRUD"&gt;CRUD&lt;/a&gt; de RESTful desde un complemento de Firefox llamado &lt;a href="https://addons.mozilla.org/es-ES/firefox/addon/poster/"&gt;Poster&lt;/a&gt;.&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;La mejor manera de probar un servicio es no creando una aplicación. Es decir, si vamos a probar como funciona algo, no tenemos que hacer un programa que utilice ese algo.&lt;br /&gt;
El objetivo principal del RESTful es proveer servicios estándar para todo tipo de cliente ¿cierto? Entonces, si hacemos una aplicación que consuma nuestro servicio, corremos el peligro de que ajustemos el servicio para que corra con nuestra aplicación y al final no sea estándar.&lt;br /&gt;
&lt;br /&gt;
Así que, antes de mostrar el RESTful, debemos instalar el complemento Poster en nuestro Firefox (porque asumimos que como buenos programadores, usamos Firefox) Este se puede descargar desde aquí:&amp;nbsp;&lt;a href="https://addons.mozilla.org/es-ES/firefox/addon/poster/"&gt;https://addons.mozilla.org/es-ES/firefox/addon/poster/&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Ahora, les comento que he ordenado un poco el proyecto que hemos estado haciendo en los post anteriores. Ahora tiene un EJB que manejará la colección de entidades (como debe ser) y que está separado de la clase de recursos (como debe ser).&lt;br /&gt;
&lt;br /&gt;
Además, el manejo de las peticiones CRUD en un REST son como sigue:&lt;br /&gt;
&lt;br /&gt;
&lt;table border="1"&gt;
&lt;tbody&gt;
&lt;tr&gt;&lt;th&gt;Verbo REST&lt;/th&gt;&lt;th&gt;URI&lt;/th&gt;&lt;th&gt;Acción a realizar&lt;/th&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;POST&lt;/td&gt;&lt;td&gt;&lt;code&gt;/persona&lt;/code&gt;&lt;/td&gt;&lt;td&gt;Create&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GET&lt;/td&gt;&lt;td&gt;&lt;code&gt;/persona/id&lt;/code&gt;&lt;/td&gt;&lt;td&gt;Read&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PUT&lt;/td&gt;&lt;td&gt;&lt;code&gt;/persona/id&lt;/code&gt;&lt;/td&gt;&lt;td&gt;Update&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DELETE&lt;/td&gt;&lt;td&gt;&lt;code&gt;/persona/id&lt;/code&gt;&lt;/td&gt;&lt;td&gt;Delete&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
Así, el código final del recurso REST es el siguiente:
&lt;br /&gt;
&lt;pre class="brush: java"&gt;@Path("/persona")
@Consumes({"application/json", "application/xml"})
@Stateless
public class PersonaService {

    @EJB
    private PersonaFacade facade;

    @POST
    public Response create(Persona p) {
        facade.insert(p);
        return Response.ok(p).build();
    }

    @GET
    @Path("{id}/")
    public Persona read(@PathParam("id") int i) {
        Persona p = facade.findById(i);
        return p;
    }

    @GET
    public List&amp;lt;Persona&amp;gt; read(@QueryParam("nombre")
            @DefaultValue("") String nombre) {
        List&amp;lt;Persona&amp;gt; l = nombre.isEmpty() ? facade.findAll() : facade.findByNombre(nombre);
        return l;
    }

    @DELETE
    @Path("/{id}")
    public Response delete(@PathParam("id") int i) {
        if (facade.delete(i)) {
            return Response.ok().build();
        }
        return Response.status(Response.Status.NOT_FOUND).build();
    }

    @PUT
    @Path("/{id}")
    public Response update(@PathParam("id") int i, Persona p) {
        p.setId(i);
        facade.update(p);
        return Response.ok().build();
    }
}

&lt;/pre&gt;
Y el EJB es el siguiente:
&lt;br /&gt;
&lt;pre class="brush: java"&gt;@Stateless
public class PersonaFacade {

    private static List&amp;lt;Persona&amp;gt; lista = new ArrayList&amp;lt;Persona&amp;gt;(); //lista temporal

    public void insert(Persona p) {
        lista.add(p); //agrega a la lista

    }

    public Persona findById(int id) {
        Persona p = new Persona(id); //crea un objeto temporal...
        int i = lista.indexOf(p); //... para buscarlo en la lista
        if (i &amp;lt; 0) {//si no lo encuentra        
            return null; //... devuelve null
        }
        return lista.get(i);  // sino, lo devuelve
    }

    public List&amp;lt;Persona&amp;gt; findAll() {
        return lista;
    }

    public List&amp;lt;Persona&amp;gt; findByNombre(String nombre) {

        List&amp;lt;Persona&amp;gt; $lista = new ArrayList&amp;lt;Persona&amp;gt;(); //un arreglo temporal
        for (Persona persona : lista) {  //se recorre la lista...
            if (persona.getNombre().contains(nombre)) { //se compara el nombre
                $lista.add(persona); //y si es parecido, lo agrega en la lista
            }
        }
        return $lista; //... para devolverlo
    }

    public boolean delete(Persona p) {
        return lista.remove(p);
    }

    public void update(Persona p) {
        int pos = lista.indexOf(p); //busca en la lista..
        if (pos &amp;gt;= 0) { //si lo encuentra...
            lista.set(pos, p); //... lo actualiza            
        }

    }

    public boolean delete(int i) {
        Persona p = findById(i);
        return delete(p);
    }
}
&lt;/pre&gt;
&lt;h2&gt;






Ejecutando Poster&lt;/h2&gt;
Ahora bien, una vez instalado el Poster en Firefox, lo abrimos haciendo clic en la barra inferior del navegador en el ícono color amarillo con una letra P. Esto nos abrirá la siguiente ventana:
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://2.bp.blogspot.com/-lapTEHt_Crs/Tm-95uTVFDI/AAAAAAAAAFE/7nCTnNDLPwU/s1600/poster01.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://2.bp.blogspot.com/-lapTEHt_Crs/Tm-95uTVFDI/AAAAAAAAAFE/7nCTnNDLPwU/s320/poster01.png" width="245" /&gt;&lt;/a&gt;&lt;/div&gt;
Es bastante fácil su utilización como lo veremos a continuación.&lt;br /&gt;
&lt;br /&gt;
Ejecutemos el proyecto desde nuestro NetBeans y veremos que se abrirá una ventana de bienvenida (no muy elegante) y un enlace para visualizar la descripción del recurso. Al hacer clic en ese enlace, se mostrará el &lt;a href="http://www.w3.org/Submission/wadl/"&gt;WADL&lt;/a&gt;&amp;nbsp;Podemos examinar por curiosidad para conocer los recursos existentes. Pero en este momento vamos a ver cómo funciona el Poster.&lt;br /&gt;
&lt;br /&gt;
En la casilla URL se deberá poner el URI del servicio completo. Para nuestro ejemplo es&amp;nbsp;http://localhost:8084/PersonasRestful/rest/persona (cambiar el puerto si es necesario)&lt;br /&gt;
&lt;br /&gt;
En la casilla central llamada "Content type" se pondrá el tipo de datos que se manejará en el envío. Le pondremos el valor: &lt;code&gt;application/json&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
En la caja grande de entrada es el contenido a enviar. Ahí pondremos los datos a enviar.&lt;br /&gt;
&lt;h3&gt;





Create&lt;/h3&gt;
&lt;div&gt;
Para crear un nuevo objeto en la "base de datos" usando el servicio, necesitamos colocar el contenido siguiente:&lt;/div&gt;
&lt;pre class="brush: js"&gt;{
  "nombre":"Ann",
  "fechaNacimiento":"2010-11-12"
}&lt;/pre&gt;
&lt;div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://2.bp.blogspot.com/-xvkDUwcO0k4/Tm_H0sZiSRI/AAAAAAAAAFI/8QHqaOfF8BE/s1600/poster02.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://2.bp.blogspot.com/-xvkDUwcO0k4/Tm_H0sZiSRI/AAAAAAAAAFI/8QHqaOfF8BE/s320/poster02.png" width="245" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
Luego, hacemos clic en el botón central "POST". El Poster nos mostrará un resultado:
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://1.bp.blogspot.com/-OIKMhaWxjJo/Tm_H5DSCq-I/AAAAAAAAAFM/eMjsNWSFcWI/s1600/poster03.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://1.bp.blogspot.com/-OIKMhaWxjJo/Tm_H5DSCq-I/AAAAAAAAAFM/eMjsNWSFcWI/s320/poster03.png" width="282" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;br /&gt;&lt;/div&gt;
Este resultado es porque se ha puesto que devuelva el objeto que se agregó.&lt;br /&gt;
Intentemos agregar más objetos y hacer POST por cada uno de ellos.&lt;/div&gt;
&lt;h3&gt;





Read&lt;/h3&gt;
&lt;div&gt;
Para obtener el listado de todos los objetos registrados en el servicio, nos aseguramos que el URL apunte a URI &lt;code&gt;/rest/persona&lt;/code&gt; y hacemos clic en el botón GET. El Poster nos mostrará el siguiente contenido.&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://1.bp.blogspot.com/-CSrDE9XgqH4/Tm_S4IqUjJI/AAAAAAAAAFc/BkfFuZtJlh0/s1600/poster04a.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="208" src="http://1.bp.blogspot.com/-CSrDE9XgqH4/Tm_S4IqUjJI/AAAAAAAAAFc/BkfFuZtJlh0/s320/poster04a.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://4.bp.blogspot.com/-F7Z_Gmot0TM/Tm_OoqpDDfI/AAAAAAAAAFQ/yta87AjP4T8/s1600/poster04.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://4.bp.blogspot.com/-F7Z_Gmot0TM/Tm_OoqpDDfI/AAAAAAAAAFQ/yta87AjP4T8/s320/poster04.png" width="282" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Esto me devuelve el listado completo. Pero si solo quiero uno de ellos, y conozco el ID, pondremos en el URI el ID de una persona. Por ejemplo &lt;code&gt;/rest/persona/2&lt;/code&gt; y luego hacemos clic en "GET".&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://1.bp.blogspot.com/-nn_uwJUexAs/Tm_SmFniA8I/AAAAAAAAAFY/JU4WEOcpE5s/s1600/poster05a.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="211" src="http://1.bp.blogspot.com/-nn_uwJUexAs/Tm_SmFniA8I/AAAAAAAAAFY/JU4WEOcpE5s/s320/poster05a.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://4.bp.blogspot.com/-wt5sRwQbMg8/Tm_SQZx56lI/AAAAAAAAAFU/fxgAtusfRC4/s1600/poster05.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://4.bp.blogspot.com/-wt5sRwQbMg8/Tm_SQZx56lI/AAAAAAAAAFU/fxgAtusfRC4/s320/poster05.png" width="282" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;h3&gt;


Update&lt;/h3&gt;
Para actualizar un registro se debe tener lo siguiente: apuntar a un URI incluyendo el ID &lt;code&gt;/rest/persona/2&lt;/code&gt; y en el contenido colocar las propiedades a actualizar. Por ejemplo:&lt;br /&gt;
&lt;pre class="brush: js"&gt;{
  "nombre":"Alfred",
  "fechaNacimiento":"2010-11-12"
}&lt;/pre&gt;
Y hacemos clic en el botón PUT&lt;br /&gt;
Esta petición no nos ha respondido nada, ya que así lo hemos pusimos en el RESTful.&lt;br /&gt;
Podemos verificar el contenido haciendo un GET de todos los objetos registrados.&lt;br /&gt;
&lt;h3&gt;





Delete&lt;/h3&gt;
&lt;div&gt;
Igual que el PUT y UPDATE... solo le indicamos el ID en el URI y hacemos clic en "DELETE". Luego verificamos haciendo un GET de todos los objetos registrados y veremos si está o no.&lt;/div&gt;
&lt;h2&gt;

Cambiando el objeto resultado&lt;/h2&gt;
Como podemos ver, todas las peticiones que hemos hecho (PUT y POST) tienen el formato JSON, pero los resultados a nuestras peticiones tienen formato XML. Bueno, por omisión el Jersey devolverá bajo ese tipo. Pero también permite devolver formato JSON si así lo solicita el cliente POSTER. Para ello vamos a la pestaña "Headers" del Poster y agregamos la siguiente cabecera: 
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Accept: application/json&lt;/li&gt;
&lt;/ul&gt;
.. y hacemos clic en "Add/Change"&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://3.bp.blogspot.com/-eMROeDKS8PU/Tm_V-mZ_mTI/AAAAAAAAAFg/PuTtD3NqyVM/s1600/poster06.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="220" src="http://3.bp.blogspot.com/-eMROeDKS8PU/Tm_V-mZ_mTI/AAAAAAAAAFg/PuTtD3NqyVM/s320/poster06.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;
Y luego, hagamos el GET de todos los objetos para visualizar el contenido.&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://4.bp.blogspot.com/-wC4AJSSsOrk/Tm_WL1_TxaI/AAAAAAAAAFk/08J98WpMUvg/s1600/poster06a.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://4.bp.blogspot.com/-wC4AJSSsOrk/Tm_WL1_TxaI/AAAAAAAAAFk/08J98WpMUvg/s320/poster06a.png" width="282" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;
Recursos&lt;/h2&gt;
El proyecto utilizado se puede descargar desde aquí:
&lt;br /&gt;
&lt;a href="http://kenai.com/projects/apuntes/downloads/download/CRUDPersonasRest/personas-restful-crud.tar.gz"&gt;http://kenai.com/projects/apuntes/downloads/download/CRUDPersonasRest/personas-restful-crud.tar.gz&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8553642737291298841-4816120806514303707?l=www.apuntesdejava.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/MATOehOkmQIO3jG6BvqyQC1joJM/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/MATOehOkmQIO3jG6BvqyQC1joJM/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/MATOehOkmQIO3jG6BvqyQC1joJM/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/MATOehOkmQIO3jG6BvqyQC1joJM/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/ApuntesDeJava?a=FLMJ-bAa-fA:ZxeUSlPhSM4:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ApuntesDeJava?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ApuntesDeJava?a=FLMJ-bAa-fA:ZxeUSlPhSM4:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ApuntesDeJava?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ApuntesDeJava?a=FLMJ-bAa-fA:ZxeUSlPhSM4:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ApuntesDeJava?i=FLMJ-bAa-fA:ZxeUSlPhSM4:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ApuntesDeJava/~4/FLMJ-bAa-fA" height="1" width="1"/&gt;</description><atom:updated xmlns:atom="http://www.w3.org/2005/Atom">2011-09-13T17:36:54.888-05:00</atom:updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/-s32W4b68fF4/TPmvEVoBOcI/AAAAAAAAACE/Pdb-CjNqGw8/s72-c/rest-ful-webservice-baner.png" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total><feedburner:origLink>http://www.apuntesdejava.com/2011/09/probando-restful-con-poster.html</feedburner:origLink></item><item><title>Contraseñas encriptadas con Java</title><link>http://feedproxy.google.com/~r/ApuntesDeJava/~3/nos4FSwQvi0/contrasenas-encriptadas-con-java.html</link><category>java</category><category>commons</category><category>seguridad</category><category>apache</category><author>noreply@blogger.com (Diego Silva)</author><pubDate>Sat, 04 Jun 2011 15:27:00 PDT</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-8553642737291298841.post-2324163446370249803</guid><description>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-Pj8dnLGbV5o/Teqg8ZrXk7I/AAAAAAAAAEg/atQbqsbl1Lc/s1600/encryption.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" height="200" src="http://4.bp.blogspot.com/-Pj8dnLGbV5o/Teqg8ZrXk7I/AAAAAAAAAEg/atQbqsbl1Lc/s200/encryption.jpg" width="200" /&gt;&lt;/a&gt;&lt;/div&gt;¿Quién no ha querido encriptar texto o archivo? Hay diversas maneras para hacer eso, por ejemplo, utilizando un diccionario donde se reemplazara cada caracter por un código.. y para poder desencriptarlo se debería utilizar el mismo diccionario para revertir el proceso. Pero si el diccionario cae en manos de alguien que no queremos que lo sepa, entonces estamos en peligro.&lt;br /&gt;
Cuando yo programaba en pascal, mi encriptación favorita era invirtiendo los bits... pero cualquiera también puede invertir los bits y listo.&lt;br /&gt;
Pero ya gente experta logró algoritmos de encriptación populares. Los más conocidos: MD5 y SHA. &lt;br /&gt;
En este post hablaremos cómo encriptar texto, sobretodo las contraseñas, utilizando MD5 o SHA.&lt;br /&gt;
&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;La historia de la &lt;a href="http://es.wikipedia.org/wiki/Criptograf%C3%ADa"&gt;criptografía &lt;/a&gt;es bastante larga e interesante, pero para nuestro día a día, solo necesitamos cómo utilizar las bibliotecas existentes en el mercado.&lt;br /&gt;
Hace un tiempo, hice un post de ello (&lt;a href="http://www.apuntesdejava.com/2009/03/md5-en-java.html"&gt;MD5 en Java&lt;/a&gt;) que consistía en utilizar el mismo API de Java para generar MD5.Pero ahora mostraré una biblioteca muy útil proporcionada por la fundación &lt;a href="http://apache.org/"&gt;ASF&lt;/a&gt;. &lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;Commons Codec&lt;/h2&gt;Podemos descargar su biblioteca desde aquí &lt;a href="http://commons.apache.org/codec/download_codec.cgi"&gt;http://commons.apache.org/codec/download_codec.cgi&lt;/a&gt;&lt;br /&gt;
Descomprimimos el archivo y tomamos el .jar llamado &lt;code&gt;commons-codec-1.5.jar&lt;/code&gt; y lo agregamos al proyecto. En NetBeans solo le damos clic derecho en &lt;code&gt;Libraries&lt;/code&gt; del Proyecto y seleccionamos el .jar.&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-rn3G5oC3e6k/Teqsx--nRwI/AAAAAAAAAEk/s-Kku-nZt0A/s1600/biblio-jar.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/-rn3G5oC3e6k/Teqsx--nRwI/AAAAAAAAAEk/s-Kku-nZt0A/s1600/biblio-jar.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
La clase &lt;a href="http://commons.apache.org/codec/apidocs/org/apache/commons/codec/digest/DigestUtils.html"&gt;&lt;code&gt;DigestUtils&lt;/code&gt;&lt;/a&gt; es nuestra clase principal para utilizar los diferentes algoritmos de encriptación.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;MD5&lt;/h3&gt;&lt;pre&gt;&lt;code&gt;        String texto="Saludos desde Apuntesdejava.com";
        String encriptMD5=DigestUtils.md5Hex(texto);
        System.out.println("md5:"+encriptMD5);
&lt;/code&gt;&lt;/pre&gt;La salida resultante es:&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;md5:e5adf3f9fe476c7816eacd3873f5b51f&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
Para comprobarlo, yo utilizo la consola de MySQL&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-nlA7WNByFdQ/Tequgeeg5UI/AAAAAAAAAEo/aYQHXl9TkIQ/s1600/md5-mysql.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="321" src="http://4.bp.blogspot.com/-nlA7WNByFdQ/Tequgeeg5UI/AAAAAAAAAEo/aYQHXl9TkIQ/s640/md5-mysql.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;h3&gt;SHA-HEX&lt;/h3&gt;Similar al MD5, solo es otro método&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;        String texto="Saludos desde Apuntesdejava.com";
        String encript=DigestUtils.shaHex(texto);
        System.out.println("shaHex:"+encript);
&lt;/code&gt;&lt;/pre&gt;La salida resultante es:&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;shaHex:2b05363b154309d7fc069cd922f316fa3f3ff866&lt;/code&gt;&lt;/pre&gt;Y en MySQL:&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-w-IYnbG-LQM/TeqvGMQzZrI/AAAAAAAAAEs/XgCMaA21cNo/s1600/sha-mysql.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/-w-IYnbG-LQM/TeqvGMQzZrI/AAAAAAAAAEs/XgCMaA21cNo/s1600/sha-mysql.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;h3&gt;SHA-256 / 512&lt;/h3&gt;Para el SHA 256 se utiliza el método &lt;a href="http://commons.apache.org/codec/apidocs/org/apache/commons/codec/digest/DigestUtils.html#sha256%28java.lang.String%29"&gt;&lt;code&gt;DigestUtils.sha256&lt;/code&gt;&lt;/a&gt;, y para 512, se utiliza &lt;a href="http://commons.apache.org/codec/apidocs/org/apache/commons/codec/digest/DigestUtils.html#sha512%28java.lang.String%29"&gt;&lt;code&gt;DigestUtils.sha512&lt;/code&gt;&lt;/a&gt;. Los resultados son como siguen:&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;sha-256:9a4557a0f654365312b430b80f0da46be2c3a9db6a083f545145398fc66c92d8
sha-512:4c0a2187e03531011c7787752b66e8848a5f146e8aa08e5b5615030c5daa9cd756150e225943b5182de2434d925a4d6889b2d129ed87f23943bce9a8342b02bd&lt;/code&gt;&lt;/pre&gt;Como podemos ver.. a mayor bits, mayor confiabilidad.&lt;br /&gt;
&lt;br /&gt;
Su contraparte, en MySQL, se utiliza la función &lt;a href="http://dev.mysql.com/doc/refman/5.5/en/encryption-functions.html#function_sha2"&gt;sha2()&lt;/a&gt;. Ojo, esta función recién está disponible en la versión 5.5.5.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-U3PXKoBm0Wo/Teqw1_brjaI/AAAAAAAAAEw/bNFwUAfUkyo/s1600/sha2-mysql.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/-U3PXKoBm0Wo/Teqw1_brjaI/AAAAAAAAAEw/bNFwUAfUkyo/s1600/sha2-mysql.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8553642737291298841-2324163446370249803?l=www.apuntesdejava.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/GCX9khK4OB_3UknKeKumMjwjkcI/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/GCX9khK4OB_3UknKeKumMjwjkcI/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/GCX9khK4OB_3UknKeKumMjwjkcI/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/GCX9khK4OB_3UknKeKumMjwjkcI/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/ApuntesDeJava?a=nos4FSwQvi0:48TystHBKVA:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ApuntesDeJava?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ApuntesDeJava?a=nos4FSwQvi0:48TystHBKVA:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ApuntesDeJava?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ApuntesDeJava?a=nos4FSwQvi0:48TystHBKVA:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ApuntesDeJava?i=nos4FSwQvi0:48TystHBKVA:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ApuntesDeJava/~4/nos4FSwQvi0" height="1" width="1"/&gt;</description><atom:updated xmlns:atom="http://www.w3.org/2005/Atom">2011-06-04T17:27:06.567-05:00</atom:updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/-Pj8dnLGbV5o/Teqg8ZrXk7I/AAAAAAAAAEg/atQbqsbl1Lc/s72-c/encryption.jpg" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.apuntesdejava.com/2011/06/contrasenas-encriptadas-con-java.html</feedburner:origLink></item><item><title>Upload en JSF 2.0</title><link>http://feedproxy.google.com/~r/ApuntesDeJava/~3/Ak-lsrPGIQ4/upload-en-jsf-20.html</link><category>java ee</category><category>jsf 2.0</category><category>java ee 6</category><category>web</category><category>servlets</category><category>jsf</category><author>noreply@blogger.com (Diego Silva)</author><pubDate>Tue, 08 Mar 2011 15:26:00 PST</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-8553642737291298841.post-3013470061540479325</guid><description>&lt;div class="separator" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em; text-align: center;"&gt;&lt;img border="0" src="https://lh4.googleusercontent.com/-anPmHmTF3vo/TW3Dc-hvxKI/AAAAAAAAAD4/uMsLIUtUdXw/s1600/upload.png" /&gt;&lt;/div&gt;Después de varias semanas desconectado por motivo de trabajo (parece que ahora sí trabajo más que antes) retomo (y espero que sea más seguido) los artículos de este blog que, según veo las estadísticas, a varios desarrolladores ayudan.&lt;br /&gt;
Y bueno, estuve haciendo una aplicación con JSF 2.0, y una de las característica que debería tener es que &amp;nbsp;permita anexar archivos. Los Servlet 3.0 - que son parte de Java EE 6 - permiten cargar archivos de manera nativa. Lo que mostraré en este post es justamente cómo utilizar el Upload de Servlet 3.0 desde una aplicación web con JSF 2.0. No usaré extensiones de JSF como el ICEFaces o el MyFaces, porque quiero hacerlo de la manera más genérica posible, de tal manera que no afecte a la implementación de JSF que estén usando.&lt;br /&gt;
&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;Supongamos que nuestra aplicación debe &amp;nbsp;registrar &amp;nbsp;una bitácora de trabajo, y en cada registro permita anexar archivos, para que después se pueda descargar.&lt;br /&gt;
&lt;br /&gt;
Nuestra aplicación web...&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://lh3.googleusercontent.com/-QVUUAkc53bI/TW3FwzXy3gI/AAAAAAAAAD8/n4xinGqipko/s1600/upload-001.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="204" src="https://lh3.googleusercontent.com/-QVUUAkc53bI/TW3FwzXy3gI/AAAAAAAAAD8/n4xinGqipko/s320/upload-001.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
... se llamará "BitacoraWeb"...&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://lh4.googleusercontent.com/-8KgUs0GbNuo/TW3F4VFpkRI/AAAAAAAAAEA/QVjBJlqNW64/s1600/upload-002.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="204" src="https://lh4.googleusercontent.com/-8KgUs0GbNuo/TW3F4VFpkRI/AAAAAAAAAEA/QVjBJlqNW64/s320/upload-002.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
... y se ejecutará en GlassFish V3...&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://lh5.googleusercontent.com/-2FHRvX1HbNk/TW3GANdLlzI/AAAAAAAAAEE/yvGx0DTkW4E/s1600/upload-003.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="204" src="https://lh5.googleusercontent.com/-2FHRvX1HbNk/TW3GANdLlzI/AAAAAAAAAEE/yvGx0DTkW4E/s320/upload-003.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
... con soporte para JSF 2.0&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://lh5.googleusercontent.com/-bcg1ebcaKww/TW3GHOk7XhI/AAAAAAAAAEI/YmmvME1YN5s/s1600/upload-004.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="204" src="https://lh5.googleusercontent.com/-bcg1ebcaKww/TW3GHOk7XhI/AAAAAAAAAEI/YmmvME1YN5s/s320/upload-004.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
Y listo...&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://lh4.googleusercontent.com/-pPynx6W7Qr4/TW3GJSqxyjI/AAAAAAAAAEM/LNwVqq_Z6eY/s1600/upload-005.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="189" src="https://lh4.googleusercontent.com/-pPynx6W7Qr4/TW3GJSqxyjI/AAAAAAAAAEM/LNwVqq_Z6eY/s320/upload-005.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
Comencemos ahora sí. (Para la siguiente haré un post bien explicado sobre cómo crear aplicaciones web en NetBeans para ahorrarme estos pasos)&lt;br /&gt;
&lt;br /&gt;
Para registrar la bitácora necesitamos de una base de datos. Lo mostraré aquí con MySQL, pero - naturalmente - ustedes pueden utilizar la que más se acomode.&lt;br /&gt;
&lt;br /&gt;
Asumiré - para este post - que existe la base de datos "bitacora" asignado al usuario "bitacora" con contraseña "bitacora"&lt;br /&gt;
&lt;br /&gt;
Ahora, necesitamos una entidad llamada "Entrada" que tendrá las siguientes propiedades:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;@Entity
public class Entrada implements Serializable {

    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    @Column
    private String descripcion;
    @ElementCollection
    private List&amp;lt;Adjunto&amp;gt; adjuntos;

    public void addAdjunto(Adjunto adjunto) {
        getAdjuntos().add(adjunto);
    }

    public List&amp;lt;Adjunto&amp;gt; getAdjuntos() {
        if (adjuntos == null) {
            adjuntos = new ArrayList&amp;lt;Adjunto&amp;gt;();
        }
        return adjuntos;
    }
//... métodos get y set por cada propiedad
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
Y la Clase &lt;code&gt;Adjunto&lt;/code&gt; tendrá la siguiente estructura:&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;
@Embeddable
public class Adjunto implements Serializable {

    @Lob
    private byte[] contenido;
    @Column
    private String tipoContenido;
    @Column
    private String nombreArchivo;

    public Adjunto() {
    }

    public Adjunto(byte[] contenido, String tipoContenido, String nombreArchivo) {
        this.contenido = contenido;
        this.tipoContenido = tipoContenido;
        this.nombreArchivo = nombreArchivo;
    }
//.. métodos set y get de las propiedades.
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
Ahora, necesitamos el manejador de la entidad &lt;code&gt;Entrada&lt;/code&gt;. Con el NetBeans, esto se nos será muy fácil: basta con seleccionar desde la opción "File &amp;gt; New" la opción "Persistence &amp;gt; Session Beans For Entity Classes"&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://lh5.googleusercontent.com/-aVL-0uXq4ws/TXGAuTreI8I/AAAAAAAAAEQ/xU7So33hBtI/s1600/upload-006.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="220" src="https://lh5.googleusercontent.com/-aVL-0uXq4ws/TXGAuTreI8I/AAAAAAAAAEQ/xU7So33hBtI/s320/upload-006.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
Seleccionamos las Entidades que queremos administrar...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://lh6.googleusercontent.com/-jm0JnfIKVnA/TXGAyUunZ9I/AAAAAAAAAEU/Tpy0z4dm2eo/s1600/upload-007.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="187" src="https://lh6.googleusercontent.com/-jm0JnfIKVnA/TXGAyUunZ9I/AAAAAAAAAEU/Tpy0z4dm2eo/s320/upload-007.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
... seleccionamos donde queremos que se creen...&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://lh6.googleusercontent.com/-TnjGa5vH-Sg/TXGA17TNOHI/AAAAAAAAAEY/3ZYNl7DVsx0/s1600/upload-008.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="160" src="https://lh6.googleusercontent.com/-TnjGa5vH-Sg/TXGA17TNOHI/AAAAAAAAAEY/3ZYNl7DVsx0/s320/upload-008.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
... y listo.&lt;br /&gt;
&lt;br /&gt;
Ahora, crearemos un ManagedBean de alcance "Session" llamado BitacoraBean. Este es el que mostrará los datos en el formulario.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://lh3.googleusercontent.com/-hPLd3bzcQmY/TXaekVSvFzI/AAAAAAAAAEc/-rH917UyR30/s1600/upload-009.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="243" src="https://lh3.googleusercontent.com/-hPLd3bzcQmY/TXaekVSvFzI/AAAAAAAAAEc/-rH917UyR30/s320/upload-009.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
No voy a detallar cada parte del código, porque es algo complejo. Además, el código colgado ya tiene sus propios comentarios. Pero sí voy a explicar partes principales de las clases principales.&lt;br /&gt;
&lt;br /&gt;
En la parte inferior del JSF hay un formulario que es donde se registrará la bitácora. Pero también hay una parte para agregar los archivos. Para esto utilicé otra página para cargar los adjuntos.&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;//...
        &amp;lt;h:form id="form"&amp;gt;
            &amp;lt;h:panelGrid columns="2"&amp;gt;
                &amp;lt;h:outputLabel value="Descripción" for="descripcion" /&amp;gt;
                &amp;lt;h:inputTextarea id="descripcion" value="#{bitacoraBean.entradaActual.descripcion}" /&amp;gt;

                &amp;lt;h:outputText value="Adjuntos"/&amp;gt;

                &amp;lt;h:panelGroup&amp;gt;
                    &amp;lt;h:commandButton value="Recargar..." id="recargar"&amp;gt;
                        &amp;lt;f:ajax render="adjuntos" /&amp;gt;
                    &amp;lt;/h:commandButton&amp;gt;
                    &amp;lt;h:button value="Agregar" onclick="return abrirAdjuntos()"/&amp;gt;

&amp;lt;!-- aqui va el codigo donde se muestra los adjuntos --&amp;gt;
                &amp;lt;/h:panelGroup&amp;gt;
            &amp;lt;/h:panelGrid&amp;gt;
            &amp;lt;h:commandButton action="#{bitacoraBean.guardarEntrada}" value="Guardar"/&amp;gt;
        &amp;lt;/h:form&amp;gt;
//...
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
Por ello existe el botón "Cargar archivo". Lo que hace este botón es abrir un JSP que tiene un formulario para cargar cualquier archivo.&lt;br /&gt;
&lt;br /&gt;
El boton "recargar" no hace nada. Solo que cuando se llama, se recarga la página, y por tanto, muestra los contenidos de la tabla de adjuntos. (Por ahora lo oculté, porque sino se confundiría con lo que quiero explicar)&lt;br /&gt;
&lt;br /&gt;
El formulario de carga es bastante simple: (archivo form.jsp)&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;//...
        &amp;lt;h1&amp;gt;Cargar archivo&amp;lt;/h1&amp;gt;
        &amp;lt;form action="&amp;lt;c:url value='/servlet/upload'  /&amp;gt;" method="POST" enctype="multipart/form-data"&amp;gt;
            Archivo:
            &amp;lt;input type="file" name="archivo" value="" /&amp;gt;
            &amp;lt;button type="submit"&amp;gt;Cargar&amp;lt;/button&amp;gt;
        &amp;lt;/form&amp;gt;
//...&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
El servlet que es apuntado por este formulario es lo principal. Veamos por qué:&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;
@WebServlet(name = "UploadServlet", urlPatterns = {"/servlet/upload"})
public class UploadServlet extends HttpServlet {

    /** 
     * Processes requests for both HTTP &amp;lt;code&amp;gt;GET&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;POST&amp;lt;/code&amp;gt; methods.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        Part filePart = request.getPart("archivo"); //obtengo el archivo adjunto
        String nombreArchivo = extraerNombre(filePart.getHeader("content-disposition")); //extraigo el nombre

        InputStream is = filePart.getInputStream(); //obtengo el Stream
        long size = filePart.getSize(); //... el tamaño
        byte[] buffer = new byte[(int) size]; //.. creo el buffer
        is.read(buffer); //.. leo el buffer en un solo bloque
        is.close(); //... cierro el buffer
        String mimeType = filePart.getContentType(); //... obtengo el tipo de archivo
        Adjunto adjunto = new Adjunto(buffer, mimeType, nombreArchivo); //... creo el objeto ajdjunto
        BitacoraBean bitacoraBean = (BitacoraBean) request.getSession().getAttribute("bitacoraBean"); //obtengo el bean
        Entrada entradaActual = bitacoraBean.getEntradaActual(); //.. obtengo la entrada actual que está con el formulario
        entradaActual.addAdjunto(adjunto); //... adjunto el objeto del archivo
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        try {
            out.println("&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;"); //imprimo en el HTML para ejecutar un javascript
            out.println("&amp;lt;script type=\"text/javascript\"&amp;gt;");
            out.println("window.opener.document.getElementById(\"form:recargar\").click()"); //busco el boton para recargar
            out.println("window.close()"); //cierro ventana
            out.println("&amp;lt;/script&amp;gt;");
            out.println("&amp;lt;/head&amp;gt;&amp;lt;/html&amp;gt;");
        } finally {
            out.close();
        }
    }

    /**
     * Método para extrar el nombre físico del archivo
     * @param header Parametro del nombre, con toda la ruta completa en el cliente
     * @return Devuelve solo el nombre del archivo
     */
    static private String extraerNombre(String header) {
        String[] parts = header.split(";");
        for (String part : parts) {
            if (part.trim().startsWith("filename=")) { //busco todos los que comienzan con filename
                String[] $parts = part.split("="); //separo el nombre
                StringBuilder $sb = new StringBuilder($parts[1]);
                String fn = $sb.substring(1, $sb.length() - 1); //el segundo es el nombre
                File f = new File(fn); //creo una entrada de archivo
                return f.getName(); //devuelvo el nombre del archivo
            }
        }
        return "";
    }

&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
Ahora bien, el boton "Recargar" es utilizado justo por el JavaScript que devuelve el Servlet. La parte que contiene para mostrar los adjuntos (o sea, lo que oculté hace un rato) es como sigue:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;
 &amp;lt;h:dataTable id="adjuntos" value="#{bitacoraBean.entradaActual.adjuntos}"  var="adjunto" binding="#{bitacoraBean.adjuntosDataTable}"&amp;gt;
   &amp;lt;h:column&amp;gt;
     &amp;lt;h:outputText value="#{adjunto.nombreArchivo}" /&amp;gt;
   &amp;lt;/h:column&amp;gt;
   &amp;lt;h:column&amp;gt;
     &amp;lt;h:commandButton value="X" action="#{bitacoraBean.quitarAdjunto}" /&amp;gt;
   &amp;lt;/h:column&amp;gt;
 &amp;lt;/h:dataTable&amp;gt;

&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
Como se ve, aquí se muestra los adjuntos tienen  tener un botón (con una "X") para quitarlo de la bitácora que se va a registrar. Este botón llama al método &lt;code&gt;quitarAdjunto&lt;/code&gt;. Pero para que funcione, se ha creado un binding llamado &lt;code&gt;adjuntosDataTable&lt;/code&gt;. El método de quitarAdjunto es como sigue:&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;
//...
    public HtmlDataTable getAdjuntosDataTable() {
        return adjuntosDataTable;
    }

    public void setAdjuntosDataTable(HtmlDataTable adjuntosDataTable) {
        this.adjuntosDataTable = adjuntosDataTable;
    }

    public String quitarAdjunto(){
        Adjunto adjunto = (Adjunto) adjuntosDataTable.getRowData();
        entradaActual.quitarAdjunto(adjunto);
        return null;
    }

//...

&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
Por ello, cuando se hace clic en el botón "X", busca el objeto asociado (getRowData()), lo quita de los adjuntos de la entrada, y devuelve null para que recargue la página.&lt;br /&gt;
&lt;br /&gt;
Listo....!!&lt;br /&gt;
&lt;br /&gt;
Ah, falta mostrar los registros de la bitácora, y que muestre los archivos. Aquí el código:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;
        &amp;lt;h2&amp;gt;Entradas de Bitácora&amp;lt;/h2&amp;gt;
        &amp;lt;h:dataTable border="1" value="#{bitacoraBean.entradas}" var="entrada"&amp;gt;
            &amp;lt;h:column&amp;gt;
                &amp;lt;f:facet name="header"&amp;gt;ID&amp;lt;/f:facet&amp;gt;
                #{entrada.id}
            &amp;lt;/h:column&amp;gt;
            &amp;lt;h:column&amp;gt;
                &amp;lt;f:facet name="header"&amp;gt;Descripción&amp;lt;/f:facet&amp;gt;
                #{entrada.descripcion}
            &amp;lt;/h:column&amp;gt;
            &amp;lt;h:column&amp;gt;
                &amp;lt;f:facet name="header"&amp;gt;Adjuntos&amp;lt;/f:facet&amp;gt;
                &amp;lt;h:dataTable value="#{entrada.adjuntos}" var="adjunto"&amp;gt;
                    &amp;lt;h:column&amp;gt;
                        &amp;lt;h:outputLink value="#{facesContext.externalContext.requestContextPath}/servlet/upload/abrir"  &amp;gt;
                            &amp;lt;h:outputText value="#{adjunto.nombreArchivo}" /&amp;gt;
                            &amp;lt;f:param name="id" value="#{entrada.id}" /&amp;gt;
                            &amp;lt;f:param name="archivo" value="#{adjunto.nombreArchivo}" /&amp;gt;
                        &amp;lt;/h:outputLink&amp;gt;
                    &amp;lt;/h:column&amp;gt;
                &amp;lt;/h:dataTable&amp;gt;

            &amp;lt;/h:column&amp;gt;
        &amp;lt;/h:dataTable&amp;gt;

&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
Cada archivo adjunto que se está mostrando está apuntado por un enlace, que es un servlet. Y este servlet es el siguiente:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;
//...
@WebServlet(name = "MostrarArchivoServlet", urlPatterns = {"/servlet/upload/abrir"})
public class MostrarArchivoServlet extends HttpServlet {

    @EJB
    private EntradaFacade entradaFacade;

    /**
     * Processes requests for both HTTP &amp;lt;code&amp;gt;GET&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;POST&amp;lt;/code&amp;gt; methods.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        String $idEntrada = request.getParameter("id"); //obtengo el ID del parametro
        String archivo = request.getParameter("archivo"); //obtengo el nombre del archivo del parametro
        Long idEntrada = Long.parseLong($idEntrada); //convierto el ID a Long...
        Entrada entrada = entradaFacade.find(idEntrada);//.. para buscarlo en la base de datos 
        if (entrada == null) { //si no existe...
            response.setStatus(HttpServletResponse.SC_NOT_FOUND); //... devuelvo un mensaje de q no existe
            return; //... y termina
        }
        List&amp;lt;Adjunto&amp;gt; adjuntos = entrada.getAdjuntos(); //ahora, obtenemos todos los adjuntos de la entrada
        Adjunto adjuntoMostrar = null; //el adjunto actual
        for (Adjunto $adjunto : adjuntos) { //recorro todos los adjuntos
            if ($adjunto.getNombreArchivo().equals(archivo)); //comparamos el nombre, y si existe...
               adjuntoMostrar = $adjunto; //.. lo capturamos
        }
        if (adjuntoMostrar == null) { //si recorrio toda la lista y no encontro nada...
            response.setStatus(HttpServletResponse.SC_NOT_FOUND); //... devolvemos un mensaje que q no existe
            return; //.. y termina
        }

        OutputStream out = response.getOutputStream();
        try {
            response.setContentType("application/octet-stream"); //...preparamos el tipo para q se descargue la adjunto
            response.setHeader("Content-Disposition", "attachment;filename=" + adjuntoMostrar.getNombreArchivo().replaceAll(" ", "_")); //preparando el 'download' al navegador

            response.setContentLength(adjuntoMostrar.getContenido().length); //ponemos el tamaño...
            out.write(adjuntoMostrar.getContenido()); //... y vaciamos el contenido

        } finally {
            out.close(); //y cerramos el flujo
        }
    }

//...

&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;h3&gt;Código fuente&lt;/h3&gt;&lt;br /&gt;
El código fuente de proyecto se puede descargar desde aquí:&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://java.net/projects/apuntes/downloads/download/web/BitacoraWeb.tar.gz"&gt;http://java.net/projects/apuntes/downloads/download/web/BitacoraWeb.tar.gz&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8553642737291298841-3013470061540479325?l=www.apuntesdejava.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/kbgvpW1z85Gc2uamKJqx5pvDj1U/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/kbgvpW1z85Gc2uamKJqx5pvDj1U/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/kbgvpW1z85Gc2uamKJqx5pvDj1U/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/kbgvpW1z85Gc2uamKJqx5pvDj1U/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/ApuntesDeJava?a=Ak-lsrPGIQ4:QUK62wPVS_U:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ApuntesDeJava?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ApuntesDeJava?a=Ak-lsrPGIQ4:QUK62wPVS_U:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ApuntesDeJava?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ApuntesDeJava?a=Ak-lsrPGIQ4:QUK62wPVS_U:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ApuntesDeJava?i=Ak-lsrPGIQ4:QUK62wPVS_U:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ApuntesDeJava/~4/Ak-lsrPGIQ4" height="1" width="1"/&gt;</description><atom:updated xmlns:atom="http://www.w3.org/2005/Atom">2011-03-08T18:26:24.387-05:00</atom:updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://lh4.googleusercontent.com/-anPmHmTF3vo/TW3Dc-hvxKI/AAAAAAAAAD4/uMsLIUtUdXw/s72-c/upload.png" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">5</thr:total><feedburner:origLink>http://www.apuntesdejava.com/2011/03/upload-en-jsf-20.html</feedburner:origLink></item><item><title>Driver de Oracle dentro de NetBeans 7.0</title><link>http://feedproxy.google.com/~r/ApuntesDeJava/~3/1txx_koIOU8/driver-de-oracle-dentro-de-netbeans-70.html</link><category>netbeans 7.0</category><category>netbeans</category><category>base de datos</category><category>oracle</category><author>noreply@blogger.com (Diego Silva)</author><pubDate>Fri, 18 Feb 2011 12:58:00 PST</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-8553642737291298841.post-7939719032580260028</guid><description>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-eCbXJP0EAcU/TV6fK_aeInI/AAAAAAAAADc/e2MRfh4qDac/s1600/ora-nb-001.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" height="126" src="http://4.bp.blogspot.com/-eCbXJP0EAcU/TV6fK_aeInI/AAAAAAAAADc/e2MRfh4qDac/s200/ora-nb-001.png" width="200" /&gt;&lt;/a&gt;&lt;/div&gt;Acabo de bajar el &lt;a href="http://netbeans.org/community/releases/70/"&gt;NetBeans 7.0 Beta 2&lt;/a&gt; con la &lt;a href="http://bits.netbeans.org/netbeans/7.0/community/daily/latest/"&gt;traducción en español&lt;/a&gt;&amp;nbsp;y comencé a probar la conectividad con Oracle. Había leído que el manejo de conexiones desde el IDE estaba mejorado (sobre todo con Oracle, ¿por que será?) y como estaba viendo un proyecto con Oracle (muchos oracle en un solo párrafo) decidí probarlo.&lt;br /&gt;
&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;Para empezar, como toda conexión desde el IDE, vamos al panel de "Prestaciones". La manera más rápida es presionando las teclas Ctrl+5. Y en ese momento aparecerá el panel con los nodos de servicios (o prestaciones) para el IDE. Entre ellos está el nodo "Bases de datos".&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-9u0M02tVhWQ/TV7b0LwFmdI/AAAAAAAAADg/WFm37ORInes/s1600/ora-nb-002.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="296" src="http://1.bp.blogspot.com/-9u0M02tVhWQ/TV7b0LwFmdI/AAAAAAAAADg/WFm37ORInes/s320/ora-nb-002.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
Y como podemos ver, ya están preconfigurados los controladores para Oracle OCI y Thin. Así que trataremos de crear una conexión utilizando ese controlador. Le damos clic derecho y seleccionamos "Usar este controlador".&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-EvFSFfjg8_k/TV7cOqpkJrI/AAAAAAAAADk/8hKougMHMJc/s1600/ora-nb-003.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="307" src="http://2.bp.blogspot.com/-EvFSFfjg8_k/TV7cOqpkJrI/AAAAAAAAADk/8hKougMHMJc/s320/ora-nb-003.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;Pero el IDE nos dirá que no hay controladores disponibles (si es la primera vez que usamos este IDE aparecerá este mensaje).&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-PWn9cx0681U/TV7cajiJkjI/AAAAAAAAADo/OkAZCmLk1ic/s1600/ora-nb-004.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="238" src="http://2.bp.blogspot.com/-PWn9cx0681U/TV7cajiJkjI/AAAAAAAAADo/OkAZCmLk1ic/s320/ora-nb-004.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
Nos sugiere de donde bajarlo, pero como ya lo había bajado anteriormente, simplemente le doy clic en "Agregar" y uso el .jar del Oracle JDBC.&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-WVSsbT9dFd4/TV7cnrcDvgI/AAAAAAAAADs/M_eWUbRoXfs/s1600/ora-nb-005.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="238" src="http://1.bp.blogspot.com/-WVSsbT9dFd4/TV7cnrcDvgI/AAAAAAAAADs/M_eWUbRoXfs/s320/ora-nb-005.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
Después, clic en "Siguiente" para ver las propiedades de la conexión. Yo opté por un servidor oracle que tengo disponible, por ello el SID puse ORCL, pero si usan el Oracle Express, el SID será XE.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-AnClq2xU1B4/TV7cppJlmQI/AAAAAAAAADw/I4IfwrQw4Bo/s1600/ora-nb-006.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="251" src="http://2.bp.blogspot.com/-AnClq2xU1B4/TV7cppJlmQI/AAAAAAAAADw/I4IfwrQw4Bo/s320/ora-nb-006.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
Hacemos clic en "Test Connection" (Ajá!, falta traducir este botón) y si está todo bien, nos mostrará el mensaje "Connection succeded" (otro más)&lt;br /&gt;
&lt;br /&gt;
Clic en "Siguiente", y el IDE nos confirmará el esquema que va a utilizar.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-Qui67e3Ig6Y/TV7cqCCj16I/AAAAAAAAAD0/0-g3q10WeK8/s1600/ora-nb-007.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="251" src="http://2.bp.blogspot.com/-Qui67e3Ig6Y/TV7cqCCj16I/AAAAAAAAAD0/0-g3q10WeK8/s320/ora-nb-007.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
Luego clic en "Terminar" y listo: Nuestro IDE ya está conectado a la base de datos. Espero que también pueda ver StoredProcedures, como el JDeveloper &lt;code&gt;:)&lt;/code&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8553642737291298841-7939719032580260028?l=www.apuntesdejava.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/mtlU-bec981wgUieyOB_DI1bZuU/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/mtlU-bec981wgUieyOB_DI1bZuU/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/mtlU-bec981wgUieyOB_DI1bZuU/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/mtlU-bec981wgUieyOB_DI1bZuU/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/ApuntesDeJava?a=1txx_koIOU8:nzkf40oQ2y0:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ApuntesDeJava?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ApuntesDeJava?a=1txx_koIOU8:nzkf40oQ2y0:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ApuntesDeJava?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ApuntesDeJava?a=1txx_koIOU8:nzkf40oQ2y0:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ApuntesDeJava?i=1txx_koIOU8:nzkf40oQ2y0:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ApuntesDeJava/~4/1txx_koIOU8" height="1" width="1"/&gt;</description><atom:updated xmlns:atom="http://www.w3.org/2005/Atom">2011-02-18T15:58:21.035-05:00</atom:updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/-eCbXJP0EAcU/TV6fK_aeInI/AAAAAAAAADc/e2MRfh4qDac/s72-c/ora-nb-001.png" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.apuntesdejava.com/2011/02/driver-de-oracle-dentro-de-netbeans-70.html</feedburner:origLink></item><item><title>JComboBox de Objetos</title><link>http://feedproxy.google.com/~r/ApuntesDeJava/~3/1ZvRzQgbUGY/jcombobox-de-objetos.html</link><category>java</category><category>swing</category><category>tips</category><author>noreply@blogger.com (Diego Silva)</author><pubDate>Thu, 03 Feb 2011 10:48:00 PST</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-8553642737291298841.post-7575220888762751279</guid><description>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_kyNzamSrUI0/TUrkeDSqZ8I/AAAAAAAAADY/kh-5wiuUjlY/s1600/java+swing+gui.gif" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_kyNzamSrUI0/TUrkeDSqZ8I/AAAAAAAAADY/kh-5wiuUjlY/s1600/java+swing+gui.gif" /&gt;&lt;/a&gt;&lt;/div&gt;Cuando se usa Swing, el problema más común es mostrar elementos en un JComboBox. Lo que "normalmente" hacen es agregar cadenas a los elementos del JCB (JComboBox), pero para obtener el elemento seleccionado, se obtendría solo el valor puestos. Algunos hasta colocan el ID del elemento a mostrar, y luego buscan el elemento seleccionado en la colección. Toda una jarana... pero ¿han notado que para obtener el elemento seleccionado se utiliza el método &lt;code&gt;getSelectedItem()&lt;/code&gt; que devuelve un objeto? Si debería mostrar String, entonces, debería devolver un String, ¿cierto? En este post explicaremos como utilizar correctamente el JCB.&lt;br /&gt;
&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;Bien, supongamos que tenemos la clase &lt;code&gt;Persona&lt;/code&gt; como el que sigue:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;//...
public class Persona {

    private int idPersona;
    private String nombre;
    private int edad;

    public Persona() {
    }

    public Persona(int idPersona, String nombre, int edad) {
        this.idPersona = idPersona;
        this.nombre = nombre;
        this.edad = edad;
    }
//.. sus get y sets
//...&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
Y lo tenemos en una colección, o un arreglo, con elementos.. así:&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;//...
        Persona[] personas=new Persona[]{
            new Persona(10, "Albert", 20),
            new Persona(15, "Bernard", 21),
            new Persona(20, "Carl", 22),
        };
//...&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
Ahora, para crear un JCB con estos elementos, la manera rápida es así: pasando el arreglo como constructor:&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;//...
personasCB = new JComboBox(personas);
//...&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
Pueden usar cualquier forma, como addItem(), pero lo que quiero dejar en claro, es que no se agregan String, sino los mismos objetos.&lt;br /&gt;
&lt;br /&gt;
Ahora, para obtener el objeto seleccionado, bastará con hacer esto:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;//...
Persona p = (Persona) personasCB.getSelectedItem();
//...&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
Y listo!!!&lt;br /&gt;
&lt;br /&gt;
&lt;div style="color: blue;"&gt;&lt;b&gt;Un momento, pero los elementos del combo me parecen cosas raras!! quiero que me devuelvan mi dinero!&lt;/b&gt;&lt;/div&gt;&lt;br /&gt;
Aún no terminé de explicar. El JCB convierte cada elemento del arreglo a String, si ponemos un arreglo de Long, lo vuelve a arreglo de String, un Double lo vuelve String.. y un objeto Persona también lo vuelve a String.&lt;br /&gt;
&lt;br /&gt;
¿Sabes dónde se tiene que indicar como debe ser convertido a String un Objeto?&lt;br /&gt;
&lt;br /&gt;
Respuesta: redefine el método &lt;code&gt;toString()&lt;/code&gt; que es heredado de la clase Object... es decir, sobreescribimos el método toString() de la clase &lt;code&gt;Persona&lt;/code&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;//...
public class Persona {

    private int idPersona;
    private String nombre;
    private int edad;
//...
    @Override
    public String toString() {
        return nombre;
    }
    
    
}
//...&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
Si quieres que aparezca con ID, cambia lo que devuelve el método toString.. si quiers un formato especial.. igual.. todo es en el método &lt;code&gt;toString()&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
El código fuente de este ejemplo se puede obtener de aquí: &lt;br /&gt;
&lt;a href="http://java.net/projects/apuntes/downloads/download/Swing%252FJComboBoxObjetos.tar.gz"&gt;http://java.net/projects/apuntes/downloads/download/Swing%252FJComboBoxObjetos.tar.gz&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8553642737291298841-7575220888762751279?l=www.apuntesdejava.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/0tpq4R_yD-JB45AcJlkRJEbm0HU/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/0tpq4R_yD-JB45AcJlkRJEbm0HU/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/0tpq4R_yD-JB45AcJlkRJEbm0HU/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/0tpq4R_yD-JB45AcJlkRJEbm0HU/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/ApuntesDeJava?a=1ZvRzQgbUGY:GN2mtdsxeck:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ApuntesDeJava?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ApuntesDeJava?a=1ZvRzQgbUGY:GN2mtdsxeck:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ApuntesDeJava?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ApuntesDeJava?a=1ZvRzQgbUGY:GN2mtdsxeck:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ApuntesDeJava?i=1ZvRzQgbUGY:GN2mtdsxeck:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ApuntesDeJava/~4/1ZvRzQgbUGY" height="1" width="1"/&gt;</description><atom:updated xmlns:atom="http://www.w3.org/2005/Atom">2011-02-03T13:48:19.932-05:00</atom:updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/_kyNzamSrUI0/TUrkeDSqZ8I/AAAAAAAAADY/kh-5wiuUjlY/s72-c/java+swing+gui.gif" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">3</thr:total><feedburner:origLink>http://www.apuntesdejava.com/2011/02/jcombobox-de-objetos.html</feedburner:origLink></item><item><title>RESTful parte 4: Actualizando y eliminando elementos de una colección.</title><link>http://feedproxy.google.com/~r/ApuntesDeJava/~3/FfcmFSTrTlA/restful-4-actualizando-y-eliminando.html</link><category>restful</category><category>netbeans 6.9</category><category>java ee</category><category>tutorial</category><category>netbeans</category><category>java ee 6</category><author>noreply@blogger.com (Diego Silva)</author><pubDate>Sat, 15 Jan 2011 18:47:00 PST</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-8553642737291298841.post-848109016910205372</guid><description>&lt;a href="http://3.bp.blogspot.com/_kyNzamSrUI0/TPmvEVoBOcI/AAAAAAAAACE/HS_DCm1ehyQ/s1600/rest-ful-webservice-baner.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_kyNzamSrUI0/TPmvEVoBOcI/AAAAAAAAACE/HS_DCm1ehyQ/s1600/rest-ful-webservice-baner.png" /&gt;&lt;/a&gt;&lt;br /&gt;
Todo mantenimiento de objetos debe tener siempre lo que en inglés se llama CRUD (Create - Read - Update - Delete). Hasta ahora hemos visto C y R. Faltan el U y el D. Así que en este artículo hablaremos de ello&lt;br /&gt;
&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;En cualquier manera de almacenamiento de datos (sea un arreglo o una base de datos) siempre se debe poder identificar a un solo objeto a través de una clave principal. ¿Cómo se puede borrar o actualizar un solo objeto si no sabemos cuál es?.&lt;br /&gt;
&lt;br /&gt;
En nuestros &lt;a href="http://www.apuntesdejava.com/search/label/restful"&gt;anteriores artículos&lt;/a&gt; hemos creado objetos y le hemos puesto un ID automático. Aunque no es la manera más optima de hacerlo (ya que le hemos puesto como ID el tamaño del arreglo), vamos a actualizar un poco esta asignación. Para ello editaremos la clase &lt;code&gt;Persona&lt;/code&gt; de tal manera que tenga un contador de objetos. Para ello hagamos lo siguiente.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: java"&gt;
//...
public class Persona {    
    private static int contador = 0;    
    public static int getNuevoId() {
        return ++contador;
    }
//...&lt;/pre&gt;
&lt;br /&gt;
Luego, en la clase &lt;code&gt;PersonasResource&lt;/code&gt;, en el método &lt;code&gt;guardar&lt;/code&gt; le cambiaremos la línea donde se asigna el ID con lo siguiente:&lt;br /&gt;
&lt;pre class="brush: java"&gt;
//...
     public Response guardar(Persona p) {
            p.setIdPersona(Persona.getNuevoId());     //nueva manera de asignar ID
            personas.add(p);
            return Response.ok(p).build();
     }
//...&lt;/pre&gt;
&lt;br /&gt;
Ahora, necesitamos también una manera óptima de identificar un objeto &lt;code&gt;Persona&lt;/code&gt; a través de su ID. Creame que usando el &lt;code&gt;for()&lt;/code&gt; no es la manera óptima. Debemos usar los mecanismos propios de Java. Para ello, debemos reescribir el método &lt;code&gt;equals()&lt;/code&gt; en la clase &lt;code&gt;Persona&lt;/code&gt;. Y, como siempre, el NetBeans nos va a ayudar. Abramos esa clase y hagamos clic derecho y seleccionamos &lt;code&gt;Insert code...&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://2.bp.blogspot.com/_kyNzamSrUI0/TTHZ4_2xz6I/AAAAAAAAACk/ffS12LK8uYU/s1600/rest4-001.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_kyNzamSrUI0/TTHZ4_2xz6I/AAAAAAAAACk/ffS12LK8uYU/s1600/rest4-001.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
y luego seleccionamos "equals() &amp;amp; hashCode()...". Ahora, seleccionamos el campo "idPersona" en ambos paneles. Esto es que se utilizará el campo "idPersona" para hacer la comparación (equals) y para agrupar la comparación (hashCode)&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://2.bp.blogspot.com/_kyNzamSrUI0/TTHaUc8Fv5I/AAAAAAAAACo/21NKHHZYAco/s1600/rest4-002.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="212" src="http://2.bp.blogspot.com/_kyNzamSrUI0/TTHaUc8Fv5I/AAAAAAAAACo/21NKHHZYAco/s400/rest4-002.jpg" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
Clic en "Generate".&lt;br /&gt;
&lt;br /&gt;
Y vemos que el NetBeans creó los métodos mencionados.&lt;br /&gt;
Una rápida explicación de esos métodos: el equals() sirve para poder comparar dos objetos. Es la única manera de comparar objetos que utilizará el Java. Así nos evitaremos hacer una comparación de un campo por nuestra cuenta cada vez que necesitemos. Y método hashCode() permite devolver un valor que permitirá reducir la comparación. Por ejemplo, si tenemos mil objetos, y todos tienen id diferentes, y necesitamos buscar un ID específico, el Java agrupará todos los que tengan el hashCode similar, y después hará la búsqueda uno por uno dentro de ese grupo reducido.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;

Obtener un objeto de la colección a través de su ID&lt;/h3&gt;
Lo que haremos es acceder a un objeto de la colección pero le damos el ID como parte del URL. Por ejemplo, hasta el momento hemos accedido a un URL como este:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;http://localhost:8080/PersonaRESTWeb/resources/listaPersonas&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
... y nuestro reto ahora es obtener el objeto con ID=2 usando este URL&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;http://localhost:8080/PersonaRESTWeb/resources/listaPersonas/2/&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
Antes de continuar, recordemos en el artículo donde se habló cómo &lt;a href="http://www.apuntesdejava.com/2010/11/restful-la-forma-mas-ligera-de-hacer_25.html"&gt;manejar un solo objeto&lt;/a&gt; en RESTful, que el recurso mismo es el que tiene un URL para devolver el objeto.Entonces, modificaremos el recurso &lt;code&gt;PersonasResource&lt;/code&gt; (el que tiene el arreglo) para que devuelva el &lt;code&gt;PersonaResource&lt;/code&gt; (el que tiene un solo objeto) y devuelva el objeto seleccionado. Entonces, debemos modificar este último recurso para que la variable &lt;code&gt;Persona&lt;/code&gt; que tiene no sea &lt;code&gt;static&lt;/code&gt;, pero que el valor de esa variable sea recibida por un método.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: java"&gt;
//...
 public class PersonaResource {
       private Persona persona;
   //...
       public void setPersona(Persona persona) {
             this.persona = persona;
       } 
}&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
Ahora sí, regresemos al recurso &lt;code&gt;PersonasResource&lt;/code&gt; (el que tiene la colección de objetos) y agreguemos una referencia al recurso &lt;code&gt;PersonaResource&lt;/code&gt;. Como es un EJB, entonces lo declaramos como tal:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: java"&gt;
//... 
@Stateless
@Path("/listaPersonas") 
public class PersonasResource {
    @EJB
    PersonaResource personaResource;
   //...&lt;/pre&gt;
&lt;br /&gt;
Luego, agregamos un método que recibirá como parámetro el ID del objeto a buscar, busca el ID en el arreglo, y si existe, le asignará al recurso &lt;code&gt;personaResource&lt;/code&gt; y lo devolverá al cliente.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: java"&gt;
//...     
public PersonaResource getPersona(Integer id) {
           if (id == null) { //si no se pasó el ID...
                 return null; //... termina el método
           }
           Persona $temp = new Persona(); //creamos un temporal...
           $temp.setIdPersona(id); //.. que tendrá el ID...
           if (personas.contains($temp)) { // ... para buscarlo en la colección. Para eso sirve el método equals(). Si existe en la colección...
                 int idx = personas.indexOf($temp);  //... obtenemos su índice...
                 Persona actual = personas.get(idx); //... lo obtenemos de la colección...
                 personaResource.setPersona(actual); //.. y lo marcamos como "actual"...
                 return personaResource; //... para que lo devuelva al cliente.
           }
             return null; //.. si no lo encuentra, devuelve null
    } 
//...&lt;/pre&gt;
Listo, y funciona... pero no tan rápido ¿Cómo sabemos que el ID será parte del URL?. Bien, agregaremos la anotación &lt;code&gt;@Path("{idPersona}/")&lt;/code&gt; de la siguiente manera&lt;br /&gt;
&lt;pre class="brush: java"&gt;
//...
     @Path("{idPersona}/")
     public PersonaResource getPersona(Integer id) {
 //...&lt;/pre&gt;
... y para asociar ese parámetro al parámetro del método, lo hacemos con la anotación &lt;code&gt;@PathParam()&lt;/code&gt; de la siguiente manera:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: java"&gt;
//...
     @Path("{idPersona}/")
     public PersonaResource getPersona( @PathParam("idPersona") Integer id) {
 //...&lt;/pre&gt;
&lt;br /&gt;
Al final, el método completo es como sigue:&lt;br /&gt;
&lt;pre  class="brush: java"&gt;
//...
     @Path("{idPersona}/")
     public PersonaResource getPersona(@PathParam("idPersona") Integer id) {
             if (id == null) { //si no se pasó el ID...
                     return null; //... termina el método
             }
             Persona $temp = new Persona(); //creamos un temporal...
             $temp.setIdPersona(id); //.. que tendrá el ID...
             if (personas.contains($temp)) { // ... para buscarlo en la colección. Para eso sirve el método equals(). Si existe en la colección...
                   int idx = personas.indexOf($temp);  //... obtenemos su índice...
                   Persona actual = personas.get(idx); //... lo obtenemos de la colección...
                   personaResource.setPersona(actual); //.. y lo marcamos como "actual"...
                   return personaResource; //... para que lo devuelva al cliente.
             }
             return null; //.. si no lo encuentra, devuelve null
     } //...&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
Listo, ahore probemos colocando unos valores como:&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;{"nombre_persona":"Albert"} {"nombre_persona":"Bernard"} {"nombre_persona":"Carl"}&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
... desde el Test de NetBeans.&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://2.bp.blogspot.com/_kyNzamSrUI0/TTJOIV0x60I/AAAAAAAAACs/3Y8Ed8mBQ6g/s1600/rest4-003.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="385" src="http://2.bp.blogspot.com/_kyNzamSrUI0/TTJOIV0x60I/AAAAAAAAACs/3Y8Ed8mBQ6g/s400/rest4-003.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;
Ahora, del árbol izquierdo, abramos el nodo "listaPersonas" y seleccionemos el nodo "{idPersona}"&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://3.bp.blogspot.com/_kyNzamSrUI0/TTJPx95O-gI/AAAAAAAAACw/lecBw4FfeaM/s1600/rest4-004.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="214" src="http://3.bp.blogspot.com/_kyNzamSrUI0/TTJPx95O-gI/AAAAAAAAACw/lecBw4FfeaM/s640/rest4-004.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
Y en el campo "idPersona", escribiremos el ID de uno de los creados, por ejemplo "2", y hacemos clic en "Test"&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://3.bp.blogspot.com/_kyNzamSrUI0/TTJQKH4sLXI/AAAAAAAAAC0/bUHxs7e79LE/s1600/rest4-005.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="182" src="http://3.bp.blogspot.com/_kyNzamSrUI0/TTJQKH4sLXI/AAAAAAAAAC0/bUHxs7e79LE/s400/rest4-005.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;
También podemos probar desde el URL de la siguiente manera. Primero toda la lista.&lt;br /&gt;
&lt;br /&gt;
http://localhost:8080/PersonaRESTWeb/resources/listaPersonas&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://3.bp.blogspot.com/_kyNzamSrUI0/TTJQzDbBnCI/AAAAAAAAAC8/uInTm9ahmt0/s1600/rest4-006.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="488" src="http://3.bp.blogspot.com/_kyNzamSrUI0/TTJQzDbBnCI/AAAAAAAAAC8/uInTm9ahmt0/s640/rest4-006.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
Y luego, el del ID=2&lt;br /&gt;
&lt;br /&gt;
http://localhost:8080/PersonaRESTWeb/resources/listaPersonas/2/&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://2.bp.blogspot.com/_kyNzamSrUI0/TTJQyDZGZXI/AAAAAAAAAC4/SK7O0fv_USw/s1600/rest4-007.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_kyNzamSrUI0/TTJQyDZGZXI/AAAAAAAAAC4/SK7O0fv_USw/s1600/rest4-007.png" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;h3&gt;

Reemplazar objeto y borrar objeto de la colección&lt;/h3&gt;
El recurso &lt;code&gt;PersonasResource&lt;/code&gt; es el que tiene la colección de objetos. Así que aquí le deberemos agregar los métodos que modifiquen y eliminen los objetos de la colección. Pero - OJO - estos no serán accedidos desde el URL. Solo fueron puestos aquí porque tiene la colección. Si se manejara una base de datos, se tendría otro EJB que maneje esos objetos. Bien, nuestro recurso tendrá los siguientes métodos:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: java"&gt;//...     
public void borrarPersona(Persona p) {
           personas.remove(p); //... busca en la lista y borra el elemento
     }
     public void cambiarPersona(Persona actual, Persona p) {
           int idx = personas.indexOf(actual); //... obtiene la posición del actual
           if (idx &amp;gt;= 0) { //... si existe...
                 p.setIdPersona(actual.getIdPersona()); //... ponerle el ID en el nuevo objeto...
                 personas.set(idx, p); //..y reemplazar el objeto en la misma posición del anterior
           }
     }//...&lt;/pre&gt;
Cada línea está comentada para que quede bien explicado.&lt;br /&gt;
&lt;br /&gt;
Recordemos otra vez que nuestro recurso &lt;code&gt;PersonaResource&lt;/code&gt; tendrá el objeto seleccionado por el ID. Y como el que tiene la colección de objetos es el recurso &lt;code&gt;PersonasResource&lt;/code&gt; y es un EJB, entonces agregaremos la referencia de la siguiente manera:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: java"&gt;
//... 
public class PersonaResource {    
//el que tiene el objeto actual       
@EJB    PersonasResource personasResource;   
//el que tiene la colección de objetos
//...&lt;/pre&gt;
&lt;br /&gt;
Entonces los métodos &lt;code&gt;@PUT&lt;/code&gt; y &lt;code&gt;@DELETE&lt;/code&gt; será sobre el objeto seleccionado. Así que en este recurso agregaremos los siguientes métodos:&lt;br /&gt;
&lt;br /&gt;
&lt;pre  class="brush: java"&gt;
//...    
@DELETE
public void borrar() {          
 personasResource.borrarPersona(persona);  //porque tiene la colección de objetos
}    
@PUT    
@Consumes({"application/xml", "application/json"})    
public void actualizar(Persona p) {
 personasResource.cambiarPersona(persona,p); //porque tiene la colección de objetos
}
//...&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
Y listo. Probemos el test de NetBeans,´agregamos los mismo objetos, y probemos la actualización: Seleccionamos el idPersona:2 y le ponemos el nuevo objeto a reemplazar, utilizando el método "PUT"&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://4.bp.blogspot.com/_kyNzamSrUI0/TTJWxfy04yI/AAAAAAAAADE/b4cR_5XImfQ/s1600/rest4-008.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_kyNzamSrUI0/TTJWxfy04yI/AAAAAAAAADE/b4cR_5XImfQ/s1600/rest4-008.png" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
Y cuando consultamos el ID=2, este será el nuevo objeto:&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://4.bp.blogspot.com/_kyNzamSrUI0/TTJWw9YDT7I/AAAAAAAAADA/PDPhTuPgRX0/s1600/rest4-009.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_kyNzamSrUI0/TTJWw9YDT7I/AAAAAAAAADA/PDPhTuPgRX0/s1600/rest4-009.png" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
Y luego para el método "DELETE", y le indicamos el de ID=1&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://3.bp.blogspot.com/_kyNzamSrUI0/TTJX2jNvANI/AAAAAAAAADI/wzbIR2xBxGs/s1600/rest4-010.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_kyNzamSrUI0/TTJX2jNvANI/AAAAAAAAADI/wzbIR2xBxGs/s1600/rest4-010.png" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
.. y luego obtenemos el listado de objetos.&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://1.bp.blogspot.com/_kyNzamSrUI0/TTJX4Bce6KI/AAAAAAAAADM/mH3KI5_W8C8/s1600/rest4-011.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="356" src="http://1.bp.blogspot.com/_kyNzamSrUI0/TTJX4Bce6KI/AAAAAAAAADM/mH3KI5_W8C8/s400/rest4-011.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;h3&gt;

Código fuente del proyecto&lt;/h3&gt;
Como siempre, aquí publico el código fuente del proyecto utilizado en este artículo para que lo prueben y vean que no miento &lt;code&gt;:)&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://kenai.com/projects/apuntes/downloads/download/CRUDPersonasRest%252FPersonaRESTWeb.tar.gz"&gt;http://kenai.com/projects/apuntes/downloads/download/CRUDPersonasRest%252FPersonaRESTWeb.tar.gz&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8553642737291298841-848109016910205372?l=www.apuntesdejava.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/CjWeLM4NUc4M80Yan_h7VVcFH28/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/CjWeLM4NUc4M80Yan_h7VVcFH28/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/CjWeLM4NUc4M80Yan_h7VVcFH28/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/CjWeLM4NUc4M80Yan_h7VVcFH28/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/ApuntesDeJava?a=FfcmFSTrTlA:wswSJQrs-k4:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ApuntesDeJava?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ApuntesDeJava?a=FfcmFSTrTlA:wswSJQrs-k4:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ApuntesDeJava?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ApuntesDeJava?a=FfcmFSTrTlA:wswSJQrs-k4:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ApuntesDeJava?i=FfcmFSTrTlA:wswSJQrs-k4:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ApuntesDeJava/~4/FfcmFSTrTlA" height="1" width="1"/&gt;</description><atom:updated xmlns:atom="http://www.w3.org/2005/Atom">2011-09-13T12:20:27.257-05:00</atom:updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/_kyNzamSrUI0/TPmvEVoBOcI/AAAAAAAAACE/HS_DCm1ehyQ/s72-c/rest-ful-webservice-baner.png" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total><feedburner:origLink>http://www.apuntesdejava.com/2011/01/restful-4-actualizando-y-eliminando.html</feedburner:origLink></item><item><title>RESTful parte 3: Manejando colecciones de objetos y objetos complejos</title><link>http://feedproxy.google.com/~r/ApuntesDeJava/~3/0OI3J7tJ4iQ/restful-parte-3-manejando-colecciones.html</link><category>restful</category><category>netbeans 6.9</category><category>java ee</category><category>tutorial</category><category>netbeans</category><category>java ee 6</category><author>noreply@blogger.com (Diego Silva)</author><pubDate>Tue, 04 Jan 2011 16:52:00 PST</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-8553642737291298841.post-7326791458112067153</guid><description>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_kyNzamSrUI0/TPmvEVoBOcI/AAAAAAAAACE/HS_DCm1ehyQ/s1600/rest-ful-webservice-baner.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_kyNzamSrUI0/TPmvEVoBOcI/AAAAAAAAACE/HS_DCm1ehyQ/s1600/rest-ful-webservice-baner.png" /&gt;&lt;/a&gt;&lt;/div&gt;Comenzamos este año nuevo con la continuación del (creo yo) más esperado tema de tutorial: &lt;a href="http://www.apuntesdejava.com/search/label/restful"&gt;RESTful&lt;/a&gt;. Y esta vez hablaremos sobre el manejo de colecciones y objetos complejos. Por ahora será de manera básica y veremos poco a poco cómo hacerlo más y más complejo.&lt;br /&gt;
&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;h2&gt;Manejo de colecciones&lt;/h2&gt;Para comenzar, tomaremos el mismo proyecto que vimos en el último &lt;a href="http://www.apuntesdejava.com/2010/11/restful-la-forma-mas-ligera-de-hacer_25.html"&gt;post&lt;/a&gt; y agregaremos otro recurso llamado &lt;code&gt;PersonaResource&lt;/code&gt; con el path apuntando por &lt;code&gt;/listaPersonas&lt;/code&gt;. &lt;br /&gt;
¿Cómo hacer esto? Bien fácil: &lt;br /&gt;
&lt;ol&gt;&lt;li&gt;Crear una clase llamada &lt;code&gt;PersonaResource&lt;/code&gt; dentro del paquete &lt;code&gt;com.apuntesdejava.rest&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Agregar las siguientes anotaciones al inicio de la declaración de la clase:&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;@Stateless
@Path("/listaPersonas")&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;/ol&gt;Es decir, al final tendremos el código para la clase de la siguiente manera:&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;package com.apuntesdejava.rest;

import javax.ejb.Stateless;
import javax.ws.rs.Path;

@Stateless
@Path("/listaPersonas")
public class PersonasResource {
}&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;h3&gt;Guardando objetos en la colección&lt;/h3&gt;Esto es realmente fácil. Es como cualquier método en Java que recibe un objeto y lo guarda en el arreglo:&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;//...
    static List&amp;lt;Persona&amp;gt; personas = new ArrayList&amp;lt;Persona&amp;gt;();

    @POST
    @Consumes({"application/xml", "application/json"})
    public Response guardar(Persona p) {
        p.setIdPersona(personas.size() + 1); //se le autoasigna un id al objeto
        personas.add(p);
        return Response.ok(p).build();
    }
//...
&lt;/code&gt;&lt;/pre&gt;Sabemos que el objeto vendrá en formato JSON o XML. Si tenemos dudas, probemos con el "Test RESTful Web services" de NetBeans.&lt;br /&gt;
&lt;br /&gt;
Probaremos enviando la siguiente cadena en el método POST.&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;{"nombre_persona":"Juan Perez",
"edad":"35",
"trabajador":"true",
"fechaNacimiento":"1976-01-01"}&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
Y veremos que en la respuesta nos devuelve con el ID de la persona autogenerada.&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;
   &amp;lt;persona id_persona="1"&amp;gt;
       &amp;lt;fechaNacimiento&amp;gt;1976-01-01T00:00:00-05:00&amp;lt;/fechaNacimiento&amp;gt;
       &amp;lt;nombre_persona&amp;gt;Juan Perez&amp;lt;/nombre_persona&amp;gt;
       &amp;lt;sexo&amp;gt;0&amp;lt;/sexo&amp;gt;
       &amp;lt;trabajador&amp;gt;true&amp;lt;/trabajador&amp;gt;
   &amp;lt;/persona&amp;gt; &lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
Como se puede en esta imagen, está el envío de la data, y la respuesta del servidor.&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_kyNzamSrUI0/TSIZxce1jwI/AAAAAAAAACU/PU-xxwr_WpU/s1600/rest-lista-001.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="400" src="http://2.bp.blogspot.com/_kyNzamSrUI0/TSIZxce1jwI/AAAAAAAAACU/PU-xxwr_WpU/s400/rest-lista-001.jpg" width="383" /&gt;&lt;/a&gt;&lt;/div&gt;Esto es bastante fácil, porque es lo mismo que se vió en el anterior post. Ahora veremos como se obtiene una lista.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;Obteniendo objetos en la colección&lt;/h3&gt;Lo bueno de utilizar RESTful en Java es que no requiere declarar métodos extraños ni clases adicionales (hasta ahora). Entonces, si queremos que nuestra clase tenga un método que devuelva una lista de objetos de una lista en base a un criterio (por ejemplo, los que tengan uno determinado texto), podría ser como el que sigue:&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;    public List&amp;lt;Persona&amp;gt; buscar(String nombre) {
        List&amp;lt;Persona&amp;gt; lista = new ArrayList&amp;lt;Persona&amp;gt;();
        for (Persona persona : personas) {
            if (persona.getNombre().indexOf(nombre) &amp;gt;= 0) {
                lista.add(persona);
            }

        }
        return lista;
    }
&lt;/code&gt;&lt;/pre&gt;¿Cierto? Bien, ahora lo convertiremos en servicio RESTful agregando la anotación &lt;code&gt;GET&lt;/code&gt;, además de qué tipos va a devolver.&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;    @GET
    @Produces({"application/xml", "application/json"})
    public List&amp;lt;Persona&amp;gt; buscar( String nombre) {
        List&amp;lt;Persona&amp;gt; lista = new ArrayList&amp;lt;Persona&amp;gt;();
        for (Persona persona : personas) {
            if (persona.getNombre().indexOf(nombre) &amp;gt;= 0) {
                lista.add(persona);
            }

        }
        return lista;
    }
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
Pero como va a recibir un parámetro, por método &lt;code&gt;@GET&lt;/code&gt; (es decir, como parte del URL.. o query string) entonces hay que darle un nombre usando &lt;code&gt;@QueryParam&lt;/code&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;    @GET
    @Produces({"application/xml", "application/json"})
    public List&amp;lt;Persona&amp;gt; buscar(@QueryParam("nombre") String nombre) {
        List&amp;lt;Persona&amp;gt; lista = new ArrayList&amp;lt;Persona&amp;gt;();
        for (Persona persona : personas) {
            if (persona.getNombre().indexOf(nombre) &amp;gt;= 0) {
                lista.add(persona);
            }

        }
        return lista;
    }
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
Ahora, probemos con el "Test REST" de NetBeans (previo registro de objetos, claro está).&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_kyNzamSrUI0/TSO00nitFyI/AAAAAAAAACY/uTAAT8BTnlg/s1600/rest3-002.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_kyNzamSrUI0/TSO00nitFyI/AAAAAAAAACY/uTAAT8BTnlg/s1600/rest3-002.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
Notemos que el nombre del parametro query no necesariamente tiene que ser el mismo nombre del parámetro del método de Java. Es decir, esto es totalmente válido:&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;    @GET
    @Produces({"application/xml", "application/json"})
    public List&amp;lt;Persona&amp;gt; buscar(@QueryParam("name") String nombre) {
//...
    }
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;h2&gt;Objetos complejos&lt;/h2&gt;Ahora bien, ya nos podemos imaginar que si permite exportar una simple colección de la manera más simple, también se puede exportar un objeto compuesto (es decir, un objeto que tenga propiedades que son otros objetos).&lt;br /&gt;
Pero antes de seguir, quiero recordar que esta parte del tutorial es aún básico. Por ahora no pretendamos poner un objeto que tenga una referencia cíclica, es decir, que tenga una propiedad que es otro objeto y que este tenga otra propiedad que apunte al primer objeto. Sí se puede hacer, pero por ahora no lo veremos porque para ello hay que hacer algunas modificaciones adicionales.&lt;br /&gt;
&lt;br /&gt;
Crearemos una clase llamada &lt;code&gt;Telefono&lt;/code&gt; que tendrá las propiedades &lt;code&gt;area&lt;/code&gt; y &lt;code&gt;numero&lt;/code&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;public class Telefono {

    private String numero;
    private String area;

    public String getArea() {
        return area;
    }

    public void setArea(String area) {
        this.area = area;
    }

    public String getNumero() {
        return numero;
    }

    public void setNumero(String numero) {
        this.numero = numero;
    }
}&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
Y, en nuestra clase &lt;code&gt;Persona&lt;/code&gt; agregaremos una colección de la clase recién creada:&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;
public class Persona {
//....
    private List&amp;lt;Telefono&amp;gt; telefonos;

    public List&amp;lt;Telefono&amp;gt; getTelefonos() {
        return telefonos;
    }

    public void setTelefonos(List&amp;lt;Telefono&amp;gt; telefonos) {
        this.telefonos = telefonos;
    }
//....&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
Ahora, probemos con la siguiente cadena JSON (no olvidar que se selecciona POST (application/json)) para registrar nuestro objeto:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;{
  "nombre_persona":"Carl",
  "telefonos"     :[
                    {"area":"51","numero":"12345"},
                    {"area":"54","numero":"98765"}
                   ]
}&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
Y al obtener la lista de los objetos, se obtiene sin ningún problema. Ya sea en XML...&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_kyNzamSrUI0/TSO5tUEjlLI/AAAAAAAAACg/K_XzhHVzqrI/s1600/rest3-003.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="325" src="http://3.bp.blogspot.com/_kyNzamSrUI0/TSO5tUEjlLI/AAAAAAAAACg/K_XzhHVzqrI/s400/rest3-003.jpg" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
... o en JSON...&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_kyNzamSrUI0/TSO5sRbqtuI/AAAAAAAAACc/PHYqNSwjWCI/s1600/rest3-004.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_kyNzamSrUI0/TSO5sRbqtuI/AAAAAAAAACc/PHYqNSwjWCI/s1600/rest3-004.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
Si quieres conocer más sobre los formatos de JSON, visita aquí: &lt;a href="http://www.json.org/json-es.html"&gt;http://www.json.org/json-es.html&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Ya haré un post dedicado únicamente a los clientes de RESTful, tanto como para probar como para hacer una aplicación desktop, javascript, javafx, mobile, etc.&lt;br /&gt;
&lt;br /&gt;
El siguiente post, cómo manejar los &lt;code&gt;java.util.Map&lt;/code&gt; y después, los métodos &lt;code&gt;@DELETE&lt;/code&gt; y &lt;code&gt;@PUT&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;El código fuente&lt;/h2&gt;Aquí está el infaltable código fuente del proyecto&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://kenai.com/projects/apuntes/downloads/download/PersonaRESTWeb%252FPersonasRESTWeb.tar.gz"&gt;http://kenai.com/projects/apuntes/downloads/download/PersonaRESTWeb%252FPersonasRESTWeb.tar.gz&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Bendiciones!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8553642737291298841-7326791458112067153?l=www.apuntesdejava.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/4m3LZ-aiYhh132DGOWFBwoi6IHg/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/4m3LZ-aiYhh132DGOWFBwoi6IHg/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/4m3LZ-aiYhh132DGOWFBwoi6IHg/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/4m3LZ-aiYhh132DGOWFBwoi6IHg/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/ApuntesDeJava?a=0OI3J7tJ4iQ:NLWqmZcPBao:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ApuntesDeJava?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ApuntesDeJava?a=0OI3J7tJ4iQ:NLWqmZcPBao:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ApuntesDeJava?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ApuntesDeJava?a=0OI3J7tJ4iQ:NLWqmZcPBao:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ApuntesDeJava?i=0OI3J7tJ4iQ:NLWqmZcPBao:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ApuntesDeJava/~4/0OI3J7tJ4iQ" height="1" width="1"/&gt;</description><atom:updated xmlns:atom="http://www.w3.org/2005/Atom">2011-01-04T19:52:06.850-05:00</atom:updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/_kyNzamSrUI0/TPmvEVoBOcI/AAAAAAAAACE/HS_DCm1ehyQ/s72-c/rest-ful-webservice-baner.png" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">6</thr:total><feedburner:origLink>http://www.apuntesdejava.com/2011/01/restful-parte-3-manejando-colecciones.html</feedburner:origLink></item><item><title>Delay</title><link>http://feedproxy.google.com/~r/ApuntesDeJava/~3/A-jKCqop-i8/delay.html</link><category>off topic</category><author>noreply@blogger.com (Diego Silva)</author><pubDate>Thu, 09 Dec 2010 08:05:00 PST</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-8553642737291298841.post-2458644757144780590</guid><description>Mantener un blog es complicado, mas no imposible.&lt;br /&gt;
&lt;br /&gt;
Me había propuesto en poner un post cada martes, así en un mes habrían al menos cuatro apuntes que podrían ayudar a la comunidad java - en especial a los hispanos. Si en estas últimas semanas no he podido publicar más artículos no fue porque no sé qué publicar, sino por falta de tiempo.&lt;br /&gt;
&lt;br /&gt;
Estamos terminando un año, y con él muchos proyectos se deben cerrar, y &amp;nbsp;para preparar (no es por presumir, pero vuestros comentarios me lo confirman) un&amp;nbsp;&lt;b&gt;buen&lt;/b&gt; artículo se necesita un tiempo exclusivo.&lt;br /&gt;
&lt;br /&gt;
Hay bastante material para publicar en mi blog, por ejemplo:&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;RESTful con objetos complejos, con entidades, con arreglos, con conversores de tipo y sus clientes en PHP, JavaScript, JavaFX, etc.&lt;/li&gt;
&lt;li&gt;Plantillas en Liferay.&lt;/li&gt;
&lt;li&gt;JPA 2.0 y todo lo que se puede hacer.&lt;/li&gt;
&lt;li&gt;JSF 2.0: más ejemplos de Ajax, y sus extensiones con ICefaces&lt;/li&gt;
&lt;li&gt;JasperServer&lt;/li&gt;
&lt;li&gt;NetBeans Platform&lt;/li&gt;
&lt;li&gt;Java EE 6 sobre WebLogic&lt;/li&gt;
&lt;li&gt;etc&lt;/li&gt;
&lt;/ul&gt;&lt;div&gt;Como se&amp;nbsp;ve, hay bastante material para publicar, sin mencionar los tutoriales de NetBeans.org que quiero traducir y los cursos virtuales que ya bastante tiempo los estoy postergando.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;Dios mediante, este blog no va a morir.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;Por lo pronto me pueden seguir en Twitter (&lt;a href="http://twitter.com/apuntesdejava"&gt;@apuntesdejava&lt;/a&gt;), FriendFeed (&lt;a href="http://friendfeed.com/apuntes-de-java"&gt;http://friendfeed.com/apuntes-de-java&lt;/a&gt;) y Facebook.&lt;br /&gt;
&lt;br /&gt;
Gracias por su preferencia.&lt;br /&gt;
&lt;br /&gt;
Bendiciones...!&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8553642737291298841-2458644757144780590?l=www.apuntesdejava.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/hll85hhV6P6RT5RoycPpco1nogk/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/hll85hhV6P6RT5RoycPpco1nogk/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/hll85hhV6P6RT5RoycPpco1nogk/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/hll85hhV6P6RT5RoycPpco1nogk/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/ApuntesDeJava?a=A-jKCqop-i8:rjZ19OMK4Js:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ApuntesDeJava?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ApuntesDeJava?a=A-jKCqop-i8:rjZ19OMK4Js:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ApuntesDeJava?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ApuntesDeJava?a=A-jKCqop-i8:rjZ19OMK4Js:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ApuntesDeJava?i=A-jKCqop-i8:rjZ19OMK4Js:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ApuntesDeJava/~4/A-jKCqop-i8" height="1" width="1"/&gt;</description><atom:updated xmlns:atom="http://www.w3.org/2005/Atom">2010-12-09T11:05:52.389-05:00</atom:updated><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total><feedburner:origLink>http://www.apuntesdejava.com/2010/12/delay.html</feedburner:origLink></item><item><title>RESTful - Parte 2: Manejando un solo objeto</title><link>http://feedproxy.google.com/~r/ApuntesDeJava/~3/ZjaYHktvOyI/restful-la-forma-mas-ligera-de-hacer_25.html</link><category>restful</category><category>netbeans 6.9</category><category>java ee</category><category>tutorial</category><category>netbeans</category><category>java ee 6</category><author>noreply@blogger.com (Diego Silva)</author><pubDate>Thu, 25 Nov 2010 02:15:00 PST</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-8553642737291298841.post-7348433803573134313</guid><description>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_BQk94ojgkDY/TNHiBoISkpI/AAAAAAAADKs/trfv2uskorU/s1600/rest-ful-webservice-baner.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_BQk94ojgkDY/TNHiBoISkpI/AAAAAAAADKs/trfv2uskorU/s1600/rest-ful-webservice-baner.png" /&gt;&lt;/a&gt;&lt;/div&gt;Hemos visto en el anterior &lt;a href="http://www.apuntesdejava.com/2010/11/restful-la-forma-mas-ligera-de-hacer.html"&gt;post &lt;/a&gt;cómo hacer un servicio REST solo para producir y consumir un texto simple. Ahora bien, en la vida real no son textos simples, sino estructuras de datos algo complicadas. Pero para ir lentos pero seguros, aprenderemos cómo hacer un servicio REST pero para manejar un solo objeto.&lt;br /&gt;
&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;Afortunadamente para nuestros proyectos, no debemos crear ningún XML, ni tener algún "parser" que convierta nuestros objetos en formato XML o algo parecido para enviar y recibir objetos por la red. Solo necesitamos crear nuestros JavaBeans... y ponerle algunos tags.&lt;br /&gt;
&lt;h2&gt;Manos a la obra...&lt;/h2&gt;Supongamos que tenemos creado el proyecto web PersonaRESTWeb sobre GlassFish v3 y sin ningún framework adicional. Recordemos que nuestro proyecto se autoconfigura en REST cuando se aplica una anotación especial.&lt;br /&gt;
&lt;h3&gt;Creando un javaBean&lt;/h3&gt;Una vez creado el proyecto, crearemos un JavaBean llamado &lt;code&gt;Persona&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;
public class Persona {

    private int idPersona;
    private String nombre;
    private java.util.Date fechaNacimiento;
    private boolean trabajador;
    private char sexo;
//...
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
... con sus respectivos set y get.&lt;br /&gt;
&lt;br /&gt;
Ahora, este JavaBean lo entendemos muy bien en Java, pero recordemos de que un servicio web debe ser compatible para otros lenguajes, y que la estructura de datos más "compatible" es el XML. Así que vamos hacer que este JavaBean se convierta en XML. Bastará con poner la anotación &lt;code&gt;@XmlRootElement&lt;/code&gt; al inicio de la declaración de la clase.&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;
@XmlRootElement
public class Persona {

    private int idPersona;
    private String nombre;
    private java.util.Date fechaNacimiento;
    private boolean trabajador;
    private char sexo;
//...
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;h3&gt;Creando recurso manejador de Persona&lt;/h3&gt;El diseño de este Servicio obliga a que exista un solo recurso manejador por cada Entidad. Por tanto, debemos crear la clase &lt;code&gt;PersonaResource&lt;/code&gt;. Y para que administre un JavaBean, declararemos un objeto static. &lt;br /&gt;
&lt;br /&gt;
Nota: Lo normal aquí es usar un manejador de persistencia (sea JPA, JDBC, etc..), pero como el objetivo de este tutorial es ver cómo funciona un REST, no gastaremos esfuerzo por conectarnos a una base de datos.&lt;br /&gt;
&lt;br /&gt;
Este es el código fuente del recurso &lt;code&gt;PersonaResource&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;
@Stateless
@Path("/personas")
public class PersonaResource {

    static Persona persona;
}

&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
Ahora, necesitamos implementar los métodos para registrar un objeto Persona desde el cliente, y leer el objeto desde el hacía hasta el cliente. Por tanto, crearemos dos métodos: registrar y leer. &lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;Leer valor del objeto&lt;/h3&gt;Esto ya lo hemos visto. Es declarar un método y declararlo con la anotación &lt;code&gt;@GET&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;
//...
    @GET
    public Persona leer(){
        return persona;
    } 
//...
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
Sí, nada más (por ahora)&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;Guardar valor al objeto&lt;/h3&gt;Esto debería ser sencillo. Bastaría con poner este código&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;
//...
    @POST
    public void guardar(Persona p) {
        persona = p;

    }
//...
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
Pero no es así. Porque toda petición que se hace a un recurso web (el que sea) siempre debe devolver algo.. así sea un error, pero debe devolver algo. En REST debe devolver un objeto &lt;code&gt;javax.ws.rs.core.Response&lt;/code&gt; que contiene el estado de la petición: si está OK, si hay error de restricción, si no responde, etc.. todos los errores que conocemos para HTTP están contenidos en ese objeto. Pero para nuestro caso, vamos a devolver el valor "ok" de la siguiente manera:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;
//...
    @POST
    public Response guardar(Persona p) {
        persona = p;
        return Response.ok(p).build();
    }
//...
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
Ahora sí... a desplegarlo y a probar... pero si lo probamos en este momento, nos mostrará la siguiente ventana.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_BQk94ojgkDY/TO3A3_TgWZI/AAAAAAAADME/z8c-HGHm5dE/s1600/rest2-01.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="273" src="http://4.bp.blogspot.com/_BQk94ojgkDY/TO3A3_TgWZI/AAAAAAAADME/z8c-HGHm5dE/s400/rest2-01.jpg" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
y.. qué pondremos en la caja de texto? Pues el objeto a enviar... pero ¿cómo? Pues un dato estándar, como XML o JSON. Por ejemplo, este código&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;
&amp;lt;persona&amp;gt;
       &amp;lt;idPersona&amp;gt;20&amp;lt;/idPersona&amp;gt;
       &amp;lt;nombre&amp;gt;Albert&amp;lt;/nombre&amp;gt;
       &amp;lt;trabajador&amp;gt;true&amp;lt;/trabajador&amp;gt;
&amp;lt;/persona&amp;gt; 
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
Lo probamos y... error!!! ¿qué pasó? &lt;br /&gt;
&lt;br /&gt;
Pues nuestro servicio REST no sabe si la data que va a recibir es un XML, o un JSON. Hay que decirle al método de ese recurso cómo va a recibir los datos. Por ahora, vamos a poner esta anotación en el método:&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;
//...
    @POST
    @Consumes("application/xml")
    public Response guardar(Persona p) {
        persona = p;
        return Response.ok(p).build();
    }
//...
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
Ahora sí, desplegamos, ejecutamos el Test y... vemos que ahora el método POST dice qué tipo permitirá:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_BQk94ojgkDY/TO3A4PGZ-CI/AAAAAAAADMI/MhVBZTE69sE/s1600/rest2-02.jpg" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="251" src="http://3.bp.blogspot.com/_BQk94ojgkDY/TO3A4PGZ-CI/AAAAAAAADMI/MhVBZTE69sE/s400/rest2-02.jpg" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
Escribimos nuevamente el texto y voila!! &lt;code&gt;Status: 200 (OK) &lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
"Bien, el XML funciona, pero el formato es un poco grande ¿se puede usar JSON?" Sí.. y lo mejor, es bien sencillo activar esa opción. &lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;
//...
    @POST
    @Consumes({"application/xml","application/json"})
    public Response guardar(Persona p) {
        persona = p;
        return Response.ok(p).build();
    }
//...
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
Listo, ahora nuestro método &lt;code&gt;guardar()&lt;/code&gt; permite recibir tanto JSON como XML. Probemos ahora colocando el siguiente valor en el módulo de prueba:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;
{  "idPersona":"20",
   "nombre":"Bernard",
   "trabajador":"true"
}
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
... seleccionamos el tipo JSON...&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_BQk94ojgkDY/TO3A4IRVzxI/AAAAAAAADMM/9n2DvM-t7tU/s1600/rest2-03.jpg" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="236" src="http://4.bp.blogspot.com/_BQk94ojgkDY/TO3A4IRVzxI/AAAAAAAADMM/9n2DvM-t7tU/s400/rest2-03.jpg" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
... y listo.. funciona!&lt;br /&gt;
&lt;br /&gt;
Si no están seguros de que guardó correctamente, ejecutemos el método GET para ver si lo guardó en el objeto&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_BQk94ojgkDY/TO3A4YR022I/AAAAAAAADMQ/sUsbtDFwAwU/s1600/rest2-04.jpg" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="323" src="http://3.bp.blogspot.com/_BQk94ojgkDY/TO3A4YR022I/AAAAAAAADMQ/sUsbtDFwAwU/s400/rest2-04.jpg" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;Modificando el tipo de formato para leer el objeto&lt;/h3&gt;Ya vimos que se puede establecer el tipo que el Servicio recibirá por la red usando &lt;code&gt;@Consumes&lt;/code&gt;. Y cuando probamos la lectura, lo convierte siempre a XML ¿se puede cambiar para que sea JSON? Por su puesto, y es igual de simple:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;
//...
    @GET
    @Produces({"application/json","application/xml"})
    public Persona leer() {
        return persona;
    }
//...

&lt;/code&gt;&lt;/pre&gt;Por omisión usará el primer tipo especificado (en este caso "json"), o  - dependiendo cómo se indique en el cliente - puede utilizar el formato XML.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_BQk94ojgkDY/TO3A4kpR0FI/AAAAAAAADMU/3X9yYTzci4E/s1600/rest2-05.jpg" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="373" src="http://2.bp.blogspot.com/_BQk94ojgkDY/TO3A4kpR0FI/AAAAAAAADMU/3X9yYTzci4E/s400/rest2-05.jpg" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;Modificando la estructura de los datos&lt;/h3&gt;Nuestro bean utiliza la propiedad &lt;code&gt;idPersona&lt;/code&gt;, y el REST lo procesa correctamente. Pero, si el estándar de los proyectos donde se va a utilizar, dice que debe ser &lt;code&gt;id_persona&lt;/code&gt; y el campo nombre sea &lt;code&gt;nombre_persona&lt;/code&gt; ¿Cómo modificamos esto?&lt;br /&gt;
&lt;br /&gt;
Esto también es fácil. Por cada método "get" que debemos cambiar el formato, le agregamos la anotación &lt;code&gt;@XmlElement&lt;/code&gt; seguido del nombre como deberá ser manejado. Vayamos al Bean Persona y pongamos esto:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;
//...

    @XmlElement(name = "id_persona")
    public int getIdPersona() {
        return idPersona;
    }

    @XmlElement(name = "nombre_persona")
    public String getNombre() {
        return nombre;
    }
//...

&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
Ahora, probemos el método "GET".&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_BQk94ojgkDY/TO3A8ou1TwI/AAAAAAAADMY/Bk662cnFHpU/s1600/rest2-06.jpg" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="400" src="http://4.bp.blogspot.com/_BQk94ojgkDY/TO3A8ou1TwI/AAAAAAAADMY/Bk662cnFHpU/s400/rest2-06.jpg" width="367" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
¿Y si, el &lt;code&gt;id_persona&lt;/code&gt; tiene que ser un atributo del XML? Cambiamos la notación &lt;code&gt;@XmlElement&lt;/code&gt; por &lt;code&gt;@XmlAttribute&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;
//...

    @XmlElement(name = "id_persona")
    public int getIdPersona() {
        return idPersona;
    }

//...

&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
Ojo, cuando es atributo y  se desea enviar en formato JSON, se debe considerar ql nombre del atributo antepuesto por un &lt;code&gt;@&lt;/code&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;
{  "@id_persona":"20",
   "nombre_persona":"Bernard",
   "trabajador":"true"
}

&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_BQk94ojgkDY/TO3A88uRwrI/AAAAAAAADMc/eYGGAUhfNiM/s1600/rest2-07.jpg" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="400" src="http://1.bp.blogspot.com/_BQk94ojgkDY/TO3A88uRwrI/AAAAAAAADMc/eYGGAUhfNiM/s400/rest2-07.jpg" width="380" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;h3&gt;"En ningún momento aparece el nombre del método &lt;code&gt;guardar()&lt;/code&gt; y &lt;code&gt;leer()&lt;/code&gt; ¿Cómo sabe qué método utilizar?"&lt;/h3&gt;Pues por el mismo método HTTP utilizado: Si se hace "POST", ejecuta el método que está asociado a &lt;code&gt;@POST&lt;/code&gt;, si se hace "GET", utiliza el &lt;code&gt;@GET&lt;/code&gt;.&lt;br /&gt;
&lt;br /&gt;
¿"Y si quiero diferenciar un 'update' de un 'create' ? " Pues utilizar otro método. Como comenté en el anterior post, el POST debe estar asociado al "create",el GET asociado a la búsqueda, el "PUT" al "update" y el "DELETE" al borrar. &lt;br /&gt;
&lt;br /&gt;
Si hay que hacer otro tipo de "POST" o de "DELETE", debemos utilizar otro objeto Recurso (con anotación &lt;code&gt;@Path&lt;/code&gt;) ya que será accedido desde otra ruta.&lt;br /&gt;
&lt;br /&gt;
Por ello comenté en el anterior post de que este diseño asegura de que los métodos de mantenimiento están asociados a una sola entidad..  y nos evitará tener métodos en servicios web que no corresponde, por ejemplo, no habrá un manejo de proveedores en un servicio de clientes.&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;Código del proyecto&lt;/h2&gt;Aquí se encuentra el código fuente del proyecto web:&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://kenai.com/projects/apuntes/downloads/download/PersonaRESTWeb%252FPersonaRESTWeb.tar.gz"&gt;http://kenai.com/projects/apuntes/downloads/download/PersonaRESTWeb%252FPersonaRESTWeb.tar.gz&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Aquí el código fuente de una aplicación Java Desktop:&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://kenai.com/projects/apuntes/downloads/download/PersonaRESTWeb%252FPersonaRESTClient.tar.gz"&gt;http://kenai.com/projects/apuntes/downloads/download/PersonaRESTWeb%252FPersonaRESTClient.tar.gz&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8553642737291298841-7348433803573134313?l=www.apuntesdejava.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/inUcyp0WVhr1xnqICLFlHvVOSgE/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/inUcyp0WVhr1xnqICLFlHvVOSgE/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/inUcyp0WVhr1xnqICLFlHvVOSgE/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/inUcyp0WVhr1xnqICLFlHvVOSgE/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/ApuntesDeJava?a=ZjaYHktvOyI:uhxvV0dytzc:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ApuntesDeJava?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ApuntesDeJava?a=ZjaYHktvOyI:uhxvV0dytzc:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ApuntesDeJava?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ApuntesDeJava?a=ZjaYHktvOyI:uhxvV0dytzc:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ApuntesDeJava?i=ZjaYHktvOyI:uhxvV0dytzc:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ApuntesDeJava/~4/ZjaYHktvOyI" height="1" width="1"/&gt;</description><atom:updated xmlns:atom="http://www.w3.org/2005/Atom">2010-11-25T14:53:39.403-05:00</atom:updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/_BQk94ojgkDY/TNHiBoISkpI/AAAAAAAADKs/trfv2uskorU/s72-c/rest-ful-webservice-baner.png" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">6</thr:total><feedburner:origLink>http://www.apuntesdejava.com/2010/11/restful-la-forma-mas-ligera-de-hacer_25.html</feedburner:origLink></item><item><title>Lo que se viene con JDK 7 &amp; NetBeans 7</title><link>http://feedproxy.google.com/~r/ApuntesDeJava/~3/myufsEgGH9Y/lo-que-se-viene-con-jdk-7-netbeans-7.html</link><category>java</category><category>java 7</category><category>netbeans 7.0</category><category>netbeans</category><category>jdk 7</category><category>jdk</category><author>noreply@blogger.com (Diego Silva)</author><pubDate>Mon, 15 Nov 2010 21:00:00 PST</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-8553642737291298841.post-5074444767576935232</guid><description>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_BQk94ojgkDY/TK4VWFA_WVI/AAAAAAAADHI/2ZMfQgswmjw/s1600/netbeans-logo.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" height="100" src="http://1.bp.blogspot.com/_BQk94ojgkDY/TK4VWFA_WVI/AAAAAAAADHI/2ZMfQgswmjw/s200/netbeans-logo.png" width="100" /&gt;&lt;/a&gt;&lt;/div&gt;Se dice que el número 7 es el número de la perfección, y para el mundo Java este número no está lejos de serlo.&lt;br /&gt;
Está cerca el JDK 7, con muchas mejoras en la sintaxis, y casi a la par también sale el NetBeans 7 con su respectiva compatibilidad.&lt;br /&gt;
&lt;br /&gt;
En este post mostraré algunas características de estos software.&lt;br /&gt;
&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;(Mientras termino la continuación del RESTful para objetos, voy mostrando esto)&lt;br /&gt;
&lt;h2&gt;Descargando e instalando JDK 7&lt;/h2&gt;Primero, debemos descargar el JDK, y este lo podemos obtener de aquí&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://dlc.sun.com.edgesuite.net/jdk7/binaries/"&gt;http://dlc.sun.com.edgesuite.net/jdk7/binaries/&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
... bajo el título &lt;b&gt;Windows Offline Installation, Multi-language JDK file&lt;/b&gt;&lt;br /&gt;
&lt;a href="http://www.java.net/download/jdk7/binaries/jdk-7-ea-bin-b118-windows-i586-11_nov_2010.exe"&gt;jdk-7-ea-bin-b118-windows-i586-11_nov_2010.exe&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div style="color: #274e13;"&gt;&lt;b&gt;Nota: Esta es la versión disponible a la fecha de este post. Si no existe, buscar dentro de &lt;a href="http://download.java.net/jdk7/"&gt;http://download.java.net/jdk7/&lt;/a&gt;.&lt;/b&gt;&lt;/div&gt;&lt;br /&gt;
La instalación del JDK no es cosa del otro mundo, ya que el instalador siempre nos dice qué opción debemos elegir... y hasta creo que es mucho más rápida.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_BQk94ojgkDY/TOFoHoZs5lI/AAAAAAAADLE/oZOI_CkEaWo/s1600/jdk7-01.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="245" src="http://2.bp.blogspot.com/_BQk94ojgkDY/TOFoHoZs5lI/AAAAAAAADLE/oZOI_CkEaWo/s320/jdk7-01.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_BQk94ojgkDY/TOFoH4NmFLI/AAAAAAAADLI/Iiq04-spzuE/s1600/jdk7-02.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="245" src="http://1.bp.blogspot.com/_BQk94ojgkDY/TOFoH4NmFLI/AAAAAAAADLI/Iiq04-spzuE/s320/jdk7-02.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Luego comprobamos que la instalación fue correcta, escribiendo en la línea de comandos &lt;code&gt;java -version&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_BQk94ojgkDY/TOFoIkYd70I/AAAAAAAADLM/skMG7UI-H2E/s1600/jdk7-03.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_BQk94ojgkDY/TOFoIkYd70I/AAAAAAAADLM/skMG7UI-H2E/s1600/jdk7-03.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
Ojo, yo aún tengo instalado el JDK 6, y si deseo utilizarlo, cambio la ruta de la variable JAVA_HOME.&lt;br /&gt;
&lt;br /&gt;
Aquí quiero hacer una notación importante. La variable de entorno JAVA_HOME debe apuntar a la carpeta o directorio que tiene el subdirectorio "bin" del Java. Por ejemplo, en este momento tengo mi variable establecida así:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_BQk94ojgkDY/TOFoI5yug_I/AAAAAAAADLQ/q9vNpskO73A/s1600/jdk7-04.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_BQk94ojgkDY/TOFoI5yug_I/AAAAAAAADLQ/q9vNpskO73A/s1600/jdk7-04.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
a pesar que ya tengo instalado la versión JDK 7.. incluso el compilador puedo utilizar la versión 6,&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_BQk94ojgkDY/TOFoIyS9s9I/AAAAAAAADLU/r7VVWa-Hgak/s1600/jdk7-05.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_BQk94ojgkDY/TOFoIyS9s9I/AAAAAAAADLU/r7VVWa-Hgak/s1600/jdk7-05.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
para utilizar la nueva versión, debo cambiar la variable de entorno al directorio de la versión 7.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_BQk94ojgkDY/TOFoNxWU28I/AAAAAAAADLY/ghlEhsgR-MI/s1600/jdk7-06.jpg" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="286" src="http://2.bp.blogspot.com/_BQk94ojgkDY/TOFoNxWU28I/AAAAAAAADLY/ghlEhsgR-MI/s640/jdk7-06.jpg" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Para cambiar el valor de la variable de entorno en Windows, entrar a las propiedades de la PC (una manera más rápida es presionando las teclas Win+Pausa) y buscando la opción "Variables de Entorno". Para XP, Vista, 7 cada ventana son diferentes, así que no diré cómo son las ventanas.&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;Descargando e instalando NetBeans 7.0&lt;/h2&gt;A la fecha de este post, el NetBeans 7.0 está en la etapa M2, así que descargaremos esta versión desde aquí:&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://bits.netbeans.org/netbeans/7.0/m2/"&gt;http://bits.netbeans.org/netbeans/7.0/m2/&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Personalmente, cada vez que quiero probar una versión del NetBeans, elijo la opción ".zip", ya que solo descargado y descomprimo el contenido y listo! ya tengo el NetBeans instalado (Eclipse, no te creas en ser el único)&lt;br /&gt;
&lt;br /&gt;
Pero para asegurarnos de que el NetBeans utilizará el JDK7, debemos modificar el archivo de configuración del IDE. Este se encuentro en el subdirectior "etc" de NetBeans. El nombre del archivo es "netbeans.conf", y agregamos esta línea&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;netbeans_jdkhome="C:\Archivos de programa\Java\jdk1.7.0"&lt;/code&gt;&lt;/pre&gt;.. y luego le damos doble clic al &lt;code&gt;netbeans.exe&lt;/code&gt; para ejecutar el IDE.&lt;br /&gt;
&lt;br /&gt;
Luego de leer la licencia, memorizarla y aceptarla, ya podemos disfrutar del IDE NetBeans 7 + JDK 7&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_BQk94ojgkDY/TOFoONGXA0I/AAAAAAAADLc/qvZUj9x6Tfg/s1600/jdk7-07.jpg" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://3.bp.blogspot.com/_BQk94ojgkDY/TOFoONGXA0I/AAAAAAAADLc/qvZUj9x6Tfg/s320/jdk7-07.jpg" width="306" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
Ahora, crearemos un nuevo proyecto de Aplicación Java, y veremos que por omisión la clase prinicipal que contiene el método &lt;code&gt;public static void &lt;b&gt;main()&lt;/b&gt;&lt;/code&gt; ya no es &lt;code&gt;Main&lt;/code&gt; ya que ocasionaba muchas confusiones para los principiantes, sino es el mismo nombre del proyecto. Ojo, puede ser cualquier nombre, pero aquí el NetBeans sugiere ese nombre.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_BQk94ojgkDY/TOFoOKBfHLI/AAAAAAAADLg/ygl7jzaRpQQ/s1600/jdk7-08.jpg" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="441" src="http://1.bp.blogspot.com/_BQk94ojgkDY/TOFoOKBfHLI/AAAAAAAADLg/ygl7jzaRpQQ/s640/jdk7-08.jpg" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
Luego, entramos a las propiedades del proyecto, y cambiamos la versión del código fuente a utilizar en nuestro proyecto.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_BQk94ojgkDY/TOFoOeUKikI/AAAAAAAADLk/_fA5mINPuPo/s1600/jdk7-09.jpg" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="460" src="http://1.bp.blogspot.com/_BQk94ojgkDY/TOFoOeUKikI/AAAAAAAADLk/_fA5mINPuPo/s640/jdk7-09.jpg" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;Características nuevas de JDK 7 en NetBeans 7.0&lt;/h2&gt;Aquí vienen las características más esperadas &lt;strike&gt;que todo el mundo se quejaba de que Java no tena&lt;/strike&gt; y que vienen a nuestra salvación.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;&lt;code&gt;switch&lt;/code&gt; con cadenas&lt;/h3&gt;Esta es - creo yo - la que muchos esperábamos: usar cadenas en &lt;code&gt;switch&lt;/code&gt;. Por definición, los &lt;code&gt;switch&lt;/code&gt; solo permiten una variable de tipo escalar (nativo), como el char, int, byte, etc... es decir, los String no "juegan". Entonces, solo con los Strings usábamos "if" encadenados, como aquí:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_BQk94ojgkDY/TOFoOnK1P8I/AAAAAAAADLo/h-emoEQbeSw/s1600/jdk7-10.jpg" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_BQk94ojgkDY/TOFoOnK1P8I/AAAAAAAADLo/h-emoEQbeSw/s1600/jdk7-10.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
Pero aquí NetBeans nos muestra una sugerencia: cuando pasamos el ratón por el foquito del margen izquierdo nos dice &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_BQk94ojgkDY/TOFoSveNNvI/AAAAAAAADLs/fMEXP0t5Gug/s1600/jdk7-11.jpg" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_BQk94ojgkDY/TOFoSveNNvI/AAAAAAAADLs/fMEXP0t5Gug/s1600/jdk7-11.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
.. y al seleccionar la opción.. adivinen qué sucede...&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_BQk94ojgkDY/TOFoSsecy2I/AAAAAAAADLw/kNWYkHF7SPo/s1600/jdk7-12.jpg" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_BQk94ojgkDY/TOFoSsecy2I/AAAAAAAADLw/kNWYkHF7SPo/s1600/jdk7-12.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;Operador "diamante": anulando Genericos redundantes&lt;/h3&gt;En la versión Java 1.5 aparecieron los &lt;a href="http://download.oracle.com/javase/1.5.0/docs/guide/language/generics.html"&gt;Genéricos&lt;/a&gt;, una notación importante para asegurar los tipos de las colecciones. Es decir, antes en un List podía tener String, objetos persona, Integer, arreglos.. etc... y para obtener un elemento debía hacerse "casting". Pero en la versión 5, con los genéricos, se podía declarar un tipo para una colección y asegurar que el objeto devuelto siempre era del mismo tipo declarado y evitaba hacer "cast". &lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;List&amp;lt;Persona&amp;gt; personas=new ArrayList&amp;lt;Persona&amp;gt;();&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
Pero había un problema: el tipo de la colección que se estaba instanciando debería ser del mismo tipo de la declaración. Es decir, no se podía hacer esto:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;List&amp;lt;Persona&amp;gt; personas=new ArrayList&amp;lt;Empleado&amp;gt;();&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
por más que &lt;code&gt;Empleado&lt;/code&gt; sea subclase de &lt;code&gt;Persona&lt;/code&gt;. Se puede utilizar caracteres comodines, pero eso es otra historia. El asunto es que para una declaración simple como la mencionada antes, debería usarse siempre el mismo tipo en la instanciación. Entonces, si ya fue declarado con un tipo, ¿Ya no debería mencionarlo en la instanciación? Pues, aquí NetBeans nos sale a la ayuda.&lt;br /&gt;
&lt;br /&gt;
Antes:&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_BQk94ojgkDY/TOFoSzjVkjI/AAAAAAAADL0/oNKbkBlLaec/s1600/jdk7-13.jpg" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_BQk94ojgkDY/TOFoSzjVkjI/AAAAAAAADL0/oNKbkBlLaec/s1600/jdk7-13.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
Después:&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_BQk94ojgkDY/TOFoWXsVqvI/AAAAAAAADL4/1fhD1NsBaKw/s1600/jdk7-14.jpg" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_BQk94ojgkDY/TOFoWXsVqvI/AAAAAAAADL4/1fhD1NsBaKw/s1600/jdk7-14.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;Multicatch&lt;/h3&gt;¿Tienes una código que contiene muchos catch, y según la recomendación de Jav se debería usar un catch específico por cada excepción para manejarla de manera específica.... y en tu código en todos los catch se hace lo mismo.. y quieres evitar de usar la clase &lt;code&gt;Exception&lt;/code&gt;? No te preocupes. Aquí aparecen los multicatch. Supongamos este código:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;
        File f=new File("d://temp.xml");
        try {
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = factory.newDocumentBuilder();
            Document d = builder.parse(f);
        } catch (SAXException ex) {
            ex.printStackTrace();
        } catch (IOException ex) {
            ex.printStackTrace();
        } catch (ParserConfigurationException ex) {
            ex.printStackTrace();
        }

&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
El IDE nos sugerirá algo en el primer "catch".&lt;br /&gt;
&lt;br /&gt;
Antes:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_BQk94ojgkDY/TOFoWsxcvHI/AAAAAAAADL8/PcryydOMabQ/s1600/jdk7-15.jpg" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_BQk94ojgkDY/TOFoWsxcvHI/AAAAAAAADL8/PcryydOMabQ/s1600/jdk7-15.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
Después:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_BQk94ojgkDY/TOFoXCrQF5I/AAAAAAAADMA/kCweMWjIWWs/s1600/jdk7-16.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_BQk94ojgkDY/TOFoXCrQF5I/AAAAAAAADMA/kCweMWjIWWs/s1600/jdk7-16.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
Estos fueron algunos.. más información de NB 7.0 lo podeís ver aquí:&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://wiki.netbeans.org/NewAndNoteworthyNB70"&gt;http://wiki.netbeans.org/NewAndNoteworthyNB70&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Hasta el siguiente apunte!!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8553642737291298841-5074444767576935232?l=www.apuntesdejava.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/Ijn9BzaN2NMd-3rReQLDQYb35HA/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Ijn9BzaN2NMd-3rReQLDQYb35HA/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/Ijn9BzaN2NMd-3rReQLDQYb35HA/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Ijn9BzaN2NMd-3rReQLDQYb35HA/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/ApuntesDeJava?a=myufsEgGH9Y:gyVQMSft2xw:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ApuntesDeJava?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ApuntesDeJava?a=myufsEgGH9Y:gyVQMSft2xw:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ApuntesDeJava?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ApuntesDeJava?a=myufsEgGH9Y:gyVQMSft2xw:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ApuntesDeJava?i=myufsEgGH9Y:gyVQMSft2xw:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ApuntesDeJava/~4/myufsEgGH9Y" height="1" width="1"/&gt;</description><atom:updated xmlns:atom="http://www.w3.org/2005/Atom">2010-11-16T00:00:05.966-05:00</atom:updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/_BQk94ojgkDY/TK4VWFA_WVI/AAAAAAAADHI/2ZMfQgswmjw/s72-c/netbeans-logo.png" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total><feedburner:origLink>http://www.apuntesdejava.com/2010/11/lo-que-se-viene-con-jdk-7-netbeans-7.html</feedburner:origLink></item><item><title>RESTful... la forma más ligera de hacer WebServices (Parte 1)</title><link>http://feedproxy.google.com/~r/ApuntesDeJava/~3/6ZqylEc0S_4/restful-la-forma-mas-ligera-de-hacer.html</link><category>restful</category><category>netbeans 6.9</category><category>tutorial java</category><category>netbeans</category><category>java ee 6</category><category>web</category><category>webservices</category><author>noreply@blogger.com (Diego Silva)</author><pubDate>Wed, 03 Nov 2010 15:29:00 PDT</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-8553642737291298841.post-9100524045807729822</guid><description>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_BQk94ojgkDY/TNHiBoISkpI/AAAAAAAADKs/trfv2uskorU/s1600/rest-ful-webservice-baner.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_BQk94ojgkDY/TNHiBoISkpI/AAAAAAAADKs/trfv2uskorU/s1600/rest-ful-webservice-baner.png" /&gt;&lt;/a&gt;&lt;/div&gt;Quienes hayan usado SOAP para WebService, sabrán que es bien fácil de diseñar, pero algo complicado de consumir: se necesita toda una API para construir los clientes utilizando el WSDL. Por ejemplo, para PHP se necesita de la biblioteca NuSOAP. Entonces, para lograr el concepto de "lenguaje único XML" es un dolor de cabeza. Y más aún si el cliente es tan simple como JavaScript, manejar XML de SOAP provocaría suicidos masivos... o no usar WebServices.&lt;br /&gt;
&lt;br /&gt;
Además, con SOAP se permite crear un solo servicio y ponerle varios métodos. Esto puede llevar a un mal diseño del servicio ya que podría tener un servicio que haga de todo: por ejemplo, un servicio de manejo de Clientes que permita también manejar Proveedores.&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://es.wikipedia.org/wiki/Representational_State_Transfer"&gt;RESTful&lt;/a&gt; es una propuesta muy interesante de &lt;a href="http://es.wikipedia.org/wiki/Roy_Fielding"&gt;Roy Fielding&lt;/a&gt; que permite manejar los servicios web con métodos definidos, manteniendo la simpleza del protocolo como XML, pero que cada servicio sea identificado únicamente con un solo &lt;a href="http://es.wikipedia.org/wiki/Uniform_Resource_Identifier"&gt;URI&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
En este post veremos cómo crear un Servicio RESTful usando NetBeans, y haremos crecer de poco a poco nuestro ejemplo... desde hacer operaciones sencillas, hasta manejar estructuras complejas.&lt;br /&gt;
&lt;br /&gt;
Cabe destacar que los servicios de las redes sociales como Flickr, Twitter, Facebook, etc son basados en RESTful.&lt;br /&gt;
&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;Para este ejemplo usaremos NetBeans 6.9.1, y GlassFish v3.0.1, ya que usaremos las características de &lt;a href="http://www.oracle.com/technetwork/java/javaee/tech/index.html"&gt;Java EE6&lt;/a&gt;. Con GlassFish v.2 igual funciona, y NetBeans ayuda en ello,&lt;br /&gt;
&lt;br /&gt;
Para comenzar, debemos entender que necesitamos de una clase para manejar un servicio. En esta clase solo pueden haber máximo cuatro métodos públicos que son ejecutados por los cuatro métodos HTTP disponibles para RESTful:&lt;br /&gt;
&lt;ol&gt;&lt;li&gt;GET&lt;/li&gt;
&lt;li&gt;POST&lt;/li&gt;
&lt;li&gt;DELETE&lt;/li&gt;
&lt;li&gt;PUT&lt;/li&gt;
&lt;/ol&gt;Los métodos GET y POST son conocidos en los formularios (&lt;code&gt;&amp;lt;form method="post" /&amp;gt;&lt;/code&gt;) ¿Tienen algo que ver? Sí, y lo veremos poco a poco. Cada uno de estos métodos determina la acción que hará el REST sobre nuestra aplicación. No deben haber más de un GET o POST o DELETE o PUT, solo tiene que haber uno de cada método. Cada uno tiene una tarea especifica:&lt;br /&gt;
&lt;ol&gt;&lt;li&gt;GET: Para obtener un valor. Puede ser un listado de objetos&lt;/li&gt;
&lt;li&gt;POST: Para guardar un nuevo objeto (instancia de identidada) en la aplicación &lt;/li&gt;
&lt;li&gt;DELETE: Para eliminar un objeto (instancia de identidad)&lt;/li&gt;
&lt;li&gt;PUT: Para actualizar un objeto.&lt;/li&gt;
&lt;/ol&gt;¿Suena a un mantenimiento CRUD? Sí, exacto. Eso es lo que es: los métodos para hacer mantenimiento a una entidad de la aplicación. Entonces, la clase que deberá tener estos métodos es como una clases EJB Facade&amp;nbsp; de una aplicación Java EE. Por tanto, esta clase se llamará "Recurso", funcionará como un EJB, solo manejará la persistencia de una etndiad, pero será accedido desde la web. ¿Cómo se hace? Bueno, iremos de poco a poco conociendo cómo hacer un mantenimiento complejo usando únicamente RESTful.&lt;br /&gt;
&lt;h2&gt;Creando proyecto y configurando REST&lt;/h2&gt;Crearemos un proyecto web común y silvestre en NetBeans. Yo crearé uno llamado &lt;code&gt;SimpleRESTweb&lt;/code&gt;. Este proyecto hará un simple cálculo de factorial. (Aunque a muchos no les guste, comenzaré siempre con una calculadora ya que es el clásico ejemplo de Entrada-&amp;gt;Procesamiento-&amp;gt;Salida.. lo demás, usando entidades, bases de datos, etc.. es lo mismo, solo que utiliza&amp;nbsp; más variables)&lt;br /&gt;
&lt;br /&gt;
Luego, crearemos una clase común y silvestre, llamada &lt;code&gt;FactorialResource&lt;/code&gt;. Tendrá (por ahora) un método llamado &lt;code&gt;factorial()&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;
public class FactorialResource {

    public long factorial(long base) {
        if (base &amp;gt;= 1) {
            return factorial(base - 1) * base;
        }
        return 1;
    }
}


&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
A esta clase se puede crear su TestCase para asegurarnos que funciona correctamente. Notemos que hasta ahora no hemos hecho nada REST. La  diversión comienza aquí:&lt;br /&gt;
&lt;br /&gt;
Agreguemos la notación &lt;code&gt;@Stateless&lt;/code&gt; al inicio de la clase. Esto convierte automáticamente a nuestra clase en un EJB&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_BQk94ojgkDY/TNCcImDzZyI/AAAAAAAADJM/q_HaQ52E-xs/s1600/rest-01.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://4.bp.blogspot.com/_BQk94ojgkDY/TNCcImDzZyI/AAAAAAAADJM/q_HaQ52E-xs/s320/rest-01.jpg" width="247" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
Luego, seguido al &lt;code&gt;@Stateless&lt;/code&gt; agregamos la anotación &lt;code&gt;@Path("/factorial")&lt;/code&gt; Esto indica que este recurso será accedido desde la ruta "/factorial" via web. Ahora, guardemos el archivo... y en ese mismo momento, el NetBeans detectará de que se ha creado un recurso REST, entonces pedirá activar esta característica en la aplicación... por tanto pedirá dónde estará activado todos los recursos REST. &lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_BQk94ojgkDY/TNCcI5XM4qI/AAAAAAAADJU/IzO4K_4Tsv4/s1600/rest-03.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_BQk94ojgkDY/TNCCU5aG3qI/AAAAAAAADI8/gVMMPnCJKoY/s1600/rest-02.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="232" src="http://1.bp.blogspot.com/_BQk94ojgkDY/TNCCU5aG3qI/AAAAAAAADI8/gVMMPnCJKoY/s400/rest-02.jpg" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
Utilizaremos el dado por defecto (&lt;code&gt;/resources&lt;/code&gt;). Clic en Ok.&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;&lt;b&gt;Nota: En GlassFish v2 (Java EE 5) solo existirán dos opciones&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
Y con esto, nuestra clase ya es un recurso REST.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_BQk94ojgkDY/TNCcI5XM4qI/AAAAAAAADJU/IzO4K_4Tsv4/s1600/rest-03.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://4.bp.blogspot.com/_BQk94ojgkDY/TNCcI5XM4qI/AAAAAAAADJU/IzO4K_4Tsv4/s320/rest-03.jpg" width="248" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
Pero aún este recurso no tiene métodos. Ahora veremos cómo convertir nuestro método convencional en un método REST.&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;Creando un método REST&lt;/h2&gt;Recordemos que solo podemos crear un método de tipo GET,POST,PUT y DELETE. Y como el método &lt;code&gt;factorial&lt;/code&gt; nos deberá devolver un solo valor según el parámetro que le especificamos, usaremos el tipo GET.&lt;br /&gt;
&lt;br /&gt;
Para ello agregamos la anotación &lt;code&gt;@GET&lt;/code&gt; antes del método.&lt;br /&gt;
&lt;br /&gt;
Y con esto, nuestro recurso ya tiene un método.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_BQk94ojgkDY/TNCcI7ZSL2I/AAAAAAAADJY/WkQeVI0bvHU/s1600/rest-04.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://3.bp.blogspot.com/_BQk94ojgkDY/TNCcI7ZSL2I/AAAAAAAADJY/WkQeVI0bvHU/s320/rest-04.jpg" width="223" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
Antes de continuar, los valores que se reciben desde el recurso REST deben ser objetos. Por tanto, nuestro método debe cambiar un poco para que no devuelva un &lt;code&gt;long&lt;/code&gt;, sino un &lt;code&gt;java.lang.String&lt;/code&gt;.&lt;br /&gt;
&lt;br /&gt;
Además, debemos indicar que el parámetro &lt;code&gt;base&lt;/code&gt; del método Java &lt;code&gt;factorial&lt;/code&gt; será recibido via URL con el nombre &lt;code&gt;base&lt;/code&gt;. Es decir, se llamará al URL así&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;..../factorial?base=5&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
Para ello usaremos la notación &lt;code&gt;@QueryParam&lt;/code&gt; antes de la declaración del parámetro y ponemos el nombre de la cadena query.&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;
@Stateless
@Path("/factorial")
public class FactorialResource {

    @GET
    public String factorial(@QueryParam("base") long base) {

        return Long.toString($factorial(base));
    }

    long $factorial(long base) {
        if (base &amp;gt;= 1) {
            return $factorial(base - 1) * base;
        }
        return 1;
    }
}

&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
El nombre del parámetro de la cadena query podría ser diferente al del método java. &lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;
//....
    @GET
    public String factorial(@QueryParam("numero") long base) {
//....

&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
Pero si se hace eso, se debería recordar que para accederlo via URL debe ser con ese mismo nombre&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;..../factorial?numero=5&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
Pero para evitar problemas, usaremos el mismo nombre. Y en caso de ser necesario, podemos cambiar el nombre. Eso ya queda a criterio del diseñador de la aplicación.&lt;br /&gt;
&lt;h2&gt;Probando la aplicación&lt;/h2&gt;Pues bien, ahora guardemos el proyecto, hagamos clic derecho sobre el ícono de proyecto y seleccionamos "Deploy". Esperamos a que se compile el proyecto, se ejecute el GlassFish y se despliegue.&lt;br /&gt;
&lt;br /&gt;
Aquí propondré tres maneras de probar el recurso REST. El primero es el más fácil, usando el URL. Bastará con abrir nuestro navegador y escribir el URL del proyecto:&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;http://localhost:8080/SimpleRESTweb/resources/factorial?base=10&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
Este URL está compuesto de lo siguiente:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;SimpleRESTweb: El contexto de la aplicación. Que generalmente es el nombre del proyecto.&lt;/li&gt;
&lt;li&gt;resources: Ubicación de los recursos REST de la aplicación. Este nombre nos lo pidió el NetBeans cuando guardamos la clase Java por primera vez con la notación &lt;code&gt;@Path&lt;/code&gt; ya que detectó que tenía recursos REST. Si se desea cambiar esta ruta, hagamos clic derecho en el nodo "RESTful Web Services" del proyecto y seleccionando "REST Resources Configuration"&lt;/li&gt;
&lt;li&gt;factorial: Es el nombre de nuestro recurso (Definido por la anotación &lt;code&gt;@Path&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;base: Es el parámetro del recurso. Justamente es una cadena Query.&lt;/li&gt;
&lt;/ul&gt;El resultado debe mostrarse tan simple como una web sin formato ni nada&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_BQk94ojgkDY/TNCSA4QLLCI/AAAAAAAADJI/tFotS_Po_pI/s1600/rest-05.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="291" src="http://3.bp.blogspot.com/_BQk94ojgkDY/TNCSA4QLLCI/AAAAAAAADJI/tFotS_Po_pI/s640/rest-05.jpg" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
Y ese es el resultado. Quizás me digan "hey, pero esto también lo puedo hacer con un servlet". Pues sí, pero no es lo mismo, ya que el Servlet puede guardar variables de sesión, y aquí en REST no... en Servlet se puede formatear en un HTML, pero aquí en REST no, porque lo que debe devolver es solo dato. &lt;br /&gt;
&lt;br /&gt;
La segunda manera que muestro cómo probar este recurso REST es usando un formulario HTML. Escribamos lo siguiente en el &lt;code&gt;index.jsp&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;
 &amp;lt;body&amp;gt;
        &amp;lt;h1&amp;gt;Calculando factorial&amp;lt;/h1&amp;gt;
        &amp;lt;form action="resources/factorial"&amp;gt;
            Base: &amp;lt;input name="base" type="text" /&amp;gt;
            &amp;lt;button&amp;gt;Calcular&amp;lt;/button&amp;gt;
        &amp;lt;/form&amp;gt;
    &amp;lt;/body&amp;gt;

&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
El resultado saldrá en otra página. &lt;br /&gt;
&lt;br /&gt;
Y la tercera forma (que es la más profesional) es usando el NetBeans. &lt;br /&gt;
&lt;br /&gt;
Hacemos clic derecho sobre el ícono del proyecto y seleccionamos "Test RESTful WebService".&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_BQk94ojgkDY/TNCcO9gSSrI/AAAAAAAADJg/zvMNDbCRsS8/s1600/rest-06.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="310" src="http://3.bp.blogspot.com/_BQk94ojgkDY/TNCcO9gSSrI/AAAAAAAADJg/zvMNDbCRsS8/s320/rest-06.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
Con esto, el IDE creará una página local que accederá al WADL de la aplicación y se mostrará en el navegador web.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_BQk94ojgkDY/TNCcPETGtDI/AAAAAAAADJk/PJt0YHbcCJc/s1600/rest-07.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="395" src="http://4.bp.blogspot.com/_BQk94ojgkDY/TNCcPETGtDI/AAAAAAAADJk/PJt0YHbcCJc/s640/rest-07.jpg" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
El &lt;a href="http://en.wikipedia.org/wiki/Web_Application_Description_Language"&gt;WADL&lt;/a&gt; es análogo al WSDL de SOAP&lt;br /&gt;
&lt;br /&gt;
Luego, podemos seleccionar del panel izquierdo el recurso que está disponible (en este caso "factorial")... &lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_BQk94ojgkDY/TNCcPA5lt3I/AAAAAAAADJo/fi6GyiPvHMU/s1600/rest-08.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="508" src="http://3.bp.blogspot.com/_BQk94ojgkDY/TNCcPA5lt3I/AAAAAAAADJo/fi6GyiPvHMU/s640/rest-08.jpg" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
... y vemos que nos muestra cuales son los parámetros (solo &lt;b&gt;base&lt;/b&gt;) que están disponibles para este recurso. Probamos escribiendo valores en el parámetro, y hacemos clic en "Test".&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_BQk94ojgkDY/TNCcPQ9xkwI/AAAAAAAADJs/QMs88v-ivgo/s1600/rest-09.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="619" src="http://3.bp.blogspot.com/_BQk94ojgkDY/TNCcPQ9xkwI/AAAAAAAADJs/QMs88v-ivgo/s640/rest-09.jpg" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;h2&gt;Consumiendo REST&lt;/h2&gt;Todo servicio web no es útil si no se sabe cómo consumir. En este post mostraremos cómo consumir este simple REST. En los siguientes post realizaremos recursos que utilizan objetos complejos.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;Usando JavaScript&lt;/h3&gt;Para consumir desde JavaScript, se debería utilizar la técnica AJAX. Y en vez de hacer toda la biblioteca de consumir AJAX con JavaScript, mejor usamos algo ya hecho... como el jQuery.&lt;br /&gt;
&lt;br /&gt;
Crearemos una página html al que llamaremos test-jquery.html. Y ahí pondremos lo siguiente.&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;
&amp;lt;html&amp;gt;
    &amp;lt;head&amp;gt;
        &amp;lt;title&amp;gt;&amp;lt;/title&amp;gt;
        &amp;lt;script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"&amp;gt;
        &amp;lt;/script&amp;gt;

        &amp;lt;meta http-equiv="Content-Type" content="text/html; charset=UTF-8"&amp;gt;
    &amp;lt;/head&amp;gt;
    &amp;lt;body&amp;gt;
        &amp;lt;h2&amp;gt;Calcular factorial&amp;lt;/h2&amp;gt;
        Número:&amp;lt;input type="text" name="base" id="base"/&amp;gt;
        &amp;lt;button type="button" id="calcularBtn"&amp;gt;Calcular&amp;lt;/button&amp;gt;
        &amp;lt;div id="resultado"&amp;gt;
            Resultado: &amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;
        &amp;lt;/div&amp;gt;
        &amp;lt;script type="text/javascript"&amp;gt;
            jQuery("#calcularBtn").click(function(){
                var base = jQuery("#base").val();
                jQuery.get("http://localhost:8080/SimpleRESTweb/resources/factorial",{
                    base:base
                },function(resultado){
                    jQuery("#resultado span").text(resultado)
                })
            })
        &amp;lt;/script&amp;gt;
    &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;

&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
Esta HTML funciona desde Firefox cuando se ejecuta desde el NetBeans,&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_BQk94ojgkDY/TNHU2QA0DlI/AAAAAAAADKE/E0Nb_Mhk81M/s1600/rest-10.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="356" src="http://4.bp.blogspot.com/_BQk94ojgkDY/TNHU2QA0DlI/AAAAAAAADKE/E0Nb_Mhk81M/s640/rest-10.jpg" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
y funciona en IExplorer si se ejecuta localmente (o sea, abriéndolo desde el explorador de archivos y activar el filtro de ActiveX que advierte el IE).&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_BQk94ojgkDY/TNHU2Z1cnYI/AAAAAAAADKI/pJzgL4-UO1c/s1600/rest-11.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="280" src="http://4.bp.blogspot.com/_BQk94ojgkDY/TNHU2Z1cnYI/AAAAAAAADKI/pJzgL4-UO1c/s640/rest-11.jpg" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;Usando Java&lt;/h3&gt;Con NetBeans más el complemento Jersey, se nos hace muy fácil consumir servicios REST. Para integrarlo con el IDE, necesitamos registrar el WADL. Esta URL lo podemos obtener así: http://host:puerto/contexto-web/resources/application.wadl&lt;br /&gt;
&lt;br /&gt;
Para nuestro ejemplo, este es&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://localhost:8080/SimpleRESTweb/resources/application.wadl"&gt;http://localhost:8080/SimpleRESTweb/resources/application.wadl&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Podemos abrirlo desde el navegador y se nos mostrará un XML que contiene la definición de los recursos (&lt;code&gt;/factorial&lt;/code&gt;) y los parámetros de cada método. En este caso hay un método GET y tiene como parámetro un long.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_BQk94ojgkDY/TNHU3EOGE9I/AAAAAAAADKM/eCM8HjrJCAo/s1600/rest-12.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="436" src="http://3.bp.blogspot.com/_BQk94ojgkDY/TNHU3EOGE9I/AAAAAAAADKM/eCM8HjrJCAo/s640/rest-12.jpg" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
Ahora bien, este URL del WADL lo vamos a necesitar para registrarlo en el NetBeans. En el IDE vayamos al panel de servicios (Ctrl+5) y hacemos clic derecho sobre el nodo "Web Services" y seleccionamos "Add Web Service..."&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_BQk94ojgkDY/TNHU3rS5yfI/AAAAAAAADKQ/sFIUJnsSzd4/s1600/rest-13.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="160" src="http://4.bp.blogspot.com/_BQk94ojgkDY/TNHU3rS5yfI/AAAAAAAADKQ/sFIUJnsSzd4/s400/rest-13.jpg" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
Luego, en la entrada de URL, pegamos la dirección del WADL. Y como nombre de paquete ponemos &lt;code&gt;simplerest&lt;/code&gt;. &lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_BQk94ojgkDY/TNHU35cVn4I/AAAAAAAADKU/WGcEIb-4Z9s/s1600/rest-14.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="236" src="http://2.bp.blogspot.com/_BQk94ojgkDY/TNHU35cVn4I/AAAAAAAADKU/WGcEIb-4Z9s/s640/rest-14.jpg" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
Y listo, ya tendremos registrado el WebService en nuestro IDE. &lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_BQk94ojgkDY/TNHU8wvqbnI/AAAAAAAADKY/oTRxNV2cba4/s1600/rest-15.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="261" src="http://2.bp.blogspot.com/_BQk94ojgkDY/TNHU8wvqbnI/AAAAAAAADKY/oTRxNV2cba4/s320/rest-15.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
Esto nos permitirá utilizar este servicio en cualquiera de nuestras aplicaciones. Por ejemplo, ahora, en Java.&lt;br /&gt;
&lt;br /&gt;
Hagamos un nuevo proyecto llamado &lt;code&gt;SimpleRESTClientJavaApp&lt;/code&gt;.&lt;br /&gt;
&lt;br /&gt;
Ahora, crearemos un nuevo archivo (Ctrl+N) y seleccionamos la categoría "Web Services" y el tipo de archivo "RESTful Java Client"&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_BQk94ojgkDY/TNHU9FtucBI/AAAAAAAADKc/k5TpRR8TyoQ/s1600/rest-16.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="440" src="http://1.bp.blogspot.com/_BQk94ojgkDY/TNHU9FtucBI/AAAAAAAADKc/k5TpRR8TyoQ/s640/rest-16.jpg" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
Luego, en el siguiente paso, pongamos como nombre de la clase &lt;code&gt;FactorialClient&lt;/code&gt;, dentro de la opción "Select the REST resource" seleccionemos la opción "IDE Registered" &lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_BQk94ojgkDY/TNHU9eE8wUI/AAAAAAAADKg/mh9F93LeBLg/s1600/rest-17.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="441" src="http://4.bp.blogspot.com/_BQk94ojgkDY/TNHU9eE8wUI/AAAAAAAADKg/mh9F93LeBLg/s640/rest-17.jpg" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
... y hagamos clic en "Browse" para seleccionar el WebService que acabamos de registrar.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_BQk94ojgkDY/TNHU-GLpw6I/AAAAAAAADKk/VroeUK6wvlM/s1600/rest-18.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="400" src="http://1.bp.blogspot.com/_BQk94ojgkDY/TNHU-GLpw6I/AAAAAAAADKk/VroeUK6wvlM/s400/rest-18.jpg" width="331" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
y clic en "Finish". Listo, el IDE nos creará la clase &lt;code&gt;FactorialClient&lt;/code&gt; que contendrá los recursos necesarios para acceder al servicio REST.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_BQk94ojgkDY/TNHU-3eWoQI/AAAAAAAADKo/3VcqkDINnKc/s1600/rest-19.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="452" src="http://2.bp.blogspot.com/_BQk94ojgkDY/TNHU-3eWoQI/AAAAAAAADKo/3VcqkDINnKc/s640/rest-19.jpg" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
Ahora, ¿cómo se consume esto?... en nuestra clase Java solo debemos instanciar la clase, pasarle el parámetro y recibir el valor. Fácil&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;
        FactorialClient client = new FactorialClient();
        long base = 15;
        String resultado = client.factorial(String.class, String.valueOf(base));
        System.out.println("Resultado: " + resultado);

&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;h2&gt;Código fuente&lt;/h2&gt;El ejemplo del servidor REST se encuentra aquí&lt;br /&gt;
&lt;a href="http://kenai.com/projects/apuntes/downloads/download/Simple%2520RESTful%252FSimpleRESTweb.tar.gz"&gt;http://kenai.com/projects/apuntes/downloads/download/Simple%2520RESTful%252FSimpleRESTweb.tar.gz&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
y el ejemplo de cliente REST en Java se puede descargar de aquí&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://kenai.com/projects/apuntes/downloads/download/Simple%2520RESTful%252FSimpleRESTClientJavaApp.tar.gz"&gt;http://kenai.com/projects/apuntes/downloads/download/Simple%2520RESTful%252FSimpleRESTClientJavaApp.tar.gz&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8553642737291298841-9100524045807729822?l=www.apuntesdejava.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/T9bw5k5Z2ajtLrP225mwyYbTMq0/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/T9bw5k5Z2ajtLrP225mwyYbTMq0/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/T9bw5k5Z2ajtLrP225mwyYbTMq0/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/T9bw5k5Z2ajtLrP225mwyYbTMq0/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/ApuntesDeJava?a=6ZqylEc0S_4:FCHzAnuc2YA:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ApuntesDeJava?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ApuntesDeJava?a=6ZqylEc0S_4:FCHzAnuc2YA:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ApuntesDeJava?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ApuntesDeJava?a=6ZqylEc0S_4:FCHzAnuc2YA:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ApuntesDeJava?i=6ZqylEc0S_4:FCHzAnuc2YA:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ApuntesDeJava/~4/6ZqylEc0S_4" height="1" width="1"/&gt;</description><atom:updated xmlns:atom="http://www.w3.org/2005/Atom">2010-11-03T17:29:06.568-05:00</atom:updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/_BQk94ojgkDY/TNHiBoISkpI/AAAAAAAADKs/trfv2uskorU/s72-c/rest-ful-webservice-baner.png" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">9</thr:total><feedburner:origLink>http://www.apuntesdejava.com/2010/11/restful-la-forma-mas-ligera-de-hacer.html</feedburner:origLink></item><item><title>Preparando capacitación virtual en NetBeans Platform</title><link>http://feedproxy.google.com/~r/ApuntesDeJava/~3/kvSpkigRz9o/ultimo-minuto-capacitacion-virtual-en.html</link><category>RCP</category><category>noticias NetBeans</category><category>netbeans</category><category>NetBeans Platform</category><author>noreply@blogger.com (Diego Silva)</author><pubDate>Wed, 27 Oct 2010 10:07:00 PDT</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-8553642737291298841.post-6268743182326058590</guid><description>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_BQk94ojgkDY/TMh287hhM4I/AAAAAAAADIo/B6NPH9SYfd8/s1600/NB-Platform-logo.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" height="27" src="http://1.bp.blogspot.com/_BQk94ojgkDY/TMh287hhM4I/AAAAAAAADIo/B6NPH9SYfd8/s200/NB-Platform-logo.png" width="200" /&gt;&lt;/a&gt;&lt;/div&gt;A &lt;a href="http://blogs.sun.com/geertjan/"&gt;Geertjan Wielenga&lt;/a&gt; (considerado como el maestro de&amp;nbsp; &lt;a href="http://netbeans.org/features/platform/index.html"&gt;NetBeans Platform)&lt;/a&gt; le he propuesto hacer un entrenamiento virtual sobre NetBeans Platform para Latinoamerica. Le agradó la idea, y me dice que reuna al menos a cinco o seis participantes.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;NetBeans Platform&lt;/b&gt; es una plataforma completa que permite desarrollar aplicaciones desktop (swing) proporcionándonos varias funcionalidades "rutinarias" que se necesitan al momento de hacer una aplicación swing, tales como manejo de ventanas, árboles, ventanas de diálogos, opciones, manejo de archivos, etc.&amp;nbsp; También se pueden desarrollar complementos que permitan ampliar la funcionalidad del mismo NetBeans IDE. Para tener una idea de lo que se puede hacer: NetBeans IDE y &lt;a href="http://jasperforge.org/projects/ireport"&gt;iReport &lt;/a&gt;están hechos sobre NetBeans Platform. &lt;br /&gt;
&lt;br /&gt;
¿Quienes se apuntan para este entrenamiento? Si estás interesado, llena tus datos aquí :&lt;br /&gt;
&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;iframe frameborder="0" height="764" marginheight="0" marginwidth="0" src="https://spreadsheets.google.com/embeddedform?formkey=dHJWLXdPYnFEQlo2SnZhcmQ2aDJmSnc6MQ" width="760"&gt;&amp;amp;lt;p&amp;amp;gt;&amp;amp;amp;amp;amp;amp;lt;p&amp;amp;amp;amp;amp;amp;gt;&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;p&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;p&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;p&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;p&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;Loading...&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;/p&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;/p&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;/p&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;/p&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;&amp;amp;amp;amp;amp;amp;lt;/p&amp;amp;amp;amp;amp;amp;gt;&amp;amp;lt;/p&amp;amp;gt;&lt;/iframe&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8553642737291298841-6268743182326058590?l=www.apuntesdejava.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/OELkTmT20ATH-fMfKsft9oPIFLg/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/OELkTmT20ATH-fMfKsft9oPIFLg/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/OELkTmT20ATH-fMfKsft9oPIFLg/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/OELkTmT20ATH-fMfKsft9oPIFLg/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/ApuntesDeJava?a=kvSpkigRz9o:REOTnOU6M-I:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ApuntesDeJava?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ApuntesDeJava?a=kvSpkigRz9o:REOTnOU6M-I:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ApuntesDeJava?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ApuntesDeJava?a=kvSpkigRz9o:REOTnOU6M-I:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ApuntesDeJava?i=kvSpkigRz9o:REOTnOU6M-I:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ApuntesDeJava/~4/kvSpkigRz9o" height="1" width="1"/&gt;</description><atom:updated xmlns:atom="http://www.w3.org/2005/Atom">2010-10-28T10:04:46.719-05:00</atom:updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/_BQk94ojgkDY/TMh287hhM4I/AAAAAAAADIo/B6NPH9SYfd8/s72-c/NB-Platform-logo.png" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">10</thr:total><feedburner:origLink>http://www.apuntesdejava.com/2010/10/ultimo-minuto-capacitacion-virtual-en.html</feedburner:origLink></item><item><title>Swing: Componentes enlazados a un bean</title><link>http://feedproxy.google.com/~r/ApuntesDeJava/~3/-qZADqul4Fc/swing-componentes-enlazados-un-bean.html</link><category>java</category><category>swing</category><category>tips</category><category>netbeans</category><author>noreply@blogger.com (Diego Silva)</author><pubDate>Mon, 25 Oct 2010 22:00:00 PDT</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-8553642737291298841.post-7672327583788156666</guid><description>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_BQk94ojgkDY/TL_N8fB2rbI/AAAAAAAADH0/EZaaGt9UV6M/s1600/java_beans.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_BQk94ojgkDY/TL_N8fB2rbI/AAAAAAAADH0/EZaaGt9UV6M/s1600/java_beans.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;La mejor manera de tener sincronizado un control swing con un javabean es utilizando enlaces (binding). La manera común y poco profesional es utilizar los set&amp;nbsp; y gets de cada atributo de un bean para asociar a cada componente.&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;//...
nombreTF.setValue(persona.getNombre());
edadTF.setValue(persona.getEdad());
//... etc&lt;/code&gt;&lt;/pre&gt;y si son 80 campos, nadie querra hacerle mantenimiento.&lt;br /&gt;
&lt;br /&gt;
Aquí es donde entran los enlaces. Mostraremos un ejemplo con NetBeans para enlazar los componentes de un formulario con un JavaBean.&lt;br /&gt;
&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;Este tip es aporte de Fernando Rodelo Mármol, seguidor de este blog, y amigo.&lt;br /&gt;
&lt;h2&gt;Creando el JavaBean&lt;/h2&gt;Primero debemos crear una clase Java. La llamaremos &lt;code&gt;Persona&lt;/code&gt;.&lt;br /&gt;
&lt;br /&gt;
Luego, crearemos tres propiedades llamadas &lt;code&gt;nombre&lt;/code&gt;, &lt;code&gt;edad&lt;/code&gt; y &lt;code&gt;sexo&lt;/code&gt;. Pero lo haremos utilizando NetBeans de la siguiente manera. &lt;br /&gt;
&lt;br /&gt;
&lt;ol&gt;&lt;li&gt;Clic derecho sobre el código del editor, justo dentro de la clase &lt;code&gt;Persona&lt;/code&gt; y seleccionar "Insert code"&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_BQk94ojgkDY/TL_Jib01V0I/AAAAAAAADHo/qMXDVeqiJP4/s1600/props-swing01.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="164" src="http://1.bp.blogspot.com/_BQk94ojgkDY/TL_Jib01V0I/AAAAAAAADHo/qMXDVeqiJP4/s320/props-swing01.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;Seleccionar "Add property".&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_BQk94ojgkDY/TL_KFLoBRhI/AAAAAAAADHs/X2jZMeA3gEY/s1600/props-swing02.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_BQk94ojgkDY/TL_KFLoBRhI/AAAAAAAADHs/X2jZMeA3gEY/s1600/props-swing02.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;Con esto se mostrará un editor para crear una nueva propiedad, al cual haremos los siguientes cambios&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;En el campo &lt;b&gt;name&lt;/b&gt; escribimos el nombre de la nueva propiedad: nombre&lt;/li&gt;
&lt;li&gt;En el campo &lt;b&gt;type&lt;/b&gt; indicamos el tipo de la propiedad: String&lt;/li&gt;
&lt;li&gt;Activamos la opción "Bound". En ese momento se mostrará el campo la declaración de una constante llamada &lt;code&gt;PROP_NOMBRE&lt;/code&gt; con el valor "nombre". Esto es para asociar la variable "nombre" con el escuchador (listener) del JavaBean.&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_BQk94ojgkDY/TL_K-cC3FFI/AAAAAAAADHw/cESplhMu9H0/s1600/props-swing03.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="367" src="http://1.bp.blogspot.com/_BQk94ojgkDY/TL_K-cC3FFI/AAAAAAAADHw/cESplhMu9H0/s400/props-swing03.jpg" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;Clic en "ok" para aceptar esta propiedad. Repetir la misma operación con los demás campos.&lt;/li&gt;
&lt;/ol&gt;Para el caso de la propiedad "sexo", consideremos utilizar dos propiedades de tipo boolean llamadas "hombre" y "mujer". &lt;br /&gt;
&lt;br /&gt;
Veamos el código generado. De no existir el IDE, deberiamos escribir todo el código. Bastante ¿no?&lt;br /&gt;
&lt;ol&gt;&lt;/ol&gt;&lt;br /&gt;
&lt;h2&gt;Enlazando JavaBean con formulario swing&lt;/h2&gt;Ahora que ya tenemos el JavaBean con su respectivo manejador de cambios de propiedades, debemos crear en el formulario swing una propiedad de tipo Persona. Además, esta propiedad debe tener sus respectivos get/set.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_BQk94ojgkDY/TMBwwo4qo5I/AAAAAAAADIE/iVHBRJnxDq4/s1600/swing-listener00.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="264" src="http://1.bp.blogspot.com/_BQk94ojgkDY/TMBwwo4qo5I/AAAAAAAADIE/iVHBRJnxDq4/s320/swing-listener00.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
En el panel de diseño del formulario vamos a enlazar cada control con cada propiedad de la propiedad persona.&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_BQk94ojgkDY/TMBwwnCvj1I/AAAAAAAADII/qn9BqHU2XCo/s1600/swing-listener01.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="201" src="http://1.bp.blogspot.com/_BQk94ojgkDY/TMBwwnCvj1I/AAAAAAAADII/qn9BqHU2XCo/s400/swing-listener01.jpg" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
Hacemos clic-derecho en el control donde irá el nombre, y seleccionamos "bind &amp;gt; Text" que significa "enlazar el texto del control"&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_BQk94ojgkDY/TMBww9XF_pI/AAAAAAAADIM/CgmKcff4UoE/s1600/swing-listener02.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="195" src="http://3.bp.blogspot.com/_BQk94ojgkDY/TMBww9XF_pI/AAAAAAAADIM/CgmKcff4UoE/s400/swing-listener02.jpg" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
El IDE nos mostrará una ventana de diálogo para configurar el enlace del control. Aquí primero seleccionamos en la opción "Binding Source" de dónde se va a tomar el campo a enlazar. Como hemos declarado nuestra propiedad "persona" dentro del formulario, entonces seleccionamos "Form"&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_BQk94ojgkDY/TMBww9ZIvJI/AAAAAAAADIQ/ZG_UIL3k2kM/s1600/swing-listener03.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="226" src="http://1.bp.blogspot.com/_BQk94ojgkDY/TMBww9ZIvJI/AAAAAAAADIQ/ZG_UIL3k2kM/s400/swing-listener03.jpg" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
En la parte inferior se mostrará un listado de los componentes del formulario. Buscamos a "persona", abrimos el nodo y seleccionamos (en este caso) la propiedad "nombre".&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_BQk94ojgkDY/TMBzqH9ZMQI/AAAAAAAADIc/OlEZXTEaQbc/s1600/swing-listener04.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://2.bp.blogspot.com/_BQk94ojgkDY/TMBzqH9ZMQI/AAAAAAAADIc/OlEZXTEaQbc/s400/swing-listener04.jpg" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;br /&gt;
Hacemos clic en "OK" y repetimos la acción en las demás propiedades.&lt;br /&gt;
&lt;br /&gt;
Es importante recalcar que la propiedad del JavaBean debe tener el mismo tipo del que maneja el control. El tipo de control lo podemos ver en la parte superior de la ventana de diálogo. Por ejemplo, el del JTextField dice "Bind property &lt;b&gt;text &lt;/b&gt;(&lt;i&gt;java.lang.String&lt;/i&gt;) to:"&lt;br /&gt;
&lt;h2&gt;Probando guardar el JavaBean&lt;/h2&gt;Ahora, cada vez que escribamos algo en los controles, se guardarán directamente en el JavaBean. ¿No me creen? Bueno, hagamos la siguiente prueba: después de escribir los valores, guardemos los valores del JavaBean en un archivo XML.&lt;br /&gt;
&lt;br /&gt;
Para ello, programaremos el siguiente código en el botón "Guardar".&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;
XMLEncoder encoder = new XMLEncoder(
                         new BufferedOutputStream(
                             new FileOutputStream(ARCHIVO_XML)));
encoder.writeObject(persona);
encoder.close();

&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
Donde la variable &lt;code&gt;ARCHIVO_XML&lt;/code&gt; es un String que contiene el nombre del archivo a guardar. &lt;br /&gt;
&lt;br /&gt;
Ahora, hagamos la prueba: llenemos el formulario, y hagamos clic en Guardar.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Y veamos el archivo XML que guardó.&lt;br /&gt;
&lt;br /&gt;
Usé el &lt;a href="http://download.oracle.com/javase/6/docs/api/java/beans/XMLEncoder.html"&gt;XMLEncoder&lt;/a&gt; para evitar todo un manejo de base de datos para este ejemplo. &lt;br /&gt;
&lt;h2&gt;Probando mostrar controles actualizados&lt;/h2&gt;Me dirán "ok Diego, ya sé que el bean está asociado a los controles.. escribo en el control y lo guarda en el JavaBean.. hice hasta&amp;nbsp; un debug y me funciona.. pero si modifico el JavaBean ¿cómo refresco el contenido de los controles? "&lt;br /&gt;
&lt;br /&gt;
Bueno, esto es automático. Basta que se haga un cambio en el JavaBean Persona, los controles se actualizan automáticamente.&lt;br /&gt;
&lt;br /&gt;
Hagamos esta prueba: en el botón "Nuevo" escribimos el siguiente código:&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;
persona.setNombre("");
persona.setEdad(0);
persona.setMujer(false);
persona.setHombre(false);
buttonGroup1.clearSelection();

&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
Funciona...!!&lt;br /&gt;
&lt;br /&gt;
&lt;b style="color: blue;"&gt;Nota&lt;/b&gt;: no intentar hacer &lt;br /&gt;
&lt;pre&gt;&lt;code&gt;persona=new Persona();&lt;/code&gt;&lt;/pre&gt;porque se crearía otro objeto y el enlace con el control se pierde. Entonces, si hay 80 campos ¿tengo que hacer esto por todos los campos? Uhmm.... sí. &lt;br /&gt;
&lt;br /&gt;
Cuando usamos enlaces (bindings) debemos considerar que el formulario tiene un objeto JavaBean asociado al mismo formulario... es como el "alma" del formulario.... funciona como el "objeto actual" del formulario. Lo que podemos hacer es usar una variable temporal para copiar sus valores al JavaBean del formulario. Así manejamos el temporal, creamos, alteramos etc.. pero solo le damos una copia de este temporal al JavaBean.&lt;br /&gt;
&lt;h2&gt;Cargando el JavaBean guardado&lt;/h2&gt;Volviendo a nuestro ejemplo.. si ya hemos guardado el JavaBean en un XML, hemos cerrado y volvemos a ejecutar el formulario... y ahora queremos cargar lo que hemos guardado ¿qué hacemos? Bueno, usamos el &lt;a href="http://download.oracle.com/javase/6/docs/api/java/beans/XMLDecoder.html"&gt;XMLDecoder&lt;/a&gt;, cargamos el valor en un objeto temporal y copiamos los valores al JavaBean persona.&lt;br /&gt;
&lt;br /&gt;
"Pero Diego.. ¿si son 80 campos?" Ok ok.. vamos a valernos de una biblioteca de &lt;a href="http://commons.apache.org/"&gt;Apache Commons&lt;/a&gt; para copiar las propiedades de un objeto a otro. Esta biblioteca se llama &lt;a href="http://commons.apache.org/beanutils/"&gt;BeanUtils&lt;/a&gt; y el método se llama &lt;a href="http://commons.apache.org/beanutils/v1.8.3/apidocs/org/apache/commons/beanutils/BeanUtils.html#copyProperties%28java.lang.Object,%20java.lang.Object%29"&gt;BeanUtils.copyProperties()&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;
XMLDecoder decoder = new XMLDecoder(
                         new BufferedInputStream(
                             new FileInputStream(ARCHIVO_XML)));
Persona $persona = (Persona) decoder.readObject();
decoder.close();
BeanUtils.copyProperties(persona, $persona);

&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
Ahora sí.. ya funciona....&lt;br /&gt;
&lt;br /&gt;
¿Y para el botón "Nuevo"?.. lo mismo, solo que no cargaremos un XML, sino copiaremos las propiedades de un objeto nuevo.&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;
Persona $persona = new Persona();
BeanUtils.copyProperties(persona, $persona);
buttonGroup1.clearSelection();

&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;h2&gt;Proyecto de ejemplo&lt;/h2&gt;Y no iba a faltar el proyecto utilizado en este post.&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://kenai.com/projects/apuntes/downloads/download/ejemplos%252Fswing%252FSwingListenerApp.tar.gz"&gt;http://kenai.com/projects/apuntes/downloads/download/ejemplos%252Fswing%252FSwingListenerApp.tar.gz&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Espero que les sea de utilidad.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8553642737291298841-7672327583788156666?l=www.apuntesdejava.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/d01KUs8AQb0qgqIMhXGU5Dhylz4/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/d01KUs8AQb0qgqIMhXGU5Dhylz4/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/d01KUs8AQb0qgqIMhXGU5Dhylz4/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/d01KUs8AQb0qgqIMhXGU5Dhylz4/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/ApuntesDeJava?a=-qZADqul4Fc:ycSzh2wdnv0:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ApuntesDeJava?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ApuntesDeJava?a=-qZADqul4Fc:ycSzh2wdnv0:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ApuntesDeJava?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ApuntesDeJava?a=-qZADqul4Fc:ycSzh2wdnv0:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ApuntesDeJava?i=-qZADqul4Fc:ycSzh2wdnv0:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ApuntesDeJava/~4/-qZADqul4Fc" height="1" width="1"/&gt;</description><atom:updated xmlns:atom="http://www.w3.org/2005/Atom">2010-11-04T12:58:56.618-05:00</atom:updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/_BQk94ojgkDY/TL_N8fB2rbI/AAAAAAAADH0/EZaaGt9UV6M/s72-c/java_beans.jpg" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.apuntesdejava.com/2010/10/swing-componentes-enlazados-un-bean.html</feedburner:origLink></item><item><title>Compilando y ejecutando una clase java.... desde java</title><link>http://feedproxy.google.com/~r/ApuntesDeJava/~3/pRpLjWYRfuc/compilando-y-ejecutando-una-clase-java.html</link><category>java</category><category>java se6</category><author>noreply@blogger.com (Diego Silva)</author><pubDate>Mon, 18 Oct 2010 22:00:00 PDT</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-8553642737291298841.post-2764927728733476840</guid><description>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_BQk94ojgkDY/TLX0wbRytmI/AAAAAAAADHg/d7Yw3MPsSOQ/s1600/SwingingDuke.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_BQk94ojgkDY/TLX0wbRytmI/AAAAAAAADHg/d7Yw3MPsSOQ/s1600/SwingingDuke.png" /&gt;&lt;/a&gt;&lt;/div&gt;El JDK 6 viene con varias funcionalidades interesantes, entre ellas la compilación de clases java desde el mismo java.&lt;br /&gt;
&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
La instancia que se encarga de tal tarea es &lt;a href="http://download.oracle.com/javase/6/docs/api/javax/tools/JavaCompiler.html"&gt;JavaCompiler&lt;/a&gt; pero su instancia se obtiene desde el método &lt;a href="http://download.oracle.com/javase/6/docs/api/javax/tools/ToolProvider.html#getSystemJavaCompiler%28%29"&gt;ToolProvider.getSystemJavaCompiler()&lt;/a&gt;. &lt;br /&gt;
&lt;br /&gt;
La compilación se resume a una simple instrucción:&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;JavaCompiler javaCompiler = ToolProvider.getSystemJavaCompiler();
int resultado = javaCompiler.run(null, null, null, "Factorial.java");
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
Hay más opciones de compilación, como por ejemplo obtener los errores de compilación, y compilación en memoria. Para más opciones de la clase, revisar el API de &lt;a href="http://download.oracle.com/javase/6/docs/api/javax/tools/JavaCompiler.html"&gt;javax.tools.JavaCompiler&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Ahora bien, ¿cómo se puede ejecutar una clase compilada? Pues se necesita cargarlo en la memoria del JVM. Fácil.... pero el reto es hacerlo en ejecución, ya que si no está en el classpath de la aplicación nunca se podrá ejecutar. Y como sabía que alguien me haría esta pregunta, hice aquí un ejemplo de ello: compilar y luego ejecutar el compilado.&lt;br /&gt;
&lt;br /&gt;
Lo que hice fue redefinir el método &lt;code&gt;loadClass()&lt;/code&gt; de la clase &lt;code&gt;&lt;a href="http://download.oracle.com/javase/6/docs/api/java/lang/ClassLoader.html"&gt;java.lang.ClassLoader&lt;/a&gt;&lt;/code&gt;, cargarlo en bytes el archivo binario .class y luego convertirlo en una clase java. &lt;br /&gt;
&lt;br /&gt;
Aquí les dejo el ejemplo para que se diviertan un rato.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Código ejemplo&lt;/b&gt;&lt;br /&gt;
&lt;a href="http://kenai.com/projects/apuntes/downloads/download/ejemplos%252Fjdk%252FCompilandoJava.tar.gz"&gt;http://kenai.com/projects/apuntes/downloads/download/ejemplos%252Fjdk%252FCompilandoJava.tar.gz&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8553642737291298841-2764927728733476840?l=www.apuntesdejava.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/512YHoRGDswPMdv22EnGFtIrgBE/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/512YHoRGDswPMdv22EnGFtIrgBE/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/512YHoRGDswPMdv22EnGFtIrgBE/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/512YHoRGDswPMdv22EnGFtIrgBE/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/ApuntesDeJava?a=pRpLjWYRfuc:js2PGzWSsvc:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ApuntesDeJava?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ApuntesDeJava?a=pRpLjWYRfuc:js2PGzWSsvc:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ApuntesDeJava?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ApuntesDeJava?a=pRpLjWYRfuc:js2PGzWSsvc:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ApuntesDeJava?i=pRpLjWYRfuc:js2PGzWSsvc:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ApuntesDeJava/~4/pRpLjWYRfuc" height="1" width="1"/&gt;</description><atom:updated xmlns:atom="http://www.w3.org/2005/Atom">2010-11-03T18:12:31.806-05:00</atom:updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/_BQk94ojgkDY/TLX0wbRytmI/AAAAAAAADHg/d7Yw3MPsSOQ/s72-c/SwingingDuke.png" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total><feedburner:origLink>http://www.apuntesdejava.com/2010/10/compilando-y-ejecutando-una-clase-java.html</feedburner:origLink></item><item><title>CouchDB, base de datos orientada a documentos</title><link>http://feedproxy.google.com/~r/ApuntesDeJava/~3/7A1CLVJG7Ws/couchdb-base-de-datos-orientada.html</link><category>java</category><category>base de datos</category><author>noreply@blogger.com (Diego Silva)</author><pubDate>Fri, 15 Oct 2010 12:54:00 PDT</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-8553642737291298841.post-5097341937852909221</guid><description>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_BQk94ojgkDY/TLiwqK5RMsI/AAAAAAAADHk/ovNGzIIFIds/s1600/couchdb-logo.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" height="55" src="http://4.bp.blogspot.com/_BQk94ojgkDY/TLiwqK5RMsI/AAAAAAAADHk/ovNGzIIFIds/s200/couchdb-logo.png" width="200" /&gt;&lt;/a&gt;&lt;/div&gt;Desde Panamá, nuestro amigo &lt;a href="http://avbravo.blogspot.com/"&gt;Arístides Villareal&lt;/a&gt;, ha publicado algunos post referente a esta base de datos orientada a documentos llamada &lt;a href="http://couchdb.apache.org/"&gt;CouchDB&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href="http://avbravo.blogspot.com/search/label/couchdb"&gt;http://avbravo.blogspot.com/search/label/couchdb&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://avbravo.blogspot.com/search/label/m21couchdb"&gt;http://avbravo.blogspot.com/search/label/m21couchdb&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
CouchDB proporciona un API JSon para que puede ser accdido desde cualquier entorno, incluyendo peticiones HTTP. Fue escribo en &lt;a href="http:///"&gt;Erlang&lt;/a&gt;, un lenguaje de programación funcional ideal para sistemas distribuidos concurrentes.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8553642737291298841-5097341937852909221?l=www.apuntesdejava.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/9VYHf9Hfme47DMFrMJVyE9WcbwU/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/9VYHf9Hfme47DMFrMJVyE9WcbwU/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/9VYHf9Hfme47DMFrMJVyE9WcbwU/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/9VYHf9Hfme47DMFrMJVyE9WcbwU/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/ApuntesDeJava?a=7A1CLVJG7Ws:m8rga8CzfrE:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ApuntesDeJava?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ApuntesDeJava?a=7A1CLVJG7Ws:m8rga8CzfrE:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ApuntesDeJava?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ApuntesDeJava?a=7A1CLVJG7Ws:m8rga8CzfrE:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ApuntesDeJava?i=7A1CLVJG7Ws:m8rga8CzfrE:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ApuntesDeJava/~4/7A1CLVJG7Ws" height="1" width="1"/&gt;</description><atom:updated xmlns:atom="http://www.w3.org/2005/Atom">2010-10-15T14:54:35.936-05:00</atom:updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/_BQk94ojgkDY/TLiwqK5RMsI/AAAAAAAADHk/ovNGzIIFIds/s72-c/couchdb-logo.png" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.apuntesdejava.com/2010/10/couchdb-base-de-datos-orientada.html</feedburner:origLink></item><item><title>EJB 3.1 en Porlets de Liferay</title><link>http://feedproxy.google.com/~r/ApuntesDeJava/~3/V72AW-2RWjQ/ejb-31-en-porlets-de-liferay.html</link><category>glassfish v3</category><category>liferay</category><category>ejb</category><category>tips</category><category>portlets</category><category>glassfish</category><category>trucos</category><category>ejb 3.1</category><author>noreply@blogger.com (Diego Silva)</author><pubDate>Mon, 11 Oct 2010 22:00:00 PDT</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-8553642737291298841.post-8828071345448143639</guid><description>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_BQk94ojgkDY/TLNs1u1qjeI/AAAAAAAADHc/6ryyRcfvdjc/s1600/beans1.gif" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_BQk94ojgkDY/TLNs1u1qjeI/AAAAAAAADHc/6ryyRcfvdjc/s1600/beans1.gif" /&gt;&lt;/a&gt;&lt;/div&gt;Ya que GlassFish v3 es compatible con Java EE6, y permite módulos web con componentes &lt;a href="http://www.oracle.com/technetwork/java/index-jsp-140203.html"&gt;EJB &lt;/a&gt;(por la característica propia de EJB 3.1).. y además Liferay puede ser instalado sobre GlassFish v3... y... los portlets son módulos web con otro archivo de despligue ¿los portlets para Liferay/GFv3 deberían permitir EJB 3.1?&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
Pues la respuesta es sencilla: Sí. Pero cuando uno desarrolla un portlet con EJB 3.1 y lo trata de desplegar sobre Lfieray 6.0, no funciona. Por alguna razón no despliega correctamente la aplicación, lanza errores de clases de SpringFramework faltantes, etc. Lo curioso es que si se despliega sobre Liferay 5, sí funciona correctamente. Entonces ¿qué pasa?. Pues bien, leyendo un poco los mensajes de error y después de varias pruebas.. pude dar con la solución.&lt;br /&gt;
&lt;br /&gt;
Para comenzar, el error que lanza es el siguiente:&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;Error in annotation processing: java.lang.NoClassDefFoundError: org/springframework/transaction/PlatformTransactionManager&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
Pero si examinamos la carpeta &lt;code&gt;lib&lt;/code&gt; del módulo de liferay, sí están las bibliotecas de Spring. &lt;br /&gt;
&lt;br /&gt;
La solución a este problema es el siguiente: debemos copiar ciertas bibliotecas de Spring a la carpeta &lt;code&gt;lib&lt;/code&gt; del dominio donde está instalado el  Liferay. Para evitar conflictos de versión del Spring, copiemos los siguientes archivos .jar del .war de Liferay a &lt;code&gt;$GLASSFISH_HOME/domains/domain1/lib&lt;/code&gt;.&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;aopalliance.jar&lt;/li&gt;
&lt;li&gt;aspectj-rt.jar&lt;/li&gt;
&lt;li&gt;aspectj-weaver.jar&lt;/li&gt;
&lt;li&gt;commons-logging.jar&lt;/li&gt;
&lt;li&gt;spring-aop.jar&lt;/li&gt;
&lt;li&gt;spring-asm.jar&lt;/li&gt;
&lt;li&gt;spring-beans.jar&lt;/li&gt;
&lt;li&gt;spring-context.jar&lt;/li&gt;
&lt;li&gt;spring-core.jar&lt;/li&gt;
&lt;li&gt;spring-expression.jar&lt;/li&gt;
&lt;li&gt;spring-transaction.jar&lt;br /&gt;
&lt;/li&gt;
&lt;/ul&gt;Ahora sí, podemos desplegar portlets que contienen EJB con total normalidad.&lt;br /&gt;
&lt;br /&gt;
Pero! (no tan rápido), como las clases portlets (descendientes de &lt;code&gt;javax.portlet.GenericPortlet&lt;/code&gt;) no son parte del estándar de un módulo web, entonces no podrá utilizarse un EJB con la notación &lt;code&gt;@EJB&lt;/code&gt; (lo que sí funciona en un Servlet). Entonces ¿cómo instanciar EJB?:&lt;br /&gt;
&lt;br /&gt;
Pues habrá que utilizar el JNDI dentro del módulo, de la siguiente manera:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;
Context c = new InitialContext();
EjbFacade facade= c.lookup("java:global/NombrePorlet/NombreEjbFacade!paquete.ejb.NombreEjbFacade");
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
Algo más explicado sobre cómo acceder a las clases EJB 3.1 se encuentra en este post: &lt;a href="http://www.apuntesdejava.com/2010/05/cliente-remoto-de-ejb-31-en-glassfish.html"&gt;Cliente remoto de EJB 3.&lt;/a&gt;1&lt;br /&gt;
&lt;br /&gt;
Espero que les sea de utilidad.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8553642737291298841-8828071345448143639?l=www.apuntesdejava.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/klDOc-KRO5NwiBl9RBlApoYfw-U/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/klDOc-KRO5NwiBl9RBlApoYfw-U/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/klDOc-KRO5NwiBl9RBlApoYfw-U/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/klDOc-KRO5NwiBl9RBlApoYfw-U/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/ApuntesDeJava?a=V72AW-2RWjQ:DUBqZ5QEVBc:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ApuntesDeJava?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ApuntesDeJava?a=V72AW-2RWjQ:DUBqZ5QEVBc:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ApuntesDeJava?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ApuntesDeJava?a=V72AW-2RWjQ:DUBqZ5QEVBc:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ApuntesDeJava?i=V72AW-2RWjQ:DUBqZ5QEVBc:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ApuntesDeJava/~4/V72AW-2RWjQ" height="1" width="1"/&gt;</description><atom:updated xmlns:atom="http://www.w3.org/2005/Atom">2010-10-12T00:00:00.354-05:00</atom:updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/_BQk94ojgkDY/TLNs1u1qjeI/AAAAAAAADHc/6ryyRcfvdjc/s72-c/beans1.gif" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total><feedburner:origLink>http://www.apuntesdejava.com/2010/10/ejb-31-en-porlets-de-liferay.html</feedburner:origLink></item><item><title>Liferay: Recursos necesarios</title><link>http://feedproxy.google.com/~r/ApuntesDeJava/~3/doRa4Z5AfYQ/liferay-recursos-necesarios.html</link><category>opinion</category><category>liferay</category><author>noreply@blogger.com (Diego Silva)</author><pubDate>Fri, 08 Oct 2010 10:22:00 PDT</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-8553642737291298841.post-3747036032393464290</guid><description>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_BQk94ojgkDY/TK9Ru_VOBiI/AAAAAAAADHM/6rRg2HhfahA/s1600/corei7c.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_BQk94ojgkDY/TK9Ru_VOBiI/AAAAAAAADHM/6rRg2HhfahA/s1600/corei7c.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;Para poner en producción un servidor web con Liferay, en base a la experiencia, sugiero lo siguiente:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Memoria: 2GB. Recomendable: 4GB&lt;/li&gt;
&lt;li&gt;CPU: 2 Core. Recomendable 4&lt;/li&gt;
&lt;li&gt;Arquitectura: 32bits, Recomendable 64 bits.&lt;/li&gt;
&lt;/ul&gt;¿Por qué tanto? Recordemos que este Liferay es para portales serios, para una empresa u organización seria. Si quieren algo más simple, y más barato, usen Joomla o algo parecido.&lt;br /&gt;
&lt;br /&gt;
Otro post más sobre Liferay y hago mi blog "Apuntes de Liferay" :). También hablaré de otros contenedores de portlets, por si liferay parece muy costoso poner en producción.&lt;br /&gt;
&lt;ul&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8553642737291298841-3747036032393464290?l=www.apuntesdejava.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/mGHSxzPKuWpe3G57HY3i3CBfoe8/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/mGHSxzPKuWpe3G57HY3i3CBfoe8/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/mGHSxzPKuWpe3G57HY3i3CBfoe8/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/mGHSxzPKuWpe3G57HY3i3CBfoe8/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/ApuntesDeJava?a=doRa4Z5AfYQ:xKflZa5yuos:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ApuntesDeJava?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ApuntesDeJava?a=doRa4Z5AfYQ:xKflZa5yuos:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ApuntesDeJava?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ApuntesDeJava?a=doRa4Z5AfYQ:xKflZa5yuos:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ApuntesDeJava?i=doRa4Z5AfYQ:xKflZa5yuos:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ApuntesDeJava/~4/doRa4Z5AfYQ" height="1" width="1"/&gt;</description><atom:updated xmlns:atom="http://www.w3.org/2005/Atom">2010-10-08T12:22:19.504-05:00</atom:updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/_BQk94ojgkDY/TK9Ru_VOBiI/AAAAAAAADHM/6rRg2HhfahA/s72-c/corei7c.jpg" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">4</thr:total><feedburner:origLink>http://www.apuntesdejava.com/2010/10/liferay-recursos-necesarios.html</feedburner:origLink></item><item><title>NetBeans 7.0</title><link>http://feedproxy.google.com/~r/ApuntesDeJava/~3/-F5O-pPRsLo/netbeans-70.html</link><category>noticias</category><category>netbeans 7.0</category><category>netbeans</category><author>noreply@blogger.com (Diego Silva)</author><pubDate>Thu, 07 Oct 2010 11:51:00 PDT</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-8553642737291298841.post-4473893213766431484</guid><description>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_BQk94ojgkDY/TK4VWFA_WVI/AAAAAAAADHI/2ZMfQgswmjw/s1600/netbeans-logo.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" height="200" src="http://1.bp.blogspot.com/_BQk94ojgkDY/TK4VWFA_WVI/AAAAAAAADHI/2ZMfQgswmjw/s200/netbeans-logo.png" width="200" /&gt;&lt;/a&gt;&lt;/div&gt;La versión NetBeans 6.10 cambia de numeración para ser la 7.0.&lt;br /&gt;
Será lanzada en marzo de 2011 y tendrá importantes cambios. Ojo a la nota:&lt;br /&gt;
&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
&lt;ol&gt;&lt;li&gt;Será compatible con el JDK 7 (beta). Cuando esté terminado el JDK 7, habrá un parche para NB 7.0 que permitirá ser compatible 100% con JDK 7 (o, me imagino, saldrá NB 7.1)&lt;/li&gt;
&lt;li&gt;No se seguirá dando soporte al Lenguaje JavaFX. Por tanto, no se podrá crear proyectos JavaFX en NB 7.0.&lt;/li&gt;
&lt;li&gt;Tendrá compatibilidad con GlassFish 3.1, WebLogic, Maven 3 y Oracle DB (no sé si MySQL aún seguirá siendo parte de NB)&lt;/li&gt;
&lt;/ol&gt;Más características del futuro NetBeans 7.0 aquí: &lt;a href="http://wiki.netbeans.org/NewAndNoteworthyNB70"&gt;http://wiki.netbeans.org/NewAndNoteworthyNB70&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8553642737291298841-4473893213766431484?l=www.apuntesdejava.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/zCyq_p-JGAvs4N4fy9U24cNgL6A/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/zCyq_p-JGAvs4N4fy9U24cNgL6A/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/zCyq_p-JGAvs4N4fy9U24cNgL6A/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/zCyq_p-JGAvs4N4fy9U24cNgL6A/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/ApuntesDeJava?a=-F5O-pPRsLo:TGMPqKnYw8s:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ApuntesDeJava?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ApuntesDeJava?a=-F5O-pPRsLo:TGMPqKnYw8s:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ApuntesDeJava?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ApuntesDeJava?a=-F5O-pPRsLo:TGMPqKnYw8s:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ApuntesDeJava?i=-F5O-pPRsLo:TGMPqKnYw8s:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ApuntesDeJava/~4/-F5O-pPRsLo" height="1" width="1"/&gt;</description><atom:updated xmlns:atom="http://www.w3.org/2005/Atom">2010-10-07T13:51:05.504-05:00</atom:updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/_BQk94ojgkDY/TK4VWFA_WVI/AAAAAAAADHI/2ZMfQgswmjw/s72-c/netbeans-logo.png" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.apuntesdejava.com/2010/10/netbeans-70.html</feedburner:origLink></item><item><title>Liferay: Registrando varios usuarios (usando complemento Hook)</title><link>http://feedproxy.google.com/~r/ApuntesDeJava/~3/L3tIGRAyzhM/liferay-registrando-varios-usuarios.html</link><category>netbeans 6.9</category><category>liferay</category><category>tutorial</category><category>netbeans</category><category>portalpack</category><category>trucos</category><author>noreply@blogger.com (Diego Silva)</author><pubDate>Tue, 21 Sep 2010 23:51:00 PDT</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-8553642737291298841.post-4510006804083051112</guid><description>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_BQk94ojgkDY/TCvK71w0q5I/AAAAAAAAC-Q/o7MsXA094ws/s1600/liferay-logo.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_BQk94ojgkDY/TCvK71w0q5I/AAAAAAAAC-Q/o7MsXA094ws/s1600/liferay-logo.png" /&gt;&lt;/a&gt;&lt;/div&gt;He estado buscando alguna opción de Liferay que me permita crear varios usuarios a la vez... pero no tuve éxito. Pensé (y hasta pregunté en el foro de liferay.com) si se podía modificar directamente la base de datos. Pero como es un sistema complejo, hacer esto podría malograr el sistema.&lt;br /&gt;
&lt;br /&gt;
Entonces pensé que debería haber otra solución utilizando el API de Liferay. Al final de todo, es una plataforma, y debería existir un API completo para ello.&lt;br /&gt;
&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Bien, el API existe, pero la documentación es bastante pobre (solo echarle un vistazo al javadoc &lt;a href="http://docs.liferay.com/portal/6.0/javadocs/"&gt;http://docs.liferay.com/portal/6.0/javadocs/&lt;/a&gt; no tiene ni una descripción de alguna clase.. al menos sirve para saber qué clases tiene el API)&lt;br /&gt;
&lt;br /&gt;
Encontré en el wiki de Liferay sobre el desarrollo de extensiones para el Portal, y este me pareció interesante: &lt;a href="http://www.liferay.com/community/wiki/-/wiki/Main/Portal+Hook+Plugins"&gt;http://www.liferay.com/community/wiki/-/wiki/Main/Portal+Hook+Plugins&lt;/a&gt;. Habla de manera general para qué sirven los Hooks dentro de Liferay y muestran algunos ejemplos.&lt;br /&gt;
&lt;br /&gt;
En líneas generales, los hooks son complementos que modifican el comportamiento del liferay. Hay de tres tipos:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Los que se ejecutan al inicio del portal&lt;/li&gt;
&lt;li&gt;Los eventos de inicio de sesión, y&lt;/li&gt;
&lt;li&gt;Los eventos de servicios.&lt;/li&gt;
&lt;/ul&gt;Como mi caso es crear usuarios masivamente, me corresponde crear un Hook cuando se ejecute el liferay. Otros ejemplos de Hook (como el de inicio de sesión) se puede encontrar en Adictosaltrabajo.com: &lt;a href="http://www.adictosaltrabajo.com/tutoriales/tutoriales.php?pagina=LiferayHookPlugin"&gt;http://www.adictosaltrabajo.com/tutoriales/tutoriales.php?pagina=LiferayHookPlugin&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
En varios tutoriales explican que debería bajarse el Kit de desarrollo (SDK) de Complementos de Liferay. Pero no se preocupen, NetBeans con el PortalPack ya nos ahorra bastante este trabajo. Así que manos a la obra.&lt;br /&gt;
&lt;h3&gt;Requisitos&lt;/h3&gt;Para este tutorial utilicé lo siguiente:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;NetBeans 6.9.1 con JDK 6.0u21&lt;/li&gt;
&lt;li&gt;PortalPack 3.0.4 (Descargable desde aquí: &lt;a href="http://contrib.netbeans.org/portalpack/pp30/download304.html"&gt;http://contrib.netbeans.org/portalpack/pp30/download304.html&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Liferay 6.0.5 en Tomcat 6.0 (Descargable desde aquí: &lt;a href="http://sourceforge.net/projects/lportal/files/Liferay%20Portal/6.0.5/liferay-portal-tomcat-6.0.5.zip/download"&gt;http://sourceforge.net/projects/lportal/files/Liferay%20Portal/6.0.5/liferay-portal-tomcat-6.0.5.zip/download&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;Si quieres saber cómo configurar el Liferay con el NetBeans, te recomiendo mi anterior post: &lt;a href="http://www.apuntesdejava.com/2010/07/nuestro-primer-portlet-en-liferay.html"&gt;Nuestro primer portlet en Liferay&lt;/a&gt;. Aunque se explica utilizando el Liferay + GlassFish, el agregar el servidor Liferay al NetBeans es el mismo procedimiento.&lt;br /&gt;
&lt;h3&gt;Creando el proyecto Hook&lt;/h3&gt;La creación de un proyecto hook en NetBeans es bien simple: consiste en crear un proyecto web común y corriente. A este le llamaremos "CrearUsuarios-hook"&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_BQk94ojgkDY/TJmMAL1Ss-I/AAAAAAAADGA/RA66kVFiIbE/s1600/hook01.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="440" src="http://2.bp.blogspot.com/_BQk94ojgkDY/TJmMAL1Ss-I/AAAAAAAADGA/RA66kVFiIbE/s640/hook01.jpg" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
Luego, escogemos el tipo de servidor que queremos utilizar. Naturalmente debemos escoger el Liferay, ya que con esto el NetBeans nos agregará las bibliotecas necesarias para nuestro proyecto.&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_BQk94ojgkDY/TJmNyrbMhaI/AAAAAAAADGE/qa5-DZLPjgs/s1600/hook02.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="411" src="http://1.bp.blogspot.com/_BQk94ojgkDY/TJmNyrbMhaI/AAAAAAAADGE/qa5-DZLPjgs/s640/hook02.jpg" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
Y en este paso, hacer clic en "Finish" sin crear ningún portlet.. porque lo que vamos a hacer es un Complemento Hook, no un Portlet.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;Creando el complemento Hook&lt;/h3&gt;Bien, hasta ahora solo hemos creado el espacio de trabajo. Ahora crearemos el Hook como si fuera un archivo más. Entramos a File &amp;gt; New File y seleccionamos en la categoría "WebSpace/Liferay Plugins" el tipo de archivo "Hook Plugin"&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_BQk94ojgkDY/TJmQwxdYr0I/AAAAAAAADGI/gLDIr_D_ciY/s1600/hook03.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="441" src="http://4.bp.blogspot.com/_BQk94ojgkDY/TJmQwxdYr0I/AAAAAAAADGI/gLDIr_D_ciY/s640/hook03.jpg" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
Después de hacer clic en "Next", especificamos qué tipo de Hook es el que vamos a crear. Como queremos que se ejecute al inicio del Portal, seleccionamos en "Event Type" el valor "application.startup.events". El nombre de la clase será &lt;code&gt;CrearUsuariosHookAction&lt;/code&gt; en el paquete &lt;code&gt;hook&lt;/code&gt;. &lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_BQk94ojgkDY/TJmQx7FuFUI/AAAAAAAADGM/-i5rdxPTk2k/s1600/hook04.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="473" src="http://2.bp.blogspot.com/_BQk94ojgkDY/TJmQx7FuFUI/AAAAAAAADGM/-i5rdxPTk2k/s640/hook04.jpg" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
Clic en Finish y listo.. ya tenemos nuestra clase en blanco listo para llenar.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_BQk94ojgkDY/TJmQzIRn_UI/AAAAAAAADGQ/f2qngdWmf2w/s1600/hook05.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="547" src="http://1.bp.blogspot.com/_BQk94ojgkDY/TJmQzIRn_UI/AAAAAAAADGQ/f2qngdWmf2w/s640/hook05.jpg" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;Registrando los usuarios&lt;/h3&gt;Como les comenté al inicio, la documentación es bastante pobre. Creo que es por la cantidad de clases que contiene. Pero no hay problema. Ya existe un ejemplo (también, sin documentación) de cómo utilizar el API de Liferay. Su nombre es &lt;code&gt;sevencogs-hook&lt;/code&gt; y está disponible en la página del proyecto Liferay en sourceforge.net. Aquí están los archivos:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Ejemplo para Liferay 5.2.x: &lt;a href="http://sourceforge.net/projects/lportal/files/Liferay%20Plugins/5.2.2/sevencogs-hook-5.2.2.1.war/download"&gt;http://sourceforge.net/projects/lportal/files/Liferay%20Plugins/5.2.2/sevencogs-hook-5.2.2.1.war/download&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Ejemplo para Liferay 6.0.x:&amp;nbsp; &lt;a href="http://sourceforge.net/projects/lportal/files/Liferay%20Plugins/6.0.5/sevencogs-hook-6.0.5.1.war/download"&gt;http://sourceforge.net/projects/lportal/files/Liferay%20Plugins/6.0.5/sevencogs-hook-6.0.5.1.war/download&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;Mi opinión es que el ejemplo de Liferay 5.2 es el más claro.&lt;br /&gt;
&lt;br /&gt;
Por si causa confusión donde encontrar el ejemplo exacto, el código fuente del Hook son los siguientes:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Versión 5.2:&amp;nbsp; &lt;a href="http://kenai.com/projects/apuntes/downloads/download/ejemplos%252Fliferay%252FStartupAction.java"&gt;http://kenai.com/projects/apuntes/downloads/download/ejemplos%252Fliferay%252FStartupAction.java&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Versión 6.0: &lt;a href="http://kenai.com/projects/apuntes/downloads/download/ejemplos%252Fliferay%252FUpgradeCompany.java"&gt;http://kenai.com/projects/apuntes/downloads/download/ejemplos%252Fliferay%252FUpgradeCompany.java&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
El código es bastante entendible. Basta entender las variables utilizadas. Aquí muestro mi código que es compatible con Liferay 6&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;
    private void doRun(long companyId) {

        try {
            String firstName = "Diego";
            String lastName = "Silva";
            boolean male = true;
            String jobTitle = "Consultor Java";
            String screenName = "diego.silva";
            long creatorUserId = 0;
            long facebookId = 0;
            boolean autoPassword = false;
            String password1 = screenName;
            String password2 = password1;
            boolean autoScreenName = false;
            String emailAddress = screenName + "@apuntesdejava.com";
            String openId = StringPool.BLANK;
            Locale locale = new Locale("ES", "PE");
            String middleName = StringPool.BLANK;
            int prefixId = 0;
            int suffixId = 0;
            int birthdayMonth = Calendar.MARCH;
            int birthdayDay = 27;
            int birthdayYear = 1976;
            Country country = CountryServiceUtil.getCountryByA2("PE");
            long countryId = country.getCountryId();
            long regionId = 0;
            Group guestGroup = GroupLocalServiceUtil.getGroup(companyId, GroupConstants.GUEST);
            long[] groupIds = new long[]{guestGroup.getGroupId()};
            long[] userGroupIds = null;
            boolean sendEmail = false;
            Role adminRole = RoleLocalServiceUtil.getRole(
                    companyId, RoleConstants.ADMINISTRATOR);

            Role powerUserRole = RoleLocalServiceUtil.getRole(
                    companyId, RoleConstants.POWER_USER);
            long[] roleIds = new long[]{
                adminRole.getRoleId(), powerUserRole.getRoleId()
            };
            int statusId = GetterUtil.getInteger(PropsUtil.get("sql.data.com.liferay.portal.model.ListType.organization.status"));
            String comments = null;
            ServiceContext serviceContext = null;
            System.out.print("Creando organización...");
            //creando la organización
            long userId=UserLocalServiceUtil.getDefaultUserId(companyId);
            long parentOrganizationId =
   OrganizationConstants.DEFAULT_PARENT_ORGANIZATION_ID;
            boolean recursable = true;
            Organization apuntesOrganization = OrganizationLocalServiceUtil.addOrganization(userId, parentOrganizationId, "Apuntes de Java",
                    OrganizationConstants.TYPE_REGULAR_ORGANIZATION,
                    recursable, regionId, countryId, statusId,
                    comments, serviceContext);
            long[] organizationIds = new long[]{apuntesOrganization.getOrganizationId()};
            System.out.println("... registrado con ID:"+apuntesOrganization.getOrganizationId());
            //registrando el usuario
            System.out.print("Creando usuario...");
            User user = UserLocalServiceUtil.addUser(creatorUserId, companyId,
                    autoPassword, password1, password2,
                    autoScreenName, screenName, emailAddress, facebookId,
                    openId, locale,
                    firstName, middleName, lastName,
                    prefixId, suffixId, male, birthdayMonth,
                    birthdayDay, birthdayYear,
                    jobTitle, groupIds, organizationIds,
                    roleIds, userGroupIds, sendEmail, serviceContext);
            System.out.println("... creado con ID:"+user.getUserId());
        } catch (PortalException ex) {
            LOGGER.log(Level.SEVERE, null, ex);
        } catch (SystemException ex) {
            LOGGER.log(Level.SEVERE, null, ex);
        }
    }
&lt;/code&gt;&lt;/pre&gt;Aquí se ve que se ha creado una organización nueva llamada "Apuntes de Java" y el usuario que es perteneciente a ella.&lt;br /&gt;
&lt;br /&gt;
La diferencia con Liferay 5, es que en el 6 hay un nuevo parámetro llamado facebookId. Todos los demás campos son iguales. Así que considere esta característica cuando hagas un Hook de crear usuarios en Liferay 5 o 6.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;Ejecutando el proyecto&lt;/h3&gt;Desde nuestro IDE bastará con ejecutar el proyecto y esperar que se despliegue en el servidor local.&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_BQk94ojgkDY/TJmmXfT277I/AAAAAAAADGc/EMtGnmkuWRU/s1600/hook06.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="225" src="http://4.bp.blogspot.com/_BQk94ojgkDY/TJmmXfT277I/AAAAAAAADGc/EMtGnmkuWRU/s320/hook06.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
Y aquí vemos la organización creada...&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_BQk94ojgkDY/TJmmX7yRYKI/AAAAAAAADGg/CSZz0FswTuM/s1600/hook07.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="312" src="http://4.bp.blogspot.com/_BQk94ojgkDY/TJmmX7yRYKI/AAAAAAAADGg/CSZz0FswTuM/s640/hook07.jpg" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
Y el usuario creado...&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_BQk94ojgkDY/TJmmYTwXsJI/AAAAAAAADGk/50qBPypFKIo/s1600/hook08.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="420" src="http://2.bp.blogspot.com/_BQk94ojgkDY/TJmmYTwXsJI/AAAAAAAADGk/50qBPypFKIo/s640/hook08.jpg" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
Para crear varios usuarios, bastará con repetir la misma operación con cada uno de ellos. O si se desea importar de una tabla preexistente, consideren hacer una conexión por JDBC a la base de datos donde se tienen los usuarios a cargar, y dentro de un &lt;code&gt;while (rs.next())&lt;/code&gt; llamar al método &lt;code&gt;UserLocalServiceUtil.addUser()&lt;/code&gt;&lt;br /&gt;
&lt;h3&gt;Desplegando en servidor de producción&lt;/h3&gt;Para ponerlo en producción, primero debemos construir el .war. Esto es simple, basta con darle clic derecho al ícono del proyecto y seleccionar &lt;code&gt;build&lt;/code&gt;. Con esto nos generará el archivo .war listo para desplegarlo en el servidor.&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_BQk94ojgkDY/TJmmY1tkVpI/AAAAAAAADGo/Psu7aJA3FCg/s1600/hook09.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="142" src="http://4.bp.blogspot.com/_BQk94ojgkDY/TJmmY1tkVpI/AAAAAAAADGo/Psu7aJA3FCg/s320/hook09.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
Hay dos maneras para desplegarlo en un servidor en producción. Una es utilizando el ControlPanel de Liferay y utilizar la opción "Instalar complemento", seleccionamos el archivo .war e instalarlo.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_BQk94ojgkDY/TJmmVY4ACNI/AAAAAAAADGU/E47RKWFu9Ro/s1600/hook10.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="227" src="http://1.bp.blogspot.com/_BQk94ojgkDY/TJmmVY4ACNI/AAAAAAAADGU/E47RKWFu9Ro/s320/hook10.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
La otra es copiar el archivo .war en el directorio &lt;code&gt;deploy&lt;/code&gt; que se encuenrta dentro del directorio instalado de Liferay.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;Código fuente&lt;/h3&gt;Y no podía faltar el código fuente del proyecto utilizado para este tutorial:&lt;br /&gt;
&lt;a href="http://kenai.com/projects/apuntes/downloads/download/ejemplos%252Fliferay%252FCrearUsuarios-hook.tar.gz"&gt;http://kenai.com/projects/apuntes/downloads/download/ejemplos%252Fliferay%252FCrearUsuarios-hook.tar.gz&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
¡Que les sea de utilidad!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8553642737291298841-4510006804083051112?l=www.apuntesdejava.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/PBq8TPhII3VA4HA1Xe9vgPRCPB8/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/PBq8TPhII3VA4HA1Xe9vgPRCPB8/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/PBq8TPhII3VA4HA1Xe9vgPRCPB8/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/PBq8TPhII3VA4HA1Xe9vgPRCPB8/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/ApuntesDeJava?a=L3tIGRAyzhM:Bm7TXhfJqXM:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ApuntesDeJava?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ApuntesDeJava?a=L3tIGRAyzhM:Bm7TXhfJqXM:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ApuntesDeJava?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ApuntesDeJava?a=L3tIGRAyzhM:Bm7TXhfJqXM:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ApuntesDeJava?i=L3tIGRAyzhM:Bm7TXhfJqXM:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ApuntesDeJava/~4/L3tIGRAyzhM" height="1" width="1"/&gt;</description><atom:updated xmlns:atom="http://www.w3.org/2005/Atom">2010-11-04T13:10:43.763-05:00</atom:updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/_BQk94ojgkDY/TCvK71w0q5I/AAAAAAAAC-Q/o7MsXA094ws/s72-c/liferay-logo.png" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">8</thr:total><feedburner:origLink>http://www.apuntesdejava.com/2010/09/liferay-registrando-varios-usuarios.html</feedburner:origLink></item><item><title>mysqldump: ignorando el tag DEFINER</title><link>http://feedproxy.google.com/~r/ApuntesDeJava/~3/HddP54eeaSI/mysqldump-ignorando-el-tag-definer.html</link><category>mysql</category><category>tips</category><category>trucos</category><author>noreply@blogger.com (Diego Silva)</author><pubDate>Thu, 16 Sep 2010 15:16:00 PDT</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-8553642737291298841.post-6814185807138443482</guid><description>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_BQk94ojgkDY/TJKR48JW0uI/AAAAAAAADF8/uKByTSJlSC4/s1600/logo-mysql-110x57.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_BQk94ojgkDY/TJKR48JW0uI/AAAAAAAADF8/uKByTSJlSC4/s1600/logo-mysql-110x57.png" /&gt;&lt;/a&gt;&lt;/div&gt;Este es otro no-apunte-de-java. Se trata del MySQL.&lt;br /&gt;
Resulta que he tratado de hacer un dump de un servidor a otro. Pero como tienen usuarios restringidos por host, y el &lt;code&gt;mysqldump&lt;/code&gt; me genera el script con el tag&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;
/*!50013 DEFINER=`root`@`10.%` SQL SECURITY DEFINER */
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
... pensé que debería haber algún parámetro de &lt;code&gt;mysqldump&lt;/code&gt; para ignorar estos tags. Pero según el mismo MySQL dicen que tendría &lt;a href="http://bugs.mysql.com/bug.php?id=24680"&gt;problemas de seguridad&lt;/a&gt; (vamos: darle derechos de pasar un VIEW o STORED PROCEDURE a alguien que no le corresponde).&lt;br /&gt;
&lt;br /&gt;
Así que tuve que valerme de un comando de unix/linux para ignorar estos tag:&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
Este comando es el famoso &lt;a href="http://www.gnu.org/software/grep/"&gt;&lt;code&gt;grep&lt;/code&gt;&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Y aquí está mi &lt;code&gt;mysqldump&lt;/code&gt; modificado:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;
mysqldump -u root -p -B  db100 | grep -v 'DEFINER' &amp;gt; dump.sql
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
Espero que les sea de utilidad.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8553642737291298841-6814185807138443482?l=www.apuntesdejava.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/2JHlBjKoEiB3vqq6bUtPg6oWwR4/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/2JHlBjKoEiB3vqq6bUtPg6oWwR4/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/2JHlBjKoEiB3vqq6bUtPg6oWwR4/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/2JHlBjKoEiB3vqq6bUtPg6oWwR4/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/ApuntesDeJava?a=HddP54eeaSI:tK-gKElPugk:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ApuntesDeJava?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ApuntesDeJava?a=HddP54eeaSI:tK-gKElPugk:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ApuntesDeJava?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ApuntesDeJava?a=HddP54eeaSI:tK-gKElPugk:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ApuntesDeJava?i=HddP54eeaSI:tK-gKElPugk:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ApuntesDeJava/~4/HddP54eeaSI" height="1" width="1"/&gt;</description><atom:updated xmlns:atom="http://www.w3.org/2005/Atom">2010-09-16T17:16:19.325-05:00</atom:updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/_BQk94ojgkDY/TJKR48JW0uI/AAAAAAAADF8/uKByTSJlSC4/s72-c/logo-mysql-110x57.png" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.apuntesdejava.com/2010/09/mysqldump-ignorando-el-tag-definer.html</feedburner:origLink></item><item><title>Enmulando EJB en Web usando Spring</title><link>http://feedproxy.google.com/~r/ApuntesDeJava/~3/AbBClyC692g/enmulando-ejb-en-web-usando-spring.html</link><category>java</category><category>ejb</category><category>spring</category><category>tutorial</category><category>web</category><category>ejb 3.1</category><author>noreply@blogger.com (Diego Silva)</author><pubDate>Tue, 14 Sep 2010 08:33:00 PDT</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-8553642737291298841.post-5975542560702640080</guid><description>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_BQk94ojgkDY/TI-HUsqPqtI/AAAAAAAADFs/D_QnvHH3MJU/s1600/spring.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_BQk94ojgkDY/TI-HUsqPqtI/AAAAAAAADFs/D_QnvHH3MJU/s1600/spring.png" /&gt;&lt;/a&gt;&lt;/div&gt;Cuando salió el EJB 3.1 con la capacidad de poderse ejecutar en un módulo web, comencé a usarlo sin parar. Con los EJB me hace más fácil conectarme a la base de datosusando JPA porque simplemente debería usar&amp;nbsp;&lt;code&gt; &lt;/code&gt;&lt;code&gt;@PersistenceContext&lt;/code&gt; respectivamente.&lt;br /&gt;
&lt;br /&gt;
Pero no todos los servidores&amp;nbsp; donde uno va a desplegar aplicaciones son Java EE6, así que las facilidades del EJB 3.1 serían truncadas.&lt;br /&gt;
&lt;br /&gt;
Afortunadamente existe Spring para ayudarnos a instanciar clases como si fueran EJB, y más aún, nos permite usar JPA y mantener las notaciones&amp;nbsp;&lt;code&gt;&lt;/code&gt;  &lt;code&gt;@PersistenceContext&lt;/code&gt;.&lt;br /&gt;
&lt;br /&gt;
Veamos cómo se hace esto.&lt;br /&gt;
&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;Para comenzar, debemos considerar que existe nuestro archivo &lt;code&gt;persistence.xml&lt;/code&gt; con la conexión a la base de datos. Para este ejemplo estoy usan la base de datos &lt;code&gt;sample&lt;/code&gt; que viene en el JavaDB. &lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;
&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;
&amp;lt;persistence version="1.0" 
   xmlns="http://java.sun.com/xml/ns/persistence" 
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
   xsi:schemaLocation="http://java.sun.com/xml/ns/persistence 
                       http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"&amp;gt;
  &amp;lt;persistence-unit name="EjbSpringWebPU" transaction-type="JTA"&amp;gt;
    &amp;lt;jta-data-source&amp;gt;jdbc/sample&amp;lt;/jta-data-source&amp;gt;
    &amp;lt;exclude-unlisted-classes&amp;gt;false&amp;lt;/exclude-unlisted-classes&amp;gt;
    &amp;lt;properties/&amp;gt;
  &amp;lt;/persistence-unit&amp;gt;
&amp;lt;/persistence&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
Nuestros "Facade" que funcionarán como los EJB, será casi como un EJB, con todo la notación de persistencia:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;
public class DiscountCodeFacade {

    @PersistenceContext(unitName = "EjbSpringWebPU")
    private EntityManager em;

    public List&amp;lt;DiscountCode&amp;gt; getDiscountCodes() {
        Query query = em.createQuery("select o from DiscountCode o");
        return query.getResultList();
    }
}&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
Hasta aquí, todo normal. Ahora, necesitamos instanciar este facade y que ya tenga la conexión a la persistencia. Bueno, en Spring se tiene que hacer esto:&lt;br /&gt;
&lt;br /&gt;
Instanciar la persistencia:&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;
    &amp;lt;bean id="EjbSpringWebPU" class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean"&amp;gt;
        &amp;lt;property name="persistenceUnitName" value="EjbSpringWebPU"/&amp;gt;
    &amp;lt;/bean&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
Luego, decirle que ejecute todas las notaciones que se solicitarán en las siguientes clases:&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;
    &amp;lt;bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
Para terminar, instanciar el Facade:&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;
    &amp;lt;bean id="DiscountCodeFacade" class="service.DiscountCodeFacade" /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
Y listo, ya se puede utilizar casi como un EJB:&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;
DiscountCodeFacade facade=ServiceFactory.getInstance().getDiscountCodeFacade();
List&amp;lt;DiscountCode&amp;gt; discountCodes = facade.getDiscountCodes();
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
El proyecto utilizado para este post se encuentra aquí:&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://java.net/downloads/apuntes/samples/web/EjbSpringWeb.tar.gz"&gt;https://java.net/downloads/apuntes/samples/web/EjbSpringWeb.tar.gz&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8553642737291298841-5975542560702640080?l=www.apuntesdejava.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/ETQlYsZXRjdEcNfqt-AUdp2NQxs/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ETQlYsZXRjdEcNfqt-AUdp2NQxs/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/ETQlYsZXRjdEcNfqt-AUdp2NQxs/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ETQlYsZXRjdEcNfqt-AUdp2NQxs/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/ApuntesDeJava?a=AbBClyC692g:2JUSXLIpVAA:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ApuntesDeJava?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ApuntesDeJava?a=AbBClyC692g:2JUSXLIpVAA:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ApuntesDeJava?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ApuntesDeJava?a=AbBClyC692g:2JUSXLIpVAA:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ApuntesDeJava?i=AbBClyC692g:2JUSXLIpVAA:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ApuntesDeJava/~4/AbBClyC692g" height="1" width="1"/&gt;</description><atom:updated xmlns:atom="http://www.w3.org/2005/Atom">2011-03-07T10:17:53.814-05:00</atom:updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/_BQk94ojgkDY/TI-HUsqPqtI/AAAAAAAADFs/D_QnvHH3MJU/s72-c/spring.png" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total><feedburner:origLink>http://www.apuntesdejava.com/2010/09/enmulando-ejb-en-web-usando-spring.html</feedburner:origLink></item></channel></rss>

