數(shù)據(jù)加載中……
          [Translation]JSON與struts2
           

          下載地址: http://code.google.com/p/jsonplugin/downloads/list

                        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è)面類型中”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.       它支持的類型有: 基本類型(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.       父類

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

          <result type="json">

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

          </result>

          e.       枚舉類型

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

          public enum AnEnum {

               ValueA,

               ValueB

            }

            JSON:  "myEnum":"ValueA"

          如果在處理枚舉類型時(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ì)自己查找注解的所有接口和父類。

          注意:這個(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>

          g)        使用方法

          把插件的jarcopy” /WEB-INF/lib”就可以了。

          h)        版本歷史

          Version

          Date

          Author

          Notes

          0.19

          Nov 02, 200t

          musachy

          Return a JSON error instead of execeptions. Some bug fixes and refactoring. Thanks Joe Germuka and the other anonymous guys

          0.18

          Aug 10, 2007

          musachy

          Add SMDMethodsHack, fix 16 ,18 ,21 thanks for the patches guys!

          0.17

          Aug 10, 2007

          Oleg Mikheev

          Ignore properties matching 'excludedProperties' when generating SMD

          0.16

          Jul 27, 2007

          musachy

          Resolve issue where method is evaluated even if its result is ignored (#14)

          0.15

          Jul 18, 2007

          musachy

          Add excludedProperties attribute to interceptor

          0.14

          Jun 27, 2007

          musachy

          Add root (OGNL expression) attribute to interceptor

          0.13

          Jun 14, 2007

          musachy

          Add 'ignoreHierarchy' property to JSON result to allow serialization of properties on base classes

          posted on 2008-01-11 16:29 牛浪de流 閱讀(4728) 評(píng)論(4)  編輯  收藏 所屬分類: Framework

          評(píng)論

          # re: [Translation]JSON與struts2[未登錄](méi) 2008-09-16 20:37 jack

          翻譯的吧,不過(guò)有個(gè)問(wèn)題,不用json rpc,jsp怎么調(diào)用json action,和操作返回結(jié)果

          # re: [Translation]JSON與struts2 2008-10-07 15:02 uname

          >Apache提供的一個(gè)插件包
          和Apache沒(méi)啥關(guān)系吧
          >Action中field必須有public的set方法
          是必須有g(shù)et方法吧

          # re: [Translation]JSON與struts2 2008-11-24 17:50 zcsunt

          太感謝了,對(duì)我的幫助很大。

          # re: [Translation]JSON與struts2[未登錄](méi) 2009-01-14 13:32 cc

          @uname
          我也正想說(shuō)這

          只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 绍兴县| 连山| 达日县| 扎鲁特旗| 禄劝| 五河县| 平乐县| 新邵县| 苍梧县| 梧州市| 衡南县| 夏津县| 石城县| 新巴尔虎右旗| 桑植县| 灵宝市| 桦南县| 深州市| 板桥市| 田阳县| 黑河市| 瓮安县| 天台县| 青海省| 高州市| 靖州| 贵溪市| 大竹县| 绥中县| 五指山市| 吉林省| 浏阳市| 桂平市| 安宁市| 五峰| 台湾省| 陕西省| 京山县| 吴川市| 西华县| 伊春市|