基于Struts2 Result Type為chain 的Action之間數(shù)據(jù)傳遞_第1頁
基于Struts2 Result Type為chain 的Action之間數(shù)據(jù)傳遞_第2頁
基于Struts2 Result Type為chain 的Action之間數(shù)據(jù)傳遞_第3頁
基于Struts2 Result Type為chain 的Action之間數(shù)據(jù)傳遞_第4頁
基于Struts2 Result Type為chain 的Action之間數(shù)據(jù)傳遞_第5頁
已閱讀5頁,還剩3頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

1、chain:基本用途是構(gòu)造成一條動作鏈。前一個Action將控制權(quán)轉(zhuǎn)交給后一個Action,而前一個Action的狀態(tài)在后一個Action里仍然保持著。我現(xiàn)在有一個場景,F(xiàn)irstAction 通過chain的方式,將控制權(quán)交給 SecondAction。FirstAction對應的頁面代碼為first.ftl,SecondAction對應的頁面代碼為second.ftl。假設(shè)我們的FirstAction如下定義:public class SecondAction extends ActionSupport    

2、private CustomUser user = null;    public String execute() throws Exception         / 利用user做事情或顯示在頁面上        / getter setter意思很明確了,通過first.

3、ftl的輸入,到DB中或其他,生成了我們的CustomUser對象,這個CustomUser對象將要在SecondAction使用。于是我們想到了要配置FirstAction 的 name為toSecond的 Result type為 chain,將 生成的CustomUser對象傳遞到 SecondAction中,我們也這樣做了,但是 經(jīng)過調(diào)試,發(fā)現(xiàn)在SecondAction中沒有得到 FirstAction中的CustomUser對象。SecondAction是這樣實現(xiàn)的:public class SecondAction extends Actio

4、nSupport    private CustomUser user = null;    public String execute() throws Exception         / 利用user做事情或顯示在頁面上        / g

5、etter setter看一下ChainingInterceptor.java的實現(xiàn),發(fā)現(xiàn)有這樣的注釋:An interceptor that copies all the properties of every object in the value stack to the currently executing object.在 FirstAction 中CustomUser user 并沒有在 va

6、lue stack 中,所以沒有拷貝到SecondAction中。知道了問題所在,就要解決。首先是想換一種方式去做,將我們要傳遞的參數(shù)通過 其他 Result type 如redirectAction去傳遞。例如:<result type="redirectAction" name="toSecond">    <param name="actionName">SecondAction</param>  

7、60; <param name="method">execute</param>    <param name="user">$user</param></result>但這樣做的缺點是,1.我們要在瀏覽器上看到很長很亂的URL(如果超過URL長度限制那就更悲劇了)。2.暴露這些參數(shù)總感覺很不爽。3.自定義的對象不能用這種方式傳遞,要么傳String、或JsonObject等。另外一個解決辦法:因為Result type為ch

8、ain時,在執(zhí)行SecondAction時,它的上一個Action,也就是FirstAction的實例并沒有被銷毀,F(xiàn)irstAction的實例被加入到了ValueStack中。所以,實現(xiàn)的思路就是,增加一個攔截器,在執(zhí)行Actioin前判斷一下,當前Action是否需要從前面的Action實例中獲取數(shù)據(jù)。這個可以通過注解的方式告訴攔截器,當前的action需要什么樣的對象。思路明確了,來看看代碼:注解類:ChainTransParam.javaimport java.lang.annotation.Documented;import java.lang.annotatio

9、n.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;Target(ElementType.FIELD)Retention(RetentionPolicy.RUNTIME)Documentedpublic interface ChainTransParam     String f

10、ieldName() default ""攔截器實現(xiàn):ChainParameterInterceptor.java/* */* * Result type 為chain時 可通過注解的方式實現(xiàn)參數(shù)傳遞 此參數(shù)為前置Action的成員變量、并提供getter方法 * 此參數(shù)并不要求一定要在值棧中 *  * author liming */public class ChainParamete

11、rInterceptor extends AbstractInterceptor     private static final long serialVersionUID = -8279316685527646358L;    Override    public String intercept(ActionInvocation invocation)

12、 throws Exception         ValueStack stack = invocation.getStack();        CompoundRoot root = stack.getRoot();        / 值棧不為null&

13、#160;且已經(jīng)有前置Action        / 棧最頂層(index = 0)為當前Action、緊接著(index = 1) 為前置Action        if (root = null | root.size() <= 2)     

14、60;       return invocation.invoke();                / 當前Action對象        Object target = invocation.getAction(); &#

15、160;      Field fields = target.getClass().getDeclaredFields();        / 遍歷此Action對象的屬性 是否有RecieveData注解        for (Field field : fields) &

