




版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、chain:基本用途是構(gòu)造成一條動(dòng)作鏈。前一個(gè)Action將控制權(quán)轉(zhuǎn)交給后一個(gè)Action,而前一個(gè)Action的狀態(tài)在后一個(gè)Action里仍然保持著。我現(xiàn)在有一個(gè)場(chǎng)景,F(xiàn)irstAction 通過(guò)chain的方式,將控制權(quán)交給 SecondAction。FirstAction對(duì)應(yīng)的頁(yè)面代碼為first.ftl,SecondAction對(duì)應(yīng)的頁(yè)面代碼為second.ftl。假設(shè)我們的FirstAction如下定義:public class SecondAction extends ActionSupport
2、private CustomUser user = null; public String execute() throws Exception / 利用user做事情或顯示在頁(yè)面上 / getter setter意思很明確了,通過(guò)first.
3、ftl的輸入,到DB中或其他,生成了我們的CustomUser對(duì)象,這個(gè)CustomUser對(duì)象將要在SecondAction使用。于是我們想到了要配置FirstAction 的 name為toSecond的 Result type為 chain,將 生成的CustomUser對(duì)象傳遞到 SecondAction中,我們也這樣做了,但是 經(jīng)過(guò)調(diào)試,發(fā)現(xiàn)在SecondAction中沒(méi)有得到 FirstAction中的CustomUser對(duì)象。SecondAction是這樣實(shí)現(xiàn)的:public class SecondAction extends Actio
4、nSupport private CustomUser user = null; public String execute() throws Exception / 利用user做事情或顯示在頁(yè)面上 / g
5、etter setter看一下ChainingInterceptor.java的實(shí)現(xiàn),發(fā)現(xiàn)有這樣的注釋?zhuān)篈n interceptor that copies all the properties of every object in the value stack to the currently executing object.在 FirstAction 中CustomUser user 并沒(méi)有在 va
6、lue stack 中,所以沒(méi)有拷貝到SecondAction中。知道了問(wèn)題所在,就要解決。首先是想換一種方式去做,將我們要傳遞的參數(shù)通過(guò) 其他 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>但這樣做的缺點(diǎn)是,1.我們要在瀏覽器上看到很長(zhǎng)很亂的URL(如果超過(guò)URL長(zhǎng)度限制那就更悲劇了)。2.暴露這些參數(shù)總感覺(jué)很不爽。3.自定義的對(duì)象不能用這種方式傳遞,要么傳String、或JsonObject等。另外一個(gè)解決辦法:因?yàn)镽esult type為ch
8、ain時(shí),在執(zhí)行SecondAction時(shí),它的上一個(gè)Action,也就是FirstAction的實(shí)例并沒(méi)有被銷(xiāo)毀,F(xiàn)irstAction的實(shí)例被加入到了ValueStack中。所以,實(shí)現(xiàn)的思路就是,增加一個(gè)攔截器,在執(zhí)行Actioin前判斷一下,當(dāng)前Action是否需要從前面的Action實(shí)例中獲取數(shù)據(jù)。這個(gè)可以通過(guò)注解的方式告訴攔截器,當(dāng)前的action需要什么樣的對(duì)象。思路明確了,來(lái)看看代碼:注解類(lèi):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 ""攔截器實(shí)現(xiàn):ChainParameterInterceptor.java/* */* * Result type 為chain時(shí) 可通過(guò)注解的方式實(shí)現(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)為當(dāng)前Action、緊接著(index = 1) 為前置Action if (root = null | root.size() <= 2)
14、60; return invocation.invoke(); / 當(dāng)前Action對(duì)象 Object target = invocation.getAction();
15、160; Field fields = target.getClass().getDeclaredFields(); / 遍歷此Action對(duì)象的屬性 是否有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); / 取得對(duì)應(yīng)字段的值
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(); / 取得對(duì)應(yīng)字段的值 則返回 / 問(wèn)題:如果前置Action中該字段本身就為null 則無(wú)法處理
26、60; if (tmp != null) break;
27、160; return value; 在攔截器的實(shí)現(xiàn)中,我是只取得前一個(gè)Action中的數(shù)據(jù),并沒(méi)有迭代尋找整個(gè)ValueStack的Action,也是可以這樣實(shí)現(xiàn)的,請(qǐng)看我的findFieldValue方法的實(shí)現(xiàn),但這個(gè)方法在此攔截器中并沒(méi)有使用上。因?yàn)槲也幌脒@樣做。代碼完畢之后,配置好攔截器,我們只要在 SecondAction中 這樣定義即可:public class SecondAction extends ActionSupport
28、 ChainTransParam private CustomUser user = null; public String execute() throws Exception / 利用user做事情或顯示在頁(yè)面上 &
29、#160; / getter setter當(dāng)在執(zhí)行SecondAction之前,攔截器會(huì)去查找FirstAction,是否有 user 對(duì)象,有則將值拷貝到 SecondAction 中。ChainTransParam 注解 允許輸入?yún)?shù)名,沒(méi)有輸入則默認(rèn)根據(jù)變量名去查找。注:Struts2 Reference里的意思是不提倡使用Result Type Chain。另:ReflectionUtils.java 實(shí)現(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. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 農(nóng)田收購(gòu)大米合同范本
- 借款合同范本表格模板
- 化工拆除工廠合同范本
- 2024年天津市腫瘤醫(yī)院空港醫(yī)院藥學(xué)部藥品調(diào)配崗招聘考試真題
- 2024年四川泰康醫(yī)院招聘考試真題
- 上下游合同范本
- 動(dòng)漫行業(yè)合同范本
- 2024年河南能源集團(tuán)招聘考試真題
- 入戶經(jīng)營(yíng)合同范本
- 公路輔助承攬合同范本
- 湘少版六年級(jí)英語(yǔ)下冊(cè)《全冊(cè)課件》
- 2024-2030年中國(guó)護(hù)眼臺(tái)燈行業(yè)市場(chǎng)發(fā)展趨勢(shì)與前景展望戰(zhàn)略分析報(bào)告
- 《土壤肥料學(xué)通論》課程教學(xué)大綱
- 第十四屆全國(guó)交通運(yùn)輸行業(yè)職業(yè)技能競(jìng)賽(公路收費(fèi)及監(jiān)控員)賽項(xiàng)題庫(kù)-下(多選題-共3部分-2)
- 集合功能的測(cè)定(雙眼視檢查)
- 2024年農(nóng)村自建房裝修合同
- 2024年《高等教育心理學(xué)》考前輔導(dǎo)必背習(xí)題庫(kù)(300題)
- 2024年江蘇農(nóng)牧科技職業(yè)學(xué)院?jiǎn)握新殬I(yè)適應(yīng)性測(cè)試題庫(kù)完美版
- 2024年廣西職業(yè)院校技能大賽中職組《智慧物流作業(yè)》模塊MC競(jìng)賽樣題
- 人事專(zhuān)員簡(jiǎn)歷模板
- 超聲心動(dòng)圖診斷心肌病臨床應(yīng)用指南解讀
評(píng)論
0/150
提交評(píng)論