`

利用struts2动态构建ExtJS Tree

阅读更多

    在研究ExtJS Tree动态构建时,按照ExtJS推进的方法是通过TreeLoader加载数据,加载的数据的格式是JSON。在ExtJS的例子check-tree.html中,直接利用后端的check-nodes.json来构建,但是在实际的工程中,有很多是根据不确定的数据内容来构建Tree的。

    在Java开发的Web中利用Struts实现后端的servlet,可以提供相应的json格式,实现ExtJS Tree的动态构建。在网上搜索相应的技术文章是,发现利用jsp作为中间转换的例子,url:http://www.blogjava.net/usherlight/archive/2008/02/19/180590.html,觉得不是很理想,在struts2中引入了plugin的机制,有现成的struts-json-plugin包,如何利用action直接通过Ext.Tree.TreeLoader直接加载Tree的数据,在上述文章中,指出:

 "最近尝试用extjs来展示树状菜单。着实花了一番功夫。树状菜单的菜单项需要动态加载,而目前版本的extjs中只支持JSON格式的数据。查了一些资料,决定使用struts2的json-plugin。首先按照例子做了一个,但是结果就是不成功,界面上只出来了一个js中生成的root节点,不能加载从后台生成的数据。研究后发现是数据格式有问题。使用json-plugin生成的数据格式如下:
{"cls":"folder","id":10,"leaf":false,"children":[{"cls":"file","id":11,"leaf":true,"children":null,"text":"S600"},{"cls":"file","id":12,"leaf":true,"children":null,"text":"SLK200"}],"text":"Benz"}
而extjs需要的数据格式如下:
[{"cls":"folder","id":10,"leaf":false,"children":[{"cls":"file","id":11,"leaf":true,"children":null,"text":"S600"},{"cls":"file","id":12,"leaf":true,"children":null,"text":"SLK200"}],"text":"Benz"}]
区别很小,就只相差最外面的两个方括号。但是少了这两个方括号,在json中,含义迥然不同,前者表示一个对象,而后者表示一个数组。而extjs中 tree的dataloader需要的数据必须是一个数组。而这样的数据格式是json-plugin自动生成的,无法改变。所以,我最后放弃了json -plugin,转而使用json-lib来解决这个问题。"

在struts-json-plugin中返回的数据的确有这个问题,经过仔细分析,在struts-json-plugin的配置中是可以解决这个问题的,通过wrapPrefix和wrapSuffix设置,可以解决上面的问题,struts config文件中的设置如下:

	<package name="test" extends="json-default" >
				<action name="menu" class="com.struts2.action.Menu">
			<result name="success" type="json">
				<param name="excludeNullProperties">true</param>
				<param name="noCache">true</param>
				<param name="wrapPrefix">[</param>
				<param name="wrapSuffix">]</param>
			</result>
		</action>
	</package>

 action的实现类Menu的代码如下:

package com.struts2.action;

import java.util.ArrayList;
import java.util.List;

public class Menu {
    private int id;
    private String text;
    private boolean leaf;
    private String cls;
    private List<Menu> children;

	public String execute() throws Exception {
		// TODO Auto-generated method stub
		this.id =1;
		this.text="text";
		this.leaf=false;
		this.cls ="cls";
		this.children = new ArrayList<Menu>();
        Menu benz = new Menu();
        benz.setText("Benz");
        benz.setCls("folder");
        benz.setLeaf(true);
        benz.setId(10);

		this.children.add(benz);

		return "success";
	}
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getText() {
		return text;
	}
	public void setText(String text) {
		this.text = text;
	}
	public boolean isLeaf() {
		return leaf;
	}
	public void setLeaf(boolean leaf) {
		this.leaf = leaf;
	}
	public String getCls() {
		return cls;
	}
	public void setCls(String cls) {
		this.cls = cls;
	}
	public List<Menu> getChildren() {
		return children;
	}
	public void setChildren(List<Menu> children) {
		this.children = children;
	}
}

 

利用ExtJS自带的例子check-tree.js,把原来的dataUrl修改为自己实现的struts的Url:

/*!
 * Ext JS Library 3.2.0
 * Copyright(c) 2006-2010 Ext JS, Inc.
 * licensing@extjs.com
 * http://www.extjs.com/license
 */

Ext.onReady(function(){
    var tree = new Ext.tree.TreePanel({
        renderTo:'tree-div',
        title: 'My Task List',
        height: 300,
        width: 400,
        useArrows:true,
        autoScroll:true,
        animate:true,
        enableDD:true,
        containerScroll: true,
        rootVisible: false,
        frame: true,
        root: {
            nodeType: 'async'
        },

        // auto create TreeLoader
        dataUrl: 'http://localhost:8080/Stock3th/menu.action',

        listeners: {
            'checkchange': function(node, checked){
                if(checked){
                    node.getUI().addClass('complete');
                }else{
                    node.getUI().removeClass('complete');
                }
            }
        },

        buttons: [{
            text: 'Get Completed Tasks',
            handler: function(){
                var msg = '', selNodes = tree.getChecked();
                Ext.each(selNodes, function(node){
                    if(msg.length > 0){
                        msg += ', ';
                    }
                    msg += node.text;
                });
                Ext.Msg.show({
                    title: 'Completed Tasks',
                    msg: msg.length > 0 ? msg : 'None',
                    icon: Ext.Msg.INFO,
                    minWidth: 200,
                    buttons: Ext.Msg.OK
                });
            }
        }]
    });

    tree.getRootNode().expand(true);
});

 则可以生成所需要的Tree了。我用的各种资源的版本为:ExtJS3.2.0,Struts2.2.1,所需要的支持jar配置文件pom.xml如下:

<?xml version="1.0" encoding="UTF-8"?>
	<!--
		/* * $Id: pom.xml 821140 2009-10-02 19:46:07Z wesw $ * * Licensed to
		the Apache Software Foundation (ASF) under one * or more contributor
		license agreements. See the NOTICE file * distributed with this work
		for additional information * regarding copyright ownership. The ASF
		licenses this file * to you under the Apache License, Version 2.0 (the
		* "License"); you may not use this file except in compliance * with
		the License. You may obtain a copy of the License at * *
		http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by
		applicable law or agreed to in writing, * software distributed under
		the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES
		OR CONDITIONS OF ANY * KIND, either express or implied. See the
		License for the * specific language governing permissions and
		limitations * under the License. */
	-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<artifactId>org.tkxing.stock</artifactId>
	<groupId>stock3th</groupId>
	<version>3.0</version>

	<properties>
		<struts2-version>2.2.1</struts2-version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.apache.struts</groupId>
			<artifactId>struts2-core</artifactId>
			<version>2.2.1</version>
		</dependency>
		<dependency>
			<groupId>org.apache.struts</groupId>
			<artifactId>struts2-json-plugin</artifactId>
			<version>2.2.1</version>
		</dependency>
		<dependency>
			<groupId>commons-logging</groupId>
			<artifactId>commons-logging</artifactId>
			<version>1.1.1</version>
		</dependency>
		<dependency>
			<groupId>org.apache</groupId>
			<artifactId>log4j</artifactId>
			<version>2.1.8</version>
		</dependency>
		<dependency>
			<groupId>javassist</groupId>
			<artifactId>javassist</artifactId>
			<version>3.9.0.GA</version>
		</dependency>

		<dependency>
			<groupId>commons-lang</groupId>
			<artifactId>commons-lang</artifactId>
			<version>2.4</version>
		</dependency>

		<dependency>
			<groupId>commons-collections</groupId>
			<artifactId>commons-collections</artifactId>
			<version>3.2.1</version>
		</dependency>

		<dependency>
			<groupId>commons-beanutils</groupId>
			<artifactId>commons-beanutils</artifactId>
			<version>1.7.0</version>
		</dependency>

		<dependency>
			<groupId>net.sf.ezmorph</groupId>
			<artifactId>ezmorph</artifactId>
			<version>1.0.6</version>
		</dependency>

	</dependencies>
</project>

 

分享到:
评论
1 楼 marui0930 2011-07-27  
研究LZ这个代码好几天了,最后发现一个问题就是json-plugin 版本为0.32即struts为2.0.x版本的时候,json-plugin没有wrapPrefix和wrapSuffix这两个方法。最后我是通过手动拼装json类型数据来实现的

相关推荐

Global site tag (gtag.js) - Google Analytics