posts - 41,  comments - 8,  trackbacks - 0
          <2014年1月>
          2930311234
          567891011
          12131415161718
          19202122232425
          2627282930311
          2345678

          常用鏈接

          留言簿(2)

          隨筆分類(lèi)

          隨筆檔案

          文章分類(lèi)

          文章檔案

          搜索

          •  

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

           Apache提供的一個(gè)插件包,可以把Action中的數(shù)據(jù)以JSON做個(gè)封裝然后返回。

          它會(huì)將整個(gè)action中的變量轉(zhuǎn)化為JSON數(shù)據(jù)(根對(duì)象在JSON中數(shù)據(jù)添加一個(gè)”root”標(biāo)識(shí))。如果要使用它,Action必須遵循以下幾點(diǎn):

          1.       返回的頁(yè)面類(lèi)型中”content-type”必須是”application/json”.(這個(gè)已經(jīng)Internet Community采用).

          2.       JSON內(nèi)容必須是符合格式要求的.

          3.       Actionfield必須有publicset方法.(是不是沒(méi)有set方法就不會(huì)將field添加到JSON數(shù)據(jù)中,有待驗(yàn)證).

          4.       它支持的類(lèi)型有: 基本類(lèi)型(int,long...String), Date, List, Map, Primitive Arrays, 其它class, 對(duì)象數(shù)組.

          5.       JSON中任何的Object會(huì)被封裝在listmap中,數(shù)據(jù)會(huì)被封裝程Long,如果是含有的數(shù)據(jù)則會(huì)被封裝程Double,數(shù)組會(huì)被封裝程List.

          下面給出JSON的數(shù)據(jù)格式:

          {

             "doubleValue": 10.10,

             "nestedBean": {

                "name": "Mr Bean"

             },

             "list": ["A", 10, 20.20, {

                "firstName": "El Zorro"

             }],

             "array": [10, 20]

          }

          說(shuō)明:

          a.       這個(gè)插件支持以下幾個(gè)注釋:

          注釋名

          簡(jiǎn)介

          默認(rèn)值

          序列化

          反序列化

          name

          配置JSONname

          empty

          yes

          no

          serialize

          serialization

          true

          yes

          no

          deserialize

          deserialization

          true

          no

          yes

          format

          格式化Date字段

          "yyyy-MM-dd'T'HH:mm:ss"

          yes

          yes

          可以通過(guò)配置來(lái)顯示指出要放在JSONfield,其中有個(gè)自己的驗(yàn)證規(guī)則需要研究.

          <!-- 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>

          b.       根對(duì)象

           <result type="json">

           <param name="root">

              person.job

           </param>

          </result>

          也可以使用攔截器配置操作父對(duì)象

          <interceptor-ref name="json">

           <param name="root">bean1.bean2</param>

          </interceptor-ref>

          c.       JSON數(shù)據(jù)用注釋封裝

          如果wrapWithComments設(shè)置為true(默認(rèn)值為false),則生成的JSON數(shù)據(jù)會(huì)變成這樣:

          /* {

             "doubleVal": 10.10,

             "nestedBean": {

                "name": "Mr Bean"

             },

             "list": ["A", 10, 20.20, {

                "firstName": "El Zorro"

             }],

             "array": [10, 20]

          } */

          這樣做可以避免js中一些潛在的風(fēng)險(xiǎn),使用時(shí)需要:

          Var responseObject = eval("("+data.substring(data.indexOf(""/"*")+2, data.lastIndexOf(""*"/"))+")");

          d.       父類(lèi)

          “root”對(duì)象中父類(lèi)的field不會(huì)默認(rèn)存放到JSON數(shù)據(jù)中,如果不想這樣做,需要在配置時(shí)指定ignoreHierarchyfalse:

          <result type="json">

           <param name="ignoreHierarchy">false</param>

          </result>

          e.       枚舉類(lèi)型

          默認(rèn)處理枚舉類(lèi)型時(shí),會(huì)被處理成JSON數(shù)據(jù)中name等于枚舉中valuevalue等于枚舉中name.

          public enum AnEnum {

               ValueA,

               ValueB

           }

           JSON: "myEnum":"ValueA"

          如果在處理枚舉類(lèi)型時(shí),在xml中配置了enumAsBean,則會(huì)被當(dāng)作一個(gè)Bean處理,在JSON數(shù)據(jù)中會(huì)有一個(gè)特別的屬性”_name”值為name().這個(gè)枚舉中的所有屬性都會(huì)被處理.

          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" }

          Xml中配置:

          <result type="json">

           <param name="enumAsBean">true</param>

          </result>

          f.        例子

          a)         Action

          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;

              }

          }

          b)        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>

           <package name="example" extends="json-default">

               <action name="JSONExample" class="example.JSONExample">

                  <result type="json"/>

               </action>

           </package>

          </struts>

          這里有兩個(gè)地方需要注意:

          1)      需要繼承json-default

          2)      <result>簽的定義

          c)         JSON數(shù)據(jù)

           { 

             "field1" : "str",

             "ints": [10, 20],

             "map": {

                 "John":"Galt"

             },

             "newName": "custom"

          }

          d)        JSON RPC

          JSON插件可以在js中調(diào)用action方法,返回執(zhí)行結(jié)果。這個(gè)已經(jīng)在dojo中有了實(shí)現(xiàn),可以用Simple Method Definition調(diào)用遠(yuǎn)程服務(wù)。來(lái)一起看看下面的例子:

          首先寫(xiě)一個(gè)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;

              }

          }

          e)         方法必須用SMDMethod加上注解,這樣才能被遠(yuǎn)程調(diào)用,為了安全因素。這個(gè)方法會(huì)產(chǎn)生一個(gè)bean對(duì)象,實(shí)現(xiàn)修改價(jià)格的功能。Action被添加上SMD注解會(huì)生成一個(gè)SMD,同時(shí)參數(shù)也會(huì)被加上SMDMethodParameter注解。像你所看到的,Action中定義了一個(gè)空方法:smd。這個(gè)方法是作為Simple Method Definition (定義class中提供的服務(wù)),在struts.xml配置<result>時(shí)使用type屬性值為”json”

          下面是bean的定義:

          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;

              }

          }

          Xml文件:

          <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>

          這里需要注意一點(diǎn):” enableSMD”這個(gè)必須在interceptorresult都要配置.

          Js代碼:

          <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.name + " is " + bean.price);

              };

              //parameter

              var bean = {name: "Mocca"};

              //execute remote method

              var defered = service.doSomething(bean, 5);

              //attach callback to defered object

              defered.addCallback(callback);

          </script>

          JsonService會(huì)發(fā)出一個(gè)請(qǐng)求到action加載SMD,同時(shí)遠(yuǎn)程方法會(huì)返回一個(gè)JSON對(duì)象,這個(gè)過(guò)程是Dojoaction中的方法創(chuàng)建了一個(gè)Proxy。因?yàn)檫@是異步調(diào)用過(guò)程,當(dāng)遠(yuǎn)程方法執(zhí)行的時(shí)候,它會(huì)返回一個(gè)對(duì)象到callback方法中。

          f)         代理的對(duì)象

          當(dāng)使用的注解不是繼承自Java,可能你使用代理會(huì)出現(xiàn)一些問(wèn)題。比如:當(dāng)你使用aop攔截你的action的時(shí)候。在這種情況下,這個(gè)插件不會(huì)自動(dòng)發(fā)現(xiàn)注解的方法。為了避免這種情況發(fā)生,你需要在xml中配置ignoreInterfacesfalse,這樣插件會(huì)自己查找注解的所有接口和父類(lèi)。

          注意:這個(gè)參數(shù)只有在Action執(zhí)行的過(guò)程是通過(guò)注解來(lái)運(yùn)行的時(shí)候才應(yīng)該設(shè)為false

          <action name="contact" class="package.ContactAction" method="smd">

             <interceptor-ref name="json">

                <param name="enableSMD">true</param>

                <param name="ignoreInterfaces">false</param>

             </interceptor-ref>

             <result type="json">

                <param name="enableSMD">true</param>

                <param name="ignoreInterfaces">false</param>

             </result>

             <interceptor-ref name="default"/>

          </action>

          posted on 2008-10-04 14:45 Loy Fu 閱讀(7757) 評(píng)論(2)  編輯  收藏 所屬分類(lèi): struts
          主站蜘蛛池模板: 临沧市| 中江县| 巴楚县| 清河县| 游戏| 沂水县| 泽州县| 卢氏县| 铜山县| 保山市| 沁水县| 阿尔山市| 沂南县| 渝中区| 剑河县| 琼海市| 福泉市| 惠东县| 淳安县| 额尔古纳市| 咸宁市| 合肥市| 兴和县| 蒙自县| 独山县| 芜湖市| 桃园市| 蒲江县| 青浦区| 陇西县| 龙岩市| 临夏县| 治县。| 长阳| 上栗县| 陆河县| 澄江县| 达孜县| 昭苏县| 隆尧县| 廊坊市|