« 返回到 AJAX

Using DWR for AJAX

标签: 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 附件
    55098 查看
    平均 (2 票)
    满分为 5,平均得分为 5.0。
    评论
    讨论主题回复 作者 日期
    Hi, I tested this and the Spring, DWR Liferay... Eugene Ramirez 2009年8月19日 下午8:13
    Hi, I have tested with liferay 5.0.2. And it is... krunal b soni 2010年7月7日 上午2:26
    To access ThemeDisplay in DWR, put this in your... Francisco Aranda 2010年9月9日 下午12:26
    Hello 3 years later. Unfortunatelly it does not... Michal Sima 2013年6月20日 上午9:36
    Works great on 6.0.5. If you need html to be... Vishal Bhanderi 2010年12月1日 上午10:43
    Hi Bhanderi, Can you pls tell me how DWR makes... Manikandan S 2011年1月28日 上午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
    在 09-8-19 下午8:13 发帖。
    Hi, I have tested with liferay 5.0.2. And it is working fine.

    Thanks
    在 10-7-7 上午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...
    在 10-9-9 下午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 });
    });
    在 10-12-1 上午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...
    在 11-1-28 上午3:03 发帖以回复 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
    在 13-6-20 上午9:36 发帖以回复 Francisco Aranda