首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 网站开发 > Ajax >

Struts 二与AJAX(第二部分)

2012-09-07 
Struts 2与AJAX(第二部分)http://www.35java.com/zhibo/forum.php?modviewthread&tid370&extrapage%3D3

Struts 2与AJAX(第二部分)
http://www.35java.com/zhibo/forum.php?mod=viewthread&tid=370&extra=page%3D3
        更多<s:tree />            在Struts 2的showcase中有两个<s:tree />的例子,分别是静态树与动态树。所谓的静态树即是在编写JSP代码时通过<s:treenode        />生成树节点。我的上一篇文章的例子就是一个典型的静态树。而动态树则是在程序运行期间,Struts 2 运行时(Runtime)根据程序中的数据动态创建树节点。虽然在两个例子中<s:tree        />的theme属性都为“ajax”,但是从严格意义上来说,这两种树都不属于AJAX树,因为它们都是在输出页面时将全部节点加载到其中,而不是在父节点展开时通过XHR(XMLHttpRequest)获取节点数据。
            动态树            下面我们先看一下动态树的例子,接着再一步步地将其改造为名副其实的AJAX 树。下例将会把WEB应用程序的目录树展现在JSP页面中。因此,我需要先包装一下java.io.File        类,代码如下:
            package tutorial;
               
                import java.io.File;
                       
                        public
        class FileWrapper                     {
                                           private                        File file;
                       
                                                   public                            FileWrapper(String path)                                 {
                                                                                       file =
new                                                File(path);
                                                                                                   }
                                                                                                          
                                                                                                           public                                                        FileWrapper(File file)                                                             {
                                                                                                                                               this.file                                                                    = file;
                                                                                                                                                   }
                                                                                                                                                          
                                                                                                                                                           public                                                                                String getId()                                     {
                                                               return
"file_"
                        + file.hashCode();
                                                           }
                                                                  
                                                                   public                                    String getName()                                         {
                                                                                                       return file.getName();
                                                                                                           }
                                                                                                                  
                                                                                                                   public                                                            String getAbsolutePath()                                                                 {
                                                                                                                                                       return file.getAbsolutePath();
                                                                                                                                                           }
                                                                                                                                                                  
                                                                                                                                                                   public                                                                                    FileWrapper[] getChildren()                                     {
                                                               File[] files = file.listFiles();
                                                                       if(files                                !=
                        null
&& files.length                         >
0)                                 {
                                                                                           int length = files.length;
                                                                                                           FileWrapper[] wrappers                                     =
                                        new FileWrapper[length];
                                                                                                   for(int                                                    i =
                                    0; i < length;                                     ++i)                                         {
                                                                                                               wrappers                                                     =
new FileWrapper(files);
                                                                                                                           }
                                                                                                                                   return wrappers;
                                                                                                                                       }
                                                                                                                                               return
new                                                                            FileWrapper[0];
                                                                                                                                                                   }
                                                                                    }
    清单1 src/tutorial/FileWrapper.java            之所以需要对File类进行如此包装,是因为<s:tree />用于动态树时,rootNode、nodeIdProperty、nodeTitleProperty        和 childCollectionProperty等属性都必填的。
            然后是Action类的代码如下:
            package tutorial;
               
                import javax.servlet.http.HttpServletRequest;
                       
                        import org.apache.struts2.interceptor.ServletRequestAware;
                               
                                import com.opensymphony.xwork2.ActionSupport;
                                       
                                        public
        class DynamicTreeAction        extends ActionSupport        implements ServletRequestAware                    {
                                           private
static
                final
long serialVersionUID                 =
                    1128593047269036737L;
                                                  
                                                   private                            HttpServletRequest request;
                                                           private                                FileWrapper root;
                               
                                                                   public
void setServletRequest(HttpServletRequest                                    request)                                         {   
                                                                                                       this.request                                                = request;
                                                                                                           }
                                                                                                                  
                                                                                                                   public                                                            FileWrapper getRoot()                                                                 {
                                                                                                                                                       return root;
                                                                                                                                                           }
                                                                                                                                                                  
                                                                                                                                                                   @Override
                                                                                                                                                                   public                                                                                    String execute()                                     {
                                                               root =
new                                    FileWrapper(request.getSession().getServletContext().getRealPath("/"));                                                  
                                                                                               return SUCCESS;
                                                                                                   }
                                                    }
    清单2 src/tutorial/DynamicTreeAction.java            上述代码取得WEB应用程序的根目录的绝对路径后,初始化FileWrapper对象root。该对象将为JSP页面的<s:tree />的根节点。如下代码所示:
            <%@ page language="java" contentType="text/html; charset=utf-8"
                                            pageEncoding="utf-8"%>
<%@ taglib prefix="s"                                                                        uri="/struts-tags"%>
        <!DOCTYPE html PUBLIC            "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html         xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Struts 2 AJAX - More Tree</title>
<s:head theme="ajax" debug="true"
        />