16、#160;           if (field.isAnnotationPresent(ChainTransParam.class)                 ChainTransParam rData = field.getAnnotation(ChainTransP

17、aram.class);                / 取得源數(shù)據(jù)字段名                String fromName = rData.fieldName();     

18、           fromName = StringUtils.isEmpty(fromName) ? field.getName() : fromName;                / 取得最近的前置Action   

19、             Object srcAction = root.get(1);                / 取得對應字段的值           

20、;     Object value = ReflectionUtils.getFieldValue(srcAction, srcAction.getClass(), field.getName();                / 設(shè)定值       &#

21、160;        ReflectionUtils.setFieldValue(target, field.getName(), field.getType(), value);                         

22、0;  return invocation.invoke();        SuppressWarnings("unused")    private Object findFieldValue(CompoundRoot root, Field field)         Object

23、 value = null;        int size = root.size();        / 按順序遍歷前置Action        for (int index = 1; index < siz

24、e; index+)             Object srcAction = root.get(index);            Object tmp = ReflectionUtils.getFieldValue(srcAction, srcAction.g

25、etClass(), field.getName();            / 取得對應字段的值 則返回            / 問題:如果前置Action中該字段本身就為null 則無法處理         

26、60;  if (tmp != null)                 break;                        &#

27、160;   return value;    在攔截器的實現(xiàn)中,我是只取得前一個Action中的數(shù)據(jù),并沒有迭代尋找整個ValueStack的Action,也是可以這樣實現(xiàn)的,請看我的findFieldValue方法的實現(xiàn),但這個方法在此攔截器中并沒有使用上。因為我不想這樣做。代碼完畢之后,配置好攔截器,我們只要在 SecondAction中 這樣定義即可:public class SecondAction extends ActionSupport  

28、  ChainTransParam    private CustomUser user = null;    public String execute() throws Exception         / 利用user做事情或顯示在頁面上      &

29、#160; / getter setter當在執(zhí)行SecondAction之前,攔截器會去查找FirstAction,是否有 user 對象,有則將值拷貝到 SecondAction 中。ChainTransParam 注解 允許輸入?yún)?shù)名,沒有輸入則默認根據(jù)變量名去查找。注:Struts2 Reference里的意思是不提倡使用Result Type Chain。另:ReflectionUtils.java 實現(xiàn):import java.lang.reflect.Field;import java.lang.reflect.Invocatio

30、nTargetException;import java.lang.reflect.Method;import mons.lang.StringUtils;import mons.logging.Log;import mons.logging.LogFactory;public abstract class ReflectionUtils     private static final Log logger = L

31、ogFactory.getLog(ReflectionUtils.class);    public static void setFieldValue(Object target, String fname, Class<?> ftype, Object fvalue)         setFieldValue(target, target.

32、getClass(), fname, ftype, fvalue);        public static void setFieldValue(Object target, Class<?> clazz, String fname, Class<?> ftype, Object fvalue)    

33、;     if (target = null | fname = null | "".equals(fname)                | (fvalue != null && !ftype.isAssi

34、gnableFrom(fvalue.getClass()             return;                try             Method

35、0;method = clazz.getDeclaredMethod(                    "set" + Character.toUpperCase(fname.charAt(0) + fname.substring(1), ftype);    &

36、#160;       /if (!Modifier.isPublic(method.getModifiers()             method.setAccessible(true);            /    &

37、#160;       method.invoke(target, fvalue);                catch (Exception me)             if (logge

38、r.isDebugEnabled()                 logger.debug(me);                        try  

39、0;              Field field = clazz.getDeclaredField(fname);                /if (!Modifier.isPublic(field.getModifiers() 

40、0;               field.setAccessible(true);                /              &

41、#160; field.set(target, fvalue);                        catch (Exception fe)              

42、   if (logger.isDebugEnabled()                     logger.debug(fe);                  

43、;                          public static Object getFieldValue(Object target, String fname)        &#

44、160;return getFieldValue(target, target.getClass(), fname);        public static Object getFieldValue(Object target, Class<?> clazz, String fname)         

45、;if (target = null | fname = null | "".equals(fname)             return null;                bo

46、olean exCatched = false;        try             String methodname = "get" + StringUtils.capitalize(fname);      

47、60;     Method method = clazz.getDeclaredMethod(methodname);            /if (!Modifier.isPublic(method.getModifiers()             

48、method.setAccessible(true);            /            return method.invoke(target);               

49、0;catch (NoSuchMethodException e)             exCatched = true;                catch (InvocationTargetException e)             exCatched = true;                catch (IllegalAccessException e)        &#

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論