`
tailsherry
  • 浏览: 135193 次
  • 性别: Icon_minigender_1
  • 来自: 珠海
社区版块
存档分类
最新评论

Struts2+JSON+YUI构建Rich Client应用(一)

阅读更多

Struts2的出现在Web2.0纷争的年代,以Ajax为代表的富客户端(Rich Client)应用正唱着Web2.0的主角。虽然Struts2本身对Ajax的应用也提供了自己的Ajax标签,但是这种比较牵强的支持也是赶鸭子上架,不是Struts本身的特长。

 

这里,就Struts对JSON支持的技术特点,来构建一个Rich Client应用,UI层使用的是YUI工具包,详情参考Yahoo的YUI网站。http://developer.yahoo.com/yui/

 

本文中所涉及的Web应用的大致结构图如下:

 

先一睹为快,该应用的实际运行界面如下:

 

 

页面功能大致是,用户加入一个New Test User和New Message,然后点击按钮Add Now,页面无刷新添加新加入的消息。

 

首先,建立一个Struts的Action类StrutsTestAction,代码如下:

package com.tail.test.actions;   
  
import java.util.ArrayList;   
import java.util.List;   
  
//import org.apache.log4j.Logger;   
  
import com.opensymphony.xwork2.ActionSupport;   
import com.tail.test.objects.Message;   
  
public class StrutsTestAction extends BaseAction {   
    // Our logger.   
//    private static Logger logger = Logger.getLogger(StrutsTestAction.class);   
       
    private String newUser;   
       
    private String newMessage;   
       
    private List<Message> messageList;   
  
    public List<Message> getMessageList() {   
        return messageList;   
    }   
  
    public void setMessageList(List<Message> messageList) {   
        this.messageList = messageList;   
    }   
  
    public String getNewMessage() {   
        return newMessage;   
    }   
  
    public void setNewMessage(String newMessage) {   
        this.newMessage = newMessage;   
    }   
  
    public String getNewUser() {   
        return newUser;   
    }   
  
    public void setNewUser(String newUser) {   
        this.newUser = newUser;   
    }   
  
    @Override  
    public String execute() throws Exception {         
        return super.execute();   
    }   
       
    public String loadMessages() {   
        messageList = new ArrayList<Message>();   
        messageList.add(new Message("tail", "This is an piece of initial message."));   
        return result(SUCCESS);   
    }   
       
    public String addMessageToUser() {   
        messageList.add(new Message(newUser, newMessage));   
        //logger.debug("Add user='" + newUser + "', message='" + newMessage + "'");   
        return result(SUCCESS);   
    }   
} 

 

其中,newUser和newMessage分别对应界面上的New Test User和New Message这两个输入框中的value。messageList则是下方显示的消息内容,注意messageList本身内含多个Message对象的List,Message类的定义如下:

package com.tail.test.objects;   
  
public class Message {   
    private String userName;   
  
    private String content;   
  
    public String getContent() {   
        return content;   
    }   
  
    public void setContent(String content) {   
        this.content = content;   
    }   
  
    public String getUserName() {   
        return userName;   
    }   
  
    public void setUserName(String userName) {   
        this.userName = userName;   
    }   
  
    public Message() {   
  
    }   
  
    public Message(String userName, String content) {   
        this.userName = userName;   
        this.content = content;   
    }   
}  

 

loadMessages()方法负责初始化装载数据,比如说我们从数据库或第三方资源中取出数据来初始化现有的List,它在页面上的实现,实际上也是结合Ajax来进行的。

 

addMessageToUser()方法对应了界面上Add Now按钮的动作内容,他们中间的交互过程也是通过Ajax来完成的,这也是这个应用的核心所在。

 

注意,这里的Struts Action Bean本身的默认的excute方法也被override过来了,而方法体本身是空的,这里这样做的目的就是,可以让界面操作用户一进入此页面,界面能马上构造出来,而不用等待服务器端的数据装载和返回,在初始装载数据量较大的时候,这一点尤其重要。这一点,大家可以结合后部分讲到的YUI部分的代码来体会。

 

现在已经有了StrutsTestAction这个工作类,那么这里的Struts核心的配置文件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="test" namespace="/" extends="json-default">  
        <global-results>  
            <!-- any exceptions should redirect to the exception page -->  
            <result name="exception" type="redirect-action">  
              <param name="actionName">exception</param>  
              <param name="namespace">/</param>  
            </result>  
        </global-results>  
       
        <action name="exception" class="com.tail.test.actions.ExceptionAction">  
            <result>/exception.jsp</result>  
        </action>  
       
        <action name="home" class="com.tail.test.actions.StrutsTestAction">  
            <result>/userMessage.jsp</result>  
            <result name="input">/userMessage.jsp</result>  
        </action>  
    </package>  
       
    <package name="tail-json" namespace="/page" extends="test">  
        <global-results>  
            <!-- Don't redirect to login for ajax requests. -->  
            <result name="login" type="httpheader">  
                <param name="status">403</param>  
            </result>  
            <!-- Send a 503 for errors in ajax requests. -->  
            <result name="error" type="httpheader">  
                <param name="status">503</param>  
            </result>  
        </global-results>  
    </package>  
       
    <package name="tail-home" namespace="/home" extends="tail-json">  
        <global-results>  
            <result name="input" type="json">  
                <param name="includeProperties">  
                    result, actionErrors.*, fieldErrors.*   
                </param>  
            </result>  
        </global-results>  
        <action name="loadMessages" method="loadMessages"  
            class="com.tail.test.actions.StrutsTestAction">  
           <result type="json">  
                <param name="includeProperties">  
                    result, messageList.*   
                </param>  
            </result>  
        </action>  
        <action name="addMessageToUser" method="addMessageToUser"  
            class="com.tail.test.actions.StrutsTestAction">  
           <result type="json">  
                <param name="includeProperties">  
                    result, messageList.*   
                </param>  
            </result>  
        </action>  
    </package>  
</struts> 

 

其中定义了三个package,前两个package没有什么好讲的,如果要详细了解其配置原理,可以参考Struts2的官方文档。

 

大家注意到,针对StrutsTestAction事实上已经在第一个package中定义了一次,为什么在第三个tail-home包中也要定义一遍呢,看到其中的json result的定义,大家应该也就看出其中的异样了。

 

不错,这里的定义主要是为了利用Struts JSON的插件功能将Action中的一个或多个属性/对象转换为json对象,提供到UI层去使用。而第一个package中定义的action,仅仅是页面第一次进入时的入口。

 

这里的result和messageList.*则是对StrutsTestAction的result和messageList属性的对外公布,includeProperties节点是支持正则表达式的,当然还有其他的json param,详细地大家可以参考struts2-jsonplugin-0.6.jar中的定义。

 

这里提到一个messageList,主要是给大家谈谈Struts2的conversion的支持,看看StrutsTestAction-conversion.properties文件的内容,大家应该就明白了。

Element_messageList = com.tail.test.objects.Message
CreateIfNull_messageList = true

 

不错,这里的定义主要是为了让json对象能被解析和传输。精确一点地说,在Action->UI的时候,他事实上用处不大,或者说可以省去。但是,如果如果经历UI->Action的时候,这个conversion定义就是必须的,否则Struts Action无法理解UI传送过来的数据。

 

分享到:
评论
3 楼 tailsherry 2008-03-25  
Here is just a demo for RICH client.

You may take a look at my following article "http://tailsherry.iteye.com/blog/149892"
2 楼 jfxia 2008-03-25  
Where is the "RICH" client?
1 楼 flash 2008-01-06  
为什么只有看的没有回的?有什么诡异之处?

相关推荐

    Struts2+JSON+YUI组合应用之二构建RichClient

    Struts2+JSON+YUI组合应用之二构建RichClient

    java开源包1

    WebSocket4J 是一个用 Java 实现的 WebSocket 协议的类库,可使用 Java 来构建交互式 Web 应用。WebSocket4J 并未实现客户端通讯协议,所以不能用它来连接 WebSocket 服务器。 Struts验证码插件 JCaptcha4Struts2 ...

    java开源包2

    WebSocket4J 是一个用 Java 实现的 WebSocket 协议的类库,可使用 Java 来构建交互式 Web 应用。WebSocket4J 并未实现客户端通讯协议,所以不能用它来连接 WebSocket 服务器。 Struts验证码插件 JCaptcha4Struts2 ...

    java开源包11

    WebSocket4J 是一个用 Java 实现的 WebSocket 协议的类库,可使用 Java 来构建交互式 Web 应用。WebSocket4J 并未实现客户端通讯协议,所以不能用它来连接 WebSocket 服务器。 Struts验证码插件 JCaptcha4Struts2 ...

    java开源包3

    WebSocket4J 是一个用 Java 实现的 WebSocket 协议的类库,可使用 Java 来构建交互式 Web 应用。WebSocket4J 并未实现客户端通讯协议,所以不能用它来连接 WebSocket 服务器。 Struts验证码插件 JCaptcha4Struts2 ...

    java开源包6

    WebSocket4J 是一个用 Java 实现的 WebSocket 协议的类库,可使用 Java 来构建交互式 Web 应用。WebSocket4J 并未实现客户端通讯协议,所以不能用它来连接 WebSocket 服务器。 Struts验证码插件 JCaptcha4Struts2 ...

    java开源包5

    WebSocket4J 是一个用 Java 实现的 WebSocket 协议的类库,可使用 Java 来构建交互式 Web 应用。WebSocket4J 并未实现客户端通讯协议,所以不能用它来连接 WebSocket 服务器。 Struts验证码插件 JCaptcha4Struts2 ...

    java开源包10

    WebSocket4J 是一个用 Java 实现的 WebSocket 协议的类库,可使用 Java 来构建交互式 Web 应用。WebSocket4J 并未实现客户端通讯协议,所以不能用它来连接 WebSocket 服务器。 Struts验证码插件 JCaptcha4Struts2 ...

    java开源包4

    WebSocket4J 是一个用 Java 实现的 WebSocket 协议的类库,可使用 Java 来构建交互式 Web 应用。WebSocket4J 并未实现客户端通讯协议,所以不能用它来连接 WebSocket 服务器。 Struts验证码插件 JCaptcha4Struts2 ...

    java开源包8

    WebSocket4J 是一个用 Java 实现的 WebSocket 协议的类库,可使用 Java 来构建交互式 Web 应用。WebSocket4J 并未实现客户端通讯协议,所以不能用它来连接 WebSocket 服务器。 Struts验证码插件 JCaptcha4Struts2 ...

    java开源包7

    WebSocket4J 是一个用 Java 实现的 WebSocket 协议的类库,可使用 Java 来构建交互式 Web 应用。WebSocket4J 并未实现客户端通讯协议,所以不能用它来连接 WebSocket 服务器。 Struts验证码插件 JCaptcha4Struts2 ...

    java开源包9

    WebSocket4J 是一个用 Java 实现的 WebSocket 协议的类库,可使用 Java 来构建交互式 Web 应用。WebSocket4J 并未实现客户端通讯协议,所以不能用它来连接 WebSocket 服务器。 Struts验证码插件 JCaptcha4Struts2 ...

    JAVA上百实例源码以及开源项目源代码

    5个目标文件,演示Address EJB的实现,创建一个EJB测试客户端,得到名字上下文,查询jndi名,通过强制转型得到Home接口,getInitialContext()函数返回一个经过初始化的上下文,用client的getHome()函数调用Home接口...

    java开源包101

    WebSocket4J 是一个用 Java 实现的 WebSocket 协议的类库,可使用 Java 来构建交互式 Web 应用。WebSocket4J 并未实现客户端通讯协议,所以不能用它来连接 WebSocket 服务器。 Struts验证码插件 JCaptcha4Struts2 ...

    Java资源包01

    WebSocket4J 是一个用 Java 实现的 WebSocket 协议的类库,可使用 Java 来构建交互式 Web 应用。WebSocket4J 并未实现客户端通讯协议,所以不能用它来连接 WebSocket 服务器。 Struts验证码插件 JCaptcha4Struts2 ...

    JAVA上百实例源码以及开源项目

    5个目标文件,演示Address EJB的实现,创建一个EJB测试客户端,得到名字上下文,查询jndi名,通过强制转型得到Home接口,getInitialContext()函数返回一个经过初始化的上下文,用client的getHome()函数调用Home接口...

Global site tag (gtag.js) - Google Analytics