<script type="text/javascript">
                            /* <![CDATA[         */
                function treeNodeSelected(arg)                    {
                                    alert(arg.source.title         + ' selected');
                        }
                       
                                        function treeNodeExpanded(arg)                    {
                                    alert(arg.source.title         + ' expanded');
                        }
                       
                                        function treeNodeCollapsed(arg)                    {
                                    alert(arg.source.title         + ' collapsed');
                        }
                       
                        dojo.addOnLoad(function()                    {               
                                    var                            t = dojo.widget.byId('appFiles');
                                                dojo.event.topic.subscribe(t.eventNames.expand,                                treeNodeExpanded);               
                                                dojo.event.topic.subscribe(t.eventNames.collapse,                                treeNodeCollapsed);
                                               
                                                        var s                 = t.selector;                                  
                                    dojo.event.connect(s, 'select',                    'treeNodeSelected');
                                });
                                                    /* ]]>         */
</script>
</head>
<body>
<h2>
                                                        Dynamic Tree Example
                                                    </h2>
<div         style="float:left;            margin-right: 50px;">
<s:tree id="appFiles" theme="ajax" rootNode="root"
                                                    nodeTitleProperty="name" nodeIdProperty="id"
                                                                childCollectionProperty="children"
        />
</div>
</body>
</html>
    清单3 WebContent/Tree.jsp            因为<s:tree />的treeCollapsedTopic和treeExpandedTopic属性都没有起作用,所以如果我们想要监听这两个事件,就必须使用上述代码的方法。
            最后是struts.xml配置文件:
            <?xml version="1.0"            encoding="UTF-8"?>
<!DOCTYPE                struts PUBLIC
                    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
                    "http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<package                        name="Struts2_AJAX_DEMO" extends="struts-default">
<action name="DynamicTree" class="tutorial.DynamicTreeAction">
        <result>Tree.jsp</result>
</action>
</package>
</struts>
    清单4 src/struts.xml            发布运行应用程序,在浏览器地址栏中键入http://localhost:8080/Struts2_Ajax2/DynamicTree.action,有如下图所示页面:
           
        图1 动态树示例   
            AJAX 树            正如我在文章开头所说,Struts 2所提供的静态树和动态树都不是严格意义上的AJAX树。下面就让我们来实现一个如假包换的AJAX树。首先要说明的是,Struts        2的<s:tree />默认是不支持这种按需加载数据的AJAX树。不过因为它是基于Dojo的树控件(Widget)所以要扩展也很方便。
            Dojo 通过名为“TreeRPCController”的控件实现 AJAX 树,它会监听被控制树的事件。当发生展开节点的事件时,TreeRPCController就会向URL发送XHR请求,该URL由TreeRPCController的RPCUrl        属性定义。XHR请求格式类似如下格式:
            http://localhost:8080/Struts2_Ajax2/AjaxTree.action?action=getChildren&data={"node":{"widgetId":"file_226092423","objectId":"C:\\Program                                                Files\\Tomcat 5.5\\webapps\\Struts2_Ajax2","index":0,"isFolder":true},"tree":{"widgetId":"appFiles","objectId":""}}&dojo.preventCache=1182913465392
    清单5 XHR样本            显而易见,请求中包含三个参数,分别是action为“getChildren”(固定值),data一个包含当前节点与树信息的JSON串和dojo.preventCache随机串,用于缓存不同节点的请求响应(父节点只会在第一次被展开时到服务器端加载数据,之后都是从浏览器的缓存中读取数据,可以提高应用程序性能)。
            首先我要先写一个加载树节点数据的Action类,代码如下:
            package tutorial;
               
                import java.util.Map;
                       
                        import com.googlecode.jsonplugin.JSONExeption;
                                import com.googlecode.jsonplugin.JSONUtil;
                                       
                                        public
        class AjaxTreeAction        extends DynamicTreeAction                    {
                                           private
static
                final
long serialVersionUID                 =
                    3970019751740942311L;
                       
                                                   private                            String action;
                                                           private                                String data;
                                                                   private                                    FileWrapper[] wrappers;
                                   
                                                                           public
void setAction(String                                        action)                                             {
                                                                                                               this.action                                                    = action;
                                                                                                                   }
                                                                                                                          
                                                                                                                           public
void setData(String                                                                data)                                                                     {
                                                                                                                                                               this.data                                                                            = data;
                                                                                                                                                                   }
                                                                                   
                                                                                                                                                                           public                                                                                        FileWrapper[] getWrappers()                                     {
                                                               return wrappers;
                                                                   }
                                   
                                                                           @Override
                                                                           public                                        String execute()                                             {
                                                                                                               if("getChildren".equals(action))                                                                                                     {
                                                                                                                                   try
                                                                    {
                                                                                                                                                                       Object o                                                                                 = JSONUtil.deserialize(data);
                                                                                                                                                                                       String path                                                                         = ((Map) ((Map) o).get("node")).get("objectId").toString();
                                                                                                                                                                                               wrappers                                                                         =
                                                                            new FileWrapper(path).getChildren();
                                                                                                                                                                           }
catch (JSONExeption                                                                                    e)                                                                                         {
                                                                                                                                                                                                               e.printStackTrace();
                                                                                                                                                                                                           }
                                                                                                                                                                                                                   return
"ajax";
                                                                                                                                                                                                                                       }   
                                                                                                                                                                                                                                               return
                                                super.execute();
                                                                                                           }
                                                        }
    清单6 src/tutorial/AjaxTreeAction.java            上述代码可能需要解释一下:
   

热点排行