<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-8553642737291298841</id><updated>2012-01-25T12:49:52.638-05:00</updated><category term='logging'/><category term='swing'/><category term='web'/><category term='netbeans 7.0'/><category term='bug'/><category term='seguridad'/><category term='junit'/><category term='articulos'/><category term='netbeans 6.5'/><category term='presentacion'/><category term='scjp'/><category term='firefox'/><category term='liferay'/><category term='concurso'/><category term='facelets'/><category term='libros'/><category term='ejb'/><category term='spring'/><category term='ejb 3.1'/><category term='tips'/><category term='tiles'/><category term='sun'/><category term='video'/><category term='eclipse'/><category term='errores'/><category term='conferencias'/><category term='chiste'/><category term='xml'/><category term='jsf'/><category term='mysql'/><category term='java'/><category term='portalpack'/><category term='java 7'/><category term='webservices'/><category term='jdk'/><category term='webinar'/><category term='formateo'/><category term='restful'/><category term='aop'/><category term='jstl'/><category term='oracle'/><category term='curso'/><category term='java ee 6'/><category term='RCP'/><category term='jasperreports'/><category term='struts'/><category term='desktop'/><category term='opinion'/><category term='jpa'/><category term='groovy'/><category term='weblogic'/><category term='ubuntu'/><category term='plugins'/><category term='comentarios'/><category term='error'/><category term='base de datos'/><category term='bugzilla'/><category term='reportes'/><category term='juegos'/><category term='encuesta'/><category term='jsf 2.0'/><category term='datasource'/><category term='wiki'/><category term='portlets'/><category term='jdbc'/><category term='netbeans 6.8'/><category term='javascript'/><category term='jfreechart'/><category term='glassfish'/><category term='tomcat'/><category term='netbeans 6.1'/><category term='youtube'/><category term='NetBeans Platform'/><category term='trucos'/><category term='commons'/><category term='ICEfaces'/><category term='netbeans 6.7'/><category term='ireport'/><category term='internet'/><category term='windows'/><category term='cdi'/><category term='java ee'/><category term='off topic'/><category term='java se6'/><category term='linux'/><category term='apache'/><category term='ibatis'/><category term='javafx'/><category term='ant'/><category term='php'/><category term='ajax'/><category term='tutorial'/><category term='jsp'/><category term='jdk 7'/><category term='documentacion'/><category term='jpa 2.0'/><category term='libraries'/><category term='netbeans'/><category term='glassfish v3'/><category term='log4j'/><category term='jquery'/><category term='noticias NetBeans'/><category term='tutorial java'/><category term='sql'/><category term='servlets'/><category term='noticias'/><category term='dao'/><category term='server'/><category term='eventos'/><category term='programador'/><category term='netbeans 6.9'/><title type='text'>Apuntes de Java</title><subtitle type='html'>&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;</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://www.apuntesdejava.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8553642737291298841/posts/default?orderby=updated'/><link rel='alternate' type='text/html' href='http://www.apuntesdejava.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/8553642737291298841/posts/default?start-index=26&amp;max-results=25&amp;orderby=updated'/><author><name>Diego Silva</name><uri>https://profiles.google.com/107299481207026512440</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>257</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-8553642737291298841.post-5210570521090499526</id><published>2011-12-29T13:20:00.002-05:00</published><updated>2011-12-29T13:20:09.532-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='plugins'/><category scheme='http://www.blogger.com/atom/ns#' term='tips'/><category scheme='http://www.blogger.com/atom/ns#' term='netbeans 7.0'/><category scheme='http://www.blogger.com/atom/ns#' term='netbeans'/><title type='text'>Un par de regalos para finalizar el año: Plugins para NetBeans</title><content type='html'>&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;</content><link rel='replies' type='application/atom+xml' href='http://www.apuntesdejava.com/feeds/5210570521090499526/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.apuntesdejava.com/2011/12/un-par-de-regalos-para-finalizar-el-ano.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8553642737291298841/posts/default/5210570521090499526'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8553642737291298841/posts/default/5210570521090499526'/><link rel='alternate' type='text/html' href='http://www.apuntesdejava.com/2011/12/un-par-de-regalos-para-finalizar-el-ano.html' title='Un par de regalos para finalizar el año: Plugins para NetBeans'/><author><name>Diego Silva</name><uri>https://profiles.google.com/107299481207026512440</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><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>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8553642737291298841.post-8696555616974813009</id><published>2011-09-26T07:00:00.000-05:00</published><updated>2011-09-26T07:00:15.276-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='java ee'/><category scheme='http://www.blogger.com/atom/ns#' term='netbeans 7.0'/><category scheme='http://www.blogger.com/atom/ns#' term='netbeans'/><category scheme='http://www.blogger.com/atom/ns#' term='java ee 6'/><category scheme='http://www.blogger.com/atom/ns#' term='aop'/><title type='text'>AOP con Java EE 6</title><content type='html'>&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;&lt;br /&gt;&lt;br /&gt;import java.lang.reflect.Method;&lt;br /&gt;import java.util.logging.Level;&lt;br /&gt;import java.util.logging.Logger;&lt;br /&gt;import javax.interceptor.AroundInvoke;&lt;br /&gt;import javax.interceptor.InvocationContext;&lt;br /&gt;&lt;br /&gt;public class MonitoreoInterceptor {&lt;br /&gt;    static final Logger LOGGER=Logger.getLogger(MonitoreoInterceptor.class.getName()); //para mostrar el log&lt;br /&gt;    &lt;br /&gt;    @AroundInvoke //Define un método interceptor que se interpondrá en los métodos del EJB&lt;br /&gt;    public Object seguimientoMetodo(InvocationContext invocationContext) throws Exception{&lt;br /&gt;        Object objetoInterceptado=invocationContext.getTarget();&lt;br /&gt;        Method metodoInterceptado=invocationContext.getMethod();&lt;br /&gt;        // para mostrar el metodo que se va a ejecutar&lt;br /&gt;        LOGGER.log(Level.INFO, "Ejecutando m\u00e9todo: {0}.{1}()", &lt;br /&gt;                new Object[]{objetoInterceptado.getClass().getName(), metodoInterceptado.getName()});&lt;br /&gt;        &lt;br /&gt;        Object o=invocationContext.proceed(); //hacemos ejecutar el método, o si hay otro interceptor, le damos la posta&lt;br /&gt;        // la variable devuelta es el resultado del método, o NULL si es un método VOID&lt;br /&gt;        &lt;br /&gt;        LOGGER.log(Level.INFO, "Saliendo del m\u00e9todo: {0}.{1}()", &lt;br /&gt;                new Object[]{objetoInterceptado.getClass().getName(), metodoInterceptado.getName()});&lt;br /&gt;        &lt;br /&gt;        LOGGER.log(Level.INFO, "EL m\u00e9todo devuelve el valor: {0}", o);&lt;br /&gt;        &lt;br /&gt;        return o; //que continue la secuencia&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&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;&lt;br /&gt;&lt;br /&gt;import com.apuntesdejava.aop.ejb.domain.Persona;&lt;br /&gt;import com.apuntesdejava.aop.ejb.interceptor.MonitoreoInterceptor;&lt;br /&gt;import java.util.ArrayList;&lt;br /&gt;import java.util.List;&lt;br /&gt;import javax.ejb.Stateless;&lt;br /&gt;import javax.interceptor.Interceptors;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;@Stateless&lt;br /&gt;public class PersonaFacade {&lt;br /&gt;&lt;br /&gt;    private static List&amp;lt;Persona&amp;gt; personas = new ArrayList&amp;lt;Persona&amp;gt;();&lt;br /&gt;&lt;br /&gt;    @Interceptors({MonitoreoInterceptor.class}) //le colocamos un conjunto de interceptores&lt;br /&gt;    public void nuevo(Persona p) { //el método es uno común y corriente.&lt;br /&gt;        personas.add(p);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    @Interceptors({MonitoreoInterceptor.class})// tambien le colocamos un conjunto de interceptores&lt;br /&gt;    public List&amp;lt;Persona&amp;gt; lista() { //este método devuelve algo&lt;br /&gt;        return personas;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&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;//...&lt;br /&gt;@WebServlet(name = "ListaServlet", urlPatterns = {"/ListaServlet"})&lt;br /&gt;public class ListaServlet extends HttpServlet {&lt;br /&gt;&lt;br /&gt;    @EJB&lt;br /&gt;    private PersonaFacade personaFacade;&lt;br /&gt;&lt;br /&gt;    protected void processRequest(HttpServletRequest request, HttpServletResponse response)&lt;br /&gt;            throws ServletException, IOException {&lt;br /&gt;        List&amp;lt;Persona&amp;gt; lista = personaFacade.lista();&lt;br /&gt;        request.setAttribute("lista", lista);&lt;br /&gt;        RequestDispatcher rd = request.getRequestDispatcher("/lista.jsp");&lt;br /&gt;        rd.forward(request, response);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;//...&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;//...&lt;br /&gt;public class Main {&lt;br /&gt;&lt;br /&gt;    @EJB&lt;br /&gt;    private static PersonaFacadeRemote personaFacade;&lt;br /&gt;&lt;br /&gt;    /**&lt;br /&gt;     * @param args the command line arguments&lt;br /&gt;     */&lt;br /&gt;    public static void main(String[] args) {&lt;br /&gt;        Persona p1 = new Persona(1, "Ana");&lt;br /&gt;        Persona p2 = new Persona(1, "Bernardo");&lt;br /&gt;        Persona p3 = new Persona(1, "Carl");&lt;br /&gt;        personaFacade.nuevo(p1);&lt;br /&gt;        personaFacade.nuevo(p2);&lt;br /&gt;        personaFacade.nuevo(p3);&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&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;</content><link rel='replies' type='application/atom+xml' href='http://www.apuntesdejava.com/feeds/8696555616974813009/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.apuntesdejava.com/2011/09/aop-con-java-ee-6.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8553642737291298841/posts/default/8696555616974813009'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8553642737291298841/posts/default/8696555616974813009'/><link rel='alternate' type='text/html' href='http://www.apuntesdejava.com/2011/09/aop-con-java-ee-6.html' title='AOP con Java EE 6'/><author><name>Diego Silva</name><uri>https://profiles.google.com/107299481207026512440</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><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>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8553642737291298841.post-5985561723078948493</id><published>2011-09-21T10:17:00.001-05:00</published><updated>2011-09-21T10:17:49.456-05:00</updated><title type='text'>Premios Open Source 2011</title><content type='html'>&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;</content><link rel='replies' type='application/atom+xml' href='http://www.apuntesdejava.com/feeds/5985561723078948493/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.apuntesdejava.com/2011/09/premios-open-source-2011.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8553642737291298841/posts/default/5985561723078948493'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8553642737291298841/posts/default/5985561723078948493'/><link rel='alternate' type='text/html' href='http://www.apuntesdejava.com/2011/09/premios-open-source-2011.html' title='Premios Open Source 2011'/><author><name>Diego Silva</name><uri>https://profiles.google.com/107299481207026512440</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8553642737291298841.post-839279860302462651</id><published>2009-11-27T10:22:00.000-05:00</published><updated>2011-09-20T10:52:56.968-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='conferencias'/><title type='text'>Java Day en la UNI - agradecimientos</title><content type='html'>Anoche se realizó el Java Day en la UNI, donde se expusieron interesantes temas respecto a la tecnología Java, los frameworks (como Spring MVC, Spring ROO) que apoyan enormemente al desarrollo de aplicaciones, las tendencias del desarrollo de sistemas basados en SOA, y más. Fue realmente impresionante.&lt;br /&gt;&lt;br /&gt;Solo que el tiempo no nos dió para más. Habían muchos temas que se quedaron en el tintero.&lt;br /&gt;&lt;br /&gt;Agradezco a &lt;a href="http://jocluisuni.blogspot.com/"&gt;José Luis Casiano&lt;/a&gt; por haberme invitado como expositor a este evento. Estuvo todo organizado... y (como le dije).. su tranquilidad me desesperaba. Otras personas estarían golpeándose la cabeza o gritando cuando algo no habría salido como espera.. pero José Luis mantuvo la calma de un cirujano en plena operación.&lt;br /&gt;&lt;br /&gt;Los que no pudieron ir ayer al evento, aquí les dejo mi presentación sobre Java EE6.&lt;br /&gt;&lt;div style="width:425px;text-align:left" id="__ss_2596960"&gt;&lt;a style="font:14px Helvetica,Arial,Sans-serif;display:block;margin:12px 0 3px 0;text-decoration:underline;" href="http://www.slideshare.net/diesil/lo-nuevo-de-java-ee6" title="Lo nuevo de Java EE6"&gt;Lo nuevo de Java EE6&lt;/a&gt;&lt;object style="margin:0px" width="425" height="355"&gt;&lt;param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=javaee6-091127091418-phpapp01&amp;stripped_title=lo-nuevo-de-java-ee6" /&gt;&lt;param name="allowFullScreen" value="true"/&gt;&lt;param name="allowScriptAccess" value="always"/&gt;&lt;embed src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=javaee6-091127091418-phpapp01&amp;stripped_title=lo-nuevo-de-java-ee6" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;div style="font-size:11px;font-family:tahoma,arial;height:26px;padding-top:2px;"&gt;View more &lt;a style="text-decoration:underline;" href="http://www.slideshare.net/"&gt;presentations&lt;/a&gt; from &lt;a style="text-decoration:underline;" href="http://www.slideshare.net/diesil"&gt;Diego Silva&lt;/a&gt;.&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;También me tocaba exponer sobre JavaFX... solo que el tiempo ya se nos había acabado. Así que aquí publico la presentación de JavaFX.&lt;br /&gt;&lt;br /&gt;&lt;div style="width:425px" id="__ss_9344411"&gt; &lt;strong style="display:block;margin:12px 0 4px"&gt;&lt;a href="http://www.slideshare.net/apuntesdejava/ria-con-javafx-9344411" title="RIA con JavaFX" target="_blank"&gt;RIA con JavaFX&lt;/a&gt;&lt;/strong&gt; &lt;iframe src="http://www.slideshare.net/slideshow/embed_code/9344411" width="425" height="355" frameborder="0" marginwidth="0" marginheight="0" scrolling="no"&gt;&lt;/iframe&gt; &lt;div style="padding:5px 0 12px"&gt; View more &lt;a href="http://www.slideshare.net/" target="_blank"&gt;presentations&lt;/a&gt; from &lt;a href="http://www.slideshare.net/apuntesdejava" target="_blank"&gt;apuntesdejava&lt;/a&gt; &lt;/div&gt; &lt;/div&gt;&lt;br /&gt;Anoche no pude acabar con la demostración de una aplicación usando JavaEE6, así que en un siguiente post publicaré el código fuente (además del proyecto para que lo puedan bajar) y de la misma manera sobre JavaFX. Tenía unos ejemplos monos.. en fin.. ya será para otra oportunidad.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8553642737291298841-839279860302462651?l=www.apuntesdejava.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.apuntesdejava.com/feeds/839279860302462651/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.apuntesdejava.com/2009/11/java-day-en-la-uni-agradecimientos.html#comment-form' title='3 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8553642737291298841/posts/default/839279860302462651'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8553642737291298841/posts/default/839279860302462651'/><link rel='alternate' type='text/html' href='http://www.apuntesdejava.com/2009/11/java-day-en-la-uni-agradecimientos.html' title='Java Day en la UNI - agradecimientos'/><author><name>Diego Silva</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp3.blogger.com/_BQk94ojgkDY/SCdCBn9Q_kI/AAAAAAAAAw8/_UdqOhLxqNc/S220/f1.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8553642737291298841.post-2212812101401064838</id><published>2011-09-20T09:45:00.000-05:00</published><updated>2011-09-20T09:45:42.503-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='comentarios'/><category scheme='http://www.blogger.com/atom/ns#' term='libros'/><category scheme='http://www.blogger.com/atom/ns#' term='java ee'/><category scheme='http://www.blogger.com/atom/ns#' term='netbeans 7.0'/><category scheme='http://www.blogger.com/atom/ns#' term='netbeans'/><category scheme='http://www.blogger.com/atom/ns#' term='java ee 6'/><title type='text'>Libro: Java EE 6 Development with NetBeans 7</title><content type='html'>&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;</content><link rel='replies' type='application/atom+xml' href='http://www.apuntesdejava.com/feeds/2212812101401064838/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.apuntesdejava.com/2011/09/libro-java-ee-6-development-with.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8553642737291298841/posts/default/2212812101401064838'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8553642737291298841/posts/default/2212812101401064838'/><link rel='alternate' type='text/html' href='http://www.apuntesdejava.com/2011/09/libro-java-ee-6-development-with.html' title='Libro: Java EE 6 Development with NetBeans 7'/><author><name>Diego Silva</name><uri>https://profiles.google.com/107299481207026512440</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8553642737291298841.post-6053561890341410095</id><published>2010-02-13T18:11:00.001-05:00</published><updated>2011-09-19T13:36:19.352-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java ee'/><category scheme='http://www.blogger.com/atom/ns#' term='jsf 2.0'/><category scheme='http://www.blogger.com/atom/ns#' term='java ee 6'/><category scheme='http://www.blogger.com/atom/ns#' term='web'/><category scheme='http://www.blogger.com/atom/ns#' term='jsf'/><title type='text'>Acceder a ManagedBean desde otro ManagedBean en JSF 2.0</title><content type='html'>Cuando se trabaja con variables sesión en JSP/Servlets es fácil guardar estas variables y también accederlas... bueno, al menos para quien ha trabajado bastante con este tipo de variables de sesión: Desde un servlet se debería escribir &lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: java"&gt;request.setAttribute("obj1",obj1);&lt;/pre&gt;&lt;br /&gt;... cuando se desea guardar una variable de sesión de alcance "request".Para uno de alcance "sesión" es una historia similar.&lt;br /&gt;&lt;br /&gt;Y desde un JSP para acceder a esta variable de sesión, usando EL, deberíamos usar algo como esto:&lt;br /&gt;&lt;pre&gt;&lt;code&gt; Mostrando objeto: ${ob1}&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Pero en JSF (en especial la versión 2.0), ya no se debería utilizar variables de sesión ya que JSF propone ManagedBeans que tengan alcance Scope, Request, Application, Custom y none. Pues bien, esto funcionaría así. &lt;br /&gt;&lt;br /&gt;Un ManagedBean:&lt;br /&gt;&lt;pre class="brush: java"&gt;&lt;br /&gt;@ManagedBean(name="bean1")&lt;br /&gt;@SessionScoped&lt;br /&gt;public class Bean1 {&lt;br /&gt;&lt;br /&gt;    public Bean1() {&lt;br /&gt;    }&lt;br /&gt;    private String nombre;&lt;br /&gt;&lt;br /&gt;    public String getNombre() {&lt;br /&gt;        return nombre;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public void setNombre(String nombre) {&lt;br /&gt;        this.nombre = nombre;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Y para accederlo desde una página JSF, debería ser así:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: xhtml"&gt;&lt;br /&gt;&amp;lt;?xml version='1.0' encoding='UTF-8' ?&amp;gt;&lt;br /&gt;&amp;lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&amp;gt;&lt;br /&gt;&amp;lt;html xmlns="http://www.w3.org/1999/xhtml"&lt;br /&gt;      xmlns:h="http://java.sun.com/jsf/html"&amp;gt;&lt;br /&gt;    &amp;lt;h:head&amp;gt;&lt;br /&gt;        &amp;lt;title&amp;gt;Facelet Title&amp;lt;/title&amp;gt;&lt;br /&gt;    &amp;lt;/h:head&amp;gt;&lt;br /&gt;    &amp;lt;h:body&amp;gt;&lt;br /&gt;        &amp;lt;h:form&amp;gt;&lt;br /&gt;            Nombre:&amp;lt;h:inputText value="#{bean1.nombre}" /&amp;gt;&lt;br /&gt;            &amp;lt;br/&amp;gt;&amp;lt;h:commandButton value="Guardar" /&amp;gt;&lt;br /&gt;        &amp;lt;/h:form&amp;gt;&lt;br /&gt;    &amp;lt;/h:body&amp;gt;&lt;br /&gt;&amp;lt;/html&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Todo normal.. y si accedemos desde otra página, bastaría con escribir &lt;code&gt;#{bean1.nombre}&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Hasta ahí todo normal y muy bien.. pero que pasaría si tenemos otro managedBean y queremos acceder al primer managedBean?&lt;br /&gt;&lt;br /&gt;Pues bien, se debería declarar una propiedad (con set/get) del tipo del primer ManagedBean, y agregarle la anotación &lt;code&gt;@ManagedProperty("#{bean1}")&lt;/code&gt; (Donde bean1 es el nombre del otro managedbean. Y listo!! solo usar.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: java"&gt;&lt;br /&gt;@ManagedBean(name = "bean2")&lt;br /&gt;@RequestScoped&lt;br /&gt;public class Bean2 {&lt;br /&gt;&lt;br /&gt;    @ManagedProperty("#{bean1}")&lt;br /&gt;    private Bean1 bean1;&lt;br /&gt;&lt;br /&gt;    /** Creates a new instance of Bean2 */&lt;br /&gt;    public Bean2() {&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public String getSaludo() {&lt;br /&gt;        return "Hola " + bean1.getNombre();&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public Bean1 getBean1() {&lt;br /&gt;        return bean1;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public void setBean1(Bean1 bean1) {&lt;br /&gt;        this.bean1 = bean1;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;El código fuente de este ejemplo se encuentra aquí: &lt;a href="http://diesil-java.googlecode.com/files/ScopesJSF20.tar.gz" target="_blank"&gt;http://diesil-java.googlecode.com/files/ScopesJSF20.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-6053561890341410095?l=www.apuntesdejava.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.apuntesdejava.com/feeds/6053561890341410095/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.apuntesdejava.com/2010/02/acceder-managedbean-desde-otro.html#comment-form' title='7 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8553642737291298841/posts/default/6053561890341410095'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8553642737291298841/posts/default/6053561890341410095'/><link rel='alternate' type='text/html' href='http://www.apuntesdejava.com/2010/02/acceder-managedbean-desde-otro.html' title='Acceder a ManagedBean desde otro ManagedBean en JSF 2.0'/><author><name>Diego Silva</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp3.blogger.com/_BQk94ojgkDY/SCdCBn9Q_kI/AAAAAAAAAw8/_UdqOhLxqNc/S220/f1.jpg'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8553642737291298841.post-4816120806514303707</id><published>2011-09-13T17:36:00.000-05:00</published><updated>2011-09-13T17:36:54.888-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='restful'/><category scheme='http://www.blogger.com/atom/ns#' term='glassfish v3'/><category scheme='http://www.blogger.com/atom/ns#' term='firefox'/><category scheme='http://www.blogger.com/atom/ns#' term='ejb'/><category scheme='http://www.blogger.com/atom/ns#' term='ajax'/><category scheme='http://www.blogger.com/atom/ns#' term='netbeans'/><category scheme='http://www.blogger.com/atom/ns#' term='ejb 3.1'/><category scheme='http://www.blogger.com/atom/ns#' term='webservices'/><title type='text'>Probando RESTful con Poster</title><content type='html'>&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")&lt;br /&gt;@Consumes({"application/json", "application/xml"})&lt;br /&gt;@Stateless&lt;br /&gt;public class PersonaService {&lt;br /&gt;&lt;br /&gt;    @EJB&lt;br /&gt;    private PersonaFacade facade;&lt;br /&gt;&lt;br /&gt;    @POST&lt;br /&gt;    public Response create(Persona p) {&lt;br /&gt;        facade.insert(p);&lt;br /&gt;        return Response.ok(p).build();&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    @GET&lt;br /&gt;    @Path("{id}/")&lt;br /&gt;    public Persona read(@PathParam("id") int i) {&lt;br /&gt;        Persona p = facade.findById(i);&lt;br /&gt;        return p;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    @GET&lt;br /&gt;    public List&amp;lt;Persona&amp;gt; read(@QueryParam("nombre")&lt;br /&gt;            @DefaultValue("") String nombre) {&lt;br /&gt;        List&amp;lt;Persona&amp;gt; l = nombre.isEmpty() ? facade.findAll() : facade.findByNombre(nombre);&lt;br /&gt;        return l;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    @DELETE&lt;br /&gt;    @Path("/{id}")&lt;br /&gt;    public Response delete(@PathParam("id") int i) {&lt;br /&gt;        if (facade.delete(i)) {&lt;br /&gt;            return Response.ok().build();&lt;br /&gt;        }&lt;br /&gt;        return Response.status(Response.Status.NOT_FOUND).build();&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    @PUT&lt;br /&gt;    @Path("/{id}")&lt;br /&gt;    public Response update(@PathParam("id") int i, Persona p) {&lt;br /&gt;        p.setId(i);&lt;br /&gt;        facade.update(p);&lt;br /&gt;        return Response.ok().build();&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;Y el EJB es el siguiente:&lt;br /&gt;&lt;pre class="brush: java"&gt;@Stateless&lt;br /&gt;public class PersonaFacade {&lt;br /&gt;&lt;br /&gt;    private static List&amp;lt;Persona&amp;gt; lista = new ArrayList&amp;lt;Persona&amp;gt;(); //lista temporal&lt;br /&gt;&lt;br /&gt;    public void insert(Persona p) {&lt;br /&gt;        lista.add(p); //agrega a la lista&lt;br /&gt;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public Persona findById(int id) {&lt;br /&gt;        Persona p = new Persona(id); //crea un objeto temporal...&lt;br /&gt;        int i = lista.indexOf(p); //... para buscarlo en la lista&lt;br /&gt;        if (i &amp;lt; 0) {//si no lo encuentra        &lt;br /&gt;            return null; //... devuelve null&lt;br /&gt;        }&lt;br /&gt;        return lista.get(i);  // sino, lo devuelve&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public List&amp;lt;Persona&amp;gt; findAll() {&lt;br /&gt;        return lista;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public List&amp;lt;Persona&amp;gt; findByNombre(String nombre) {&lt;br /&gt;&lt;br /&gt;        List&amp;lt;Persona&amp;gt; $lista = new ArrayList&amp;lt;Persona&amp;gt;(); //un arreglo temporal&lt;br /&gt;        for (Persona persona : lista) {  //se recorre la lista...&lt;br /&gt;            if (persona.getNombre().contains(nombre)) { //se compara el nombre&lt;br /&gt;                $lista.add(persona); //y si es parecido, lo agrega en la lista&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;        return $lista; //... para devolverlo&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public boolean delete(Persona p) {&lt;br /&gt;        return lista.remove(p);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public void update(Persona p) {&lt;br /&gt;        int pos = lista.indexOf(p); //busca en la lista..&lt;br /&gt;        if (pos &amp;gt;= 0) { //si lo encuentra...&lt;br /&gt;            lista.set(pos, p); //... lo actualiza            &lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public boolean delete(int i) {&lt;br /&gt;        Persona p = findById(i);&lt;br /&gt;        return delete(p);&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&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;{&lt;br /&gt;  "nombre":"Ann",&lt;br /&gt;  "fechaNacimiento":"2010-11-12"&lt;br /&gt;}&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;{&lt;br /&gt;  "nombre":"Alfred",&lt;br /&gt;  "fechaNacimiento":"2010-11-12"&lt;br /&gt;}&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;</content><link rel='replies' type='application/atom+xml' href='http://www.apuntesdejava.com/feeds/4816120806514303707/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.apuntesdejava.com/2011/09/probando-restful-con-poster.html#comment-form' title='1 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8553642737291298841/posts/default/4816120806514303707'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8553642737291298841/posts/default/4816120806514303707'/><link rel='alternate' type='text/html' href='http://www.apuntesdejava.com/2011/09/probando-restful-con-poster.html' title='Probando RESTful con Poster'/><author><name>Diego Silva</name><uri>https://profiles.google.com/107299481207026512440</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><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>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8553642737291298841.post-848109016910205372</id><published>2011-01-15T21:47:00.002-05:00</published><updated>2011-09-13T12:20:27.257-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='restful'/><category scheme='http://www.blogger.com/atom/ns#' term='netbeans 6.9'/><category scheme='http://www.blogger.com/atom/ns#' term='java ee'/><category scheme='http://www.blogger.com/atom/ns#' term='tutorial'/><category scheme='http://www.blogger.com/atom/ns#' term='netbeans'/><category scheme='http://www.blogger.com/atom/ns#' term='java ee 6'/><title type='text'>RESTful parte 4: Actualizando y eliminando elementos de una colección.</title><content type='html'>&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;&lt;br /&gt;//...&lt;br /&gt;public class Persona {    &lt;br /&gt;    private static int contador = 0;    &lt;br /&gt;    public static int getNuevoId() {&lt;br /&gt;        return ++contador;&lt;br /&gt;    }&lt;br /&gt;//...&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;&lt;br /&gt;//...&lt;br /&gt;     public Response guardar(Persona p) {&lt;br /&gt;            p.setIdPersona(Persona.getNuevoId());     //nueva manera de asignar ID&lt;br /&gt;            personas.add(p);&lt;br /&gt;            return Response.ok(p).build();&lt;br /&gt;     }&lt;br /&gt;//...&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;&lt;br /&gt;//...&lt;br /&gt; public class PersonaResource {&lt;br /&gt;       private Persona persona;&lt;br /&gt;   //...&lt;br /&gt;       public void setPersona(Persona persona) {&lt;br /&gt;             this.persona = persona;&lt;br /&gt;       } &lt;br /&gt;}&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;&lt;br /&gt;//... &lt;br /&gt;@Stateless&lt;br /&gt;@Path("/listaPersonas") &lt;br /&gt;public class PersonasResource {&lt;br /&gt;    @EJB&lt;br /&gt;    PersonaResource personaResource;&lt;br /&gt;   //...&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;&lt;br /&gt;//...     &lt;br /&gt;public PersonaResource getPersona(Integer id) {&lt;br /&gt;           if (id == null) { //si no se pasó el ID...&lt;br /&gt;                 return null; //... termina el método&lt;br /&gt;           }&lt;br /&gt;           Persona $temp = new Persona(); //creamos un temporal...&lt;br /&gt;           $temp.setIdPersona(id); //.. que tendrá el ID...&lt;br /&gt;           if (personas.contains($temp)) { // ... para buscarlo en la colección. Para eso sirve el método equals(). Si existe en la colección...&lt;br /&gt;                 int idx = personas.indexOf($temp);  //... obtenemos su índice...&lt;br /&gt;                 Persona actual = personas.get(idx); //... lo obtenemos de la colección...&lt;br /&gt;                 personaResource.setPersona(actual); //.. y lo marcamos como "actual"...&lt;br /&gt;                 return personaResource; //... para que lo devuelva al cliente.&lt;br /&gt;           }&lt;br /&gt;             return null; //.. si no lo encuentra, devuelve null&lt;br /&gt;    } &lt;br /&gt;//...&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;&lt;br /&gt;//...&lt;br /&gt;     @Path("{idPersona}/")&lt;br /&gt;     public PersonaResource getPersona(Integer id) {&lt;br /&gt; //...&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;&lt;br /&gt;//...&lt;br /&gt;     @Path("{idPersona}/")&lt;br /&gt;     public PersonaResource getPersona( @PathParam("idPersona") Integer id) {&lt;br /&gt; //...&lt;/pre&gt;&lt;br /&gt;Al final, el método completo es como sigue:&lt;br /&gt;&lt;pre  class="brush: java"&gt;&lt;br /&gt;//...&lt;br /&gt;     @Path("{idPersona}/")&lt;br /&gt;     public PersonaResource getPersona(@PathParam("idPersona") Integer id) {&lt;br /&gt;             if (id == null) { //si no se pasó el ID...&lt;br /&gt;                     return null; //... termina el método&lt;br /&gt;             }&lt;br /&gt;             Persona $temp = new Persona(); //creamos un temporal...&lt;br /&gt;             $temp.setIdPersona(id); //.. que tendrá el ID...&lt;br /&gt;             if (personas.contains($temp)) { // ... para buscarlo en la colección. Para eso sirve el método equals(). Si existe en la colección...&lt;br /&gt;                   int idx = personas.indexOf($temp);  //... obtenemos su índice...&lt;br /&gt;                   Persona actual = personas.get(idx); //... lo obtenemos de la colección...&lt;br /&gt;                   personaResource.setPersona(actual); //.. y lo marcamos como "actual"...&lt;br /&gt;                   return personaResource; //... para que lo devuelva al cliente.&lt;br /&gt;             }&lt;br /&gt;             return null; //.. si no lo encuentra, devuelve null&lt;br /&gt;     } //...&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;//...     &lt;br /&gt;public void borrarPersona(Persona p) {&lt;br /&gt;           personas.remove(p); //... busca en la lista y borra el elemento&lt;br /&gt;     }&lt;br /&gt;     public void cambiarPersona(Persona actual, Persona p) {&lt;br /&gt;           int idx = personas.indexOf(actual); //... obtiene la posición del actual&lt;br /&gt;           if (idx &amp;gt;= 0) { //... si existe...&lt;br /&gt;                 p.setIdPersona(actual.getIdPersona()); //... ponerle el ID en el nuevo objeto...&lt;br /&gt;                 personas.set(idx, p); //..y reemplazar el objeto en la misma posición del anterior&lt;br /&gt;           }&lt;br /&gt;     }//...&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;&lt;br /&gt;//... &lt;br /&gt;public class PersonaResource {    &lt;br /&gt;//el que tiene el objeto actual       &lt;br /&gt;@EJB    PersonasResource personasResource;   &lt;br /&gt;//el que tiene la colección de objetos&lt;br /&gt;//...&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;&lt;br /&gt;//...    &lt;br /&gt;@DELETE&lt;br /&gt;public void borrar() {          &lt;br /&gt; personasResource.borrarPersona(persona);  //porque tiene la colección de objetos&lt;br /&gt;}    &lt;br /&gt;@PUT    &lt;br /&gt;@Consumes({"application/xml", "application/json"})    &lt;br /&gt;public void actualizar(Persona p) {&lt;br /&gt; personasResource.cambiarPersona(persona,p); //porque tiene la colección de objetos&lt;br /&gt;}&lt;br /&gt;//...&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;</content><link rel='replies' type='application/atom+xml' href='http://www.apuntesdejava.com/feeds/848109016910205372/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.apuntesdejava.com/2011/01/restful-4-actualizando-y-eliminando.html#comment-form' title='2 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8553642737291298841/posts/default/848109016910205372'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8553642737291298841/posts/default/848109016910205372'/><link rel='alternate' type='text/html' href='http://www.apuntesdejava.com/2011/01/restful-4-actualizando-y-eliminando.html' title='RESTful parte 4: Actualizando y eliminando elementos de una colección.'/><author><name>Diego Silva</name><uri>https://profiles.google.com/107299481207026512440</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><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>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8553642737291298841.post-2324163446370249803</id><published>2011-06-04T17:27:00.000-05:00</published><updated>2011-06-04T17:27:06.567-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='commons'/><category scheme='http://www.blogger.com/atom/ns#' term='seguridad'/><category scheme='http://www.blogger.com/atom/ns#' term='apache'/><title type='text'>Contraseñas encriptadas con Java</title><content type='html'>&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";&lt;br /&gt;        String encriptMD5=DigestUtils.md5Hex(texto);&lt;br /&gt;        System.out.println("md5:"+encriptMD5);&lt;br /&gt;&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";&lt;br /&gt;        String encript=DigestUtils.shaHex(texto);&lt;br /&gt;        System.out.println("shaHex:"+encript);&lt;br /&gt;&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&lt;br /&gt;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;</content><link rel='replies' type='application/atom+xml' href='http://www.apuntesdejava.com/feeds/2324163446370249803/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.apuntesdejava.com/2011/06/contrasenas-encriptadas-con-java.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8553642737291298841/posts/default/2324163446370249803'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8553642737291298841/posts/default/2324163446370249803'/><link rel='alternate' type='text/html' href='http://www.apuntesdejava.com/2011/06/contrasenas-encriptadas-con-java.html' title='Contraseñas encriptadas con Java'/><author><name>Diego Silva</name><uri>https://profiles.google.com/107299481207026512440</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><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>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8553642737291298841.post-3013470061540479325</id><published>2011-03-08T18:26:00.000-05:00</published><updated>2011-03-08T18:26:24.387-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java ee'/><category scheme='http://www.blogger.com/atom/ns#' term='jsf 2.0'/><category scheme='http://www.blogger.com/atom/ns#' term='java ee 6'/><category scheme='http://www.blogger.com/atom/ns#' term='web'/><category scheme='http://www.blogger.com/atom/ns#' term='servlets'/><category scheme='http://www.blogger.com/atom/ns#' term='jsf'/><title type='text'>Upload en JSF 2.0</title><content type='html'>&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&lt;br /&gt;public class Entrada implements Serializable {&lt;br /&gt;&lt;br /&gt;    private static final long serialVersionUID = 1L;&lt;br /&gt;    @Id&lt;br /&gt;    @GeneratedValue(strategy = GenerationType.AUTO)&lt;br /&gt;    private Long id;&lt;br /&gt;    @Column&lt;br /&gt;    private String descripcion;&lt;br /&gt;    @ElementCollection&lt;br /&gt;    private List&amp;lt;Adjunto&amp;gt; adjuntos;&lt;br /&gt;&lt;br /&gt;    public void addAdjunto(Adjunto adjunto) {&lt;br /&gt;        getAdjuntos().add(adjunto);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public List&amp;lt;Adjunto&amp;gt; getAdjuntos() {&lt;br /&gt;        if (adjuntos == null) {&lt;br /&gt;            adjuntos = new ArrayList&amp;lt;Adjunto&amp;gt;();&lt;br /&gt;        }&lt;br /&gt;        return adjuntos;&lt;br /&gt;    }&lt;br /&gt;//... métodos get y set por cada propiedad&lt;br /&gt;&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;&lt;br /&gt;@Embeddable&lt;br /&gt;public class Adjunto implements Serializable {&lt;br /&gt;&lt;br /&gt;    @Lob&lt;br /&gt;    private byte[] contenido;&lt;br /&gt;    @Column&lt;br /&gt;    private String tipoContenido;&lt;br /&gt;    @Column&lt;br /&gt;    private String nombreArchivo;&lt;br /&gt;&lt;br /&gt;    public Adjunto() {&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public Adjunto(byte[] contenido, String tipoContenido, String nombreArchivo) {&lt;br /&gt;        this.contenido = contenido;&lt;br /&gt;        this.tipoContenido = tipoContenido;&lt;br /&gt;        this.nombreArchivo = nombreArchivo;&lt;br /&gt;    }&lt;br /&gt;//.. métodos set y get de las propiedades.&lt;br /&gt;&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;//...&lt;br /&gt;        &amp;lt;h:form id="form"&amp;gt;&lt;br /&gt;            &amp;lt;h:panelGrid columns="2"&amp;gt;&lt;br /&gt;                &amp;lt;h:outputLabel value="Descripción" for="descripcion" /&amp;gt;&lt;br /&gt;                &amp;lt;h:inputTextarea id="descripcion" value="#{bitacoraBean.entradaActual.descripcion}" /&amp;gt;&lt;br /&gt;&lt;br /&gt;                &amp;lt;h:outputText value="Adjuntos"/&amp;gt;&lt;br /&gt;&lt;br /&gt;                &amp;lt;h:panelGroup&amp;gt;&lt;br /&gt;                    &amp;lt;h:commandButton value="Recargar..." id="recargar"&amp;gt;&lt;br /&gt;                        &amp;lt;f:ajax render="adjuntos" /&amp;gt;&lt;br /&gt;                    &amp;lt;/h:commandButton&amp;gt;&lt;br /&gt;                    &amp;lt;h:button value="Agregar" onclick="return abrirAdjuntos()"/&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;!-- aqui va el codigo donde se muestra los adjuntos --&amp;gt;&lt;br /&gt;                &amp;lt;/h:panelGroup&amp;gt;&lt;br /&gt;            &amp;lt;/h:panelGrid&amp;gt;&lt;br /&gt;            &amp;lt;h:commandButton action="#{bitacoraBean.guardarEntrada}" value="Guardar"/&amp;gt;&lt;br /&gt;        &amp;lt;/h:form&amp;gt;&lt;br /&gt;//...&lt;br /&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;//...&lt;br /&gt;        &amp;lt;h1&amp;gt;Cargar archivo&amp;lt;/h1&amp;gt;&lt;br /&gt;        &amp;lt;form action="&amp;lt;c:url value='/servlet/upload'  /&amp;gt;" method="POST" enctype="multipart/form-data"&amp;gt;&lt;br /&gt;            Archivo:&lt;br /&gt;            &amp;lt;input type="file" name="archivo" value="" /&amp;gt;&lt;br /&gt;            &amp;lt;button type="submit"&amp;gt;Cargar&amp;lt;/button&amp;gt;&lt;br /&gt;        &amp;lt;/form&amp;gt;&lt;br /&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;&lt;br /&gt;@WebServlet(name = "UploadServlet", urlPatterns = {"/servlet/upload"})&lt;br /&gt;public class UploadServlet extends HttpServlet {&lt;br /&gt;&lt;br /&gt;    /** &lt;br /&gt;     * 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.&lt;br /&gt;     * @param request servlet request&lt;br /&gt;     * @param response servlet response&lt;br /&gt;     * @throws ServletException if a servlet-specific error occurs&lt;br /&gt;     * @throws IOException if an I/O error occurs&lt;br /&gt;     */&lt;br /&gt;    protected void processRequest(HttpServletRequest request, HttpServletResponse response)&lt;br /&gt;            throws ServletException, IOException {&lt;br /&gt;&lt;br /&gt;        Part filePart = request.getPart("archivo"); //obtengo el archivo adjunto&lt;br /&gt;        String nombreArchivo = extraerNombre(filePart.getHeader("content-disposition")); //extraigo el nombre&lt;br /&gt;&lt;br /&gt;        InputStream is = filePart.getInputStream(); //obtengo el Stream&lt;br /&gt;        long size = filePart.getSize(); //... el tamaño&lt;br /&gt;        byte[] buffer = new byte[(int) size]; //.. creo el buffer&lt;br /&gt;        is.read(buffer); //.. leo el buffer en un solo bloque&lt;br /&gt;        is.close(); //... cierro el buffer&lt;br /&gt;        String mimeType = filePart.getContentType(); //... obtengo el tipo de archivo&lt;br /&gt;        Adjunto adjunto = new Adjunto(buffer, mimeType, nombreArchivo); //... creo el objeto ajdjunto&lt;br /&gt;        BitacoraBean bitacoraBean = (BitacoraBean) request.getSession().getAttribute("bitacoraBean"); //obtengo el bean&lt;br /&gt;        Entrada entradaActual = bitacoraBean.getEntradaActual(); //.. obtengo la entrada actual que está con el formulario&lt;br /&gt;        entradaActual.addAdjunto(adjunto); //... adjunto el objeto del archivo&lt;br /&gt;        response.setContentType("text/html;charset=UTF-8");&lt;br /&gt;        PrintWriter out = response.getWriter();&lt;br /&gt;        try {&lt;br /&gt;            out.println("&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;"); //imprimo en el HTML para ejecutar un javascript&lt;br /&gt;            out.println("&amp;lt;script type=\"text/javascript\"&amp;gt;");&lt;br /&gt;            out.println("window.opener.document.getElementById(\"form:recargar\").click()"); //busco el boton para recargar&lt;br /&gt;            out.println("window.close()"); //cierro ventana&lt;br /&gt;            out.println("&amp;lt;/script&amp;gt;");&lt;br /&gt;            out.println("&amp;lt;/head&amp;gt;&amp;lt;/html&amp;gt;");&lt;br /&gt;        } finally {&lt;br /&gt;            out.close();&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    /**&lt;br /&gt;     * Método para extrar el nombre físico del archivo&lt;br /&gt;     * @param header Parametro del nombre, con toda la ruta completa en el cliente&lt;br /&gt;     * @return Devuelve solo el nombre del archivo&lt;br /&gt;     */&lt;br /&gt;    static private String extraerNombre(String header) {&lt;br /&gt;        String[] parts = header.split(";");&lt;br /&gt;        for (String part : parts) {&lt;br /&gt;            if (part.trim().startsWith("filename=")) { //busco todos los que comienzan con filename&lt;br /&gt;                String[] $parts = part.split("="); //separo el nombre&lt;br /&gt;                StringBuilder $sb = new StringBuilder($parts[1]);&lt;br /&gt;                String fn = $sb.substring(1, $sb.length() - 1); //el segundo es el nombre&lt;br /&gt;                File f = new File(fn); //creo una entrada de archivo&lt;br /&gt;                return f.getName(); //devuelvo el nombre del archivo&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;        return "";&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;&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;&lt;br /&gt; &amp;lt;h:dataTable id="adjuntos" value="#{bitacoraBean.entradaActual.adjuntos}"  var="adjunto" binding="#{bitacoraBean.adjuntosDataTable}"&amp;gt;&lt;br /&gt;   &amp;lt;h:column&amp;gt;&lt;br /&gt;     &amp;lt;h:outputText value="#{adjunto.nombreArchivo}" /&amp;gt;&lt;br /&gt;   &amp;lt;/h:column&amp;gt;&lt;br /&gt;   &amp;lt;h:column&amp;gt;&lt;br /&gt;     &amp;lt;h:commandButton value="X" action="#{bitacoraBean.quitarAdjunto}" /&amp;gt;&lt;br /&gt;   &amp;lt;/h:column&amp;gt;&lt;br /&gt; &amp;lt;/h:dataTable&amp;gt;&lt;br /&gt;&lt;br /&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;&lt;br /&gt;//...&lt;br /&gt;    public HtmlDataTable getAdjuntosDataTable() {&lt;br /&gt;        return adjuntosDataTable;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public void setAdjuntosDataTable(HtmlDataTable adjuntosDataTable) {&lt;br /&gt;        this.adjuntosDataTable = adjuntosDataTable;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public String quitarAdjunto(){&lt;br /&gt;        Adjunto adjunto = (Adjunto) adjuntosDataTable.getRowData();&lt;br /&gt;        entradaActual.quitarAdjunto(adjunto);&lt;br /&gt;        return null;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;//...&lt;br /&gt;&lt;br /&gt;&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;&lt;br /&gt;        &amp;lt;h2&amp;gt;Entradas de Bitácora&amp;lt;/h2&amp;gt;&lt;br /&gt;        &amp;lt;h:dataTable border="1" value="#{bitacoraBean.entradas}" var="entrada"&amp;gt;&lt;br /&gt;            &amp;lt;h:column&amp;gt;&lt;br /&gt;                &amp;lt;f:facet name="header"&amp;gt;ID&amp;lt;/f:facet&amp;gt;&lt;br /&gt;                #{entrada.id}&lt;br /&gt;            &amp;lt;/h:column&amp;gt;&lt;br /&gt;            &amp;lt;h:column&amp;gt;&lt;br /&gt;                &amp;lt;f:facet name="header"&amp;gt;Descripción&amp;lt;/f:facet&amp;gt;&lt;br /&gt;                #{entrada.descripcion}&lt;br /&gt;            &amp;lt;/h:column&amp;gt;&lt;br /&gt;            &amp;lt;h:column&amp;gt;&lt;br /&gt;                &amp;lt;f:facet name="header"&amp;gt;Adjuntos&amp;lt;/f:facet&amp;gt;&lt;br /&gt;                &amp;lt;h:dataTable value="#{entrada.adjuntos}" var="adjunto"&amp;gt;&lt;br /&gt;                    &amp;lt;h:column&amp;gt;&lt;br /&gt;                        &amp;lt;h:outputLink value="#{facesContext.externalContext.requestContextPath}/servlet/upload/abrir"  &amp;gt;&lt;br /&gt;                            &amp;lt;h:outputText value="#{adjunto.nombreArchivo}" /&amp;gt;&lt;br /&gt;                            &amp;lt;f:param name="id" value="#{entrada.id}" /&amp;gt;&lt;br /&gt;                            &amp;lt;f:param name="archivo" value="#{adjunto.nombreArchivo}" /&amp;gt;&lt;br /&gt;                        &amp;lt;/h:outputLink&amp;gt;&lt;br /&gt;                    &amp;lt;/h:column&amp;gt;&lt;br /&gt;                &amp;lt;/h:dataTable&amp;gt;&lt;br /&gt;&lt;br /&gt;            &amp;lt;/h:column&amp;gt;&lt;br /&gt;        &amp;lt;/h:dataTable&amp;gt;&lt;br /&gt;&lt;br /&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;&lt;br /&gt;//...&lt;br /&gt;@WebServlet(name = "MostrarArchivoServlet", urlPatterns = {"/servlet/upload/abrir"})&lt;br /&gt;public class MostrarArchivoServlet extends HttpServlet {&lt;br /&gt;&lt;br /&gt;    @EJB&lt;br /&gt;    private EntradaFacade entradaFacade;&lt;br /&gt;&lt;br /&gt;    /**&lt;br /&gt;     * 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.&lt;br /&gt;     * @param request servlet request&lt;br /&gt;     * @param response servlet response&lt;br /&gt;     * @throws ServletException if a servlet-specific error occurs&lt;br /&gt;     * @throws IOException if an I/O error occurs&lt;br /&gt;     */&lt;br /&gt;    protected void processRequest(HttpServletRequest request, HttpServletResponse response)&lt;br /&gt;            throws ServletException, IOException {&lt;br /&gt;&lt;br /&gt;        String $idEntrada = request.getParameter("id"); //obtengo el ID del parametro&lt;br /&gt;        String archivo = request.getParameter("archivo"); //obtengo el nombre del archivo del parametro&lt;br /&gt;        Long idEntrada = Long.parseLong($idEntrada); //convierto el ID a Long...&lt;br /&gt;        Entrada entrada = entradaFacade.find(idEntrada);//.. para buscarlo en la base de datos &lt;br /&gt;        if (entrada == null) { //si no existe...&lt;br /&gt;            response.setStatus(HttpServletResponse.SC_NOT_FOUND); //... devuelvo un mensaje de q no existe&lt;br /&gt;            return; //... y termina&lt;br /&gt;        }&lt;br /&gt;        List&amp;lt;Adjunto&amp;gt; adjuntos = entrada.getAdjuntos(); //ahora, obtenemos todos los adjuntos de la entrada&lt;br /&gt;        Adjunto adjuntoMostrar = null; //el adjunto actual&lt;br /&gt;        for (Adjunto $adjunto : adjuntos) { //recorro todos los adjuntos&lt;br /&gt;            if ($adjunto.getNombreArchivo().equals(archivo)); //comparamos el nombre, y si existe...&lt;br /&gt;               adjuntoMostrar = $adjunto; //.. lo capturamos&lt;br /&gt;        }&lt;br /&gt;        if (adjuntoMostrar == null) { //si recorrio toda la lista y no encontro nada...&lt;br /&gt;            response.setStatus(HttpServletResponse.SC_NOT_FOUND); //... devolvemos un mensaje que q no existe&lt;br /&gt;            return; //.. y termina&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        OutputStream out = response.getOutputStream();&lt;br /&gt;        try {&lt;br /&gt;            response.setContentType("application/octet-stream"); //...preparamos el tipo para q se descargue la adjunto&lt;br /&gt;            response.setHeader("Content-Disposition", "attachment;filename=" + adjuntoMostrar.getNombreArchivo().replaceAll(" ", "_")); //preparando el 'download' al navegador&lt;br /&gt;&lt;br /&gt;            response.setContentLength(adjuntoMostrar.getContenido().length); //ponemos el tamaño...&lt;br /&gt;            out.write(adjuntoMostrar.getContenido()); //... y vaciamos el contenido&lt;br /&gt;&lt;br /&gt;        } finally {&lt;br /&gt;            out.close(); //y cerramos el flujo&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;//...&lt;br /&gt;&lt;br /&gt;&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;</content><link rel='replies' type='application/atom+xml' href='http://www.apuntesdejava.com/feeds/3013470061540479325/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.apuntesdejava.com/2011/03/upload-en-jsf-20.html#comment-form' title='5 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8553642737291298841/posts/default/3013470061540479325'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8553642737291298841/posts/default/3013470061540479325'/><link rel='alternate' type='text/html' href='http://www.apuntesdejava.com/2011/03/upload-en-jsf-20.html' title='Upload en JSF 2.0'/><author><name>Diego Silva</name><uri>https://profiles.google.com/107299481207026512440</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><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>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8553642737291298841.post-5975542560702640080</id><published>2010-09-14T10:33:00.003-05:00</published><updated>2011-03-07T10:17:53.814-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='ejb'/><category scheme='http://www.blogger.com/atom/ns#' term='spring'/><category scheme='http://www.blogger.com/atom/ns#' term='tutorial'/><category scheme='http://www.blogger.com/atom/ns#' term='web'/><category scheme='http://www.blogger.com/atom/ns#' term='ejb 3.1'/><title type='text'>Enmulando EJB en Web usando Spring</title><content type='html'>&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;&lt;br /&gt;&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;&lt;br /&gt;&amp;lt;persistence version="1.0" &lt;br /&gt;   xmlns="http://java.sun.com/xml/ns/persistence" &lt;br /&gt;   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" &lt;br /&gt;   xsi:schemaLocation="http://java.sun.com/xml/ns/persistence &lt;br /&gt;                       http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"&amp;gt;&lt;br /&gt;  &amp;lt;persistence-unit name="EjbSpringWebPU" transaction-type="JTA"&amp;gt;&lt;br /&gt;    &amp;lt;jta-data-source&amp;gt;jdbc/sample&amp;lt;/jta-data-source&amp;gt;&lt;br /&gt;    &amp;lt;exclude-unlisted-classes&amp;gt;false&amp;lt;/exclude-unlisted-classes&amp;gt;&lt;br /&gt;    &amp;lt;properties/&amp;gt;&lt;br /&gt;  &amp;lt;/persistence-unit&amp;gt;&lt;br /&gt;&amp;lt;/persistence&amp;gt;&lt;br /&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;&lt;br /&gt;public class DiscountCodeFacade {&lt;br /&gt;&lt;br /&gt;    @PersistenceContext(unitName = "EjbSpringWebPU")&lt;br /&gt;    private EntityManager em;&lt;br /&gt;&lt;br /&gt;    public List&amp;lt;DiscountCode&amp;gt; getDiscountCodes() {&lt;br /&gt;        Query query = em.createQuery("select o from DiscountCode o");&lt;br /&gt;        return query.getResultList();&lt;br /&gt;    }&lt;br /&gt;}&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;&lt;br /&gt;    &amp;lt;bean id="EjbSpringWebPU" class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean"&amp;gt;&lt;br /&gt;        &amp;lt;property name="persistenceUnitName" value="EjbSpringWebPU"/&amp;gt;&lt;br /&gt;    &amp;lt;/bean&amp;gt;&lt;br /&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;&lt;br /&gt;    &amp;lt;bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Para terminar, instanciar el Facade:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;    &amp;lt;bean id="DiscountCodeFacade" class="service.DiscountCodeFacade" /&amp;gt;&lt;br /&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;&lt;br /&gt;DiscountCodeFacade facade=ServiceFactory.getInstance().getDiscountCodeFacade();&lt;br /&gt;List&amp;lt;DiscountCode&amp;gt; discountCodes = facade.getDiscountCodes();&lt;br /&gt;&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;</content><link rel='replies' type='application/atom+xml' href='http://www.apuntesdejava.com/feeds/5975542560702640080/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.apuntesdejava.com/2010/09/enmulando-ejb-en-web-usando-spring.html#comment-form' title='2 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8553642737291298841/posts/default/5975542560702640080'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8553642737291298841/posts/default/5975542560702640080'/><link rel='alternate' type='text/html' href='http://www.apuntesdejava.com/2010/09/enmulando-ejb-en-web-usando-spring.html' title='Enmulando EJB en Web usando Spring'/><author><name>Diego Silva</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp3.blogger.com/_BQk94ojgkDY/SCdCBn9Q_kI/AAAAAAAAAw8/_UdqOhLxqNc/S220/f1.jpg'/></author><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>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8553642737291298841.post-283651759896711314</id><published>2010-06-08T00:00:00.001-05:00</published><updated>2011-02-19T18:07:58.147-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='swing'/><category scheme='http://www.blogger.com/atom/ns#' term='tips'/><category scheme='http://www.blogger.com/atom/ns#' term='tutorial'/><category scheme='http://www.blogger.com/atom/ns#' term='netbeans'/><category scheme='http://www.blogger.com/atom/ns#' term='ant'/><category scheme='http://www.blogger.com/atom/ns#' term='trucos'/><title type='text'>Empaquetar una aplicación para distribuir, desde NetBeans</title><content type='html'>Uno de los tantos motivos por lo que utilizo NetBeans en lugar de otro IDE, es que utiliza la &lt;a href="http://ant.apache.org/"&gt;Apache Ant&lt;/a&gt; para compilar, crear .jar .war .ear, javadoc, etc.. prácticamente para todo, y solo usando un archivo .xml. Y lo mejor es que se puede personalizar el .xml a nuestro antojo.&lt;br /&gt;&lt;br /&gt;En este post se va a explicar cómo empaquetar una aplicación Swing en un archivo .zip para ser distribuido a los usuarios finales.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;h3&gt;¿Qué hace NetBeans?&lt;/h3&gt;Si al hacer una aplicación Swing con NetBeans utilizamos diversas bibliotecas adicionales, el IDE nos puede crear una carpeta lista para distribuir a los usuarios incluyendo todas los .jars necesarios. Para ello hacemos clic derecho sobre el ícono del proyecto y seleccionamos "Build" (o Clean and Build)&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/TAaAM1SZ3JI/AAAAAAAAC70/xEKP1hcCde0/s1600/ant01.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="164" src="http://2.bp.blogspot.com/_BQk94ojgkDY/TAaAM1SZ3JI/AAAAAAAAC70/xEKP1hcCde0/s320/ant01.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&amp;nbsp;Al hacer esto, el NetBeans compila, y construye la carpeta "dist" para distribuir. Esta carpeta se encuentra en la misma carpeta del proyecto. Podemos verla en el panel "Files" del NetBeans (Teclas Ctrl+2)&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_BQk94ojgkDY/TAaANCkdgKI/AAAAAAAAC74/lI96HR7tnu4/s1600/ant02.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_BQk94ojgkDY/TAaANCkdgKI/AAAAAAAAC74/lI96HR7tnu4/s1600/ant02.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;Ahora bien ¿qué hacemos con ese .jar? En el README.TXT lo explica. Pero NetBeans también lo dice en el panel "Output" (Ctrl+4) después de construir la aplicación.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_BQk94ojgkDY/TAaANPySUyI/AAAAAAAAC78/1_rq34z7Mm0/s1600/ant03.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="98" src="http://3.bp.blogspot.com/_BQk94ojgkDY/TAaANPySUyI/AAAAAAAAC78/1_rq34z7Mm0/s400/ant03.jpg" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;"Para ejecutar esta aplicación desde la línea de comandos sin usar Ant, intente:..." y luego dice cuál es el comando que se tiene que hacer.&lt;br /&gt;&lt;br /&gt;Si copiamos esa línea, abrimos la ventana del Símbolo del Sistema, y pegamos esa instrucción para ejecutarlo, pues nos ejecutará la aplicación sin problemas. Es más, se podría copiar a los usuarios finales este directorio "dist" y decirles que si quieren ejecutarlo hagan esto: abrir una ventana del Símbolo del Sistema, escribir esa instrucción&amp;nbsp; y listo.........creo que al usuario no le va a gustar hacer esto ¿Por qué no mejor hacer un programa que al hacer doble clic ya se ejecuté? Buena idea.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Creando un .bat&lt;/h3&gt;De por sí, se puede hacer doble clic al archivo .jar para ejecutar la aplicación, pero funciona si es que en el computador del usuario no tiene algún descompresor de archivos asociado a los archivos .jar. Por ejemplo, si se tiene instalado el WinRAR, al hacer doble clic sobre el archivo .jar, en lugar de que se ejecute, se abrirá el WinRAR y mostrará el contenido del .jar... esto no es lo que queremos. La mejor manera es crear un archivo .bat que haga la llamada al comando java -jar bla bla&lt;br /&gt;&lt;br /&gt;Esto le podemos decir al NetBeans que lo haga. Para ello, entramos al panel "Files" (Ctrl+2) y buscamos el archivo &lt;code&gt;build.xml&lt;/code&gt;. Este es una extensión al .xml que utiliza el NetBeans para construir la aplicación.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_BQk94ojgkDY/TAaANEWLHlI/AAAAAAAAC8A/CGbt3VVQuhk/s1600/ant04.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_BQk94ojgkDY/TAaANEWLHlI/AAAAAAAAC8A/CGbt3VVQuhk/s1600/ant04.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&amp;nbsp;Abrimos este archivo, lo revisamos un poco (todo está comentado y hay algunas instrucciones) y pondremos el tag &lt;code&gt;&amp;lt;target name='-post-jar'/&amp;gt;&lt;/code&gt; que nos permitirá realizar una tarea después de que el NetBeans haya creado el .jar&lt;br /&gt;&lt;pre&gt;&lt;code&gt;    &amp;lt;target name="-post-jar"&amp;gt;        &amp;lt;echo file="${dist.dir}/run.bat"&amp;gt;java -jar ${application.title}.jar&amp;lt;/echo&amp;gt;    &amp;lt;/target&amp;gt; &lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;El tag de la tarea &lt;code&gt;&lt;a href="http://ant.apache.org/manual/Tasks/echo.html"&gt;&amp;lt;echo /&amp;gt;&lt;/a&gt; &lt;/code&gt; crea una salida a la consola, pero con el atributo &lt;code&gt;file&lt;/code&gt; le estamos diciendo que la salida lo haga a un archivo. Para saber cuáles son los valores de las variables utilizadas en la construcción del proyecto, podemos revisar el archivo &lt;code&gt;nbproject/project.properties&lt;/code&gt;.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_BQk94ojgkDY/TAaANXfj1LI/AAAAAAAAC8E/x_17BmUX1WU/s1600/ant04a.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_BQk94ojgkDY/TAaANXfj1LI/AAAAAAAAC8E/x_17BmUX1WU/s1600/ant04a.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Por ello utilicé las variables &lt;code&gt;dist.dir, application.title&lt;/code&gt;.&lt;br /&gt;&lt;br /&gt;Ahora bien, hagamos un "Build" al proyecto y veamos lo que hizo en la carpeta &lt;code&gt;dist&lt;/code&gt;.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_BQk94ojgkDY/TAaAR_ZVJ5I/AAAAAAAAC8I/6OLUSvfITvw/s1600/ant05.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_BQk94ojgkDY/TAaAR_ZVJ5I/AAAAAAAAC8I/6OLUSvfITvw/s1600/ant05.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&amp;nbsp;Y si vemos el contenido será justamente lo que hemos pensado. Abrimos una ventana del explorador de windows, y le damos doble clic al .bat. Listo, usuario satisfecho.&lt;br /&gt;&lt;br /&gt;Pero.. sale una ventana negra fea con el comando de ejecución de la aplicación. Bueno, esto se puede solucionar. Podemos reemplazar la instrucción &lt;br /&gt;&lt;pre&gt;&lt;code&gt;&amp;lt;echo file="${dist.dir}/run.bat"&amp;gt;java -jar ${application.title}.jar&amp;lt;/echo&amp;gt;&lt;/code&gt;&lt;/pre&gt;Por&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&amp;lt;echo file="${dist.dir}/run.bat"&amp;gt;&lt;span style="color: blue;"&gt;start javaw&lt;/span&gt; -jar ${application.title}.jar&amp;lt;/echo&amp;gt;&lt;/code&gt;&lt;/pre&gt;El comando de Windows &lt;code&gt;start&lt;/code&gt; permite ejecutar una aplicación y "soltarlo" para que se ejecute como un proceso más del Sistema Operativo. Y el comando &lt;code&gt;javaw&lt;/code&gt; es un comando adicional al JRE que permite ejecutar una aplicación java sin mostrar una ventana del Símbolo del Sistema.&lt;br /&gt;&lt;br /&gt;Bien, ahora solo nos bastaría con copiar a los usuarios finales el .bat, el .jar y las bibliotecas adicionales so hubiera. Lo empaquetamos y se lo enviamos.&lt;br /&gt;&lt;br /&gt;¿Hay un poco de flojera para comprimir los archivos? ¿y si me falta uno?&lt;br /&gt;&lt;h3&gt;Creando un .zip&lt;/h3&gt;El Ant también permite comprimir archivos usando la tarea &lt;a href="http://ant.apache.org/manual/Tasks/zip.html"&gt;&lt;code&gt;&amp;lt;zip /&amp;gt;&lt;/code&gt;&lt;/a&gt;. Es realmente fácil.&lt;br /&gt;&lt;br /&gt;Creamos el siguiente tag después del &lt;code&gt;&amp;lt;echo /&amp;gt;&lt;/code&gt;.&lt;br /&gt;&lt;pre&gt;&lt;code&gt;        &amp;lt;zip destfile="${dist.dir}/${application.title}.zip" basedir="${dist.dir}" /&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Hagamos "Clean and Build" al proyecto, y listo, ya tenemos nuestro archivo .zip para enviar a los usuarios finales.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_BQk94ojgkDY/TAaASLTSvTI/AAAAAAAAC8M/minR9rKxC2I/s1600/ant06.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_BQk94ojgkDY/TAaASLTSvTI/AAAAAAAAC8M/minR9rKxC2I/s1600/ant06.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_BQk94ojgkDY/TAaASJQIfjI/AAAAAAAAC8Q/xCrgClbvX3U/s1600/ant07.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="186" src="http://2.bp.blogspot.com/_BQk94ojgkDY/TAaASJQIfjI/AAAAAAAAC8Q/xCrgClbvX3U/s400/ant07.jpg" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Y les decimos "Estimados bla bla bla, descompriman el achivo .zip para ejecutar la aplicación".&lt;br /&gt;¿También tenemos flojera de enviar el mail a los usuarios? &lt;code&gt;:)&lt;/code&gt;&lt;br /&gt;&lt;h3&gt;Documentación&lt;/h3&gt;Si deseas conocer más tareas que vienen incluidas en el ANT, revisa la siguiente página.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Apache Ant User Manual: &lt;a href="http://ant.apache.org/manual/index.html"&gt;http://ant.apache.org/manual/index.html&lt;/a&gt; &lt;/li&gt;&lt;/ul&gt;Ahí está la tarea &lt;code&gt;mail&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Proyecto&lt;/h3&gt;Y como de costumbre, aquí está el proyecto utilizado en este ejemplo:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://java.net/downloads/apuntes/samples/netbeans/DemoSwingAntCustomized.tar.gz"&gt;http://java.net/downloads/apuntes/samples/netbeans/DemoSwingAntCustomized.tar.gz&lt;/a&gt; &lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8553642737291298841-283651759896711314?l=www.apuntesdejava.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.apuntesdejava.com/feeds/283651759896711314/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.apuntesdejava.com/2010/06/empaquetar-una-aplicacion-para.html#comment-form' title='5 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8553642737291298841/posts/default/283651759896711314'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8553642737291298841/posts/default/283651759896711314'/><link rel='alternate' type='text/html' href='http://www.apuntesdejava.com/2010/06/empaquetar-una-aplicacion-para.html' title='Empaquetar una aplicación para distribuir, desde NetBeans'/><author><name>Diego Silva</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp3.blogger.com/_BQk94ojgkDY/SCdCBn9Q_kI/AAAAAAAAAw8/_UdqOhLxqNc/S220/f1.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_BQk94ojgkDY/TAaAM1SZ3JI/AAAAAAAAC70/xEKP1hcCde0/s72-c/ant01.jpg' height='72' width='72'/><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8553642737291298841.post-21819929363501961</id><published>2010-07-06T00:00:00.231-05:00</published><updated>2011-02-19T18:03:35.149-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='glassfish v3'/><category scheme='http://www.blogger.com/atom/ns#' term='liferay'/><category scheme='http://www.blogger.com/atom/ns#' term='tutorial'/><category scheme='http://www.blogger.com/atom/ns#' term='portlets'/><category scheme='http://www.blogger.com/atom/ns#' term='glassfish'/><category scheme='http://www.blogger.com/atom/ns#' term='web'/><title type='text'>Instalación de Liferay en un servidor GlassFish v3 para producción</title><content type='html'>&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;En un &lt;a href="http://www.apuntesdejava.com/2010/06/portales-en-java.html"&gt;anterior post&lt;/a&gt; mencioné los Portales en Java, y la facilidad que nos da el utilizar una plataforma con muchas funcionalidades, y nosotros simplemente deberíamos hacer los componentes que faltan. Estos componentes se llaman Portlets.&lt;br /&gt;&lt;br /&gt;Ahora mencionaré uno de los gestores de Portlets en Java que, según mi opinión, es bastante útil. Su nombre LIFERAY. Pero no hablaré de sus cualidades, ni todo lo que puede hacer.. eso ya lo hizo &lt;a href="http://periospino.blogspot.com/2010/03/gestor-de-contenidos-java-el-poderoso.html"&gt;Pedro Edison en su blog&lt;/a&gt; &lt;code&gt;:)&lt;/code&gt;, y como no hay que amontonar la red con lo mismo, esta vez mostraré cómo instalar el LIFERAY desde cero. No desde la instalación de un .exe, sino desde un archivo .war y sobre GlassFish v3 usando MySQL como gestor de base de datos.&lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;Esto no lo he inventado, sino lo tomé del &lt;a href="http://docs.liferay.com/portal/5.2/official/liferay-administration-guide.pdf"&gt;tutorial mismo&lt;/a&gt; de Liferay... pero como está en inglés, y el lector promedio de este blog busca más información en castellano, quiero hacer un aporte a la comunidad con este post.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://draft.blogger.com/post-edit.g?blogID=8553642737291298841&amp;amp;postID=21819929363501961" name="lr1"&gt;&lt;/a&gt;&lt;br /&gt;&lt;h3&gt;Recursos&lt;/h3&gt;&lt;br /&gt;Para esta tarea necesitamos lo siguiente:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;b&gt;Sistema operativo&lt;/b&gt;, cualquiera compatible con Java. Aunque estos pasos funcionan en todos los sistemas operativos con Java SE 6, en este post lo orientaré más a Windows... porque el lector promedio de este blog busca más información en Windows... etc etc etc.&lt;/li&gt;&lt;li&gt;&lt;b&gt;JDK 6.&lt;/b&gt; El cual lo puedes descargar desde aquí: &lt;a href="http://java.sun.com/javase/downloads/widget/jdk6.jsp"&gt;http://java.sun.com/javase/downloads/widget/jdk6.jsp&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;GlassFish v3&lt;/b&gt;. Si no lo has instalado, aquí lo mostraremos de la manera más fácil. Puedes descargar la versión .zip desde aquí: &lt;a href="http://download.java.net/glassfish/3.0.1/release/glassfish-3.0.1-ml.zip"&gt;http://download.java.net/glassfish/3.0.1/release/glassfish-3.0.1-ml.zip&lt;/a&gt;. Esta es la versión multilingual, es decir, nos aparecerá en castellano los textos para entendernos mejor.&lt;/li&gt;&lt;li&gt;El .&lt;b&gt;war de Liferay&lt;/b&gt;: &lt;a href="http://downloads.sourceforge.net/lportal/liferay-portal-5.2.3.war"&gt;http://downloads.sourceforge.net/lportal/liferay-portal-5.2.3.war&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;Archivos adicionales&lt;/b&gt; para preconfigurar el Contenedor Web: &lt;a href="http://downloads.sourceforge.net/lportal/liferay-portal-dependencies-5.2.3.zip"&gt;http://downloads.sourceforge.net/lportal/liferay-portal-dependencies-5.2.3.zip&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;MySQL &lt;/b&gt;instalado ya sea localmente o en otro host, pero que tengamos acceso a ese computador. Pude haber hecho con PostgreSQL, pero tengo un par de inconvenientes: me han bloqueado todo tipo de instalación en el computador de donde trabajo, y... conozco casi nada sobre PostgreSQL.. así que mis disculpas a los amigos del elefantito. Pero si sois curiosos, sabréis como acomodar esto.&lt;br /&gt;&lt;b&gt;OJO&lt;/b&gt;: que sea el MySQL puro, no uno de esos que vienen enlatados con Apache + PHP + PHPMyAdmin. Ya hablaré de este paquetito *AMP en otro post, que para unos es un alivio, pero puede ser un dolor de cabeza si no se usa con prudencia. El MySQL se puede descargar desde aquí: &lt;a href="http://dev.mysql.com/downloads/mysql/"&gt;http://dev.mysql.com/downloads/mysql/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;El &lt;b&gt;JDBC&lt;/b&gt; de la base de datos que vamos a utilizar. Cómo estamos en MySQL, este se puede descargar desde aquí: &lt;a href="http://dev.mysql.com/downloads/connector/j/"&gt;http://dev.mysql.com/downloads/connector/j/&lt;/a&gt; Si decides usar otro motor de base de datos, pues no te olvides de conseguir el JDBC correspondiente.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;Hasta aquí es lo necesario para una instalación básica. Pero quiero compartir mi experiencia de esta instalación:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;b&gt;Usar el JDK de Sun.&lt;/b&gt; Toda esta instalación funciona bien con OpenJDK sobre un Ubuntu, CentOS, etc... pero el Captcha para autenticación no funciona correctamente sobre OpenJDK, por tanto usar el JDK de Sun.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Descargar el &lt;a href="http://xerces.apache.org/xerces-j/"&gt;Xerces-J&lt;/a&gt;.&lt;/b&gt; La instalación descrita aquí funciona correctamente, pero cuando se agregan nuevos portlets, el Contenedor Web no es capaz de interpretar los archivos de despliegue de ellos. Para este ejemplo usaremos la versión 2.9.0: &lt;a href="http://archive.apache.org/dist/xml/xerces-j/Xerces-J-bin.2.9.0.zip"&gt;http://archive.apache.org/dist/xml/xerces-j/Xerces-J-bin.2.9.0.zip&lt;/a&gt;&lt;/li&gt;&lt;/ol&gt;&lt;a href="http://draft.blogger.com/post-edit.g?blogID=8553642737291298841&amp;amp;postID=21819929363501961" name="lr2"&gt;&lt;/a&gt;&lt;br /&gt;&lt;h3&gt;Instalación y preconfiguración de GlassFish v3&amp;nbsp; &lt;/h3&gt;La instalación de GlassFish v3 es bastante simple, más aún si es un .zip como el que sugerí para descargar: Solo hay que descomprimirlo. Por ejemplo, lo descomprimiremos en la raíz de C: Y tendrá una estructura como esta.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_BQk94ojgkDY/TDIVcQ32p5I/AAAAAAAAC-s/YjWxG3_jIbM/s1600/gf1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://3.bp.blogspot.com/_BQk94ojgkDY/TDIVcQ32p5I/AAAAAAAAC-s/YjWxG3_jIbM/s320/gf1.jpg" width="234" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;A partir de este momento, cada vez que mencione &lt;code&gt;%GLASSFISH_HOME%&lt;/code&gt; se entenderá al directorio del GlassFish que se descomprimió. Es decir &lt;code&gt;c:\glassfishv3&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="importante"&gt;&lt;b&gt;Importante:&lt;/b&gt; Mucho se acostumbra crear una carpeta con el mismo nombre del archivo comprimido, lo cual es una práctica no recomendada aquí, ya que el comprimido ya tiene una carpeta. Si se hace eso, se tendría una carpeta llamada glassfishv3, y dentro otra vez glassfishv3, y ocasionará confusión. Por tanto, no usar la opción "crear una carpeta con el nombre del archivo .zip". Simplemente descomprimirlo directamente a la raíz de "C:". Ojo que ya lo advertí &lt;code&gt;:P&lt;/code&gt;.&lt;/div&gt;&lt;br /&gt;Ahora, extraemos el contenido del archivo liferay-portal-dependencies-5.2.3.zip en cualquier carpeta, luego tomamos los archivos .jar que se obtuvieron   y los pondremos dentro de &lt;code&gt;%GLASSFISH%\glassfish\domains\domain1\lib&lt;/code&gt;. En esta misma carpeta ponemos el .jar del JDBC de MySQL, y los archivos &lt;code&gt;xercesImpl.jar&lt;/code&gt; y &lt;code&gt;xml-apis.jar&lt;/code&gt; de Xerces&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://1.bp.blogspot.com/_BQk94ojgkDY/TD-XxqEN8iI/AAAAAAAADCE/P9nQ4k8zVfc/s1600/web-gf-files.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="300" src="http://1.bp.blogspot.com/_BQk94ojgkDY/TD-XxqEN8iI/AAAAAAAADCE/P9nQ4k8zVfc/s400/web-gf-files.jpg" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;br /&gt;Después de esto, iniciamos el GlassFish v3...&lt;br /&gt;&lt;pre&gt;&lt;code&gt;%GLASSFISH_HOME%\bin\asadmin start-domain&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_BQk94ojgkDY/TDIft5AUpeI/AAAAAAAAC-0/nQK7HHp-9GA/s1600/gf3.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="142" src="http://2.bp.blogspot.com/_BQk94ojgkDY/TDIft5AUpeI/AAAAAAAAC-0/nQK7HHp-9GA/s400/gf3.jpg" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;...  para continuar con el siguiente paso.&lt;br /&gt;&lt;br /&gt;Debemos modificar las propiedades de la máquina virtual donde se ejecutará el Liferay. Para ello seleccionamos del menú de la izquierda: Configuration &amp;gt; JVM Settings.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_BQk94ojgkDY/TDIyK_qCrvI/AAAAAAAAC_I/DFsko38AGPI/s1600/glassfish_jvm_liferay.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_BQk94ojgkDY/TDIyK_qCrvI/AAAAAAAAC_I/DFsko38AGPI/s1600/glassfish_jvm_liferay.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;Y cambiamos los valores de MaxPermSize y Xmx a los siguientes:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;-XX:MaxPermSize=256m&lt;/li&gt;&lt;li&gt;-Xmx1024m&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Clic en "Save". Detenemos el GlassFish, y lo volvemos a iniciar.&lt;br /&gt;&lt;pre&gt;&lt;code&gt;%GLASSFISH_HOME%\bin\asadmin stop-domain%GLASSFISH_HOME%\bin\asadmin start-domain&lt;/code&gt;&lt;/pre&gt;&lt;a href="http://draft.blogger.com/post-edit.g?blogID=8553642737291298841&amp;amp;postID=21819929363501961" name="lr3"&gt;&lt;/a&gt;&lt;br /&gt;&lt;h3&gt;Preparación de la base de datos&lt;/h3&gt;El Liferay utiliza una base de datos por omisión llamada &lt;a href="http://hsqldb.org/"&gt;HSQLDB&lt;/a&gt;, pero podemos configurarlo para que funcione con cualquier otra base de datos. En este caso veremos con MySQL. En sí, se necesita crear una base de datos en MySQL, configurar un Pool de Conexiones, y ajustar un poco el .war para que utilice este Pool.&lt;br /&gt;&lt;br /&gt;&lt;div class="sugerencia"&gt;&lt;b&gt;Sugerencia:&lt;/b&gt; Antes de hacer esto, recomiendo siempre crear un usuario que acceda a esta base de datos, y no usar el root para tal fin. ¿Cómo crear ese usuario?.&lt;br /&gt;Desde una ventana del símbolo del sistema, ejecutar &lt;br /&gt;&lt;pre&gt;&lt;code&gt;mysql -u root -p&lt;/code&gt;&lt;/pre&gt;Con esto se ejecutará el cliente de MySQL con el usuario root y pedirá la contraseña. Bueno, le ponemos y nos mostrará el prompt &lt;code&gt;mysql&amp;gt;&lt;/code&gt;.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Escribimos lo siguiente para crear la base de datos &lt;code&gt;lportal&lt;/code&gt;:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;create database lportal;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;y luego escribimos lo siguiente para el usuario &lt;code&gt;lportal&lt;/code&gt; que accederá a esa base de datos:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;grant all on lportal.* to lportal@localhost identified by "lportal";&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/TDIvNF24pMI/AAAAAAAAC_E/7KJdohY_PbM/s1600/liferay-mysql.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="183" src="http://1.bp.blogspot.com/_BQk94ojgkDY/TDIvNF24pMI/AAAAAAAAC_E/7KJdohY_PbM/s400/liferay-mysql.jpg" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;span id="goog_651726637"&gt;&lt;/span&gt;&lt;span id="goog_651726638"&gt;&lt;/span&gt;&lt;br /&gt;Más sobre los permisos en MySQL, aquí:&amp;nbsp;&lt;a href="http://dev.mysql.com/doc/refman/5.1/en/grant.html"&gt;http://dev.mysql.com/doc/refman/5.1/en/grant.html&lt;/a&gt;&lt;/div&gt;Ahora sí, seguimos...&lt;br /&gt;&lt;a href="http://draft.blogger.com/post-edit.g?blogID=8553642737291298841&amp;amp;postID=21819929363501961" name="lr4"&gt;&lt;/a&gt;&lt;br /&gt;&lt;h3&gt;Configuración del pool de conexiones en GFv3 para Liferay&lt;/h3&gt;Entramos a la consola web de GFv3 (http://localhost:4848) y seleccionamos del árbol de la izquierda Resources &amp;gt; JDBC &amp;gt; Connections Pool&lt;br /&gt;&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/TDIhNPk4pDI/AAAAAAAAC-4/S8DrRtCJ4lc/s1600/gf4.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://3.bp.blogspot.com/_BQk94ojgkDY/TDIhNPk4pDI/AAAAAAAAC-4/S8DrRtCJ4lc/s320/gf4.jpg" width="263" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&amp;nbsp;Hacemos clic en el botón "New..." para crear una nuevo Pool de Conexiones. Escribimos:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Name: &lt;b&gt;LiferayPool&lt;/b&gt;&lt;/li&gt;&lt;li&gt;Resource Type: &lt;b&gt;javax.sql.ConnectionPoolDataSource&lt;/b&gt;&lt;/li&gt;&lt;li&gt;Database vendor: &lt;b&gt;MySQL&lt;/b&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_BQk94ojgkDY/TDIipLo0DQI/AAAAAAAAC-8/EFMqLsq00Tg/s1600/gf5.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="181" src="http://1.bp.blogspot.com/_BQk94ojgkDY/TDIipLo0DQI/AAAAAAAAC-8/EFMqLsq00Tg/s400/gf5.jpg" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&amp;nbsp;Clic en Next.&lt;br /&gt;Ahora, se mostrarán todas las propiedades de la conexión a la base de datos. Activamos el primer check llamado Ping: Enabled. Esto nos permitirá verificar si la conexión fue correcta después de crear el pool de conexiones. Luego buscamos las siguientes propiedades, y ponemos los valores que se muestran a continuación:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;URL:&lt;b&gt;jdbc:mysql://localhost/lportal&lt;/b&gt;&lt;/li&gt;&lt;li&gt;User: &lt;b&gt;lportal&lt;/b&gt;&lt;/li&gt;&lt;li&gt;Password: &lt;b&gt;lportal&lt;/b&gt;&lt;/li&gt;&lt;li&gt;UseUnicode: &lt;b&gt;true&lt;/b&gt;&lt;/li&gt;&lt;li&gt;CharacterEncoding:&lt;b&gt;UTF-8&lt;/b&gt;&lt;/li&gt;&lt;li&gt;EmulateLocators: &lt;b&gt;true&lt;/b&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Hacemos clic en el botón "Save", y si todo está correcto, se creará sin problema.&lt;br /&gt;&lt;br /&gt;Con esto solo hemos creado un Pool de Conexión, ahora necesitamos registrarlo en el JNDI del Servidor. Para ello, seleccionamos la opción Resources &amp;gt; JDBC &amp;gt; JDBC Resources&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_BQk94ojgkDY/TDI9R7hZv8I/AAAAAAAAC_Q/NKtTQoKoS7E/s1600/liferay-jndi.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_BQk94ojgkDY/TDI9R7hZv8I/AAAAAAAAC_Q/NKtTQoKoS7E/s1600/liferay-jndi.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Hacemos clic en "New..." y escribimos los siguientes valores en los campos:&lt;br /&gt;JNDI Name:&amp;nbsp;&lt;span class="Apple-style-span" style="font-family: monospace; white-space: pre;"&gt;&lt;b&gt;jdbc/&lt;/b&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: monospace; white-space: pre;"&gt;&lt;span class="Apple-style-span" style="color: #38761d;"&gt;&lt;b&gt;L&lt;/b&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: blue;"&gt;&lt;b&gt;iferay&lt;/b&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: #38761d;"&gt;&lt;b&gt;P&lt;/b&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: blue;"&gt;&lt;b&gt;ool&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;Pool Name: &lt;b&gt;LiferayPool&lt;/b&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_BQk94ojgkDY/TDI9SB_8nII/AAAAAAAAC_U/laxxgetYp5E/s1600/liferay-jndi2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="197" src="http://3.bp.blogspot.com/_BQk94ojgkDY/TDI9SB_8nII/AAAAAAAAC_U/laxxgetYp5E/s400/liferay-jndi2.jpg" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="margin: 0px;"&gt;¡¡El nombre del recurso es importante!! Debe estar en mayúsculas y minúsculas.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Clic en OK y listo. Seguimos con el siguiente paso.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;a href="http://draft.blogger.com/post-edit.g?blogID=8553642737291298841&amp;amp;postID=21819929363501961" name="lr5"&gt;&lt;/a&gt;&lt;br /&gt;&lt;h3&gt;Despliegue del .war&lt;/h3&gt;Como comenté hace un momento, el .war de liferay está preparado para funcionar con una base de datos incrustada llamada HSQLDB. Lo que necesitamos es que se conecte a nuestro MySQL. Por algo hemos preparado el Pool de conexiones. Así que necesitamos editar un archivo llamado &lt;code&gt;portal-ext.properties&lt;/code&gt;, adjuntarle el atributo:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;jdbc.default.jndi.name=jdbc/LiferayPool &lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;... y luego ponerlo dentro del .war (en el directorio WEB-INF/classes dentro del .war) antes de desplegarlo. &lt;br /&gt;&lt;br /&gt;Notar que el nombre del JNDI (&lt;span class="Apple-style-span" style="font-family: monospace; white-space: pre;"&gt;jdbc/&lt;b&gt;&lt;span class="Apple-style-span" style="color: #38761d;"&gt;L&lt;/span&gt;&lt;span class="Apple-style-span" style="color: blue;"&gt;iferay&lt;/span&gt;&lt;span class="Apple-style-span" style="color: #38761d;"&gt;P&lt;/span&gt;&lt;span class="Apple-style-span" style="color: blue;"&gt;ool&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;) &amp;nbsp;debe ser exacto cómo se configuró en GlassFish en el paso anterior.&lt;br /&gt;&lt;br /&gt;Si te es complicado crear el archivo, aquí puedes descargarlo: &lt;a href="http://java.net/downloads/apuntes/resources/liferay/portal-ext.properties"&gt;http://java.net/downloads/apuntes/resources/liferay/portal-ext.properties&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Y si te es complicado poner el .properties dentro del .war, aquí ya tengo un .war preparado (que es el que uso en las instalaciones de Liferay)&lt;br /&gt;&lt;a href="http://java.net/downloads/apuntes/resources/liferay/liferay-portal-5.2.3.war"&gt;http://java.net/downloads/apuntes/resources/liferay/liferay-portal-5.2.3.war&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #cc0000;"&gt;&lt;b&gt;Ahora sí, tomar mucho cuidado con lo siguiente que se va a explicar respecto al despliegue del .war&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;En la consola del GlassFish, ir a la opción "Applications" del menú izquierdo, y hacemos clic en el botón "Deploy...". En la opción "Location", seleccionamos el archivo .war que de liferay. Al hacer esto, se mostrarán más opciones que corresponden a la configuración del despliegue del .war.&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: blue;"&gt;En la casilla llamada "Context Root:" aparecerá el nombre del archivo .war. &lt;/span&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="color: blue;"&gt;Borrar este nombre y poner el signo "/".&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_BQk94ojgkDY/TDIvMu7pr9I/AAAAAAAAC_A/40bs9VpX9uE/s1600/liferay-war.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="288" src="http://4.bp.blogspot.com/_BQk94ojgkDY/TDIvMu7pr9I/AAAAAAAAC_A/40bs9VpX9uE/s400/liferay-war.jpg" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Ahora, clic en "OK".&lt;br /&gt;&lt;br /&gt;Esto tomará un tiempo procesar. Aún cuando ya se haya mostrado el mensaje en GlassFish que fue desplegado correctamente, no necesariamente habrá terminado, porque estará configurando archivos, bibliotecas, creando las tablas de la base de datos, preparando otros recurso, etc etc etc. Así que en esta parte tener paciencia. Se puede revisar el log para ver en qué está. &lt;code&gt;%GLASSFISH_HOME%\glassfish\domains\domain1\logs\server.log&lt;/code&gt;.&lt;br /&gt;&lt;br /&gt;La Ruta del contexto (Context Root) es importante porque la aplicación se mostrará en la raiz del host, y varios componentes de la aplicación se ubicarán en la misma ubicación, como "/c" y "/widgets".&lt;br /&gt;&lt;a href="http://draft.blogger.com/post-edit.g?blogID=8553642737291298841&amp;amp;postID=21819929363501961" name="lr6"&gt;&lt;/a&gt;&lt;br /&gt;&lt;h3&gt;Ejecutando el Liferay&lt;/h3&gt;Después del despliegue, ya podemos verlo en funcionamiento abriendo la siguiente dirección: &lt;a href="http://localhost:8080/"&gt;http://localhost:8080&lt;/a&gt; Sin ruta de contexto, ya que (como acabo de mencionar) está en la raíz del host.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_BQk94ojgkDY/TDJD913qrwI/AAAAAAAAC_Y/ECUOJMjX5Ck/s1600/liferay-prod.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="257" src="http://4.bp.blogspot.com/_BQk94ojgkDY/TDJD913qrwI/AAAAAAAAC_Y/ECUOJMjX5Ck/s400/liferay-prod.jpg" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;El usuario creado por omisión para administrar este Portal es &lt;span class="Apple-style-span" style="color: blue;"&gt;&lt;b&gt;test@liferay.com&amp;nbsp;&lt;/b&gt;&lt;/span&gt;y su contraseña es &lt;b&gt;&lt;span class="Apple-style-span" style="color: blue;"&gt;test&lt;/span&gt;&lt;/b&gt;.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Conclusión&lt;/h3&gt;Y esto sería todo para tener en producción un Contenedor de Portlets sobre GlassFish v3. De por sí el GFv3 es pesado para manejar en desarrollo, más aún si se utiliza con Liferay, así que hay que considerarlo si se utiliza en un computador de desarrollo con pocos recursos (entiéndase, no usar Pentium D.. sino algo muy superior, ni menos con 2GB de RAM).&lt;br /&gt;&lt;br /&gt;En un siguiente Post veremos (ahora sí) cómo configurar NetBeans 6.9 con un servidor liferay y haremos nuestro primer portlet.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Hasta el siguiente post!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8553642737291298841-21819929363501961?l=www.apuntesdejava.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.apuntesdejava.com/feeds/21819929363501961/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.apuntesdejava.com/2010/07/instalacion-de-liferay-en-un-servidor.html#comment-form' title='21 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8553642737291298841/posts/default/21819929363501961'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8553642737291298841/posts/default/21819929363501961'/><link rel='alternate' type='text/html' href='http://www.apuntesdejava.com/2010/07/instalacion-de-liferay-en-un-servidor.html' title='Instalación de Liferay en un servidor GlassFish v3 para producción'/><author><name>Diego Silva</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp3.blogger.com/_BQk94ojgkDY/SCdCBn9Q_kI/AAAAAAAAAw8/_UdqOhLxqNc/S220/f1.jpg'/></author><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>21</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8553642737291298841.post-6380763892572794441</id><published>2010-07-20T00:00:00.002-05:00</published><updated>2011-02-19T18:00:15.417-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='netbeans 6.9'/><category scheme='http://www.blogger.com/atom/ns#' term='liferay'/><category scheme='http://www.blogger.com/atom/ns#' term='tutorial'/><category scheme='http://www.blogger.com/atom/ns#' term='portlets'/><category scheme='http://www.blogger.com/atom/ns#' term='netbeans'/><category scheme='http://www.blogger.com/atom/ns#' term='portalpack'/><title type='text'>Nuestro primer Portlet en Liferay</title><content type='html'>&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;Hasta el momento hemos visto cómo &lt;a href="http://www.apuntesdejava.com/2010/07/instalacion-de-liferay-en-un-servidor.html"&gt;configurar Liferay sobre un Servidor Glassfish v3 para producción&lt;/a&gt;. Esto nos permite tener un Portal en blanco listo para que nosotros le configuremos todo. Es decir, el Liferay que viene preconfigurado con el GF, Tomcat o Jetty que está disponible en la &lt;a href="http://www.liferay.com/es/downloads/liferay-portal/overview"&gt;página de descarga de liferay.com&lt;/a&gt;, tiene contenido preparado, textos de ejemplo, temas, aplicaciones completas, etc. Además que viene configurado con HSQLDB. Si al preconfigurado le cambiamos el acceso a la base de datos para que utilice el MySQL o cualquiera, en ese momento todo el contenido del Portal estará en blanco.&lt;br /&gt;&lt;br /&gt;Recomiendo la versión preconfigurada de liferay para conocer un poco cómo funciona, y además, para usarlo como caja de arena para probar nuestros portlets.&lt;br /&gt;&lt;br /&gt;En este post veremos cómo hacer un Portlet para Liferay usando NetBeans 6.x&lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;Quizás te preguntarás por qué quiero usar más GlassFish que Tomcat, así sea para una aplicación web simple. No tengo nada en contra de Tomcat, fue mi primer contenedor Servlet/JSP que utilicé (exactamente la versión 3). Es rápido y simple de usar. Pero para mi me es un problema cuando quiero gestionar con base de datos. Tomcat maneja su &lt;a href="http://tomcat.apache.org/tomcat-6.0-doc/jndi-datasource-examples-howto.html"&gt;Pool de conexiones&lt;/a&gt; de manera eficiente, pero configurarlo no es muy agradable que digamos (editar un archivo .xml que es parte del .war no creo que sea muy portable si quiero pasar de desarrollo a producción sin editar nada) Mientras que en&lt;a href="http://docs.sun.com/app/docs/doc/821-1751/ablih?l=en&amp;amp;a=view"&gt; GlassFish la configuración del DataSource&lt;/a&gt; se hace desde la misma consola del servidor.&lt;br /&gt;Bueno, esto fue un offtopic del post, explicando porqué uso más GlassFish que Tomcat.&lt;br /&gt;&lt;br /&gt;Comencemos con la preparación de nuestro NetBeans para desarrollar un portlet:&lt;br /&gt;&lt;h3&gt;Configurando NetBeans con un Servidor Liferay+Glassfish v3&lt;/h3&gt;Previamente ya debe estar instalado los &lt;a href="http://www.apuntesdejava.com/2010/07/instalando-portal-pack-en-netbeans-69.html"&gt;plugins del PortalPack, que lo vimos en un post anterior&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;b&gt;Abrimos nuestro NetBeans &lt;/b&gt;y vayamos al panel de Prestaciones (Services) con Ctrl+5. Abrimos el nodo "Servidores" y hacemos clic derecho sobre ese nodo, seleccionando la opción "Agregar Servidor".     &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&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/TD5PQ9oyyiI/AAAAAAAADAU/7rru0cD06qs/s1600/liferay-porlet2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_BQk94ojgkDY/TD5PQ9oyyiI/AAAAAAAADAU/7rru0cD06qs/s320/liferay-porlet2.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;Seleccionamos de la lista&lt;/b&gt; "Liferay Portal Server 5.1.x/5.2.x" y hacemos clic en Siguiente.   &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&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/TD5P1irCcsI/AAAAAAAADAc/Xd234XqH2y0/s1600/liferay-porlet3.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="271" src="http://1.bp.blogspot.com/_BQk94ojgkDY/TD5P1irCcsI/AAAAAAAADAc/Xd234XqH2y0/s400/liferay-porlet3.jpg" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Seleccionamos el tipo de Servidor a GlassFish, y el GlassFish Home a "C:\glassfishv3\glassfish".   &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&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;a href="http://2.bp.blogspot.com/_BQk94ojgkDY/TD-Yf-RRdpI/AAAAAAAADCM/UyYTc-ys1wY/s1600/gf-nb-add.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="230" src="http://2.bp.blogspot.com/_BQk94ojgkDY/TD-Yf-RRdpI/AAAAAAAADCM/UyYTc-ys1wY/s400/gf-nb-add.jpg" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Clic en "Siguiente". Dejamos los valores por omisión, y clic en "Terminar"&lt;/li&gt;&lt;/ol&gt;&lt;h3&gt;Ejecutando Liferay desde NetBeans&lt;/h3&gt;Bien, ahora que ya tenemos nuestro NetBeans configurado con Liferay, será bueno primero iniciar el Liferay para ver sobre donde vamos a trabajar. Para ello, hacemos clic derecho sobre el ícono del Liferay que hemos acabado de agregar al NetBeans, y seleccionamos "Start".&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/TD5SIHpWFEI/AAAAAAAADAs/hF5u8JgLjwc/s1600/liferay-porlet5.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_BQk94ojgkDY/TD5SIHpWFEI/AAAAAAAADAs/hF5u8JgLjwc/s320/liferay-porlet5.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;... y &lt;strike&gt;si tienes un computador tan lento como el que tengo en la oficina, en unas horas&lt;/strike&gt; en unos momentos, se mostrará el Liferay en el navegador.&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/TECkXQVlzHI/AAAAAAAADCo/Samo7o6TPS4/s1600/portlet-web09.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="276" src="http://2.bp.blogspot.com/_BQk94ojgkDY/TECkXQVlzHI/AAAAAAAADCo/Samo7o6TPS4/s400/portlet-web09.jpg" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Nuestro primer portlet básico&lt;/h3&gt;Un portlet es en realidad una aplicación web que se distribuye en .war y que tiene archivos .xml de despliegue adicionales. Como aplicación web, también cuenta con su ruta de contexto (context-path), sus configuraciones del web.xml y demás. Ahora con la versión JavaEE6, también puede contener EJB 3.1, ya que - como acabo de decir - es una aplicación web. Solo que esta aplicación web no se desplegará desde la consola del contenedor web, sino desde el mismo contenedor de portlets, en este caso, desde liferay.&lt;br /&gt;&lt;h4&gt;Creando un proyecto web&lt;/h4&gt;&lt;ol&gt;&lt;li&gt;Así que comencemos creando una aplicación web desde Archivo &amp;gt; Nuevo proyecto &amp;gt; Java Web &amp;gt; Web Application. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&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/TD9aFEU-ndI/AAAAAAAADBE/u6xgn3gN1DU/s1600/portlet-web01.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="272" src="http://4.bp.blogspot.com/_BQk94ojgkDY/TD9aFEU-ndI/AAAAAAAADBE/u6xgn3gN1DU/s400/portlet-web01.jpg" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Clic en Siguiente. Luego indicamos el nombre del proyecto y su ubicación. Le ponemos que se llamará SimplePortlet, y tomar la ubicación predeterminada. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&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/TD9abskU9sI/AAAAAAAADBM/UVprdSCxjCM/s1600/portlet-web02.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="272" src="http://4.bp.blogspot.com/_BQk94ojgkDY/TD9abskU9sI/AAAAAAAADBM/UVprdSCxjCM/s400/portlet-web02.jpg" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/li&gt;&lt;li&gt;Clic en Siguiente. Seleccionamos el servidor donde se desplegará. En este caso seleccionamos el que acabamos de agregar al IDE hace un momento. Notar que cuenta la versión del Java EE y la ruta de contexto.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&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/TD9a1RpDQcI/AAAAAAAADBU/kIf6NWjrOjs/s1600/portlet-web03.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="253" src="http://2.bp.blogspot.com/_BQk94ojgkDY/TD9a1RpDQcI/AAAAAAAADBU/kIf6NWjrOjs/s400/portlet-web03.jpg" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Clic en Siguiente. Cuando nos pida los "Frameworks" a utilizar, activamos el que dice "Portlet Support". Y más abajo dice "Create Portlet". Lo dejamos desactivado para crearlo posteriormente. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&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/TD9bQgzkYvI/AAAAAAAADBc/z4orECR8Rzg/s1600/portlet-web04.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="253" src="http://4.bp.blogspot.com/_BQk94ojgkDY/TD9bQgzkYvI/AAAAAAAADBc/z4orECR8Rzg/s400/portlet-web04.jpg" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Clic en Terminar.&lt;/li&gt;&lt;/ol&gt;Vemos que es un proyecto web mas archivos .xml adicionales....&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_BQk94ojgkDY/TD9fd_wz7qI/AAAAAAAADBk/5lfvVrsu4Ds/s1600/portlet-web05.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_BQk94ojgkDY/TD9fd_wz7qI/AAAAAAAADBk/5lfvVrsu4Ds/s320/portlet-web05.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;Insisto diciendo que es un proyecto web, para que no sea chocante tratar de pensar que es otro tipo de proyecto y no se hagan preguntas como:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;¿Puedo ponerle mis imágenes? ¿Dónde?&lt;/li&gt;&lt;li&gt;¿Puedo usar .css?&lt;/li&gt;&lt;li&gt;¿Puedo poner .js?&lt;/li&gt;&lt;li&gt;¿Dónde pongo las clases?&lt;/li&gt;&lt;li&gt;etc... etc.. etc&lt;/li&gt;&lt;/ul&gt;Este proyecto podrá tener más de un portlet. Así que comenzaremos a crear el primero.&lt;br /&gt;&lt;h4&gt;Creado un portlet&lt;/h4&gt;&lt;br /&gt;&lt;div class="advertencia"&gt;&lt;b&gt;Advertencia&lt;/b&gt;: Al momento de hacer este post, encontré problemas para desplegar un portlet desde NetBeans + PortalPack al Liferay/GFv3. Esto es porque el PortalPack considera que el Servidor a utilizar es Liferay/GFv2 o Tomcat. Utiliza el JSR88 para desplegarlo sobre GFv2, y este JSR88 ya no está disponible para GFv3. En resumen. Si utilizas el Liferay+GFv2, el despliegue será inmediato. Pero para este post haremos la manera no cómoda pero que funciona: desplegar el Portlet desde la Consola de Liferay.&lt;/div&gt;&lt;ol&gt;&lt;li&gt;Hagamos clic en Nuevo &amp;gt; Archivo nuevo (Ctrl+N) y seleccionamos Portlets &amp;gt; Portlet &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&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/TD9iyWNsGZI/AAAAAAAADBs/fBAlFcX8m-o/s1600/portlet-web06.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="272" src="http://3.bp.blogspot.com/_BQk94ojgkDY/TD9iyWNsGZI/AAAAAAAADBs/fBAlFcX8m-o/s400/portlet-web06.jpg" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Clic en Siguiente. Luego escogemos como nombre de la clase Portlet &lt;code&gt;FactorialPorlet&lt;/code&gt; del paquete &lt;code&gt;portlets&lt;/code&gt;. Eso es solo la característica de la clase. Pero esta clase debe tener características como Porlet, por ejemplo el nombre, descripción, etc. Así que pongamos los siguientes valores: &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;PortletName: FactorialPortlet&lt;/li&gt;&lt;li&gt;Portlet Display Name: Factorial Portlet&lt;/li&gt;&lt;li&gt;Porlet Description: Portlet que calcula el factorial&lt;/li&gt;&lt;li&gt;Portlet title: Factorial en Portlet&lt;/li&gt;&lt;li&gt;Portlet Short Title: Factorial&lt;/li&gt;&lt;li&gt;Activar los checks&amp;nbsp; "Edit" y "Help". Estas serán páginas adicionales que interactuará con el usuario.&lt;/li&gt;&lt;/ul&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_BQk94ojgkDY/TD9kKNhAzaI/AAAAAAAADB0/iI9UQd36GPI/s1600/portlet-web07.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="275" src="http://2.bp.blogspot.com/_BQk94ojgkDY/TD9kKNhAzaI/AAAAAAAADB0/iI9UQd36GPI/s400/portlet-web07.jpg" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Clic en Siguiente. Activamos el check para que nos cree los .jsp correspondientes.        &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&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/TD9klkFgsbI/AAAAAAAADB8/kFPXveMWh_Q/s1600/portlet-web08.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="156" src="http://4.bp.blogspot.com/_BQk94ojgkDY/TD9klkFgsbI/AAAAAAAADB8/kFPXveMWh_Q/s400/portlet-web08.jpg" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Clic en Terminar.&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;Con esto nos habrá creado una clase &lt;code&gt;FactorialPortlet&lt;/code&gt;, y dentro de WEB-INF/jsp estarán los archivos .jsp que serán utilizados para el interfaz de usuario.&lt;br /&gt;&lt;br /&gt;Vemos que hay dos métodos que nos llaman la atención (que nos recuerdan al doGet y doPost de los Servlets) &lt;code&gt;processAction()&lt;/code&gt;, &lt;code&gt;doView&lt;/code&gt;, &lt;code&gt;doEdit&lt;/code&gt; y &lt;code&gt;doHelp&lt;/code&gt;. Estos métodos son invocados por el Portal para mostrar una página dependiendo de la petición que haya hecho el usuario. Si solo quiere ver, se ejecutará el &lt;code&gt;doView&lt;/code&gt;, si va a editar las preferencias del portlet, ejecutará &lt;code&gt;doEdit&lt;/code&gt;, y si quiere ver la ayuda del portlet, se ejecutará &lt;code&gt;doHelp&lt;/code&gt;. Pero cuando se quiere atender una petición, se ejecutará el método &lt;code&gt;processAction()&lt;/code&gt;. Notemos que dentro está la clase &lt;code&gt;PortletRequestDispatcher&lt;/code&gt; que no es más que una especialización de la clase &lt;code&gt;RequestDispatcher&lt;/code&gt; utilizada en los servlet bajo el modelo MVC. Así que, aquí no hay modo de fallar &lt;code&gt;:)&lt;/code&gt;.&lt;br /&gt;&lt;br /&gt;Ahora, editemos el archivo &lt;code&gt;FactorialPortlet.java&lt;/code&gt; para que calcule el Factorial. Primero, el método que hace el cálculo.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;    static long factorial(long base) {        if (base &amp;lt; 2) {            return 1;        }        return base + factorial(base - 1);    }&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Y, editemos el método &lt;code&gt;processAction()&lt;/code&gt; para leer un parámetro de la web, lo calculamos, y lo mostramos al usuario.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;    public void processAction(ActionRequest request, ActionResponse response) throws PortletException, IOException {        String numero = request.getParameter("numero");        System.out.println("Parametro leido:" + numero);        if (numero != null &amp;amp;&amp;amp; !numero.isEmpty()) {            try {                long $numero = Long.parseLong(numero);                long factorial = factorial($numero);                System.out.println("resultado:" + factorial);                request.setAttribute("factorial", factorial);            } catch (NumberFormatException ex) {                ex.printStackTrace();            }        }    }&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Ahora, nos falta el formulario. Abramos el archivo &lt;code&gt;FactorialPortlet_view.jsp&lt;/code&gt;, y escribamos el siguiente código:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&amp;lt;%@page contentType="text/html"%&amp;gt;&amp;lt;%@page pageEncoding="UTF-8"%&amp;gt;&amp;lt;%@ page import="javax.portlet.*"%&amp;gt;&amp;lt;%@ taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet"%&amp;gt;&amp;lt;h3&amp;gt;Cálculo de factorial&amp;lt;/h3&amp;gt;&amp;lt;form action="&amp;lt;portlet:actionURL/&amp;gt;" method="post"&amp;gt;    Ingrese un número:    &amp;lt;input type="text" name="numero" /&amp;gt;&amp;lt;br/&amp;gt;    &amp;lt;button type="submit"&amp;gt;Calcular&amp;lt;/button&amp;gt;    &amp;lt;div&amp;gt;        Resultado: ${factorial}    &amp;lt;/div&amp;gt;&amp;lt;/form&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;La mayor parte del formulario nos es conocido: tiene input, botones, imprime resultado, etc. Pero el tag &lt;code&gt;&amp;lt;portlet:actionURL/&amp;gt;&lt;/code&gt; quizás no sea claro, pero puede darnos la idea de qué es. Este tag devuelve la ubicación del mismo portlet dentro de toda la página de portlets. Me explico mejor:&lt;br /&gt;&lt;br /&gt;Recordemos que cuando hacemos un formulario en JSP, siempre el &lt;code&gt;action&lt;/code&gt; debe apuntar a una dirección web que recibirá los parámetros del formulario: puede ser un Servlet u otro JSP. Ahora, ¿qué pasaría si tuvieramos varios forms en una misma página que apuntan a diferentes direcciones? ¿Cómo hacemos para que diferencie que un formulario es diferente a otro y diferenciar las peticiones? Pues, hacer que el url del action sea totalmente diferente. Pues bien, bajo la misma lógica, el tag &lt;code&gt;&amp;lt;portlet:actionURL/&amp;gt;&lt;/code&gt; nos ahorra saber cuál es el URL del Portlet que debemos ejecutar, además que le pone una identificación única para diferenciarlos de los demás Portlets. &lt;br /&gt;&lt;h4&gt;Creando el archivo de despliegue&lt;/h4&gt;Para crear un archivo .war que contiene el Portlet, es bastante simple. Es tan igual como cuando se crea un archivo. Clic derecho el ícono de proyecto, y seleccionar Limpiar y Construir (Clean and Build).&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/TECqa15m8OI/AAAAAAAADCw/tMrrifUJaSw/s1600/portlet-web10.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="154" src="http://4.bp.blogspot.com/_BQk94ojgkDY/TECqa15m8OI/AAAAAAAADCw/tMrrifUJaSw/s320/portlet-web10.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;Con esto, nos creará un archivo .war. Veamos donde lo creado en el panel de Salida (Ctrl+4) del NetBeans.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_BQk94ojgkDY/TEC5owugiyI/AAAAAAAADC0/cRFNYTrXJVM/s1600/portlet-web11.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="180" src="http://4.bp.blogspot.com/_BQk94ojgkDY/TEC5owugiyI/AAAAAAAADC0/cRFNYTrXJVM/s640/portlet-web11.jpg" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;h4&gt;Desplegando el .war&lt;/h4&gt;Para desplegar un .war tenemos dos maneras: la larga, y la corta. Solo mencionaré la forma corta. Es simple: basta con copiar el .war en la carpeta "deploy" del GlassFish...&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_BQk94ojgkDY/TEC6t-1cARI/AAAAAAAADDI/6e1TdIBKXW4/s1600/portlet-web16.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="248" src="http://2.bp.blogspot.com/_BQk94ojgkDY/TEC6t-1cARI/AAAAAAAADDI/6e1TdIBKXW4/s320/portlet-web16.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;...esperamos unos segundos y el archivo desparecerá. Esperamos unos segundos más y estará desplegado en el Servidor.&lt;br /&gt;&lt;h4&gt;Colocando el Portlet en el Portal&lt;/h4&gt;Primero debemos iniciar la sesión (por omisión es &lt;b&gt;test@liferay.com&lt;/b&gt; con contraseña &lt;b&gt;test&lt;/b&gt;). Luego, en&amp;nbsp;el parte superior derecha está menú "dock", al que le damos clic y seleccionamos "Add application"&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_BQk94ojgkDY/TEC5pBCFKOI/AAAAAAAADC4/6GmhAUnq2Kw/s1600/portlet-web12.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://2.bp.blogspot.com/_BQk94ojgkDY/TEC5pBCFKOI/AAAAAAAADC4/6GmhAUnq2Kw/s320/portlet-web12.jpg" width="207" /&gt;&lt;/a&gt;&lt;/div&gt;Esto hará que se muestre un panel en la margen izquierda y veamos una ventana con todas los portlets disponibles, agrupados por categorías. Nuestro portlet está en la categoría "User_Portlets".&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/TEC5p5LNK8I/AAAAAAAADDE/eQRrYKJjNBg/s1600/portlet-web15.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://1.bp.blogspot.com/_BQk94ojgkDY/TEC5p5LNK8I/AAAAAAAADDE/eQRrYKJjNBg/s320/portlet-web15.jpg" width="168" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Le damos clic en "Add" para agregar el Portlet, o si gustamos, lo arrastramos y lo soltamos en cualquier parte de la página.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_BQk94ojgkDY/TEC7ybJE0FI/AAAAAAAADDM/oU73tE6fS6g/s1600/portlet-web17.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="258" src="http://2.bp.blogspot.com/_BQk94ojgkDY/TEC7ybJE0FI/AAAAAAAADDM/oU73tE6fS6g/s400/portlet-web17.jpg" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Y lo hacemos funcionar...&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_BQk94ojgkDY/TEC8hSUq0iI/AAAAAAAADDQ/xh8lEOilzno/s1600/portlet-web18.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="204" src="http://3.bp.blogspot.com/_BQk94ojgkDY/TEC8hSUq0iI/AAAAAAAADDQ/xh8lEOilzno/s320/portlet-web18.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="color: #38761d;"&gt;&lt;b&gt;Nota:&lt;/b&gt; Para cambiar la categoría del Portlet, debemos editar el archivo &lt;code&gt;liferay-display.xml&lt;/code&gt; desde NetBeans.&lt;/div&gt;&lt;br /&gt;&lt;h3&gt;Conclusión&lt;/h3&gt;Este post me fue lo más accidentando que me he atrevido a hacer. Pudo haber sido más simple o más completo, pero a medida que hago el tutorial, también construyo el proyecto para asegurarme que todo lo que digo sea correcto. Pero me encontré con problemas de versiones, componentes faltantes, y más cosas no esperadas. Quería terminar con el .JSF, pero ya no me dio el&amp;nbsp; tiempo. Será para otro post. (También tengo que hacer cosas en donde trabajo.) En fin. Este post me motivó hacerlo ya que implementé el Liferay para el Site de la oficina donde trabajo. Aún no está del todo terminado, hicimos un par de portlets que funcionan bien, solo nos falta hacer un par más, implementar un nuevo Theme con los colores de la oficina y listo. Así que cada cosa que encuentro, lo voy colocando en mi blog.&lt;br /&gt;&lt;br /&gt;Un tip importante que aprendí cuando hemos desarrollado los portlets de manera rápida (ya que mi computador es bastante lento para desplegar un .war en liferay),  es:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Cambiar en las propiedades del proyecto a para que utilice el GlassFish v3 en lugar del Liferay&lt;/li&gt;&lt;li&gt;Desarrollar, probar, ejecutar, depurar como si se tratase de una aplicación web. Considerando los elementos de portlets, adaptar la aplicación para que funcione sin él. (Recordar que el método processAction() es similar a un Servlet, así que convendría utilizar un servlet por mientras.&lt;/li&gt;&lt;li&gt;Luego, cuando esté listo, acomodar los tags de la aplicación para pasar a liferay.&lt;/li&gt;&lt;li&gt;Cambiar en las propiedades del proyecto para que utilice Liferay en lugar de GlassFish v3.&lt;/li&gt;&lt;li&gt;Construir el .war&lt;/li&gt;&lt;li&gt;Desplegar el .war al Liferay.&lt;/li&gt;&lt;/ol&gt;&amp;nbsp;Se pueden agregar más servlets, componentes JQuery, Ajax, Dojo, etc.&lt;br /&gt;&lt;br /&gt;Espero que te haya hecho de utilidad. &lt;br /&gt;&lt;br /&gt;El proyecto que utilicé en este post está aquí: &lt;a href="http://java.net/downloads/apuntes/samples/web/SimplePortlet.tar.gz"&gt;http://java.net/downloads/apuntes/samples/web/SimplePortlet.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-6380763892572794441?l=www.apuntesdejava.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.apuntesdejava.com/feeds/6380763892572794441/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.apuntesdejava.com/2010/07/nuestro-primer-portlet-en-liferay.html#comment-form' title='8 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8553642737291298841/posts/default/6380763892572794441'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8553642737291298841/posts/default/6380763892572794441'/><link rel='alternate' type='text/html' href='http://www.apuntesdejava.com/2010/07/nuestro-primer-portlet-en-liferay.html' title='Nuestro primer Portlet en Liferay'/><author><name>Diego Silva</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp3.blogger.com/_BQk94ojgkDY/SCdCBn9Q_kI/AAAAAAAAAw8/_UdqOhLxqNc/S220/f1.jpg'/></author><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>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8553642737291298841.post-7939719032580260028</id><published>2011-02-18T15:58:00.000-05:00</published><updated>2011-02-18T15:58:21.035-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='netbeans 7.0'/><category scheme='http://www.blogger.com/atom/ns#' term='netbeans'/><category scheme='http://www.blogger.com/atom/ns#' term='base de datos'/><category scheme='http://www.blogger.com/atom/ns#' term='oracle'/><title type='text'>Driver de Oracle dentro de NetBeans 7.0</title><content type='html'>&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;</content><link rel='replies' type='application/atom+xml' href='http://www.apuntesdejava.com/feeds/7939719032580260028/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.apuntesdejava.com/2011/02/driver-de-oracle-dentro-de-netbeans-70.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8553642737291298841/posts/default/7939719032580260028'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8553642737291298841/posts/default/7939719032580260028'/><link rel='alternate' type='text/html' href='http://www.apuntesdejava.com/2011/02/driver-de-oracle-dentro-de-netbeans-70.html' title='Driver de Oracle dentro de NetBeans 7.0'/><author><name>Diego Silva</name><uri>https://profiles.google.com/107299481207026512440</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><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>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8553642737291298841.post-463310037758058432</id><published>2010-06-29T11:11:00.057-05:00</published><updated>2011-02-17T19:33:37.315-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='netbeans 6.9'/><category scheme='http://www.blogger.com/atom/ns#' term='ajax'/><category scheme='http://www.blogger.com/atom/ns#' term='tutorial'/><category scheme='http://www.blogger.com/atom/ns#' term='netbeans'/><category scheme='http://www.blogger.com/atom/ns#' term='jsf 2.0'/><category scheme='http://www.blogger.com/atom/ns#' term='jsf'/><title type='text'>Ajax en JSF 2.0 - Ejemplo 2: Tabla actualizada según se escriba</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_BQk94ojgkDY/TCUpEUCgg3I/AAAAAAAAC9w/hrdXwZBwNtQ/s1600/jsf20-con-ajax.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img src="http://2.bp.blogspot.com/_BQk94ojgkDY/TCUpEUCgg3I/AAAAAAAAC9w/hrdXwZBwNtQ/s1600/jsf20-con-ajax.png" border="0" /&gt;&lt;/a&gt;&lt;/div&gt;Siguiendo con los ejemplos &lt;strike&gt;después de mucho tiempo&lt;/strike&gt;, ahora mostraré cómo actualizar una lista dependiendo del texto que se escribe en un input-text, pero usando Ajax. Es decir, a medida que se escribe, se actualizará el contenido del texto. Todo esto usando JSF 2.0 con su tag &lt;code&gt;&amp;lt;ajax /&amp;gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;&lt;h3&gt;El EJB&lt;/h3&gt;Para comenzar, debemos tener un lista de elementos que se actualizarán de acuerdo a un parámetro. Yo tengo un EJB que hace una consulta por JPA-API a mi base de datos "samples" (Esta base de datos viene como parte de las bases de datos de ejemplo de Java DB / Apache Derby y que son accesibles desde NetBeans). La entidad que estoy manejando es el &lt;code&gt;Manufacturer&lt;/code&gt;.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code class="prettyprint"&gt;    public List&amp;lt;Manufacturer&amp;gt; findByName(String name) {        String $name = "%" + name.replaceAll(" ", "%") + "%";        CriteriaBuilder criteriaBuilder = em.getCriteriaBuilder();        CriteriaQuery&amp;lt;Manufacturer&amp;gt; criteriaQuery = criteriaBuilder.createQuery(Manufacturer.class);        Root&amp;lt;Manufacturer&amp;gt; manufacturer = criteriaQuery.from(Manufacturer.class);        criteriaQuery.select(manufacturer);        criteriaQuery.where(criteriaBuilder.like(manufacturer.get("name").as(String.class), $name));        List&amp;lt;Manufacturer&amp;gt; list = em.createQuery(criteriaQuery).getResultList();        return list;    }&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;h3&gt;El ManagedBean&lt;/h3&gt;Ahora, el ManagedBean que se comunicará con la interfaz de usuario y le dirá qué mostrar. Este tiene un atributo llamado &lt;code&gt;"nombre"&lt;/code&gt; que estará asociado al input-text del formulario que el usuario verá. Lo que escriba se guardará ahí, y será tomado para la búsqueda en la base de datos.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code class="prettyprint"&gt;@ManagedBean(name = "formBean")@SessionScopedpublic class ManufacturerManagedBean {    static final Logger LOGGER = Logger.getLogger(ManufacturerManagedBean.class.getName());    @EJB    private ManufacturerFacade manufacturerFacade; //el EJB    private String nombre = ""; //el atributo que estará asociado al input-text    private List&amp;lt;Manufacturer&amp;gt; manufacturerList; //la lista a mostrar    /** Creates a new instance of ManufacturerManagedBean */    public ManufacturerManagedBean() {    }    public String getNombre() {        return nombre;    }    public void setNombre(String nombre) {        this.nombre = nombre;    }    public List&amp;lt;Manufacturer&amp;gt; getListByName() {        if (manufacturerList == null) { //si es la primera vez que se accederá a la lista...            manufacturerList = manufacturerFacade.findByName(nombre); //... actualizar el contenido        }        return manufacturerList; //devuelve la lista con los elementos encontrados    }    public void nombreChangeListener(AjaxBehaviorEvent  event) {        //cada vez que haya un cambio en el texto, vuelve a generar la lista        manufacturerList = manufacturerFacade.findByName(nombre);    }}&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;h3&gt;El .xhtml&lt;/h3&gt;Y, en la tercera capa, vemos el .xhtml que mostrará el contenido actualizado y el formulario.&lt;br /&gt;&lt;br /&gt;El contenido será mostrado en un &lt;code&gt;&amp;lt;h:dataTable /&amp;gt; &lt;/code&gt; como cualquier resultado. Tendrá como ID=&lt;code&gt;manufacturerTable&lt;/code&gt;. Este ID es importante porque es por donde el Ajax le dirá qué elemento de la página debe actualizar.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code class="prettyprint"&gt;            &amp;lt;h:dataTable value="#{formBean.listByName}" border="1" var="item" id="manufacturerTable"&amp;gt;                &amp;lt;h:column&amp;gt;                    &amp;lt;f:facet name="header"&amp;gt;                        ID                    &amp;lt;/f:facet&amp;gt;                    &amp;lt;h:outputText value="#{item.manufacturerId}" /&amp;gt;                &amp;lt;/h:column&amp;gt;                &amp;lt;h:column&amp;gt;                    &amp;lt;f:facet name="header"&amp;gt;                        Nombre                    &amp;lt;/f:facet&amp;gt;                    &amp;lt;h:outputText value="#{item.name}" /&amp;gt;                &amp;lt;/h:column&amp;gt;                &amp;lt;h:column&amp;gt;                    &amp;lt;f:facet name="header"&amp;gt;                        e-mail                    &amp;lt;/f:facet&amp;gt;                    &amp;lt;h:outputText value="#{item.email}" /&amp;gt;                &amp;lt;/h:column&amp;gt;            &amp;lt;/h:dataTable&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Ahora, la parte más esperada: el input-text con el Ajax.&lt;br /&gt;&lt;br /&gt;Realmente consiste en un tag h:inputText que tiene dentro un tag f:ajax. El que hace realmente el trabajo es este último tag.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;            &amp;lt;h:inputText id="nombreFiltro" autocomplete="off" value="#{formBean.nombre}"  &amp;gt;                &amp;lt;f:ajax render="manufacturerTable" event="keyup" listener="#{formBean.nombreChangeListener}"/&amp;gt;            &amp;lt;/h:inputText&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;El atributo &lt;code&gt;render&lt;/code&gt; dice qué IDs del HTML se van a actualizar. Aquí dice que es el ID del dataTable. &lt;/li&gt;&lt;li&gt;El atributo &lt;code&gt;event&lt;/code&gt; dice qué evento del tag inputText (porque está manejando los eventos del tag que lo envuelve) va ejecutar el ajax. En este caso será el evento keyup del input-text.&lt;/li&gt;&lt;li&gt;El atributo &lt;code&gt;listener&lt;/code&gt; indica cuál es el método que se ejecutará cuando suceda el evento. En este caso es el método &lt;code&gt;nombreChangeListener&lt;/code&gt; del ManagedBean que hemos creado hace un momento.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Y listo, lo ejecutamos y ya.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_BQk94ojgkDY/TCUu70t_1nI/AAAAAAAAC90/99ectqqTtEo/s1600/jsf-ajax-tabla-texto.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img src="http://2.bp.blogspot.com/_BQk94ojgkDY/TCUu70t_1nI/AAAAAAAAC90/99ectqqTtEo/s640/jsf-ajax-tabla-texto.jpg" border="0" height="483" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;h3&gt;El proyecto&lt;/h3&gt;&lt;br /&gt;Este proyecto, como todos los demás, debería ejecutarse si problemas en un NetBeans IDE 6.8/6.9, usando GlassFish v3. Aquí está para descargarlo.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="https://java.net/downloads/apuntes/samples/web/JSF20AjaxTextoCambiaTabla.tar.gz"&gt;https://java.net/downloads/apuntes/samples/web/JSF20AjaxTextoCambiaTabla.tar.gz&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8553642737291298841-463310037758058432?l=www.apuntesdejava.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.apuntesdejava.com/feeds/463310037758058432/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.apuntesdejava.com/2010/06/ajax-en-jsf-20-ejemplo-2-tabla.html#comment-form' title='8 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8553642737291298841/posts/default/463310037758058432'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8553642737291298841/posts/default/463310037758058432'/><link rel='alternate' type='text/html' href='http://www.apuntesdejava.com/2010/06/ajax-en-jsf-20-ejemplo-2-tabla.html' title='Ajax en JSF 2.0 - Ejemplo 2: Tabla actualizada según se escriba'/><author><name>Diego Silva</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp3.blogger.com/_BQk94ojgkDY/SCdCBn9Q_kI/AAAAAAAAAw8/_UdqOhLxqNc/S220/f1.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_BQk94ojgkDY/TCUpEUCgg3I/AAAAAAAAC9w/hrdXwZBwNtQ/s72-c/jsf20-con-ajax.png' height='72' width='72'/><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8553642737291298841.post-1851829313234652604</id><published>2008-08-08T13:22:00.006-05:00</published><updated>2011-02-07T10:23:20.914-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='jasperreports'/><category scheme='http://www.blogger.com/atom/ns#' term='tutorial'/><category scheme='http://www.blogger.com/atom/ns#' term='reportes'/><category scheme='http://www.blogger.com/atom/ns#' term='netbeans'/><category scheme='http://www.blogger.com/atom/ns#' term='glassfish'/><category scheme='http://www.blogger.com/atom/ns#' term='ireport'/><category scheme='http://www.blogger.com/atom/ns#' term='netbeans 6.1'/><category scheme='http://www.blogger.com/atom/ns#' term='web'/><category scheme='http://www.blogger.com/atom/ns#' term='jsf'/><title type='text'>Reportes en NetBeans 6.1 con iReport/JasperReports y Visual Web JavaServer Faces</title><content type='html'>[Este tutorial también se encuentra en los &lt;a href="http://wiki.netbeans.org/Avbravo_TutorialesEspanol"&gt;tutoriales en Español de NetBeans.&lt;/a&gt; Ya que es un Wiki, se puede tener el tutorial actualizado]&lt;br /&gt;&lt;a href="http://draft.blogger.com/post-edit.g?blogID=8553642737291298841&amp;amp;postID=1851829313234652604" id="Introducci.C3.B3n" name="Introducci.C3.B3n"&gt;&lt;/a&gt;&lt;br /&gt;&lt;h3&gt;&lt;span class="mw-headline"&gt;Introducción&lt;/span&gt;&lt;/h3&gt;&lt;i&gt;Microsoft&lt;/i&gt; tiene su &lt;i&gt;Visual Studio&lt;/i&gt;, &lt;i&gt;Java&lt;/i&gt; tiene a &lt;i&gt;NetBeans&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;i&gt;Microsoft&lt;/i&gt; tiene su &lt;i&gt;Crystal Reports&lt;/i&gt;, &lt;i&gt;Java&lt;/i&gt; tiene &lt;i&gt;JasperReports&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;Java no tiene nada qué envidiar a Visual Studio. Ni menos en los reportes.&lt;br /&gt;&lt;br /&gt;JasperReports es un framework bastante completo para desarrollar reportes tanto web como desktop en Java.&lt;br /&gt;&lt;br /&gt;Aunque el formato fuente de un reporte en JasperReports es un archivo XML, existe una herramienta que permite crear un reporte de manera visual. Su nombre: iReport.&lt;br /&gt;&lt;br /&gt;Pero como estamos usando como IDE a NetBeans, podemos elaborar nuestro reporte sin salir del IDE. Para ello, existe un plugin (archivo .nbm) para NetBeans que muestra el iReport dentro del mismo IDE.&lt;br /&gt;&lt;br /&gt;&lt;a class="external free" href="http://downloads.sourceforge.net/ireport/iReport-nb-0.9.2.nbm" rel="nofollow" title="http://downloads.sourceforge.net/ireport/iReport-nb-0.9.2.nbm"&gt;http://downloads.sourceforge.net/ireport/iReport-nb-0.9.2.nbm&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://draft.blogger.com/post-edit.g?blogID=8553642737291298841&amp;amp;postID=1851829313234652604" id="Instalando_el_plugin" name="Instalando_el_plugin"&gt;&lt;/a&gt;&lt;br /&gt;&lt;h3&gt;&lt;span class="mw-headline"&gt;Instalando el plugin&lt;/span&gt;&lt;/h3&gt;Después de descargar el archivo .nbm, abrimos el IDE NetBeans. Entramos al menú Tools &amp;gt; Plugins, y en la ficha &lt;i&gt;Downloaded&lt;/i&gt;, hacemos clic en el botón &lt;i&gt;Add plugins...&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;Seleccionamos el archivo .nbm que previamente hemos descargado. Después de esto se mostrará la ventana lista para instalarse el plugin:&lt;br /&gt;&lt;br /&gt;&lt;a class="image" href="http://draft.blogger.com/File:Pantallazo-Plugins_ReportesEnNetBeansConIReport.png" title="Image:Pantallazo-Plugins_ReportesEnNetBeansConIReport.png"&gt;&lt;img alt="Image:Pantallazo-Plugins_ReportesEnNetBeansConIReport.png" border="0" height="448" src="http://wiki.netbeans.org/wiki/images/a/aa/Pantallazo-Plugins_ReportesEnNetBeansConIReport.png" width="767" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Y hacemos clic en el botón &lt;i&gt;Install&lt;/i&gt;. Se nos mostrará la siguiente ventana:&lt;br /&gt;&lt;br /&gt;&lt;a class="new" href="http://wiki.netbeans.org/wiki/index.php?title=Special:Upload&amp;amp;wpDestFile=Pantallazo-NetBeans_IDE_Installer.png" title="File:Pantallazo-NetBeans IDE Installer.png"&gt;File:Pantallazo-NetBeans IDE Installer.png&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Clic en &lt;i&gt;Next&lt;/i&gt;. Aceptamos los términos de la licencia, y hacemos clic en &lt;i&gt;Install&lt;/i&gt;. Nos mostrará la ventana de advertencia ya que el plugin es posible que no sea confiable:&lt;br /&gt;&lt;br /&gt;&lt;a class="new" href="http://wiki.netbeans.org/wiki/index.php?title=Special:Upload&amp;amp;wpDestFile=Pantallazo-Verify_Certificate.png" title="File:Pantallazo-Verify Certificate.png"&gt;File:Pantallazo-Verify Certificate.png&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Pero como sabemos de dónde lo hemos descargado, hacemos clic en &lt;i&gt;Continue&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;Al finalizar la instalación del plugin, veremos que hay una opción nueva en la barra de herramientas, &lt;br /&gt;&lt;br /&gt;&lt;a class="image" href="http://draft.blogger.com/File:Ireportnb1_ReportesEnNetBeansConIReport.jpg" title="Image:ireportnb1_ReportesEnNetBeansConIReport.jpg"&gt;&lt;img alt="Image:ireportnb1_ReportesEnNetBeansConIReport.jpg" border="0" height="63" src="http://wiki.netbeans.org/wiki/images/e/e9/Ireportnb1_ReportesEnNetBeansConIReport.jpg" width="250" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;y se muestra un panel nuevo de salida llamado "iReport output"&lt;br /&gt;&lt;br /&gt;&lt;a class="image" href="http://draft.blogger.com/File:Ireportnb2_ReportesEnNetBeansConIReport.jpg" title="Image:ireportnb2_ReportesEnNetBeansConIReport.jpg"&gt;&lt;img alt="Image:ireportnb2_ReportesEnNetBeansConIReport.jpg" border="0" height="93" src="http://wiki.netbeans.org/wiki/images/1/1c/Ireportnb2_ReportesEnNetBeansConIReport.jpg" width="195" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://draft.blogger.com/post-edit.g?blogID=8553642737291298841&amp;amp;postID=1851829313234652604" id="Verificando_la_biblioteca_instalada." name="Verificando_la_biblioteca_instalada."&gt;&lt;/a&gt;&lt;br /&gt;&lt;h4&gt;&lt;span class="mw-headline"&gt;Verificando la biblioteca instalada.&lt;/span&gt;&lt;/h4&gt;&lt;br /&gt;Entremos a &lt;i&gt;Tools &amp;gt; Libraries&lt;/i&gt; y seleccionemos la biblioteca &lt;i&gt;JasperReports 2.0.5-snapshot&lt;/i&gt;. Revisemos el panel del classpath y veremos que hay una referencia marcada de rojo.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://wiki.netbeans.org/wiki/images/5/51/Pantallazo-Library_Manager.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://wiki.netbeans.org/wiki/images/5/51/Pantallazo-Library_Manager.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Pues bien, significa que según la ubicación donde se instaló el módulo no encuentra la ubicación del .jar que necesitamos para nuestra aplicación. Por tanto, lo configuraremos manualmente.&lt;br /&gt;&lt;br /&gt;Hacemos clic en el botón &lt;i&gt;Add Jar/Folder..&lt;/i&gt; y buscamos la carpeta donde está instalada el NetBeans. Veremos que dentro hay una carpeta llamada &lt;i&gt;ireport&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://wiki.netbeans.org/wiki/images/7/75/Pantallazo-Browse_JAR-Folder.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://wiki.netbeans.org/wiki/images/7/75/Pantallazo-Browse_JAR-Folder.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Entramos a esa carpeta, luego a &lt;i&gt;modules &amp;gt; ext&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;Buscamos el archivo &lt;i&gt;jasperreports-3.0.1.jar&lt;/i&gt;,lo seleccionamos&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://wiki.netbeans.org/wiki/images/2/2d/Pantallazo-Browse_JAR-Folder-1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://wiki.netbeans.org/wiki/images/2/2d/Pantallazo-Browse_JAR-Folder-1.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;y hacemos clic en &lt;i&gt;Add JAR/Folder&lt;/i&gt;.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Como podemos deducir, el problema que no encontraba el archivo &lt;i&gt;jasperreports-2.0.5.jar&lt;/i&gt; era porque no existía. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://draft.blogger.com/post-edit.g?blogID=8553642737291298841&amp;amp;postID=1851829313234652604" id="Creando_un_proyecto" name="Creando_un_proyecto"&gt;&lt;/a&gt;&lt;br /&gt;&lt;h3&gt;&lt;span class="mw-headline"&gt;Creando un proyecto&lt;/span&gt;&lt;/h3&gt;Lo que haremos en esta aplicación es mostrar en una lista todas las personas registradas en la base de datos &lt;i&gt;TRAVEL&lt;/i&gt;. El usuario seleccionará uno de ellos, y hará clic en  un botón llamado &lt;i&gt;Mostrar Viajes&lt;/i&gt; para mostrar en un reporte todos los viajes relacionados a esta persona. Además, habrá un botón de opción (Radio Button) que permitirá escoger el formato del reporte: en PDF o en HTML.&lt;br /&gt;&lt;br /&gt;Crearemos un proyecto web llamado &lt;b&gt;TravelReport&lt;/b&gt; el cual utilizará el framework &lt;i&gt;Visual Web JavaServer Faces&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Además, agregamos la biblioteca 'JasperReports 2.0.5-snapshot'&lt;br /&gt;&lt;br /&gt;&lt;a class="new" href="http://wiki.netbeans.org/wiki/index.php?title=Special:Upload&amp;amp;wpDestFile=Pantallazo-Project_Properties_-_TravelReport.png" title="File:Pantallazo-Project Properties - TravelReport.png"&gt;File:Pantallazo-Project Properties - TravelReport.png&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://draft.blogger.com/post-edit.g?blogID=8553642737291298841&amp;amp;postID=1851829313234652604" id="La_p.C3.A1gina_con_la_lista_de_personas" name="La_p.C3.A1gina_con_la_lista_de_personas"&gt;&lt;/a&gt;&lt;br /&gt;&lt;h3&gt;&lt;span class="mw-headline"&gt;La página con la lista de personas&lt;/span&gt;&lt;/h3&gt;De la paleta de componentes seleccionamos un &lt;i&gt;Label&lt;/i&gt; y lo soltamos en el &lt;i&gt;Page1.jsp&lt;/i&gt;. El texto que tendrá el componente &lt;i&gt;label&lt;/i&gt; será "Seleccione una persona:".&lt;br /&gt;&lt;br /&gt;Además, de la paleta de componentes arrastramos un &lt;i&gt;Listbox&lt;/i&gt; y lo soltamos debajo  del &lt;i&gt;label&lt;/i&gt; que acabamos de pegar. En el panel de propiedades escribimos como &lt;i&gt;id&lt;/i&gt; de este componente el valor &lt;i&gt;personasLB&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;También pegaremos un &lt;i&gt;Radio button group&lt;/i&gt; al costado de la lista. Pondremos &lt;i&gt;formatoCG&lt;/i&gt; como valor de la propiedad &lt;i&gt;id&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Luego le damos clic derecho sobre el &lt;i&gt;Radio button group&lt;/i&gt; que acabamos de pegar y seleccionamos la opción &lt;i&gt;Configure Default Options...&lt;/i&gt; Editamos las opciones para que tengan como en la siguiente imagen:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a class="new" href="http://wiki.netbeans.org/wiki/index.php?title=Special:Upload&amp;amp;wpDestFile=Pantallazo-Options_Customizer_-_formatoCG.png" title="File:Pantallazo-Options Customizer - formatoCG.png"&gt;File:Pantallazo-Options Customizer - formatoCG.png&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Le damos nuevamente clic derecho y seleccionamos &lt;i&gt;Add Binding attribute&lt;/i&gt;. Hacemos lo mismo con el componente &lt;i&gt;personasLB&lt;/i&gt;. &lt;br /&gt;&lt;br /&gt;Para finalizar con el diseño de esta página,  pegaremos un componente &lt;i&gt;button&lt;/i&gt; y tendrá como texto "Mostrar Reporte".&lt;br /&gt;&lt;br /&gt;El diseño de la página debe quedar así:&lt;br /&gt;&lt;br /&gt;&lt;a class="new" href="http://wiki.netbeans.org/wiki/index.php?title=Special:Upload&amp;amp;wpDestFile=Pantallazo-TravelReport_-_Page1.png" title="File:Pantallazo-TravelReport - Page1.png"&gt;File:Pantallazo-TravelReport - Page1.png&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://draft.blogger.com/post-edit.g?blogID=8553642737291298841&amp;amp;postID=1851829313234652604" id="Accediendo_a_la_base_de_datos" name="Accediendo_a_la_base_de_datos"&gt;&lt;/a&gt;&lt;br /&gt;&lt;h3&gt;&lt;span class="mw-headline"&gt;Accediendo a la base de datos&lt;/span&gt;&lt;/h3&gt;&lt;br /&gt;Entramos al panel de &lt;i&gt;Services&lt;/i&gt; del panel izquierdo, o presionando Ctrl+5. Abrimos el nodo &lt;i&gt;Databases&lt;/i&gt;, hacemos clic derecho sobre la conexión a la base de datos &lt;i&gt;travel&lt;/i&gt; y seleccionamos &lt;i&gt;Connect...&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;Seleccionamos el nodo &lt;i&gt;Tables &amp;gt;&amp;gt; PERSON&lt;/i&gt;, lo arrastramos y lo soltamos sobre el componente &lt;i&gt;personasLB&lt;/i&gt;. Sabremos que se realizó ya que las opciones que se mostrarán en el diseño serán "abc" tres veces.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Hacemos clic derecho sobre &lt;i&gt;personasLB&lt;/i&gt; y seleccionamos &lt;i&gt;Bind to data..&lt;/i&gt;. Debe lucir así: &lt;br /&gt;&lt;br /&gt;&lt;a class="new" href="http://wiki.netbeans.org/wiki/index.php?title=Special:Upload&amp;amp;wpDestFile=Pantallazo-Bind_to_Data_-_personasLB.png" title="File:Pantallazo-Bind to Data - personasLB.png"&gt;File:Pantallazo-Bind to Data - personasLB.png&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://draft.blogger.com/post-edit.g?blogID=8553642737291298841&amp;amp;postID=1851829313234652604" id="Dise.C3.B1ando_el_reporte" name="Dise.C3.B1ando_el_reporte"&gt;&lt;/a&gt;&lt;br /&gt;&lt;h3&gt;&lt;span class="mw-headline"&gt;Diseñando el reporte&lt;/span&gt;&lt;/h3&gt;Lo que necesitamos antes de programar cómo debe mostrarse el reporte, es, justamente, diseñar el reporte.&lt;br /&gt;&lt;br /&gt;Presionamos Ctrl+N para mostrar el asistente para crear un nuevo archivo. Seleccionamos la categoría &lt;i&gt;Report&lt;/i&gt; y el tipo de archivo &lt;i&gt;Report&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a class="new" href="http://wiki.netbeans.org/wiki/index.php?title=Special:Upload&amp;amp;wpDestFile=Pantallazo-New_File.png" title="File:Pantallazo-New File.png"&gt;File:Pantallazo-New File.png&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Clic en el botón &lt;i&gt;Next&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;Escribimos &lt;i&gt;viajes.jrxml&lt;/i&gt; como nombre del archivo, y en el campo &lt;i&gt;Folder&lt;/i&gt; seleccionamos a través del botón &lt;i&gt;Browse&lt;/i&gt; la carpeta &lt;i&gt;src/java/travelreport&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a class="new" href="http://wiki.netbeans.org/wiki/index.php?title=Special:Upload&amp;amp;wpDestFile=Pantallazo-New_Report.png" title="File:Pantallazo-New Report.png"&gt;File:Pantallazo-New Report.png&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Clic en el botón &lt;i&gt;Next&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;En la ventana donde se selecciona el Datasource, hacemos clic en el botón &lt;i&gt;New..&lt;/i&gt;, y en la ventana de diálogo que se muestra, seleccionamos &lt;i&gt;NetBeans Database JDBC Connection&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;a class="image" href="http://draft.blogger.com/File:Pantallazo-nbjdbconn_ReportesEnNetBeansConIReport.png" title="Image:Pantallazo-nbjdbconn_ReportesEnNetBeansConIReport.png"&gt;&lt;img alt="Image:Pantallazo-nbjdbconn_ReportesEnNetBeansConIReport.png" border="0" height="533" src="http://wiki.netbeans.org/wiki/images/f/fb/Pantallazo-nbjdbconn_ReportesEnNetBeansConIReport.png" width="448" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Clic en el botón &lt;i&gt;Next&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;Escribimos '&lt;i&gt;travelDB&lt;/i&gt; como nombre, y de la lista desplegable seleccionamos la conexión para la base de datos &lt;i&gt;travel&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a class="image" href="http://draft.blogger.com/File:Pantallazo-nbjdbconn1_ReportesEnNetBeansConIReport.png" title="Image:Pantallazo-nbjdbconn1_ReportesEnNetBeansConIReport.png"&gt;&lt;img alt="Image:Pantallazo-nbjdbconn1_ReportesEnNetBeansConIReport.png" border="0" height="295" src="http://wiki.netbeans.org/wiki/images/8/80/Pantallazo-nbjdbconn1_ReportesEnNetBeansConIReport.png" width="448" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Podemos hacer clic en el botón &lt;i&gt;Test&lt;/i&gt; para comprobar que esté correcta la conexión.&lt;br /&gt;&lt;br /&gt;Clic en el botón &lt;i&gt;Save&lt;/i&gt;. &lt;br /&gt;&lt;br /&gt;Clic en el  botón &lt;i&gt;Design query&lt;/i&gt; para diseñar la consulta del reporte.&lt;br /&gt;&lt;br /&gt;En este diseñador de consultas, desplegamos la lista que se encuentra en la parte media izquierda y seleccionamos la base de datos &lt;i&gt;TRAVEL&lt;/i&gt;. Con esto se mostrarán las tablas de la base de datos.&lt;br /&gt;&lt;br /&gt;&lt;a class="new" href="http://wiki.netbeans.org/wiki/index.php?title=Special:Upload&amp;amp;wpDestFile=Pantallazo-_query1.png" title="File:Pantallazo- query1.png"&gt;File:Pantallazo- query1.png&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Hacemos doble clic en la tabla &lt;i&gt;TRIP&lt;/i&gt;. Un ícono que representa a la tabla &lt;i&gt;TRIP&lt;/i&gt; se mostrará en el panel derecho de la ventana.  Hacemos doble clic también en la tabla &lt;i&gt;TRIPTYPE&lt;/i&gt;. Veremos que se mostró la asociación existente entre ambas tablas.&lt;br /&gt;&lt;br /&gt;Activamos las casillas de verificación de los campos &lt;i&gt;DEPDATE&lt;/i&gt;, &lt;i&gt;DEPCITY&lt;/i&gt; y &lt;i&gt;DESTCITY&lt;/i&gt; de la &lt;i&gt;TRIP&lt;/i&gt;, y &lt;i&gt;DESCRIPTION&lt;/i&gt; de la tabla &lt;i&gt;TRIPTYPE&lt;/i&gt;. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Clic en el botón &lt;i&gt;Ok&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;El diseño de la consulta va a quedar así:&lt;br /&gt;&lt;br /&gt;&lt;a class="new" href="http://wiki.netbeans.org/wiki/index.php?title=Special:Upload&amp;amp;wpDestFile=Pantallazo-_query3.png" title="File:Pantallazo- query3.png"&gt;File:Pantallazo- query3.png&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Clic en el botón &lt;i&gt;Ok&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;Ahora vemos el comando SQL generada por el diseñador.&lt;br /&gt;&lt;br /&gt;&lt;a class="new" href="http://wiki.netbeans.org/wiki/index.php?title=Special:Upload&amp;amp;wpDestFile=Pantallazo-New_File-2.png" title="File:Pantallazo-New File-2.png"&gt;File:Pantallazo-New File-2.png&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Clic en el botón &lt;i&gt;Next&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;En la selección de campos, hacemos clic en el botón "&amp;gt;&amp;gt;" para agregar todos los campos en el reporte.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a class="new" href="http://wiki.netbeans.org/wiki/index.hp?title=Special:Upload&amp;amp;wpDestFile=Pantallazo-New_File-3.png" title="File:Pantallazo-New File-3.png"&gt;File:Pantallazo-New File-3.png&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Clic en el botón &lt;i&gt;Next&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;En la selección de grupos, hacemos clic en el botón &lt;i&gt;Next&lt;/i&gt;, ya que no haremos alguna agrupación en el reporte.&lt;br /&gt;&lt;br /&gt;En la selección de diseño ("Layout") del reporte, seleccionamos &lt;i&gt;Tabular Layout&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;&lt;a class="new" href="http://wiki.netbeans.org/wiki/index.php?title=Special:Upload&amp;amp;wpDestFile=Pantallazo-New_File-4.png" title="File:Pantallazo-New File-4.png"&gt;File:Pantallazo-New File-4.png&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Clic en el botón &lt;i&gt;Next&lt;/i&gt;. Finalmente, clic en el botón &lt;i&gt;Finish&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;El IDE nos mostrará el diseño del reporte que acabamos de crear utilizando el asistente. Podemos editarlo para que luzca como en la siguiente imagen:&lt;br /&gt;&lt;br /&gt;&lt;a class="new" href="http://wiki.netbeans.org/wiki/index.php?title=Special:Upload&amp;amp;wpDestFile=Pantallazo-NetBeans_IDE_6.1-reporte1.png" title="File:Pantallazo-NetBeans IDE 6.1-reporte1.png"&gt;File:Pantallazo-NetBeans IDE 6.1-reporte1.png&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://draft.blogger.com/post-edit.g?blogID=8553642737291298841&amp;amp;postID=1851829313234652604" id="Modificando_el_reporte_para_que_permita_par.C3.A1metros." name="Modificando_el_reporte_para_que_permita_par.C3.A1metros."&gt;&lt;/a&gt;&lt;br /&gt;&lt;h3&gt;&lt;span class="mw-headline"&gt;Modificando el reporte para que permita parámetros.&lt;/span&gt;&lt;/h3&gt;Entramos a la opción &lt;i&gt;Window &amp;gt; Navigating &amp;gt; Report Inspector&lt;/i&gt;. Se abrirá un panel llamado &lt;i&gt;Report Inspector&lt;/i&gt; en la parte lateral izquierda inferior.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Hacemos clic derecho sobre el nodo &lt;i&gt;Parameters&lt;/i&gt; y &lt;i&gt;Add parameter&lt;/i&gt;. Con esto se agregará un nuevo nodo llamado &lt;i&gt;parameter1&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;Lo seleccionamos y modificamos las propiedades colocando lo siguiente:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt; &lt;b&gt;name&lt;/b&gt;: personId&lt;br /&gt;&lt;/li&gt;&lt;li&gt; &lt;b&gt;Default value expresion&lt;/b&gt;: "1"&lt;br /&gt;&lt;/li&gt;&lt;li&gt; &lt;b&gt;use as a prompt&lt;/b&gt;: (sin seleccionar)&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;a class="new" href="http://wiki.netbeans.org/wiki/index.php?title=Special:Upload&amp;amp;wpDestFile=Pantallazo-NetBeans_IDE_6.1-parameterPersonId.png" title="File:Pantallazo-NetBeans IDE 6.1-parameterPersonId.png"&gt;File:Pantallazo-NetBeans IDE 6.1-parameterPersonId.png&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Hacemos clic derecho en una zona en blanco del diseñador de reportes, y seleccionamos &lt;i&gt;Edit query&lt;/i&gt;. Se nos presentará el diseñador de consultas para el reporte actual.&lt;br /&gt;&lt;br /&gt;&lt;a class="new" href="http://wiki.netbeans.org/wiki/index.php?title=Special:Upload&amp;amp;wpDestFile=Pantallazo-Report_query.png" title="File:Pantallazo-Report query.png"&gt;File:Pantallazo-Report query.png&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Tenemos dos caminos para agregar el parámetro &lt;i&gt;personId&lt;/i&gt; en la consulta&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt; Agregando el valor &lt;b&gt;WHERE TRIP.PERSONID = $P{personId}&lt;/b&gt; desde la misma ventana de edición del comando SQL.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt; Utilizando el diseñador de reporte, haciendo clic en el botón &lt;i&gt;Query designer&lt;/i&gt;. Para ello, desde el diseñador de consulta, damos clic derecho sobre el nodo &lt;i&gt;WHERE&lt;/i&gt; y seleccionamos &lt;i&gt;add condition&lt;/i&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;a class="image" href="http://draft.blogger.com/File:Pantallazo-condition_ReportesEnNetBeansConIReport.edit-1.png" title="Image:Pantallazo-condition_ReportesEnNetBeansConIReport.edit-1.png"&gt;&lt;img alt="Image:Pantallazo-condition_ReportesEnNetBeansConIReport.edit-1.png" border="0" height="267" src="http://wiki.netbeans.org/wiki/images/4/4c/Pantallazo-condition_ReportesEnNetBeansConIReport.edit-1.png" width="424" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;De cualquier manera, el query debe ser similar a este:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;SELECT&lt;br /&gt;     TRIP."DEPDATE" AS TRIP_DEPDATE,&lt;br /&gt;     TRIP."DEPCITY" AS TRIP_DEPCITY,&lt;br /&gt;     TRIP."DESTCITY" AS TRIP_DESTCITY,&lt;br /&gt;     TRIPTYPE."DESCRIPTION" AS TRIPTYPE_DESCRIPTION&lt;br /&gt;FROM&lt;br /&gt;     "TRAVEL"."TRIPTYPE" TRIPTYPE INNER JOIN "TRAVEL"."TRIP" TRIP ON TRIPTYPE."TRIPTYPEID" = TRIP."TRIPTYPEID"&lt;br /&gt;&lt;br /&gt;WHERE&lt;br /&gt;     TRIP.PERSONID = $P{personId}&lt;br /&gt;&lt;/pre&gt;Hacemos clic en el botón &lt;i&gt;Ok&lt;/i&gt; para cerrar la ventana &lt;i&gt;Report query&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;Podemos hacer clic en el botón &lt;i&gt;Preview&lt;/i&gt; de la barra de herramientas del diseño del reporte para ver una muestra de cómo se visualizaría el reporte.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://draft.blogger.com/post-edit.g?blogID=8553642737291298841&amp;amp;postID=1851829313234652604" id="Adicionando_ImageServlet_a_la_aplicaci.C3.B3n" name="Adicionando_ImageServlet_a_la_aplicaci.C3.B3n"&gt;&lt;/a&gt;&lt;br /&gt;&lt;h3&gt;&lt;span class="mw-headline"&gt;Adicionando ImageServlet a la aplicación&lt;/span&gt;&lt;/h3&gt;Los reportes HTML de JasperReports utilizan algunos recursos propios como ciertas imágenes que ayudan a mostrarse un reporte correctamente. Para ello, debemos agregar un Servlet de JasperReports para que interprete las peticiones de imágenes usando sus propios recursos.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Abrimos el archivo &lt;i&gt;web.xml&lt;/i&gt;, seleccionamos la sección &lt;i&gt;Servlets&lt;/i&gt;, y hacemos clic en el botón &lt;i&gt;Add Servlet Element&lt;/i&gt; que se encuentra en la parte superior derecha. En la ventana de diálogo que se muestra, escribimos los siguientes valores:&lt;br /&gt;&lt;br /&gt;&lt;a class="image" href="http://draft.blogger.com/File:AddImageServlet_ReportesEnNetBeansConIReport.jpg" title="Image:AddImageServlet_ReportesEnNetBeansConIReport.jpg"&gt;&lt;img alt="Image:AddImageServlet_ReportesEnNetBeansConIReport.jpg" border="0" height="259" src="http://wiki.netbeans.org/wiki/images/f/f2/AddImageServlet_ReportesEnNetBeansConIReport.jpg" width="507" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Clic en el botón &lt;i&gt;OK&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://draft.blogger.com/post-edit.g?blogID=8553642737291298841&amp;amp;postID=1851829313234652604" id="Programando_el_lanzamiento_del_reporte." name="Programando_el_lanzamiento_del_reporte."&gt;&lt;/a&gt;&lt;br /&gt;&lt;h3&gt;&lt;span class="mw-headline"&gt;Programando el lanzamiento del reporte.&lt;/span&gt;&lt;/h3&gt;Hasta ahora hemos hecho todo el diseño visual. Ahora haremos la parte de la programación del botón &lt;i&gt;Mostrar reporte&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Regresamos a la ventana &lt;i&gt;Page1.jsp&lt;/i&gt; y estando en el modo "Design" vamos a la ventana &lt;i&gt;Navigator&lt;/i&gt;. Examinamos los nodos y le damos doble clic en el nodo &lt;i&gt;ApplicationBean1&lt;/i&gt;. El código fuente de &lt;i&gt;ApplicationBean1.java&lt;/i&gt; se abrirá en el editor. &lt;br /&gt;&lt;br /&gt;&lt;div class="nb_information"&gt;&lt;b&gt;sugerencia:&lt;/b&gt; podemos escribir las siguientes líneas de código presionando Ctrl+Espacio cuando se desea escribir una clase o un método de tal manera que el IDE nos pueda sugerir cuáles son las clases que se utilizará y agregará los &lt;i&gt;imports&lt;/i&gt; necesarios.  También se puede copiar estas líneas de código y pegarlas en el editor del IDE, y luego presionar Ctrl+Mayúscula+I para importar las clases que se utilizan en la clase &lt;br /&gt;&lt;br /&gt;&lt;/div&gt;. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Agregemos el siguiente método:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;public void jasperReport(String tipo, String dataSourceName, Map&amp;lt;String, String&amp;gt; params) throws ClassNotFoundException {&lt;br /&gt;        ExternalContext econtext = getExternalContext();&lt;br /&gt;        InputStream inputStream = ApplicationBean1.class.getResourceAsStream("/travelreport/viajes.jasper");&lt;br /&gt;        if (inputStream == null) {&lt;br /&gt;            throw new ClassNotFoundException("Archivo viajes.jasper no se encontró");&lt;br /&gt;        }&lt;br /&gt;        FacesContext fcontext = FacesContext.getCurrentInstance();&lt;br /&gt;        try {&lt;br /&gt;            JRExporter exporter = null;&lt;br /&gt;            Context  ctx=new InitialContext();&lt;br /&gt;            DataSource ds=(DataSource) ctx.lookup(dataSourceName);&lt;br /&gt;            Connection conn=ds.getConnection();&lt;br /&gt;            &lt;br /&gt;            JasperPrint jasperPrint = JasperFillManager.fillReport(inputStream, params, conn);&lt;br /&gt;            HttpServletResponse response = (HttpServletResponse) econtext.getResponse();&lt;br /&gt;&lt;br /&gt;            HttpServletRequest request = (HttpServletRequest) econtext.getRequest();&lt;br /&gt;&lt;br /&gt;            response.setContentType(tipo);&lt;br /&gt;            if ("application/pdf".equals(tipo)) {&lt;br /&gt;                exporter = new JRPdfExporter();&lt;br /&gt;                exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);&lt;br /&gt;                exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, response.getOutputStream());&lt;br /&gt;            } else if ("text/html".equals(tipo)) {&lt;br /&gt;                exporter = new JRHtmlExporter();&lt;br /&gt;                exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);&lt;br /&gt;                exporter.setParameter(JRExporterParameter.OUTPUT_WRITER, response.getWriter());&lt;br /&gt;                exporter.setParameter(JRHtmlExporterParameter.IMAGES_URI, request.getContextPath() + "/image?image=");&lt;br /&gt;            }&lt;br /&gt;            if (exporter&amp;nbsp;!= null) {&lt;br /&gt;                exporter.exportReport();&lt;br /&gt;            }&lt;br /&gt;        } catch (Exception ex) {&lt;br /&gt;            Logger.getLogger(ApplicationBean1.class.getName()).log(Level.SEVERE, null, ex);&lt;br /&gt;            throw new FacesException(ex);&lt;br /&gt;        }&lt;br /&gt;        fcontext.responseComplete();&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;Ahora, desde la ventana &lt;i&gt;Page1.jsp&lt;/i&gt; hacemos doble clic en el botón &lt;i&gt;Mostrar reporte&lt;/i&gt;. Con esto se mostrará el método &lt;i&gt;button1_action()&lt;/i&gt;. Editemos el método para que luzca así:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;public String button1_action() {&lt;br /&gt;        try {&lt;br /&gt;            Map&amp;lt;String, String&amp;gt; params = new HashMap&amp;lt;String, String&amp;gt;();&lt;br /&gt;            params.put("personId", getPersonasLB().getSelected().toString());&lt;br /&gt;            String dataSourceName = getSessionBean1().getPersonRowSet().getDataSourceName();&lt;br /&gt;&lt;br /&gt;            String tipo = (String) formatoCG.getSelected();&lt;br /&gt;            getApplicationBean1().jasperReport(tipo, dataSourceName, params);&lt;br /&gt;&lt;br /&gt;        } catch (Exception ex) {&lt;br /&gt;            Logger.getLogger(Page1.class.getName()).log(Level.SEVERE, null, ex);&lt;br /&gt;            error(ex.toString());&lt;br /&gt;        }&lt;br /&gt;        return null;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;a href="http://draft.blogger.com/post-edit.g?blogID=8553642737291298841&amp;amp;postID=1851829313234652604" id="Ejecutando_la_aplicaci.C3.B3n" name="Ejecutando_la_aplicaci.C3.B3n"&gt;&lt;/a&gt;&lt;br /&gt;&lt;h3&gt;&lt;span class="mw-headline"&gt;Ejecutando la aplicación&lt;/span&gt;&lt;/h3&gt;Ejecutamos el proyecto con la tecla F6.&lt;br /&gt;&lt;br /&gt;&lt;a class="image" href="http://draft.blogger.com/File:Pantallazo-ProjectRunning_ReportesEnNetBeansConIReport.png" title="Image:Pantallazo-ProjectRunning_ReportesEnNetBeansConIReport.png"&gt;&lt;img alt="Image:Pantallazo-ProjectRunning_ReportesEnNetBeansConIReport.png" border="0" height="230" src="http://wiki.netbeans.org/wiki/images/a/aa/Pantallazo-ProjectRunning_ReportesEnNetBeansConIReport.png" width="285" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Seleccionemos una persona de la lista, seleccionamos una opción del tipo de reporte (html o pdf) y hacemos clic en el botón "Mostrar reporte".&lt;br /&gt;&lt;br /&gt;Reporte en HTML:&lt;br /&gt;&lt;br /&gt;&lt;a class="image" href="http://draft.blogger.com/File:Reporte-html1_ReportesEnNetBeansConIReport.jpg" title="Image:reporte-html1_ReportesEnNetBeansConIReport.jpg"&gt;&lt;img alt="Image:reporte-html1_ReportesEnNetBeansConIReport.jpg" border="0" height="286" src="http://wiki.netbeans.org/wiki/images/2/25/Reporte-html1_ReportesEnNetBeansConIReport.jpg" width="661" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Reporte en PDF:&lt;br /&gt;&lt;br /&gt;&lt;a class="image" href="http://draft.blogger.com/File:Reporte-pdf1_ReportesEnNetBeansConIReport.jpg" title="Image:reporte-pdf1_ReportesEnNetBeansConIReport.jpg"&gt;&lt;img alt="Image:reporte-pdf1_ReportesEnNetBeansConIReport.jpg" border="0" height="502" src="http://wiki.netbeans.org/wiki/images/8/81/Reporte-pdf1_ReportesEnNetBeansConIReport.jpg" width="1015" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://draft.blogger.com/post-edit.g?blogID=8553642737291298841&amp;amp;postID=1851829313234652604" id="Recursos" name="Recursos"&gt;&lt;/a&gt;&lt;br /&gt;&lt;h3&gt;&lt;span class="mw-headline"&gt;Recursos&lt;/span&gt;&lt;/h3&gt;El código fuente del proyecto utilizado en este tutorial se encuentra aquí &lt;a class="external free" href="http://diesil-java.googlecode.com/files/TravelReport.tar.gz" rel="nofollow" title="http://diesil-java.googlecode.com/files/TravelReport.tar.gz"&gt;http://diesil-java.googlecode.com/files/TravelReport.tar.gz&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://draft.blogger.com/post-edit.g?blogID=8553642737291298841&amp;amp;postID=1851829313234652604" id="Ver_tambi.C3.A9n" name="Ver_tambi.C3.A9n"&gt;&lt;/a&gt;&lt;br /&gt;&lt;h3&gt;&lt;span class="mw-headline"&gt;Ver también&lt;/span&gt;&lt;/h3&gt;&lt;ul&gt;&lt;li&gt; &lt;a class="external text" href="http://testwww.netbeans.org/kb/55/vwp-reports.html" rel="nofollow" title="http://testwww.netbeans.org/kb/55/vwp-reports.html"&gt;Generating Reports and PDFs From a Web Application&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt; &lt;a class="external text" href="http://www.netbeans.org/kb/60/web/databoundcomponents.html" rel="nofollow" title="http://www.netbeans.org/kb/60/web/databoundcomponents.html"&gt;Using Databound Components to Access a Database&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8553642737291298841-1851829313234652604?l=www.apuntesdejava.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.apuntesdejava.com/feeds/1851829313234652604/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.apuntesdejava.com/2008/08/reportes-en-netbeans-61-con.html#comment-form' title='2 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8553642737291298841/posts/default/1851829313234652604'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8553642737291298841/posts/default/1851829313234652604'/><link rel='alternate' type='text/html' href='http://www.apuntesdejava.com/2008/08/reportes-en-netbeans-61-con.html' title='Reportes en NetBeans 6.1 con iReport/JasperReports y Visual Web JavaServer Faces'/><author><name>Diego Silva</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp3.blogger.com/_BQk94ojgkDY/SCdCBn9Q_kI/AAAAAAAAAw8/_UdqOhLxqNc/S220/f1.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8553642737291298841.post-7575220888762751279</id><published>2011-02-03T13:48:00.000-05:00</published><updated>2011-02-03T13:48:19.932-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='swing'/><category scheme='http://www.blogger.com/atom/ns#' term='tips'/><title type='text'>JComboBox de Objetos</title><content type='html'>&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;//...&lt;br /&gt;public class Persona {&lt;br /&gt;&lt;br /&gt;    private int idPersona;&lt;br /&gt;    private String nombre;&lt;br /&gt;    private int edad;&lt;br /&gt;&lt;br /&gt;    public Persona() {&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public Persona(int idPersona, String nombre, int edad) {&lt;br /&gt;        this.idPersona = idPersona;&lt;br /&gt;        this.nombre = nombre;&lt;br /&gt;        this.edad = edad;&lt;br /&gt;    }&lt;br /&gt;//.. sus get y sets&lt;br /&gt;//...&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;//...&lt;br /&gt;        Persona[] personas=new Persona[]{&lt;br /&gt;            new Persona(10, "Albert", 20),&lt;br /&gt;            new Persona(15, "Bernard", 21),&lt;br /&gt;            new Persona(20, "Carl", 22),&lt;br /&gt;        };&lt;br /&gt;//...&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;//...&lt;br /&gt;personasCB = new JComboBox(personas);&lt;br /&gt;//...&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;//...&lt;br /&gt;Persona p = (Persona) personasCB.getSelectedItem();&lt;br /&gt;//...&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;//...&lt;br /&gt;public class Persona {&lt;br /&gt;&lt;br /&gt;    private int idPersona;&lt;br /&gt;    private String nombre;&lt;br /&gt;    private int edad;&lt;br /&gt;//...&lt;br /&gt;    @Override&lt;br /&gt;    public String toString() {&lt;br /&gt;        return nombre;&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    &lt;br /&gt;}&lt;br /&gt;//...&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;</content><link rel='replies' type='application/atom+xml' href='http://www.apuntesdejava.com/feeds/7575220888762751279/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.apuntesdejava.com/2011/02/jcombobox-de-objetos.html#comment-form' title='3 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8553642737291298841/posts/default/7575220888762751279'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8553642737291298841/posts/default/7575220888762751279'/><link rel='alternate' type='text/html' href='http://www.apuntesdejava.com/2011/02/jcombobox-de-objetos.html' title='JComboBox de Objetos'/><author><name>Diego Silva</name><uri>https://profiles.google.com/107299481207026512440</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><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>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8553642737291298841.post-7326791458112067153</id><published>2011-01-04T19:52:00.000-05:00</published><updated>2011-01-04T19:52:06.850-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='restful'/><category scheme='http://www.blogger.com/atom/ns#' term='netbeans 6.9'/><category scheme='http://www.blogger.com/atom/ns#' term='java ee'/><category scheme='http://www.blogger.com/atom/ns#' term='tutorial'/><category scheme='http://www.blogger.com/atom/ns#' term='netbeans'/><category scheme='http://www.blogger.com/atom/ns#' term='java ee 6'/><title type='text'>RESTful parte 3: Manejando colecciones de objetos y objetos complejos</title><content type='html'>&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&lt;br /&gt;@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;&lt;br /&gt;&lt;br /&gt;import javax.ejb.Stateless;&lt;br /&gt;import javax.ws.rs.Path;&lt;br /&gt;&lt;br /&gt;@Stateless&lt;br /&gt;@Path("/listaPersonas")&lt;br /&gt;public class PersonasResource {&lt;br /&gt;}&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;//...&lt;br /&gt;    static List&amp;lt;Persona&amp;gt; personas = new ArrayList&amp;lt;Persona&amp;gt;();&lt;br /&gt;&lt;br /&gt;    @POST&lt;br /&gt;    @Consumes({"application/xml", "application/json"})&lt;br /&gt;    public Response guardar(Persona p) {&lt;br /&gt;        p.setIdPersona(personas.size() + 1); //se le autoasigna un id al objeto&lt;br /&gt;        personas.add(p);&lt;br /&gt;        return Response.ok(p).build();&lt;br /&gt;    }&lt;br /&gt;//...&lt;br /&gt;&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",&lt;br /&gt;"edad":"35",&lt;br /&gt;"trabajador":"true",&lt;br /&gt;"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;&lt;br /&gt;   &amp;lt;persona id_persona="1"&amp;gt;&lt;br /&gt;       &amp;lt;fechaNacimiento&amp;gt;1976-01-01T00:00:00-05:00&amp;lt;/fechaNacimiento&amp;gt;&lt;br /&gt;       &amp;lt;nombre_persona&amp;gt;Juan Perez&amp;lt;/nombre_persona&amp;gt;&lt;br /&gt;       &amp;lt;sexo&amp;gt;0&amp;lt;/sexo&amp;gt;&lt;br /&gt;       &amp;lt;trabajador&amp;gt;true&amp;lt;/trabajador&amp;gt;&lt;br /&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) {&lt;br /&gt;        List&amp;lt;Persona&amp;gt; lista = new ArrayList&amp;lt;Persona&amp;gt;();&lt;br /&gt;        for (Persona persona : personas) {&lt;br /&gt;            if (persona.getNombre().indexOf(nombre) &amp;gt;= 0) {&lt;br /&gt;                lista.add(persona);&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;        }&lt;br /&gt;        return lista;&lt;br /&gt;    }&lt;br /&gt;&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&lt;br /&gt;    @Produces({"application/xml", "application/json"})&lt;br /&gt;    public List&amp;lt;Persona&amp;gt; buscar( String nombre) {&lt;br /&gt;        List&amp;lt;Persona&amp;gt; lista = new ArrayList&amp;lt;Persona&amp;gt;();&lt;br /&gt;        for (Persona persona : personas) {&lt;br /&gt;            if (persona.getNombre().indexOf(nombre) &amp;gt;= 0) {&lt;br /&gt;                lista.add(persona);&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;        }&lt;br /&gt;        return lista;&lt;br /&gt;    }&lt;br /&gt;&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&lt;br /&gt;    @Produces({"application/xml", "application/json"})&lt;br /&gt;    public List&amp;lt;Persona&amp;gt; buscar(@QueryParam("nombre") String nombre) {&lt;br /&gt;        List&amp;lt;Persona&amp;gt; lista = new ArrayList&amp;lt;Persona&amp;gt;();&lt;br /&gt;        for (Persona persona : personas) {&lt;br /&gt;            if (persona.getNombre().indexOf(nombre) &amp;gt;= 0) {&lt;br /&gt;                lista.add(persona);&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;        }&lt;br /&gt;        return lista;&lt;br /&gt;    }&lt;br /&gt;&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&lt;br /&gt;    @Produces({"application/xml", "application/json"})&lt;br /&gt;    public List&amp;lt;Persona&amp;gt; buscar(@QueryParam("name") String nombre) {&lt;br /&gt;//...&lt;br /&gt;    }&lt;br /&gt;&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 {&lt;br /&gt;&lt;br /&gt;    private String numero;&lt;br /&gt;    private String area;&lt;br /&gt;&lt;br /&gt;    public String getArea() {&lt;br /&gt;        return area;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public void setArea(String area) {&lt;br /&gt;        this.area = area;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public String getNumero() {&lt;br /&gt;        return numero;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public void setNumero(String numero) {&lt;br /&gt;        this.numero = numero;&lt;br /&gt;    }&lt;br /&gt;}&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;&lt;br /&gt;public class Persona {&lt;br /&gt;//....&lt;br /&gt;    private List&amp;lt;Telefono&amp;gt; telefonos;&lt;br /&gt;&lt;br /&gt;    public List&amp;lt;Telefono&amp;gt; getTelefonos() {&lt;br /&gt;        return telefonos;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public void setTelefonos(List&amp;lt;Telefono&amp;gt; telefonos) {&lt;br /&gt;        this.telefonos = telefonos;&lt;br /&gt;    }&lt;br /&gt;//....&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;{&lt;br /&gt;  "nombre_persona":"Carl",&lt;br /&gt;  "telefonos"     :[&lt;br /&gt;                    {"area":"51","numero":"12345"},&lt;br /&gt;                    {"area":"54","numero":"98765"}&lt;br /&gt;                   ]&lt;br /&gt;}&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;</content><link rel='replies' type='application/atom+xml' href='http://www.apuntesdejava.com/feeds/7326791458112067153/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.apuntesdejava.com/2011/01/restful-parte-3-manejando-colecciones.html#comment-form' title='6 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8553642737291298841/posts/default/7326791458112067153'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8553642737291298841/posts/default/7326791458112067153'/><link rel='alternate' type='text/html' href='http://www.apuntesdejava.com/2011/01/restful-parte-3-manejando-colecciones.html' title='RESTful parte 3: Manejando colecciones de objetos y objetos complejos'/><author><name>Diego Silva</name><uri>https://profiles.google.com/107299481207026512440</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><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>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8553642737291298841.post-2458644757144780590</id><published>2010-12-09T11:05:00.000-05:00</published><updated>2010-12-09T11:05:52.389-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='off topic'/><title type='text'>Delay</title><content type='html'>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;</content><link rel='replies' type='application/atom+xml' href='http://www.apuntesdejava.com/feeds/2458644757144780590/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.apuntesdejava.com/2010/12/delay.html#comment-form' title='1 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8553642737291298841/posts/default/2458644757144780590'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8553642737291298841/posts/default/2458644757144780590'/><link rel='alternate' type='text/html' href='http://www.apuntesdejava.com/2010/12/delay.html' title='Delay'/><author><name>Diego Silva</name><uri>https://profiles.google.com/107299481207026512440</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8553642737291298841.post-7348433803573134313</id><published>2010-11-25T05:15:00.004-05:00</published><updated>2010-11-25T14:53:39.403-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='restful'/><category scheme='http://www.blogger.com/atom/ns#' term='netbeans 6.9'/><category scheme='http://www.blogger.com/atom/ns#' term='java ee'/><category scheme='http://www.blogger.com/atom/ns#' term='tutorial'/><category scheme='http://www.blogger.com/atom/ns#' term='netbeans'/><category scheme='http://www.blogger.com/atom/ns#' term='java ee 6'/><title type='text'>RESTful - Parte 2: Manejando un solo objeto</title><content type='html'>&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;&lt;br /&gt;public class Persona {&lt;br /&gt;&lt;br /&gt;    private int idPersona;&lt;br /&gt;    private String nombre;&lt;br /&gt;    private java.util.Date fechaNacimiento;&lt;br /&gt;    private boolean trabajador;&lt;br /&gt;    private char sexo;&lt;br /&gt;//...&lt;br /&gt;&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;&lt;br /&gt;@XmlRootElement&lt;br /&gt;public class Persona {&lt;br /&gt;&lt;br /&gt;    private int idPersona;&lt;br /&gt;    private String nombre;&lt;br /&gt;    private java.util.Date fechaNacimiento;&lt;br /&gt;    private boolean trabajador;&lt;br /&gt;    private char sexo;&lt;br /&gt;//...&lt;br /&gt;&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;&lt;br /&gt;@Stateless&lt;br /&gt;@Path("/personas")&lt;br /&gt;public class PersonaResource {&lt;br /&gt;&lt;br /&gt;    static Persona persona;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&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;&lt;br /&gt;//...&lt;br /&gt;    @GET&lt;br /&gt;    public Persona leer(){&lt;br /&gt;        return persona;&lt;br /&gt;    } &lt;br /&gt;//...&lt;br /&gt;&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;&lt;br /&gt;//...&lt;br /&gt;    @POST&lt;br /&gt;    public void guardar(Persona p) {&lt;br /&gt;        persona = p;&lt;br /&gt;&lt;br /&gt;    }&lt;br /&gt;//...&lt;br /&gt;&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;&lt;br /&gt;//...&lt;br /&gt;    @POST&lt;br /&gt;    public Response guardar(Persona p) {&lt;br /&gt;        persona = p;&lt;br /&gt;        return Response.ok(p).build();&lt;br /&gt;    }&lt;br /&gt;//...&lt;br /&gt;&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;&lt;br /&gt;&amp;lt;persona&amp;gt;&lt;br /&gt;       &amp;lt;idPersona&amp;gt;20&amp;lt;/idPersona&amp;gt;&lt;br /&gt;       &amp;lt;nombre&amp;gt;Albert&amp;lt;/nombre&amp;gt;&lt;br /&gt;       &amp;lt;trabajador&amp;gt;true&amp;lt;/trabajador&amp;gt;&lt;br /&gt;&amp;lt;/persona&amp;gt; &lt;br /&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;&lt;br /&gt;//...&lt;br /&gt;    @POST&lt;br /&gt;    @Consumes("application/xml")&lt;br /&gt;    public Response guardar(Persona p) {&lt;br /&gt;        persona = p;&lt;br /&gt;        return Response.ok(p).build();&lt;br /&gt;    }&lt;br /&gt;//...&lt;br /&gt;&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;&lt;br /&gt;//...&lt;br /&gt;    @POST&lt;br /&gt;    @Consumes({"application/xml","application/json"})&lt;br /&gt;    public Response guardar(Persona p) {&lt;br /&gt;        persona = p;&lt;br /&gt;        return Response.ok(p).build();&lt;br /&gt;    }&lt;br /&gt;//...&lt;br /&gt;&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;&lt;br /&gt;{  "idPersona":"20",&lt;br /&gt;   "nombre":"Bernard",&lt;br /&gt;   "trabajador":"true"&lt;br /&gt;}&lt;br /&gt;&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;&lt;br /&gt;//...&lt;br /&gt;    @GET&lt;br /&gt;    @Produces({"application/json","application/xml"})&lt;br /&gt;    public Persona leer() {&lt;br /&gt;        return persona;&lt;br /&gt;    }&lt;br /&gt;//...&lt;br /&gt;&lt;br /&gt;&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;&lt;br /&gt;//...&lt;br /&gt;&lt;br /&gt;    @XmlElement(name = "id_persona")&lt;br /&gt;    public int getIdPersona() {&lt;br /&gt;        return idPersona;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    @XmlElement(name = "nombre_persona")&lt;br /&gt;    public String getNombre() {&lt;br /&gt;        return nombre;&lt;br /&gt;    }&lt;br /&gt;//...&lt;br /&gt;&lt;br /&gt;&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;&lt;br /&gt;//...&lt;br /&gt;&lt;br /&gt;    @XmlElement(name = "id_persona")&lt;br /&gt;    public int getIdPersona() {&lt;br /&gt;        return idPersona;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;//...&lt;br /&gt;&lt;br /&gt;&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;&lt;br /&gt;{  "@id_persona":"20",&lt;br /&gt;   "nombre_persona":"Bernard",&lt;br /&gt;   "trabajador":"true"&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&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;</content><link rel='replies' type='application/atom+xml' href='http://www.apuntesdejava.com/feeds/7348433803573134313/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.apuntesdejava.com/2010/11/restful-la-forma-mas-ligera-de-hacer_25.html#comment-form' title='6 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8553642737291298841/posts/default/7348433803573134313'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8553642737291298841/posts/default/7348433803573134313'/><link rel='alternate' type='text/html' href='http://www.apuntesdejava.com/2010/11/restful-la-forma-mas-ligera-de-hacer_25.html' title='RESTful - Parte 2: Manejando un solo objeto'/><author><name>Diego Silva</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp3.blogger.com/_BQk94ojgkDY/SCdCBn9Q_kI/AAAAAAAAAw8/_UdqOhLxqNc/S220/f1.jpg'/></author><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>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8553642737291298841.post-5074444767576935232</id><published>2010-11-16T00:00:00.123-05:00</published><updated>2010-11-16T00:00:05.966-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='java 7'/><category scheme='http://www.blogger.com/atom/ns#' term='netbeans 7.0'/><category scheme='http://www.blogger.com/atom/ns#' term='netbeans'/><category scheme='http://www.blogger.com/atom/ns#' term='jdk 7'/><category scheme='http://www.blogger.com/atom/ns#' term='jdk'/><title type='text'>Lo que se viene con JDK 7 &amp; NetBeans 7</title><content type='html'>&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;&lt;br /&gt;        File f=new File("d://temp.xml");&lt;br /&gt;        try {&lt;br /&gt;            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();&lt;br /&gt;            DocumentBuilder builder = factory.newDocumentBuilder();&lt;br /&gt;            Document d = builder.parse(f);&lt;br /&gt;        } catch (SAXException ex) {&lt;br /&gt;            ex.printStackTrace();&lt;br /&gt;        } catch (IOException ex) {&lt;br /&gt;            ex.printStackTrace();&lt;br /&gt;        } catch (ParserConfigurationException ex) {&lt;br /&gt;            ex.printStackTrace();&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;&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;</content><link rel='replies' type='application/atom+xml' href='http://www.apuntesdejava.com/feeds/5074444767576935232/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.apuntesdejava.com/2010/11/lo-que-se-viene-con-jdk-7-netbeans-7.html#comment-form' title='2 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8553642737291298841/posts/default/5074444767576935232'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8553642737291298841/posts/default/5074444767576935232'/><link rel='alternate' type='text/html' href='http://www.apuntesdejava.com/2010/11/lo-que-se-viene-con-jdk-7-netbeans-7.html' title='Lo que se viene con JDK 7 &amp; NetBeans 7'/><author><name>Diego Silva</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp3.blogger.com/_BQk94ojgkDY/SCdCBn9Q_kI/AAAAAAAAAw8/_UdqOhLxqNc/S220/f1.jpg'/></author><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>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8553642737291298841.post-4747312675825407855</id><published>2010-08-18T16:19:00.001-05:00</published><updated>2010-11-04T13:26:43.454-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='java ee'/><category scheme='http://www.blogger.com/atom/ns#' term='tips'/><category scheme='http://www.blogger.com/atom/ns#' term='web'/><category scheme='http://www.blogger.com/atom/ns#' term='servlets'/><title type='text'>Descargar XLS y PDF sin abrirlos en el navegador (versión Servlet)</title><content type='html'>&lt;div class="separator" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em; text-align: center;"&gt;&lt;img border="0" height="76" src="http://4.bp.blogspot.com/_BQk94ojgkDY/TGxMZ09g_UI/AAAAAAAADFQ/y0FU9pBvvC4/s200/download-button.jpg" width="80" /&gt; &lt;/div&gt;&lt;br /&gt;Anteriormente hice un post de cómo "&lt;a href="http://www.apuntesdejava.com/2007/04/descargar-xls-y-pdf-sin-abrirlos-en-el.html"&gt;Descargar XLS y PDF sin abrirlos en el navegador&lt;/a&gt;" pero fue realizado con PHP. Ahora les traigo el mismo ejemplo pero usando Servlet&lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Para realizar esto, es necesario tener un Servlet que reciba como parametro el &lt;code&gt;url&lt;/code&gt; que le indica dónde está el archivo a mostrar para descargar. En este ejemplo he preparado para que descargue desde cualquier host.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;    protected void doGet(HttpServletRequest request, HttpServletResponse response)&lt;br /&gt;            throws ServletException, IOException {&lt;br /&gt;        String paramUrl = request.getParameter("url"); //el URL enviado como parametro&lt;br /&gt;        URL url = new URL(paramUrl);&lt;br /&gt;&lt;br /&gt;        response.setContentType("application/octet-strem");&lt;br /&gt;        response.setHeader("Content-Disposition", "attachment;filename='" + url.getFile() + "'"); //preparando el 'download' al navegador&lt;br /&gt;&lt;br /&gt;        URLConnection connection = url.openConnection();&lt;br /&gt;        InputStream in = connection.getInputStream(); //conectando para descargar&lt;br /&gt;        OutputStream out = new DataOutputStream(response.getOutputStream());&lt;br /&gt;&lt;br /&gt;        byte[] buffer = new byte[BUFFER_SIZE];&lt;br /&gt;        int sizeRead = 0;&lt;br /&gt;        while ((sizeRead = in.read(buffer)) &amp;gt;= 0) { //leyendo del host&lt;br /&gt;            out.write(buffer, 0, sizeRead); //escribiendo para el navegador&lt;br /&gt;        }&lt;br /&gt;        in.close(); // y cerrando&lt;br /&gt;        out.close(); // todo&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;    }&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;El proyecto utilizado para este ejemplo se encuentra aquí:&lt;br /&gt;&lt;a href="http://kenai.com/projects/apuntes/downloads/download/ejemplos%252Fweb%252FDescargarWebApp.tar.gz"&gt;http://kenai.com/projects/apuntes/downloads/download/ejemplos%252Fweb%252FDescargarWebApp.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-4747312675825407855?l=www.apuntesdejava.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.apuntesdejava.com/feeds/4747312675825407855/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.apuntesdejava.com/2010/08/descargar-xls-y-pdf-sin-abrirlos-en-el.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8553642737291298841/posts/default/4747312675825407855'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8553642737291298841/posts/default/4747312675825407855'/><link rel='alternate' type='text/html' href='http://www.apuntesdejava.com/2010/08/descargar-xls-y-pdf-sin-abrirlos-en-el.html' title='Descargar XLS y PDF sin abrirlos en el navegador (versión Servlet)'/><author><name>Diego Silva</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp3.blogger.com/_BQk94ojgkDY/SCdCBn9Q_kI/AAAAAAAAAw8/_UdqOhLxqNc/S220/f1.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_BQk94ojgkDY/TGxMZ09g_UI/AAAAAAAADFQ/y0FU9pBvvC4/s72-c/download-button.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8553642737291298841.post-9026954184222505327</id><published>2010-09-09T19:00:00.001-05:00</published><updated>2010-11-04T13:19:48.571-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='glassfish v3'/><category scheme='http://www.blogger.com/atom/ns#' term='liferay'/><category scheme='http://www.blogger.com/atom/ns#' term='tutorial'/><category scheme='http://www.blogger.com/atom/ns#' term='portlets'/><category scheme='http://www.blogger.com/atom/ns#' term='glassfish'/><title type='text'>Instalando Liferay 6 en GlassFish v3</title><content type='html'>&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;Retomando los tutoriales, ahora vengo con lo de la instalación de Liferay 6 en GlassFish v3.&lt;br /&gt;&lt;br /&gt;La verdad, es casi lo mismo que está explicado en el anterior post "&lt;a href="http://www.apuntesdejava.com/2010/07/instalacion-de-liferay-en-un-servidor.html"&gt;Instalación de Liferay en un servidor GF v3 para producción&lt;/a&gt;", con la excepción de que se debe considerar algunos cambios:&lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;Los archivos se deben descargar de aquí (al momento que se escribió este post, la versión disponible es la 6.0.5): &lt;a href="https://sourceforge.net/projects/lportal/files/Liferay%20Portal/6.0.5/"&gt;https://sourceforge.net/projects/lportal/files/Liferay Portal/6.0.5/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://draft.blogger.com/goog_791314962"&gt;&lt;/a&gt;&lt;br /&gt;Dentro hay varios archivos, los principales que vamos a utilizar para desplegar el liferay son los siguientes:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Bibliotecas de dependencias: &lt;a href="https://sourceforge.net/projects/lportal/files/Liferay%20Portal/6.0.5/liferay-portal-dependencies-6.0.5.zip/download"&gt;https://sourceforge.net/projects/lportal/files/Liferay Portal/6.0.5/liferay-portal-dependencies-6.0.5.zip/download&lt;/a&gt;&lt;/li&gt;&lt;li&gt;.War del portal: &lt;a href="https://sourceforge.net/projects/lportal/files/Liferay%20Portal/6.0.5/liferay-portal-6.0.5.war/download"&gt;https://sourceforge.net/projects/lportal/files/Liferay Portal/6.0.5/liferay-portal-6.0.5.war/download&lt;/a&gt; &lt;/li&gt;&lt;/ul&gt;&lt;div style="color: #cc0000;"&gt;&lt;b&gt;Nota:&lt;/b&gt;&lt;/div&gt;&lt;ul&gt;&lt;li&gt;No se necesitará el archivo &lt;code&gt;XercesImpl.jar&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;Se debe reemplazar un archivo del GlassFish. Este archivo se llama &lt;code&gt;commons-codec-repackaged.jar&lt;/code&gt; y se encuentra dentro de &lt;code&gt;$GLASSFISH_HOME/glassfish/modules&lt;/code&gt;. En su lugar debe estar la biblioteca &lt;code&gt;commons-codec.jar&lt;/code&gt;. Esta se puede obtener desde aquí: &lt;a href="http://commons.apache.org/codec/"&gt;http://commons.apache.org/codec/&lt;/a&gt; (Exactamente, 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;/li&gt;&lt;li&gt;Cuando se configure el Pool de Conexiones para LiferayPool, poner &lt;code&gt;emulateLocators=false&lt;/code&gt; &lt;/li&gt;&lt;/ul&gt;Todo lo demás, es exactamente lo mismo como se explicó en el anterior post. Hasta también podeis usar el &lt;code&gt;portal-ext.properties&lt;/code&gt; para utilizar la base de datos como Pool de Conexiones: &lt;a href="http://kenai.com/projects/apuntes/downloads/download/ejemplos%252Fliferay%252Fportal-ext.properties"&gt;http://kenai.com/projects/apuntes/downloads/download/ejemplos%252Fliferay%252Fportal-ext.properties&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;¿Y la migración desde una versión anterior?&amp;nbsp; La verdad me está resultando difícil. A mi me interesa, ya que tengo un portal que quiero migrarlo a esta nueva versión. Así que ya os avisaré cuando lo haya logrado.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8553642737291298841-9026954184222505327?l=www.apuntesdejava.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.apuntesdejava.com/feeds/9026954184222505327/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.apuntesdejava.com/2010/09/instalando-liferay-6-en-glassfish-v3.html#comment-form' title='2 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8553642737291298841/posts/default/9026954184222505327'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8553642737291298841/posts/default/9026954184222505327'/><link rel='alternate' type='text/html' href='http://www.apuntesdejava.com/2010/09/instalando-liferay-6-en-glassfish-v3.html' title='Instalando Liferay 6 en GlassFish v3'/><author><name>Diego Silva</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp3.blogger.com/_BQk94ojgkDY/SCdCBn9Q_kI/AAAAAAAAAw8/_UdqOhLxqNc/S220/f1.jpg'/></author><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>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8553642737291298841.post-4510006804083051112</id><published>2010-09-22T01:51:00.001-05:00</published><updated>2010-11-04T13:10:43.763-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='netbeans 6.9'/><category scheme='http://www.blogger.com/atom/ns#' term='liferay'/><category scheme='http://www.blogger.com/atom/ns#' term='tutorial'/><category scheme='http://www.blogger.com/atom/ns#' term='netbeans'/><category scheme='http://www.blogger.com/atom/ns#' term='portalpack'/><category scheme='http://www.blogger.com/atom/ns#' term='trucos'/><title type='text'>Liferay: Registrando varios usuarios (usando complemento Hook)</title><content type='html'>&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;&lt;br /&gt;    private void doRun(long companyId) {&lt;br /&gt;&lt;br /&gt;        try {&lt;br /&gt;            String firstName = "Diego";&lt;br /&gt;            String lastName = "Silva";&lt;br /&gt;            boolean male = true;&lt;br /&gt;            String jobTitle = "Consultor Java";&lt;br /&gt;            String screenName = "diego.silva";&lt;br /&gt;            long creatorUserId = 0;&lt;br /&gt;            long facebookId = 0;&lt;br /&gt;            boolean autoPassword = false;&lt;br /&gt;            String password1 = screenName;&lt;br /&gt;            String password2 = password1;&lt;br /&gt;            boolean autoScreenName = false;&lt;br /&gt;            String emailAddress = screenName + "@apuntesdejava.com";&lt;br /&gt;            String openId = StringPool.BLANK;&lt;br /&gt;            Locale locale = new Locale("ES", "PE");&lt;br /&gt;            String middleName = StringPool.BLANK;&lt;br /&gt;            int prefixId = 0;&lt;br /&gt;            int suffixId = 0;&lt;br /&gt;            int birthdayMonth = Calendar.MARCH;&lt;br /&gt;            int birthdayDay = 27;&lt;br /&gt;            int birthdayYear = 1976;&lt;br /&gt;            Country country = CountryServiceUtil.getCountryByA2("PE");&lt;br /&gt;            long countryId = country.getCountryId();&lt;br /&gt;            long regionId = 0;&lt;br /&gt;            Group guestGroup = GroupLocalServiceUtil.getGroup(companyId, GroupConstants.GUEST);&lt;br /&gt;            long[] groupIds = new long[]{guestGroup.getGroupId()};&lt;br /&gt;            long[] userGroupIds = null;&lt;br /&gt;            boolean sendEmail = false;&lt;br /&gt;            Role adminRole = RoleLocalServiceUtil.getRole(&lt;br /&gt;                    companyId, RoleConstants.ADMINISTRATOR);&lt;br /&gt;&lt;br /&gt;            Role powerUserRole = RoleLocalServiceUtil.getRole(&lt;br /&gt;                    companyId, RoleConstants.POWER_USER);&lt;br /&gt;            long[] roleIds = new long[]{&lt;br /&gt;                adminRole.getRoleId(), powerUserRole.getRoleId()&lt;br /&gt;            };&lt;br /&gt;            int statusId = GetterUtil.getInteger(PropsUtil.get("sql.data.com.liferay.portal.model.ListType.organization.status"));&lt;br /&gt;            String comments = null;&lt;br /&gt;            ServiceContext serviceContext = null;&lt;br /&gt;            System.out.print("Creando organización...");&lt;br /&gt;            //creando la organización&lt;br /&gt;            long userId=UserLocalServiceUtil.getDefaultUserId(companyId);&lt;br /&gt;            long parentOrganizationId =&lt;br /&gt;   OrganizationConstants.DEFAULT_PARENT_ORGANIZATION_ID;&lt;br /&gt;            boolean recursable = true;&lt;br /&gt;            Organization apuntesOrganization = OrganizationLocalServiceUtil.addOrganization(userId, parentOrganizationId, "Apuntes de Java",&lt;br /&gt;                    OrganizationConstants.TYPE_REGULAR_ORGANIZATION,&lt;br /&gt;                    recursable, regionId, countryId, statusId,&lt;br /&gt;                    comments, serviceContext);&lt;br /&gt;            long[] organizationIds = new long[]{apuntesOrganization.getOrganizationId()};&lt;br /&gt;            System.out.println("... registrado con ID:"+apuntesOrganization.getOrganizationId());&lt;br /&gt;            //registrando el usuario&lt;br /&gt;            System.out.print("Creando usuario...");&lt;br /&gt;            User user = UserLocalServiceUtil.addUser(creatorUserId, companyId,&lt;br /&gt;                    autoPassword, password1, password2,&lt;br /&gt;                    autoScreenName, screenName, emailAddress, facebookId,&lt;br /&gt;                    openId, locale,&lt;br /&gt;                    firstName, middleName, lastName,&lt;br /&gt;                    prefixId, suffixId, male, birthdayMonth,&lt;br /&gt;                    birthdayDay, birthdayYear,&lt;br /&gt;                    jobTitle, groupIds, organizationIds,&lt;br /&gt;                    roleIds, userGroupIds, sendEmail, serviceContext);&lt;br /&gt;            System.out.println("... creado con ID:"+user.getUserId());&lt;br /&gt;        } catch (PortalException ex) {&lt;br /&gt;            LOGGER.log(Level.SEVERE, null, ex);&lt;br /&gt;        } catch (SystemException ex) {&lt;br /&gt;            LOGGER.log(Level.SEVERE, null, ex);&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&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;</content><link rel='replies' type='application/atom+xml' href='http://www.apuntesdejava.com/feeds/4510006804083051112/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.apuntesdejava.com/2010/09/liferay-registrando-varios-usuarios.html#comment-form' title='8 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8553642737291298841/posts/default/4510006804083051112'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8553642737291298841/posts/default/4510006804083051112'/><link rel='alternate' type='text/html' href='http://www.apuntesdejava.com/2010/09/liferay-registrando-varios-usuarios.html' title='Liferay: Registrando varios usuarios (usando complemento Hook)'/><author><name>Diego Silva</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp3.blogger.com/_BQk94ojgkDY/SCdCBn9Q_kI/AAAAAAAAAw8/_UdqOhLxqNc/S220/f1.jpg'/></author><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>8</thr:total></entry></feed>
