6 Replies Latest reply on Nov 15, 2006 6:41 AM by gllambi

    Injection and remoting

    gllambi

      Injection works well if an action is made with remoting?

      I've got a web application similar to the Register example that comes with Seam, but the action in the button is made using Remoting. The problem here is that the Login Bean (Entity) doesn't inject in the Register Session Bean. Do I have to inject it manually?

      In the same example, I used ajax4jsf and the injection was done correctly. Can anyone explain me why with ajax4jsf this works and why not with remoting?

      Thanks a lot.

        • 1. Re: Injection and remoting
          shane.bryzak

          Injection should work just fine. Can you post a code sample?

          • 2. Re: Injection and remoting
            gllambi

             

            "sbryzak2" wrote:
            Injection should work just fine. Can you post a code sample?


            Here is the Session Bean

            package org.seam.ejemplo.login.session;
            
            import java.util.List;
            
            import javax.ejb.Stateless;
            import javax.persistence.EntityManager;
            import javax.persistence.PersistenceContext;
            
            import org.jboss.seam.annotations.In;
            import org.jboss.seam.annotations.Logger;
            import org.jboss.seam.annotations.Name;
            import org.jboss.seam.core.FacesMessages;
            import org.jboss.seam.log.Log;
            import org.seam.ejemplo.login.beans.Cliente;
            
            /**
             * @author gllambi
             *
             */
            @Stateless
            @Name("login")
            public class LoginAction implements Login {
            
             @In
             private Cliente cliente;
            
             @PersistenceContext
             private EntityManager em;
            
             @Logger
             private Log log;
            
             public String login() {
             List existing = em.createQuery(
             "select usuario from Cliente where usuario=:usuarioParam")
             .setParameter("usuarioParam", cliente.getUsuario())
             .getResultList();
             if (!existing.isEmpty()) {
             log.info("Se logueo el client #{cliente.usuario}");
             return "exito";
             } else {
             log.info("No existe el cliente");
             FacesMessages.instance().add("El cliente #{cliente.usuario} no fue registrado. Regístrese");
             return null;
             }
             }
            }
            


            Here is the interface

            package org.seam.ejemplo.login.session;
            
            import javax.ejb.Local;
            
            import org.jboss.seam.annotations.WebRemote;
            
            /**
             * @author gllambi
             *
             */
            @Local
            public interface Login {
            
            
             /**
             * Se valida el cliente y su contraseña
             * @return
             */
             @WebRemote
             public String login();
            
            }
            


            Here is the page
            <%@ taglib uri="http://java.sun.com/jsf/html" prefix="h"%>
            <%@ taglib uri="http://java.sun.com/jsf/core" prefix="f"%>
            <%@ taglib uri="https://ajax4jsf.dev.java.net/ajax" prefix="a4j"%>
            
            <html>
            <head>
            <link href="<%=request.getContextPath()%>/estilos/estilo.css"
             rel="stylesheet" type="text/css">
            <f:loadBundle basename="mensajes" var="msg" />
            <title>Login</title>
            <script type="text/javascript"
             src="<%=request.getContextPath()%>/seam/remoting/resource/remote.js">
            <!--
            // This space intentionally left blank
            //-->
            </script>
            <script type="text/javascript"
             src="<%=request.getContextPath()%>/seam/remoting/interface.js?login">
            <!--
            // This space intentionally left blank
            //-->
            </script>
            <script type="text/javascript">
             //<![CDATA[
             function login() {
             Seam.Component.getInstance("login").login(loginCallback);
             }
             function loginCallback(result) {
             alert('El resultado de la operación es '+result);
             }
             // ]]>
            </script>
            </head>
            <body>
            <center><f:view>
             <h:form id="loginForm">
             <h:messages styleClass="error" id="mensajesError" />
             <h:panelGrid columns="2">
             <h:outputText id="etiquetaUsuario" value="#{msg.user}" />
             <h:inputText id="usuario" value="#{cliente.usuario}" />
             <h:outputText id="etiquetaPassword" value="#{msg.password}" />
             <h:inputText id="password" value="#{cliente.password}" />
             </h:panelGrid>
             <h:commandButton onclick="javascript:login()"
             value="Remoting #{msg.login} Button" />
             <a4j:commandButton action="#{login.login}"
             value="Ajax #{msg.login} Button">
             </a4j:commandButton>
             <h:commandButton action="#{login.login}"
             value="Seam #{msg.login} Button" />
             </h:form>
            </f:view></center>
            </body>
            </html>
            


            And here is the web.xml

            <web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
             <display-name>Login</display-name>
             <context-param>
             <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
             <param-value>client</param-value>
             </context-param>
             <context-param>
             <description>
             This parameter tells MyFaces if javascript code should be
             allowed in the rendered HTML output. If javascript is
             allowed, command_link anchors will have javascript code that
             submits the corresponding form. If javascript is not
             allowed, the state saving info and nested parameters will be
             added as url parameters. Default: "true"
             </description>
             <param-name>org.apache.myfaces.ALLOW_JAVASCRIPT</param-name>
             <param-value>true</param-value>
             </context-param>
             <context-param>
             <description>
             This parameter tells MyFaces if javascript code should be
             allowed in the rendered HTML output. If javascript is
             allowed, command_link anchors will have javascript code that
             submits the corresponding form. If javascript is not
             allowed, the state saving info and nested parameters will be
             added as url parameters. Default: "false"
            
             Setting this param to true should be combined with
             STATE_SAVING_METHOD "server" for best results.
            
             This is an EXPERIMENTAL feature. You also have to enable the
             detector filter/filter mapping below to get JavaScript
             detection working.
             </description>
             <param-name>org.apache.myfaces.DETECT_JAVASCRIPT</param-name>
             <param-value>false</param-value>
             </context-param>
             <context-param>
             <description>
             If true, rendered HTML code will be formatted, so that it is
             "human readable". i.e. additional line separators and
             whitespace will be written, that do not influence the HTML
             code. Default: "true"
             </description>
             <param-name>org.apache.myfaces.PRETTY_HTML</param-name>
             <param-value>true</param-value>
             </context-param>
             <context-param>
             <description>
             If true, a javascript function will be rendered that is able
             to restore the former vertical scroll on every request.
             Convenient feature if you have pages with long lists and you
             do not want the browser page to always jump to the top if
             you trigger a link or button action that stays on the same
             page. Default: "false"
             </description>
             <param-name>org.apache.myfaces.AUTO_SCROLL</param-name>
             <param-value>true</param-value>
             </context-param>
             <filter>
             <filter-name>Seam Redirect Filter</filter-name>
             <filter-class>
             org.jboss.seam.servlet.SeamRedirectFilter
             </filter-class>
             </filter>
             <filter>
             <filter-name>extensionsFilter</filter-name>
             <filter-class>
             org.apache.myfaces.webapp.filter.ExtensionsFilter
             </filter-class>
             <init-param>
             <description>
             Set the size limit for uploaded files. Format: 10 - 10
             bytes 10k - 10 KB 10m - 10 MB 1g - 1 GB
             </description>
             <param-name>uploadMaxFileSize</param-name>
             <param-value>100m</param-value>
             </init-param>
             <init-param>
             <description>
             Set the threshold size - files below this limit are
             stored in memory, files above this limit are stored on
             disk.
            
             Format: 10 - 10 bytes 10k - 10 KB 10m - 10 MB 1g - 1 GB
             </description>
             <param-name>uploadThresholdSize</param-name>
             <param-value>100k</param-value>
             </init-param>
             </filter>
             <filter>
             <display-name>Ajax4jsf Filter</display-name>
             <filter-name>ajax4jsf</filter-name>
             <filter-class>org.ajax4jsf.Filter</filter-class>
             </filter>
             <filter-mapping>
             <filter-name>Seam Redirect Filter</filter-name>
             <url-pattern>*.seam</url-pattern>
             </filter-mapping>
             <filter-mapping>
             <filter-name>extensionsFilter</filter-name>
             <url-pattern>*.seam</url-pattern>
             </filter-mapping>
             <filter-mapping>
             <filter-name>extensionsFilter</filter-name>
             <url-pattern>/faces/*</url-pattern>
             </filter-mapping>
             <filter-mapping>
             <filter-name>ajax4jsf</filter-name>
             <servlet-name>Faces Servlet</servlet-name>
             <dispatcher>REQUEST</dispatcher>
             <dispatcher>FORWARD</dispatcher>
             <dispatcher>INCLUDE</dispatcher>
             </filter-mapping>
             <!-- Listener, that does all the startup work (configuration, init). -->
             <listener>
             <listener-class>
             org.apache.myfaces.webapp.StartupServletContextListener
             </listener-class>
             </listener>
             <listener>
             <listener-class>
             org.jboss.seam.servlet.SeamListener
             </listener-class>
             </listener>
             <!-- Faces Servlet -->
             <servlet>
             <servlet-name>Faces Servlet</servlet-name>
             <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
             <load-on-startup>1</load-on-startup>
             </servlet>
             <servlet>
             <servlet-name>Seam Remoting</servlet-name>
             <servlet-class>
             org.jboss.seam.remoting.SeamRemotingServlet
             </servlet-class>
             </servlet>
             <!-- Faces Servlet Mapping -->
             <servlet-mapping>
             <servlet-name>Faces Servlet</servlet-name>
             <url-pattern>*.seam</url-pattern>
             </servlet-mapping>
             <servlet-mapping>
             <servlet-name>Seam Remoting</servlet-name>
             <url-pattern>/seam/remoting/*</url-pattern>
             </servlet-mapping>
             <!-- Welcome files -->
             <welcome-file-list>
             <welcome-file>index.jsp</welcome-file>
             </welcome-file-list>
             <login-config>
             <auth-method>BASIC</auth-method>
             </login-config>
            </web-app>
            


            Thanks

            • 3. Re: Injection and remoting
              shane.bryzak

              The login() method in your example is clearly intended to be invoked within a JSF context - it adds messages via FacesMessages and returns an action string. Remoting is not intended to be used to call action methods such as this.

              If however this is just an experiment to see how remoting works, and you're wondering why "cliente" isn't being injected from your form, it's because remoting calls need to explicitly specify any parameters that you require to be passed. I.e. your login method prototype would need to be:

               public String login(Cliente client)
              


              On the client side you would need to create a new Cliente object and populate it with the username and password, then pass this object as a parameter in your remote call.

              • 4. Re: Injection and remoting
                gllambi

                Thank you very much for the fast reply.

                "sbryzak2" wrote:
                The login() method in your example is clearly intended to be invoked within a JSF context - it adds messages via FacesMessages and returns an action string. Remoting is not intended to be used to call action methods such as this.


                I'm new to Remoting and Ajax, can you give me a good example when to use it?


                If however this is just an experiment to see how remoting works, and you're wondering why "cliente" isn't being injected from your form, it's because remoting calls need to explicitly specify any parameters that you require to be passed. I.e. your login method prototype would need to be:
                 public String login(Cliente client)
                


                On the client side you would need to create a new Cliente object and populate it with the username and password, then pass this object as a parameter in your remote call.


                So it's not posible to inject it with the @In annotation?

                Thanks a lot!

                • 5. Re: Injection and remoting
                  shane.bryzak

                   

                  "gllambi" wrote:

                  I'm new to Remoting and Ajax, can you give me a good example when to use it?


                  It's hard to give a definitive answer, because I'm sure there's some usage scenarios that I haven't even thought of yet. In general, you should use it when your page can benefit from making a fine-grained API call against a Seam component, without needing to refresh your entire page.


                  So it's not posible to inject it with the @In annotation?


                  Not right now, however one of the things in my todo list (there's a feature request in JIRA for it) is to integrate the page context with remoting. Once this is done, you will be able to inject values from the page context into your component.

                  • 6. Re: Injection and remoting
                    gllambi

                    Thank you very much!