JSON 的含義?

JSON 的全稱是 JavaScript Object Notation,是一種輕量級的數據交換格式。JS ON 與 XML 具備相同的特性,例如易於人編寫和閱讀,易於機器生成和解析。可是 JSON 比 XML 數據傳輸的有效性要高出不少。JSON 徹底獨立與編程語言,使用文本格式保存。 JSON 數據有兩種結構:  Name-Value 對構成的集合,相似於 Java 中的 Map。  Value 的有序列表,相似於 Java 中的 Array。 一個 JSON 格式的數據示例: { "Name": "Apple", "Expiry": "2007/10/11 13:54", "Price": 3.99, "Sizes": [ "Small", "Medium", "Large" ] } 更多關於 JSON 數據格式的說明參看 JSON 官方網站:http://www.json.org(中文 內容參看:http://www.json.org/json-zh.html) GWT 與 JSON GWT 中支持的客戶端服務器端方法調用和數據傳遞的標準格式是 RPC。 JSON 並不 是 GWT 支持的標準的數據傳遞格式。那麼如何使用 JSON 來做爲 GWT 的數據傳遞格式 呢?須要如下幾步。 第一,引用 HTTP 和 JSON 支持。 第二,在客戶端建立 JSON 數據,提交到服務器 第三,在服務器上重寫數據格式解析的代碼,使之支持 JSON 格式的數據 第四,在服務器上組織 JSON 格式的數據,返回給客戶端。 第五,客戶端解析服務器傳回的 JSON 數據,正確的顯示 引用 HTTP 和 JSON 支持 找到.gwt.xml 文件,在其中的 <inherits name='com.google.gwt.user.User'/> 在以後添加以下的內容: <inherits name="com.google.gwt.json.JSON"/> <inherits name="com.google.gwt.http.HTTP"/> 其中 com.google.gwt.json.JSON 指的是要使用 JSON,com.google.gwt.http.H TTP 值得是經過 HTTP 調用服務器上的服務方法。 客戶端構造 JSON 數據 客戶端須要使用 com.google.gwt.json.client 包內的類來組裝 JSON 格式的數據, 數據格式以下: 數據類型 說明 JSONArray JSONValue 構成的數組類型 JSONBoolean JSON boolean 值 JSONException 訪問 JSON 結構的數據出錯的狀況下能夠拋出此異 常 JSONNull JSON Null 根式的數據 JSONNumber JSON Number 類型的數據 JSONObject JSON Object 類型的數據 JSONParser 將 String 格式的 JSON 數據解析爲 JSONValue 類 型的數據 JSONString JSON String 類型的數據 JSONValue 全部 JSON 類型值的超級類型 組合一個簡單的 JSON 數據: JSONObject input = new JSONObject(); JSONString value = new JSONString("mazhao"); input.put("name", value); JSON 數據格式爲:{name: "mazhao"} 組合一個包含數組類型的複雜 JSON 數據: JSONObject input = new JSONObject(); JSONString value = new JSONString("mazhao"); input.put("name", value); JSONArray arrayValue = new JSONArray(); arrayValue.set(0, new JSONString("array item 0")); arrayValue.set(1, new JSONString("array item 1")); arrayValue.set(2, new JSONString("array item 2")); input.put("array", arrayValue); JSON 數據格式爲: {name: "mazhao", array: {"array item 0", "array item 1", "array item 2"}} 注意上述的 JSON 類型的數據,使用的都是 com.google.gwt.json.client 包內的類 型。這些類型最終會被編譯爲 JavaScript 執行。 服務端重寫數據解析代碼,支持 JSON 格式的數據 在服務器上,須要使用 JSON Java 支持類才能將 JSON 格式的數據轉換爲各類類型 的數據,固然也能夠本身寫一些解析用的代碼。這裏咱們使用了 www.json.org 上的代碼 來完成。這組代碼與 com.google.gwt.json.client 的代碼很類似,只是在 org.json 包內 部。 怎麼解析 JSON 數據呢?針對上述中的複雜的 JSON 數據: {name: "mazhao", array: {"array item 0", "array item 1", "array item 2"}} 可使用以下的方式解析: JSONObject jsonObject = new JSONObject(payload); String name = jsonObject.getString("name"); System.out.println("name is:" + name); JSONArray jsonArray = jsonObject.getJSONArray("array"); for(int i = 0; i < jsonArray.length(); i++) { System.out.println("item " + i + " :" + jsonArray.getString(i)); } 其中 payload 指的是上述的 JSON 格式的數據。 那麼如何寫 GWT 的 Service 來獲得 Payload 的數據呢?須要兩點, 第一, 須要創建 一個 Service 類,第二,覆蓋父類的 processCall 方法。 示例代碼: package com.jpleasure.gwt.json.server; import com.google.gwt.user.client.rpc.SerializationException; import com.google.gwt.user.server.rpc.RemoteServiceServlet; import com.jpleasure.gwt.json.client.HelloWorldService; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; /** * Created by IntelliJ IDEA. * User: vaio * Date: 2007-9-4 * Time: 22:08:31 * To change this template use File | Settings | File Templates. */ public class HelloWorldServiceImpl extends RemoteServiceServlet implemen ts HelloWorldService { public String processCall(String payload) throws SerializationException { try { JSONObject jsonObject = new JSONObject(payload); String name = jsonObject.getString("name"); System.out.println("name is:" + name); JSONArray jsonArray = jsonObject.getJSONArray("array"); for(int i = 0; i < jsonArray.length(); i++) { System.out.println("item " + i + " :" + jsonArray.getString(i)); } } catch (JSONException e) { e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. } return "success"; } } 在服務器上組織 JSON 格式的數據,返回給客戶端 同上 客戶端解析服務器傳回的 JSON 數據,正確的顯示 同上 Struts2返回json須要jsonplugin-0[1].25的 包 而後咱們的配置文件中須要繼承 json-default Java 代碼 1. <?xml version="1.0" encoding="UTF-8" ?> 2. <!DOCTYPE struts PUBLIC 3. "-//Apache Software Foundation//DTD Struts Configuration 2.0// EN" 4. "http://struts.apache.org/dtds/struts-2.0.dtd"> 5. 6. <struts> 7. 8. <package name="com.action.testJson" extends="json-default" nam espace="/" > 9. <action name="jsonUser" class="com.action.testJson.JsonAction " method="testUser"> 10. <result type="json"/> 11. </action> 12. <!-- Add actions here --> 13. </package> 14.</struts> <?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="com.action.testJson" extends="json-default" namespace="/" > <action name="jsonUser" class="com.action.testJson.JsonAction" method="testUser"> <result type="json"/> </action> <!-- Add actions here --> </package> </struts> 而後咱們的 Action 中須要返回的 json 信息須要加上註解 Java 代碼 1. //pizza 2. package com.action.testJson; 3. 4. import java.util.ArrayList; 5. import java.util.List; 6. 7. import com.googlecode.jsonplugin.annotations.JSON; 8. import com.opensymphony.xwork2.ActionSupport; 9. 10.public class JsonAction extends ActionSupport { 11. 12. private static final long serialVersionUID = -4082165361641669835 L; 13. 14. Users user=new Users(); 15. List userList=new ArrayList(); 16. 17. 18. public String testUser(){ 19. System.out.println("in the json Acton"); 20. userInit(); 21. userList.add(user); 22. return SUCCESS; 23. } 24. 25. public void userInit(){ 26. user.setAge(1); 27. user.setName("張澤峯"); 28. user.setPassword("nofengPassword"); 29. } 30. 31. @JSON(name="userString") 32. public Users getUser() { 33. return user; 34. } 35. 36. @JSON(name="userList") 37. public List getUserList() { 38. return userList; 39. } 40. 41. public void setUser(Users user) { 42. this.user = user; 43. } 44. 45. public void setUserList(List userList) { 46. this.userList = userList; 47. } 48. 49. 50.} JSON Plugin 的說明 Edit Page Browse Space Add Page Add News Added by Musachy Barroso, last edited by ghostroller on Jul 04, 2008 (view change) SHOW COMMENT Name JSON Plugin Publisher Musachy Barroso License Open Source (ASL2) Version 0.30 Compatibility Struts 2.0.6 or later Homepage http://code.google.com/p/jsonplugin/ Download http://code.google.com/p/jsonplugin/downloads/list Rating?  1  2  3  4  5 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: 1. The "content-type" must be "application/json" 2. The JSON content must be well formed, see json.org for grammar. 3. Action must have a public "setter" method for fields that must be populated. 4. 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. 5. 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. 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>com.googlecode</groupId> <artifactId>jsonplugin</artifactId> <version>0.26</version> </dependency> ... </dependencies> <repository> <id>Maven Plugin Repository</id> <url>http://struts2plugin-maven-repo.googlecode.com/svn/trunk/</url> <snapshots> <enabled>false</enabled> </snapshots> <releases> <enabled>true</enabled> </releases> </repository> 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 "yyyy-MM-dd'T'HH:mm:ss" yes yes format/parse a Date field 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> Wrap with Comments wrapWithComments can turn safe JSON text into dangerous text. For example, ["*/ alert('XSS'); /*"] Thanks to Douglas Crockford for the tip! 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("\*\/"))+")"); 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> 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 1. Add the map inside a package that extends "json-default" 2. 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 (V0.20) 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> 在Struts 2中使用JSon ajax支持 來源: 做者: 發佈時間:2007-12-19 JSON 插件提供了一種名爲 json的 ResultType,一旦爲某個 Action 指定了 一個類型爲 json 的 Result,則該 Result 無需映射到任何視圖資源。由於 JSON 插件會負責將 Action 裏的狀態信息序列化成 JSON 格式的數據,並將該數據返 回給客戶端頁面的 JavaScript。 簡單地說, JSON插件容許咱們在JavaScript中異步調用Action, 並且Action 再也不須要使用視圖資源來顯示該 Action 裏的狀態信息,而是由 JSON 插件負責 將 Action 裏的狀態信息返回給調用頁面——經過這種方式,就可以完成 Ajax 交互。 Struts2提供了一種可插拔方式來管理插件, 安裝 Struts2 的 JSON 插件和安 裝普通插件並無太大的區別,相同只須要將 Struts2插件的 JAR 文檔複製到 Web 應用的 WEB-INF/lib路徑下便可。 安裝 JSON 插件按以下步驟進行: (1) 登錄http://code.google.com/p/jsonplugin/downloads/list站點, 下載Struts2 的 JSON 插件的最新版本,當前最新版本是 0.7,咱們可以下載該版本的 JSON 插件。 (2)將下載到的 jsonplugin-0.7.jar 文檔複製到 Web 應用的 WEB-INF 路徑 下,便可完成 JSON 插件的安裝。 實現 Actio 邏輯 假設 wo,en 輸入頁面中包含了三個表單域,這三個表單域對於三個請求參 數,所以應該使用 Action 來封裝這三個請求參數。三個表單域的 name 分別爲 field一、field2 和 field3。 處理該請求的 Action 類代碼以下: public class JSONExample { //封裝請求參數的三個屬性 private String field1; private transient String field2; private String field3; //封裝處理結果的屬性 private int[] ints = {10, 20}; private Map map = new HashMap(); private String customName = "custom"; //三個請求參數對應的 setter 和 getter 方法 public String getField1() { return field1; } public void setField1(String field1) { this.field1 = field1; } //此處省略了 field1 和 field2 兩個字段的 setter 和 getter 方法 ... //封裝處理結果的屬性的 setter 和 getter 方法 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; } public String execute() { map.put("name", "yeeku"); return Action.SUCCESS; } } 在上面代碼中,使用了 JSON 註釋,註釋時指定了 name 域,name 域指定 Action 屬性被序列化成 JSON 對象的屬性名。 除此以外,JSON 註釋還支持以下 幾個域: serialize:配置是否序列化該屬性 deserialize:配置是否反序列化該屬性。 format:配置用於格式化輸出、解析日期表單域的格式。例如 "yyyy-MM-dd'T'HH:mm:ss"。 配置該 Action 和配置普通 Action 存在小小的區別,應該爲該 Action 配置 類型爲 json 的 Result。而這個 Result 無需配置任何視圖資源。 配置該 Action 的 struts.xml 文檔代碼以下: <?xml version="1.0" encoding="GBK"?> <!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.i18n.encoding" value="UTF-8"/> <package name="example" extends="json-default"> <action name="JSONExample" class="lee.JSONExample"> <result type="json"/> </action> </package> </struts> 在上面配置文檔中有兩個值得注意的地方: 第一個地方是配置 struts.i18n.encoding 常量時,再也不是使用 GBK 編碼,而 是 UTF-8 編碼, 這是由於 Ajax 的 POST請求都是以 UTF-8 的方式進行編碼的。 第二個地方是配置包時,本身的包繼承了 json-default 包,而再也不繼承默認 的 default 包,這是由於只有在該包下才有 json 類型的 Result。
相關文章
相關標籤/搜索