Struts-json-plugin使用手册(翻译自官方文档)
为了在网上找到struts-json-plugin-xx.jar的源码,可真是费了九牛二虎之力,最后也还是没能如愿以偿,最后只得在Apache-SVN上一页一页的翻看源码来完成上一篇文章,真是悲惨...不过凡事不总是那么绝对——我想这也是生活的魅力所在,居然让我不经意间发现了Apache官网上的一篇关于struts-json-plugin的使用说明文档,非常的详细,非常的全面,不仅有配置说明,还有一个范例工程,赶紧将其拿出来与大家分享。
?
JSON 插件提供了一个 "json" 结果类型来把 action 序列化成 JSON. 这一序列化的过程是递归的, 意即整个对象图,从 action 类开始 (未包括基类) 将会被序列化 (可以用 "root" 属性来指定自己的根对象). 如果使用了 json 拦截器, action 将可通过请求中的 JSON 内容组装出来, 该拦截器遵循以下几条规则:
给定下面的 JSON 字符串:
?
{ "doubleValue": 10.10, "nestedBean": { "name": "Mr Bean" }, "list": ["A", 10, 20.20, { "firstName": "El Zorro" }], "array": [10, 20] }
?
action 中必须有一个 "setDoubleValue" 方法, 参数为 "float" 或者 "double"(拦截器将会把值转换为相应的类型). 还必须有一个 "setNestedBean" 方法,它的参数类型可以为任何类类型, 其中含有参数为 "String" 的 "setName" 方法. 还必须有一个参数为 "List" 的 "setList" 方法, 这个 List 中将会包含: "A" (String), 10 (Long), 20.20 (Double), Map ("firstName" -> "El Zorro"). "setArray" 方法可以是 "List", 或任何数字类型数组作参数的.本插件可通过把插件 jar 包到你的应用的 /WEB-INF/lib 目录来完成安装. 没有别的文件需要拷贝或被创建.
使用 maven 的话, 加入下列到你的 pom 中:
?
?
<dependencies> ... <dependency> <groupId>org.apache.struts</groupId> <artifactId>struts2-json-plugin</artifactId> <version>STRUTS_VERSION</version> </dependency> ...</dependencies>
?
定制化序列化和反序列化使用 JSON 注解来达到定制序列化和反序列化过程. 可用的 JSON 注解如下:
?
?
名称描述默认值序列化反序列化name定制字段名emptyyesnoserialize标识为可被序列化trueyesnodeserialize标识为可被反序列化truenoyesformat用于格式化或解析 Date 字段的格式"yyyy-MM-dd'T'HH:mm:ss"yesyes?
?
排除属性
?
逗号分隔的正则表达式列表可传递给 JSON Result 和 Interceptor(拦截器), 被任何 一个正则表达式匹配的属性将会在序列化过程时忽略掉:
?
<!-- Result fragment --><result type="json"> <param name="excludeProperties"> login.password, studentList.*\.sin </param></result><!-- Interceptor fragment --><interceptor-ref name="json"> <param name="enableSMD">true</param> <param name="excludeProperties"> login.password, studentList.*\.sin </param></interceptor-ref>
?
包含属性逗号分隔的正则表达式列表可被传递给 JSON Result, 用于限制哪些属性可用于序列化. 只有当能够匹配任何一个正则表达式的属性才会包含在序列化输出中.
?
?
<!-- Result fragment --><result type="json"> <param name="includeProperties"> ^entries\[\d+\]\.clientNumber, ^entries\[\d+\]\.scheduleNumber, ^entries\[\d+\]\.createUserId </param></result>
?
?
根对象?使用 "root" 属性(OGNL 表达式) 指定被用于序列化的根对象.
?
<result type="json"> <param name="root"> person.job </param></result>
?
?
"root" 属性(OGNL 表达式) 也可以用于拦截器来指定被组装的对象, 确保这个对象不会是 null.
?
<interceptor-ref name="json"> <param name="root">bean1.bean2</param></interceptor-ref>
?
?
包装可能会有某些原因,你想要用些文本对 JSON 输出包装一下, 像用注释包裹, 加上前缀, 或使用文件上载让结果显示在 textarea 之中. 用 wrapPrefix 在开始处加上内容,wrapPostfix 添加内容在尾端. 这两个参数优先使用,而 "wrapWithComments" 和 "prefix" 自从 0.34 后就不推荐使用. 例子:
进行注释:
?
<result type="json"> <param name="wrapPrefix">/*</param> <param name="wrapSuffix">*/</param></result>
?
添加前缀:
?
<result type="json"> <param name="wrapPrefix">{}&&</param></result>
?
?
包裹上传的文件内容:
?
<result type="json"> <param name="wrapPrefix"><![CDATA[<html><body><textarea>]]></param> <param name="wrapSuffix"><![CDATA[</textarea></body></html>]]></param></result>
?
包裹以注释?
["*/ alert('XSS'); /*"]
谢谢 Douglas Crockford 的提示! 应考虑用 prefix.
假如被序列化的 JSON 是 {name: 'El Zorro'}. 那么此时输出就会是: {}&& ({name: 'El Zorro'}
假如 "wrapWithComments" (默认为 false) 属性被设为 true, 生成的被包裹上注释的 JSON 就如下:
?
/* { "doubleVal": 10.10, "nestedBean": { "name": "Mr Bean" }, "list": ["A", 10, 20.20, { "firstName": "El Zorro" }], "array": [10, 20] } */
?
?欲取消上面的注释,可用:
?var responseObject = eval("("+data.substring(data.indexOf("\/\*")+2, data.lastIndexOf("\*\/"))+")");??前缀?
假如参数 prefix 被设置为 true, 生成的 JSON 将被附上前缀 "{}&& ". 这有助于防止被劫持. 详细内容请看 this Dojo Ticket:
?
<result type="json"> <param name="prefix">true</param></result>
??
?
基类 ?默认时,定义在 "root" 对象的基类中的属性不会被序列化, 要序列化来自于所有基类(直到 Object) 中的属性,需在 JSON result 里设置 "ignoreHierarchy" 为 false:
?
<result type="json"> <param name="ignoreHierarchy">false</param></result>
?
枚举类型默认的, Enum 被序列化为 name=value 对,这里的 value = name().
?
public enum AnEnum { ValueA, ValueB } JSON: "myEnum":"ValueA"
?
使用 result 的参数 "enumAsBean" 可使得 Enum 像一个 bean 一样的被序列化,特定的属性为 _name,值为 name(). 所有的枚举属性都会被序列化.?
?
?
public enum AnEnum { ValueA("A"), ValueB("B"); private String val; public AnEnum(val) { this.val = val; } public getVal() { return val; } }
?
?
JSON: myEnum: { "_name": "ValueA", "val": "A" }
?
在 struts.xml 中启用该参数:
?
<result type="json"> <param name="enumAsBean">true</param></result>
?
?
压缩输出.设置 enableGZIP 属性为 true 可用 gzip 压缩响应输出. 在请求后 "Accept-Encoding" 头中必须包含 "gzip" 才能正常工作.
?
<result type="json"> <param name="enableGZIP">true</param></result>
?
防止浏览器缓存响应数据noCache 设置为 true(默认为 false) 会设置如下响应头:
?
Cache-Control: no-cacheExpires: 0Pragma: No-cache?
<result type="json"> <param name="noCache">true</param></result>
?
?
排除值为 null 的属性默认的,为 null 的字段也被序列化,生成像 {property_name: null}. 这能够通过设置 excludeNullProperties 为 true 来防止.
?
<result type="json"> <param name="excludeNullProperties">true</param></result>
?
?
状态和错误代码使用 statusCode 来设置响应状态代码:
?
<result type="json"> <param name="statusCode">304</param></result>
?
?
同时可用 errorCode 来发送一个错误(the server might end up sending something to the client which is not the serialized JSON):
?
<result type="json"> <param name="errorCode">404</param></result>
?
JSONPTo enable JSONP, set the parameter callbackParameter in either the JSON Result or the Interceptor. A parameter with that name will be read from the request, and it value will be used as the JSONP function. Assuming that a request is made with the parameter "callback"="exec":?
?
<result type="json"> <param name="callbackParameter">callback</param></result>
?
And that the serialized JSON is {name: 'El Zorro'}. Then the output will be: exec({name: 'El Zorro'})
Content TypeContent type will be set to application/json-rpc by default if SMD is being used, or application/json otherwise. Sometimes it is necessary to set the content type to something else, like when uploading files with Dojo and YUI. Use the contentType parameter in those cases.
?
<result type="json"> <param name="contentType">text/html</param></result>??
?
?
以上是前辈"隔叶黄莺 Unmi Blog"对该文档的翻译,感谢前辈的无私奉献!除上述翻译的部分,原文中还有三个具体的范例,除了示范普通的JSON调用外,还有一个JSON RPC范例,笔者看的不是很明白,所以这里不敢多说什么。原文地址:https://cwiki.apache.org/confluence/display/WW/JSON+Plugin,感兴趣的童鞋可以去看看。
?
?
?