Struts 与 dojo 整合研究
1, Struts 的 dojo 标签
Struts 框架有一些 Ajax 的插件,例如:
· Ajax Parts - The AjaxParts Taglib (APT) is a component of the Java Web Parts (JWP) project ( http://javawebparts.sourceforge.net ) that allows for 100% declarative
(read: no Javascript coding required!) AJAX functionality within a Java-based webapp.
· Dojo - The Ajax Tags Dojo Plugin was represented as a theme for Struts 2.0. For Struts 2.1, the Dojo tags are bundled as a plugin.
· YUI – The Yahoo User Interface (YUI) Plugin has only a few tags are available so far, but the YUI tags tend to be easier to use than the Dojo versions.
· jQuery - The jQuery Plugin provide ajax functionality and UI Widgets an JavaScript Grid based on the jQuery javascript framework..
其中 Ajax Tags Dojo Plugin 在 struts2.1 中已经被废除了,主要是由于 dojo 之前的版本不稳定,最新的 dojo 插件 ( struts2-dojo-plugin-2.2.3.jar ) 也只支持 dojo0.4
版本的核心,一共 11 个标签 ,如果不用 struts 的 dojo 标签就设计到数据转换的问题,下面第 2 点说明。
2, struts 与 dojo 的数据转换方法
1) json 格式的数据比 xml 在 web2.0 的应用中性能要好,主要是因为 javascript 对 json 的解析和序列化比 xml 要方便,因此考虑用 json 做前后端的数据传输格
式。另外由于后端处理 request 的时候和是否是 Ajax 请求并无关系,主要是在后台返回 response 的时候,前台的 script 对数据格式有一定的要求,所以本文主要
分析后台在应用 Struts 之后返回 json 数据给前台的处理方法。
2) 那么在前台与后台传输 json 格式的数据时候,关于后台的数据转换问题,有几种常做的方法 :
a, 让 Struts 直接返回 stream 给前台,做法是:应用 Struts 的 ”stream” 这种 result type ,让 action 返回一个 inputStream 给前台,这个
stream 里写一个 json 格式的字符串,其中 json 格式的字符串,可以在后台拼字符串,或者应用 json 格式转换插件将 object 转换成 json 格式的字符串,这样的
开源插件有很多种( http://json.org/ 网站上有各种序列化 json 的插件的链接)。
b, 让 Struts 直接返回一个 JSON 的 response ,这需要使用 JSON 插件! JSON 插件提供了一种名为 json 的Action Result Type 。一旦为Action 指定了该
结果处理类型,JSON 插件就会自动将Action 里的数据序列化成JSON 格式的数据,并返回给客户端物理视图的JavaScript 。简单的说,JSON 插件允许我们在JavaScript 中
异步的调用Action ,而且Action 不需要指定视图来显示Action 的信息显示。而是由JSON 插件来负责具体将Action 里面具体的信息返回给调用页面。
3, Jsonplugin 的用法 (https://cwiki.apache.org/confluence/display/WW/JSON%20Plugin )
在反序列化时,我一直没有试出来,最后在研究struts2-json-plugin-2.2.3.jar插件的源码之后,发现这个插件的反序列化做的还是比较粗放的,不能精确的反序列化对象,最后
还是用struts2的域模型驱动来实现的这个功能。
下面来看代码:
1,所需jar包: (主要是struts的jar包和jsonplugin的jar包,有一些别的包是做其他实验用的)
2, Action的代码:
package com.action;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.struts2.json.annotations.JSON;
import com.bean.Address;
import com.bean.Movie;
import com.opensymphony.xwork2.Action;
import com.opensymphony.xwork2.ActionSupport;
public class JSONExample extends ActionSupport{
private String field1 = null;
private int[] ints = { 10, 20 };
private Map<String , Movie> map = null;
private String customName = "custom";
private Movie movie = null;
private List<Movie> movieList = null;
private Date todayDate = new Date();
// 'transient' fields are not serialized
private transient String field2;
// fields without getter method are not serialized
private String field3;
public String execute() {
System.out.println("execute method begin!");
System.out.println("map 是 "+getMap().getClass().getName()+"类型");
System.out.println("map = "+getMap());
System.out.println("movieList 是 "+getMovieList().getClass().getName()+"类型");
System.out.println("movieList = "+getMovieList());
System.out.println("execute method end!");
return Action.SUCCESS;
}
// @JSON(serialize=false)
public String getField1() {
return field1;
}
public void setField1(String field1) {
this.field1 = field1;
}
public int[] getInts() {
return ints;
}
public void setInts(int[] ints) {
this.ints = ints;
}
public Map getMap() {
return map;
}
public void setMap(Map<String, Movie> map) {
this.map = map;
}
//@JSON(name = "newName")
public String getCustomName() {
return this.customName;
}
public Movie getMovie() {
return movie;
}
public void setMovie(Movie movie) {
this.movie = movie;
}
public List getMovieList() {
return movieList;
}
public void setMovieList(List<Movie> movieList) {
this.movieList = movieList;
}
@JSON(format="yyyy/MM/dd")
public Date getTodayDate() {
return todayDate;
}
public void setTodayDate(Date todayDate) {
this.todayDate = todayDate;
}
}
3,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>
<constant name="struts.devMode" value="true"/>
<package name="stream" extends="json-default">
<action name="JSONExample" class="com.action.JSONExample">
<result type="json">
<!--
<param name="root">
moive
</param>
<param name="excludeProperties">
moive,field1
</param>
<param name="ignoreHierarchy">
false
</param>
-->
</result>
</action>
</package>
</struts>
这里配置好之后,在前台请求JSONExample之后struts2就会返回json格式的数据给前台了!至于dojo怎么处理这个json格式的数据那就是你的事了!其实这个例子就是wiki文档的例子,我自己做了一些实验而已,jsonRPC的应用也是一个不错的研究点,下次有心得还是会和大家一起分享讨论!
下面的源码是核心源码,jar包和dojo大家可以自己下载。我用的是struts2 2.2.3版得dojo是1.6.1的,其中需要说明的是,struts2的不同版本需要不同的jsonplugin插件,一般自带的包里就可以。
主要源码在附件中下载:
附录:
1 ,在后台可以用 json_java 包 做parse Java to json的工作!
2 , json-lib-2.1-jdk15.jar 也是一个后台做 json 和 java 对象之间转换的包, struts 文档有介绍!
3 , jsonplugin-0.34.jar 包是做转换和提供 json result type!
struts2-json-plugin-2.2.3.jar 的包结构与上面的包结构一么一样,是同样的功能,不同的开源项目?
这两个包都 Provides a result type 'json' that serializes an action into JSON, and a 'json' interceptor that populates an action form a request containing a json string.
4 , struts2jsonresult.jar 提供 json result type!是另外一种做json序列化的选择,有兴趣的可以去wiki上看看文档 http://code.google.com/p/struts2jsonresult/w/list
It provides a "json" result type that serializes beans into JSON!
jsonplugin( jsonplugin-0.34.jar, struts2-json-plugin-2.2.3.jar )与 struts2jsonresult.jar 的 Difference :
- No interceptor is provided by this plugin, only the json result type is provided.
- more powerful include/exclude patterns are supported(thanks to the features of flexjson)
存在的问题:
1, 反序列化未实现,即前台 dojo 直接发 json 的数据格式的请求,让 jsonplugin 自动序列化成 java 对象的工作。但可用struts2的域模型驱动来做,比较好做,jsonplugin插件并不是最佳的反序列化的选择!
2, 调研 jsonRPC 的应用(之后会上传,期待你的关注哦^_^)
3, 本文源码文件也许没有组织好,文章也写的比较粗放,欢迎大家指正!