« Volver a AJAX

Using DWR for AJAX

Etiquetas: development

Table of Contents [-]

    DWR is an easy to use and powerful open source AJAX library. Here's how to use it in Liferay:

    - Download DWR jar from http://getahead.ltd.uk/dwr, copy jar to the global classpath (if using the extension environment copy them to ext\ext-lib\portal)

    - To install the DWR servlet, in the web.xml file add the following (if using the extension environment add following in ext\ext-web\docroot\WEB-INF\web.xml):

       <servlet>
          <servlet-name>DwrServlet</servlet-name>
          <servlet-class>uk.ltd.getahead.dwr.DWRServlet</servlet-class>
          <load-on-startup>12</load-on-startup>
       </servlet>
       <servlet-mapping>
          <servlet-name>DwrServlet</servlet-name>
          <url-pattern>/dwr/*</url-pattern>
       </servlet-mapping>

    - If you are using DWR 2.x then the servlet-class line should properly contain the following: org.directwebremoting.servlet.DwrServlet.

    During development, you will want to enable the debug page, which allows you to test the classes that have been remoted using the URL host/dwr:

       <servlet>
          <servlet-name>DwrServlet</servlet-name>
          <servlet-class>uk.ltd.getahead.dwr.DWRServlet</servlet-class>
          <load-on-startup>12</load-on-startup>
          <init-param>
             <param-name>debug</param-name>
             <param-value>true</param-value>
          </init-param>
       </servlet>

    - Add the dwr.xml (see DWR site for details) file inside the WEB-INF directory of Liferay's WAR (if using the extension environment add it to ext\ext-web\docroot\WEB-INF). For example:

       <dwr>
        <allow>
        <create creator="new" javascript="EchoService">
        <param name="class" value="com.example.EchoDwr"/>
        </create>
        </allow>
       </dwr>

    - Sample backend class, which creates an HTML fragment that decorates the passed in message:

       public class EchoDwr {
         public static String echo(String message) throws Exception {
          
          WebContext webContext = WebContextFactory.get();
          HttpSession session = webContext.getSession();
       
          String userId = PortalUtil.getUserId(session);
          if (userId == null) {
             throw new Exception("Must be logged in to run this.");
          }
          
          HttpServletRequest request = webContext.getHttpServletRequest();
          request.setAttribute("message", message);
          
          String html = webContext.forwardToString("/html/portlet/example/echo.jsp");
       
          return html; 
       }

    - the /html/portlet/example/echo.jsp referred to above can be any JSP that generates an HTML fragment. For example:

       <%
          String message = (String)request.getAttribute("message");
       %>
       <b><%= message %></b>

    - To invoke this from JSP:

       <%-- DWR AJAX setup --%>
       <script type='text/javascript' src='/dwr/interface/EchoService.js'></script>
       <script type='text/javascript' src='/dwr/engine.js'></script>
       <script type='text/javascript' src='/dwr/util.js'></script>
       
       <script type="text/javascript">
          <%-- invoke EchoDwr.echo() via AJAX --%>
          EchoService.echo("<%= someValue %>",
          { callback:function(dataFromServer) {
             <portlet:namespace />processResults("dataDivId", dataFromServer);
          }, errorHandler:function(errorString, exception) {
             <portlet:namespace />showError("errorDivId", errorString); }
          } );
          
          <%-- process AJAX response --%>
          function <portlet:namespace />processResults(divId, data)
          {
             if (data != null) {
           DWRUtil.setValue(divId, data);
             }
          }
       
          <%-- handle AJAX error, error callback is optional --%>
          function <portlet:namespace />showError(errorDiv, message) {
             DWRUtil.setValue(errorDiv, "Error: "+message+"");
          }
       </script>

    - At runtime, the caller JSP invokes the remote object asynchronously using the DWR generated javascript method "EchoService.echo()". This request is passed to the DWR servlet which maps this to the method EchoDwr.echo(). This method passes the parameters to a JSP which renders HTML output and returns it as a String. This is returned to the calling page. Upon receipt, the page calls processResults() to change the content of the given DIV to the returned HTML String.

    - In the remote object (e.g. EchoDwr), the HTTP request object does not contain the Liferay injected attributes such as Theme. If such information is required, it must be added to the method signature and passed in from the calling JSP (e.g. pass in the Theme ID, since Strings are easily serialized, where as the ThemeDisplay object is not)

    - The remote object can return various types of objects, or even an Array of objects. DWR will automatically serialize types like String & Integer. You can create a Converter object to serialize custom objects.

    - Each AJAX request uses an HTTP connection. To reduce the load on the server, multiple requests can be batched into one request. After all of the remote calls in the batch complete, a single response is sent and DWR passes the data to the callbacks.

       <%-- javascript --%>
       DWREngine.beginBatch();
       service.doSomething1();
       service.doSomething2();
       ...
       DWREngine.endBatch();
    0 archivos adjuntos
    55085 Accesos
    Promedio (2 Votos)
    La valoración media es de 5.0 estrellas de 5.
    Comentarios
    Respuestas anidadas Autor Fecha
    Hi, I tested this and the Spring, DWR Liferay... Eugene Ramirez 19 de agosto de 2009 20:13
    Hi, I have tested with liferay 5.0.2. And it is... krunal b soni 7 de julio de 2010 2:26
    To access ThemeDisplay in DWR, put this in your... Francisco Aranda 9 de septiembre de 2010 12:26
    Hello 3 years later. Unfortunatelly it does not... Michal Sima 20 de junio de 2013 9:36
    Works great on 6.0.5. If you need html to be... Vishal Bhanderi 1 de diciembre de 2010 10:43
    Hi Bhanderi, Can you pls tell me how DWR makes... Manikandan S 28 de enero de 2011 3:03

    Hi, I tested this and the Spring, DWR Liferay sample for liferay 5.2.3, both throws NumberFormatException when initializing the DWR. Both work in 5.2.2. Anybody have the same issue? Thanks
    Publicado el día 19/08/09 20:13.
    Hi, I have tested with liferay 5.0.2. And it is working fine.

    Thanks
    Publicado el día 7/07/10 2:26.
    To access ThemeDisplay in DWR, put this in your portlet controller at doView() or HandleRenderRequest() if you are using Spring

    ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(WebKeys.THEME_DISPLAY);
    request.getPortletSess­ion().setAttribute("themeDisplay", themeDisplay, PortletSession.APPLICATION_SCOPE);

    Then you can access themeDisplay in your DWR class

    WebContext webContext = WebContextFactory.get();
    HttpSession session = webContext.getSession();
    ThemeDisplay themeDisplay = (ThemeDisplay) session.getAttribute("themeDisplay");

    And there you are, you can access user information, PermissionChecker, etc...
    Publicado el día 9/09/10 12:26.
    Works great on 6.0.5. If you need html to be shown make sure you disable DWR html escaping

    EchoService.echo(function(data) {
    dwr.util.setValue("dataDivId", data, { escapeHtml:false });
    });
    Publicado el día 1/12/10 10:43.
    Hi Bhanderi,
    Can you pls tell me how DWR makes work in 6.0.5. I tried in 5.2.3 its working but its not working in 6.0.5...
    Its throwing exception current URL call...
    Publicado el día 28/01/11 3:03 en respuesta a Vishal Bhanderi.
    Hello 3 years later. Unfortunatelly it does not work. I did exactly how you explained, but the following code does not work:

    WebContext webContext = WebContextFactory.get();
    HttpSession sesion = webContext.getSession();
    ThemeDisplay themeDisplay = (ThemeDisplay) sesion.getAttribute("themeDisplay");
    themeDisplay.getUser().getExpandoBridge()­.setAttribute("foo", "bar");

    I have the following exception:
    com.liferay.portal.security.auth.PrincipalException: PermissionChecker not initialized
    Publicado el día 20/06/13 9:36 en respuesta a Francisco Aranda.