Name |
JSON Plugin |
---|---|
Publisher |
|
License |
Open Source (ASL2) |
Version |
0.9 |
Compatibility |
Struts 2.0.6 |
Homepage |
|
Download |
Overview
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:
{ "doubleVal": 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.
Customizing Serialization and Deserialization
Use the JSON annotation to customize the serialization/deserialization process. Available JSON annotation fields:
Name |
Description |
Default Value |
Serialization |
Deserialization |
---|---|---|---|---|
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 |
A comma-delimited list of regular expression can be passed to the JSON Result, properties matching any of these regular expression will be ignored on the serialization process:
<result type="json"> <param name="excludeProperties"> login.password, studentList.*\.sin </param> </result>
Use the "root" attribute(OGNL expression) to specify the root object to be serialized.
<result type="json"> <param name="root"> person.job </param> </result>
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] } */
This can be used to avoid potential Javascript Hijacks. To strip those comments use:
var responseObject = eval("("+data.substring(data.indexOf("\/\*")+2, data.lastIndexOf("\*\/"))+")");
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> <constant name="struts.enable.DynamicMethodInvocation" value="false" /> <constant name="struts.devMode" value="true" /> <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" }
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.
Version History
Version |
Date |
Author |
Notes |
---|---|---|---|
0.1-BETA |
Jan 11, 2007 |
Initial release |