- 浏览: 159308 次
- 性别:
- 来自: 深圳
最新评论
-
决战冰河:
你好,我遇到一个相似的问题。soap请求包为:<para ...
axis 调用cxf boolean获取为null或者异常 -
dingding5060:
额,LZ啥意思?之前都不安装jdk的吗?不知道LZ是否有这样的 ...
org.apache.cxf.interceptor.Fault: Could not send Message -
lxdhq1011:
你好,我想问一下android调用webservice,如何调 ...
在android中调用webservice
Apache Struts 2 Documentation--JSON Plugin
本文来源:http://struts.apache.org/2.2.3/docs/json-plugin.html
The JSON plugin provides a "json" result type that serializes actions into JSON. The serialization process is recursive, meaning that the whole object graph, starting on the action class (base class not included) will be serialized (root object can be customized using the "root" attribute). If the interceptor is used, the action will be populated from the JSON content in the request, these are the rules of the interceptor:
- The "content-type" must be "application/json"
- The JSON content must be well formed, see json.org for grammar.
- Action must have a public "setter" method for fields that must be populated.
- Supported types for population are: Primitives (int,long...String), Date, List, Map, Primitive Arrays, Other class (more on this later), and Array of Other class.
- Any object in JSON, that is to be populated inside a list, or a map, will be of type Map (mapping from properties to values), any whole number will be of type Long, any decimal number will be of type Double, and any array of type List.
Given this JSON string:
{ "doubleValue": 10.10, "nestedBean": { "name": "Mr Bean" }, "list": ["A", 10, 20.20, { "firstName": "El Zorro" }], "array": [10, 20] }
The action must have a "setDoubleValue" method, taking either a "float" or a "double" argument (the interceptor will convert the value to the right one). There must be a "setNestedBean" whose argument type can be any class, that has a "setName" method taking as argument an "String". There must be a "setList" method that takes a "List" as argument, that list will contain: "A" (String), 10 (Long), 20.20 (Double), Map ("firstName" -> "El Zorro"). The "setArray" method can take as parameter either a "List", or any numeric array.
So serialize your objects to JSON in javascript see json2 |
Installation
This plugin can be installed by copying the plugin jar into your application's /WEB-INF/lib directory. No other files need to be copied or created.
To use maven, add this to your pom:
<dependencies> ... <dependency> <groupId>org.apache.struts</groupId> <artifactId>struts2-json-plugin</artifactId> <version>STRUTS_VERSION</version> </dependency> ... </dependencies>
Customizing Serialization and Deserialization
Use the JSON annotation to customize the serialization/deserialization process. Available JSON annotation fields:
name | Customize field name | empty | yes | no |
serialize | Include in serialization | true | yes | no |
deserialize | Include in deserialization | true | no | yes |
format | Format used to format/parse a Date field | "yyyy-MM-dd'T'HH:mm:ss" | yes | yes |
Excluding properties
A comma-delimited list of regular expressions can be passed to the JSON Result and Interceptor, properties matching any of these regular expressions will be ignored on the serialization process:
<!-- 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>
Including properties
A comma-delimited list of regular expressions can be passed to the JSON Result to restrict which properties will be serialized. ONLY properties matching any of these regular expressions will be included in the serialized output.
Note Exclude property expressions take precedence over include property expressions. That is, if you use include and exclude property expressions on the same result, include property expressions will not be applied if an exclude exclude property expression matches a property first. |
<!-- Result fragment --> <result type="json"> <param name="includeProperties"> ^entries\[\d+\]\.clientNumber, ^entries\[\d+\]\.scheduleNumber, ^entries\[\d+\]\.createUserId </param> </result>
Root Object
Use the "root" attribute(OGNL expression) to specify the root object to be serialized.
<result type="json"> <param name="root"> person.job </param> </result>
The "root" attribute(OGNL expression) can also be used on the interceptor to specify the object that must be populated, make sure this object is not null.
<interceptor-ref name="json"> <param name="root">bean1.bean2</param> </interceptor-ref>
Wrapping
For several reasons you might want to wrap the JSON output with some text, like wrapping with comments, adding a prefix, or to use file uploads which require the result to be wrapped in a textarea. Use wrapPrefix to add content in the beginning and wrapPostfix to add content at the end. This settings take precedence over "wrapWithComments" and "prefix" which are deprecated from 0.34 on. Examples:
Wrap with comments:
<result type="json"> <param name="wrapPrefix">/*</param> <param name="wrapSuffix">*/</param> </result>
Add a prefix:
<result type="json"> <param name="wrapPrefix">{}&&</param> </result>
Wrap for file upload:
<result type="json"> <param name="wrapPrefix"><![CDATA[<html><body><textarea>]]></param> <param name="wrapSuffix"><![CDATA[</textarea></body></html>]]></param> </result>
Wrap with Comments
wrapWithComments is deprecated from 0.34, use wrapPrefix and wrapSuffix instead. |
wrapWithComments can turn safe JSON text into dangerous text. For example,
["*/ alert('XSS'); /*"] Thanks to Douglas Crockford for the tip!. Consider using prefix instead. |
If the serialized JSON is {name: 'El Zorro'}. Then the output will be: {}&& ({name: 'El Zorro'}
If the "wrapWithComments" (false by default) attribute is set to true, the generated JSON is wrapped with comments like:
/* { "doubleVal": 10.10, "nestedBean": { "name": "Mr Bean" }, "list": ["A", 10, 20.20, { "firstName": "El Zorro" }], "array": [10, 20] } */
To strip those comments use:
var responseObject = eval("("+data.substring(data.indexOf("\/\*")+2, data.lastIndexOf("\*\/"))+")");
Prefix
prefix is deprecated from 0.34, use wrapPrefix and wrapSuffix instead. |
If the parameter prefix is set to true, the generated JSON will be prefixed with "{}&& ". This will help prevent hijacking. See this Dojo Ticket for details:
<result type="json"> <param name="prefix">true</param> </result>
Base Classes
By default properties defined on base classes of the "root" object won't be serialized, to serialize properties in all base classes (up to Object) set "ignoreHierarchy" to false in the JSON result:
<result type="json"> <param name="ignoreHierarchy">false</param> </result>
Enumerations
By default, an Enum is serialized as a name=value pair where value = name().
public enum AnEnum { ValueA, ValueB } JSON: "myEnum":"ValueA"
Use the "enumAsBean" result parameter to serialize Enum's as a bean with a special property _name with value name(). All properties of the enum are also serialized.
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" }
Enable this parameter through struts.xml:
<result type="json"> <param name="enumAsBean">true</param> </result>
Compressing the output.
Set the enableGZIP attribute to true to gzip the generated json response. The request must include "gzip" in the "Accept-Encoding" header for this to work.
<result type="json"> <param name="enableGZIP">true</param> </result>
Preventing the browser from caching the response
Set noCache to true(false by default) to set the following headers in the response:
- Cache-Control: no-cache
- Expires: 0
- Pragma: No-cache
<result type="json"> <param name="noCache">true</param> </result>
Excluding properties with null values
By default fields with null values are serialized like {property_name: null}. This can be prevented by setting excludeNullProperties to true.
<result type="json"> <param name="excludeNullProperties">true</param> </result>
Status and Error code
Use statusCode to set the status of the response:
<result type="json"> <param name="statusCode">304</param> </result>
And errorCode to send an error(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>
JSONP
To 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 Type
Content 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>
Example
Setup Action
This simple action has some fields:
Example:
import java.util.HashMap; import java.util.Map; import com.opensymphony.xwork2.Action; public class JSONExample { private String field1 = "str"; private int[] ints = {10, 20}; private Map map = new HashMap(); private String customName = "custom"; //'transient' fields are not serialized private transient String field2; //fields without getter method are not serialized private String field3; public String execute() { map.put("John", "Galt"); return Action.SUCCESS; } 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 map) { this.map = map; } @JSON(name="newName") public String getCustomName() { return this.customName; } }
Write the mapping for the action
- Add the map inside a package that extends "json-default"
- Add a result of type "json"
Example:
<?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="example" extends="json-default"> <action name="JSONExample" class="example.JSONExample"> <result type="json"/> </action> </package> </struts>
JSON example output
{ "field1" : "str", "ints": [10, 20], "map": { "John":"Galt" }, "newName": "custom" }
JSON RPC
The json plugin can be used to execute action methods from javascript and return the output. This feature was developed with Dojo in mind, so it uses Simple Method Definition to advertise the remote service. Let's work it out with an example(useless as most examples).
First write the action:
package smd; import com.googlecode.jsonplugin.annotations.SMDMethod; import com.opensymphony.xwork2.Action; public class SMDAction { public String smd() { return Action.SUCCESS; } @SMDMethod public Bean doSomething(Bean bean, int quantity) { bean.setPrice(quantity * 10); return bean; } }
Methods that will be called remotely must be annotated with the SMDMethod annotation, for security reasons. The method will take a bean object, modify its price and return it. The action can be annotated with the SMD annotation to customize the generated SMD (more on that soon), and parameters can be annotated with SMDMethodParameter. As you can see, we have a "dummy", smd method. This method will be used to generate the Simple Method Definition (a definition of all the services provided by this class), using the "json" result.
The bean class:
package smd; public class Bean { private String type; private int price; public String getType() { return type; } public void setType(String type) { this.type = type; } public int getPrice() { return price; } public void setPrice(int price) { this.price = price; } }
The mapping:
<package name="RPC" namespace="/nodecorate" extends="json-default"> <action name="SMDAction" class="smd.SMDAction" method="smd"> <interceptor-ref name="json"> <param name="enableSMD">true</param> </interceptor-ref> <result type="json"> <param name="enableSMD">true</param> </result> </action> </package>
Nothing special here, except that both the interceptor and the result must be applied to the action, and "enableSMD" must be enabled for both.
Now the javascript code:
<s:url id="smdUrl" namespace="/nodecorate" action="SMDAction" /> <script type="text/javascript"> //load dojo RPC dojo.require("dojo.rpc.*"); //create service object(proxy) using SMD (generated by the json result) var service = new dojo.rpc.JsonService("${smdUrl}"); //function called when remote method returns var callback = function(bean) { alert("Price for " + bean.type + " is " + bean.price); }; //parameter var bean = {type: "Mocca"}; //execute remote method var defered = service.doSomething(bean, 5); //attach callback to defered object defered.addCallback(callback); </script>
Dojo's JsonService will make a request to the action to load the SMD, which will return a JSON object with the definition of the available remote methods, using that information Dojo creates a "proxy" for those methods. Because of the asynchronous nature of the request, when the method is executed, a deferred object is returned, to which a callback function can be attached. The callback function will receive as a parameter the object returned from your action. That's it.
Proxied objects
As annotations are not inherited in Java, some user might experience problems while trying to serialize objects that are proxied. eg. when you have attached AOP interceptors to your action.
In this situation, the plugin will not detect the annotations on methods in your action.
To overcome this, set the "ignoreInterfaces" result parameter to false (true by default) to request that the plugin inspects all interfaces and superclasses of the action for annotations on the action's methods.
NOTE: This parameter should only be set to false if your action could be a proxy as there is a performance cost caused by recursion through the interfaces.
<action name="contact" class="package.ContactAction" method="smd"> <interceptor-ref name="json"> <param name="enableSMD">true</param> <param name="ignoreSMDMethodInterfaces">false</param> </interceptor-ref> <result type="json"> <param name="enableSMD">true</param> <param name="ignoreInterfaces">false</param> </result> <interceptor-ref name="default"/> </action>
相关推荐
- **插件(Plugins)**:每个插件通常对应一个单独的JAR,如`struts2-convention-plugin.jar`(约定优于配置)、`struts2-json-plugin.jar`(JSON支持)等。 - **依赖库(Dependent Libraries)**:Struts 2依赖于...
2) A directory called "apache-maven-3.x.y" will be created. 3) Add the bin directory to your PATH, eg: Unix-based operating systems (Linux, Solaris and Mac OS X) export PATH=/usr/local/apache-...
Apache Struts 2.5.13 is an elegant, extensible framework for creating enterprise-ready Java web applications. It is available in a full distribution, or as separate library, source, example and ...
5. **文档(Documentation)**: 解释库的API和如何使用它们来构建JSON-RPC服务端。 **开发流程** 使用"jsonrpc-c-master"进行开发通常包括以下几个步骤: 1. **理解库API**: 阅读库的头文件和文档,了解如何初始化...
Apache Struts 2.5.13 is an elegant, extensible framework for creating enterprise-ready Java web applications. It is available in a full distribution, or as separate library, source, example and ...
chm格式的帮助文档,全英文版。这是第一部分(共两部分)
Apache Kafka 是一个分布式流处理平台,由LinkedIn 开发并捐赠给了Apache 软件基金会,现在已成为大数据领域的重要组件。Kafka 主要用于构建实时数据管道和流应用,它能够高效地处理大量的实时数据,同时提供了消息...
其中包括27个Java源文件、7个Markdown文档、2个JSON文件、1个gitignore文件、1个LICENSE文件、1个NOTICE文件、1个PNG图片文件、1个licenses/LICENSE-living-documentation文件和1个licenses/LICENSE-maven-...
Apache Struts 2.5.13 is an elegant, extensible framework for creating enterprise-ready Java web applications. It is available in a full distribution, or as separate library, source, example and ...
class-validator-jsonschema 将装饰有类转换为与OpenAPI兼容的JSON模式。 目的是提供一种尽力而为的转换:由于某些class-validator修饰符缺少直接的JSON Schema对应项,因此转换必然有些自以为是。 为了解决这个...
rails-documentation-2-0-2
例如,假设XML数据存储在变量`xmlData`中,可以这样调用:`var jsonData = $.xml2json(xmlData);` 4. **处理JSON数据**: 转换完成后,`jsonData`就是一个标准的JavaScript对象,可以按照JavaScript的方式进行遍历、...
Last Published: 2013-03-16 Struts 1 | Struts 2 | Apache APACHE STRUTS Welcome Releases Announcements License Kickstart FAQ Website Stats Thanks! Sponsorship DOCUMENTATION Key Technologies Struts ...
JDK 11 Documentation - Java Core Libraries Developer Guide JDK 11 Documentation - Java Core Libraries Developer Guide JDK 11 Documentation - Java Core Libraries Developer Guide JDK 11 Documentation - ...
3. **jquery.xml2json.js**:这个文件是jQuery的一个插件,实现了将XML数据转换为JSON对象的功能。它利用jQuery的便利性,提供了一个简单易用的API供开发者调用。 4. **testing.js**:这很可能是用于测试`jquery....
webRTC接口文档 中文
rails-documentation-1-2-0-rc1.chm
JDK 12 Documentation - Java Core Libraries Developer Guide JDK 12 Documentation - Java Core Libraries Developer Guide JDK 12 Documentation - Java Core Libraries Developer Guide JDK 12 Documentation - ...
"gtkmm-documentation-master.zip" 文件包含的是 gtkmm 的官方源代码和相关文档的源码,对于深入理解并使用 gtkmm 进行开发非常有帮助。 1. gtkmm 概述: gtkmm 是 GTK+ 的 C++ 封装,它提供了完整的面向对象接口...
Android.4.2 API速查手册,3个压缩包