ParametersInterceptorÀ¹½ØÆ÷¼ò½é
¸ÃÀ¹½ØÆ÷´¦ÓÚdefaultStackµÚÊ®ÎåµÄλÖ㬲»µÃ²»ËµµÄÊÇ£¬µÚÊ®ËÄλµÄActionMappingParametersInteceptor¼Ì³Ð×ÔParametersInterceptor£¬Ö»ÊǸ³Öµ²ÎÊýÔ´²»Ò»Ñù£¬¿´ÍêParametersInterceptorºó£¬»ØÍ·ÔÙÔÙÀí½âActionMappingParametersInteceptor¾Í»á¸ü¼òµ¥ÁË¡£
ParametersInterceptorÀ¹½ØÆ÷Óּ̳Ð×ÔMethodFilterInterceptor£¬ÆäÖ÷Òª¹¦ÄÜÊÇ°ÑActionContextÖеÄÇëÇó²ÎÊýÉèÖõ½ValueStackÖУ¬Èç¹ûÕ»¶¥Êǵ±Ç°ActionÔò°ÑÇëÇó²ÎÊýÉèÖõ½ÁËActionÖУ¬Èç¹ûÕ»¶¥ÊÇÒ»¸ömodel(ActionʵÏÖÁËModelDriven½Ó¿Ú)Ôò°Ñ²ÎÊýÉèÖõ½ÁËmodelÖС£
Ç°Ãæ½²½âµÄÒ»¸öPrepareInterceptorÒ²ÊǼ̳Ð×ÔMethodFilterInterceptor£¬µ±Ê±Ã»Óн²½â£¬ÊÇÒòΪPrepareInterceptorÔÚdefaultStackûÓнøÐз½·¨¹ýÂË£¬ParametersInterceptorÀ¹½ØÆ÷ÔÚdefaultStackÖжԷ½·¨Ò²Ã»ÓнøÐйýÂË£¬ËùÒÔÔÝʱҲ²»½²·Åµ½AnnotationValidationInterceptor½²½â£¬ÏȰѸÃÀ¹½ØÆ÷µÄdoIntercept·½·¨¿´³ÉÊÇÒÔÇ°µÄintercept·½·¨¡£
µ«¸ÃÀ¹½ØÆ÷ÅäÖÃÁËÇëÇó²ÎÊý¹ýÂË£¬ÏÂÃæÊÇParametersInterceptorÀ¹½ØÆ÷ÔÚdefaultStackÖÐÅäÖõIJÎÊý¹ýÂ˲ÎÊý£º
±í1
<interceptor-ref name="params"> <param name="excludeParams">dojo\..*,^struts\..*</param> </interceptor-ref> |
ÕâÀï´«µÝÁËÒ»¸öÃûΪexcludeParamsµÄ²ÎÊý£¬ÆäֵΪÓöººÅ(,)·Ö¸ôµÄÕýÔò±í´ïʽ£¬ÓÐÓÃÖ¸¶¨ÄÄЩÀàÐ͵ÄÇëÇó²ÎÊý²»ÐèÒªÉèÖõ½ValueStackÖÐ
ÏÂÃæÊǸÃÀ¹½ØÆ÷µÄdoIntercept·½·¨Ô´Â룺
±í2
@Override public String doIntercept(ActionInvocation invocation) throws Exception { Object action = invocation.getAction();//»ñÈ¡µ±Ç°Ö´ÐеÄAction¶ÔÏó
//ÅжÏActionÊÇ·ñʵÏÖÁËNoParameters½Ó¿Ú£¬ÊµÏָýӿڱíʾ¸ÃActionûÓÐÈκÎÇëÇó²ÎÊý if (!(action instanceof NoParameters)) { ActionContext ac = invocation.getInvocationContext();//»ñÈ¡ActionContext¶ÔÏó final Map<String, Object> parameters = retrieveParameters(ac);//»ñÈ¡ÇëÇó²ÎÊýMap //Ê¡ÂÔ... if (parameters != null) {//Èç¹ûÇëÇó²ÎÊý²»Îªnull
//»ñÈ¡ActionContextÄÚ²¿µÄcontext Map£¬¼´OgnlContext¶ÔÏó Map<String, Object> contextMap = ac.getContextMap(); try { //Ê¡ÂÔ... ValueStack stack = ac.getValueStack();//»ñÈ¡ÖµÕ» setParameters(action, stack, parameters);//ΪֵջÉèÖòÎÊý } finally { //Ê¡ÂÔ... } } } return invocation.invoke();//µ÷ÓÃÏÂÒ»¸öÀ¹½ØÆ÷ } |
ÉÏÃæµÄ·½·¨ÖÐÊ¡ÂÔÁËһЩ·ÇÖØÒª´úÂ룬ʣϵĴúÂëÊDz»ÊǺܼòµ¥ÄØ£¿retrieveParameters·½·¨ÓÃÓÚ»ñÈ¡ÇëÇó²ÎÊýMap£¬ÏÂÃæÊÇÔ´Â룺
±í3
protected Map<String, Object> retrieveParameters(ActionContext ac) { return ac.getParameters(); } |
setParameters·½·¨²ÅÊǸÃÀ¹½ØÆ÷µÄÖ÷ÒªÂß¼£¬ÏÖÔÚ½øÈë¸Ã·½·¨£º
±í4
protectedvoid setParameters(Object action, ValueStack stack, final Map<String, Object> parameters) { ParameterNameAware parameterNameAware = (action instanceof ParameterNameAware) ? (ParameterNameAware) action : null;//ÅжÏActionÓÐÎÞʵÏÖParameterNameAware½Ó¿Ú
Map<String, Object> params; Map<String, Object> acceptableParameters;//ºÏ·¨²ÎÊý¼¯ºÏ //ÅжϲÎÊýÉèÖÃÊÇ·ñÓÐÐò£¬orderedĬÈÏΪfalse£¬¼´ÎÞÐò if (ordered) { params = new TreeMap<String, Object>(getOrderedComparator());//Èç¹ûÓÐÐòÔòÒª»ñÈ¡±È½ÏÆ÷ acceptableParameters = new TreeMap<String, Object>(getOrderedComparator()); params.putAll(parameters); } else { params = new TreeMap<String, Object>(parameters); acceptableParameters = new TreeMap<String, Object>(); } //µü´úÇëÇó²ÎÊý for (Map.Entry<String, Object> entry : params.entrySet()) { String name = entry.getKey(); //ÅжϲÎÊýÊÇ·ñºÏ·¨£¬Èç¹ûActionʵÏÖÁËParameterNameAwareÔòacceptableName(name)·µ»Øtrue //ÇÒparameterNameAware.acceptableParameterName(name) //Ò²·µ»Øtrue¸Ã²ÎÊý²ÅÊǺϷ¨µÄ£»Èç¹ûActionûÓÐʵÏÖParameterNameAwareÔò²ÎÊýÊÇ·ñºÏ·¨ÓÉacceptableName(name)·½·¨¾ö¶¨ boolean acceptableName = acceptableName(name) && (parameterNameAware == null || parameterNameAware.acceptableParameterName(name)); //Èç¹û²ÎÊýºÏ·¨ if (acceptableName) { acceptableParameters.put(name, entry.getValue());//°ÑºÏ·¨²ÎÊýÌí¼Óµ½ºÏ·¨²ÎÊý¼¯ºÏÖÐ } }
ValueStack newStack = valueStackFactory.createva lueStack(stack); //Ê¡ÂÔ... for (Map.Entry<String, Object> entry : acceptableParameters.entrySet()) {//µü´úºÏ·¨²ÎÊý String name = entry.getKey();//²ÎÊýÃû Object value = entry.getValue();//²ÎÊýÖµ try { newStack.setValue(name, value);//½«¸Ã²ÎÊýÉèÖõ½ValueStackÖÐ } catch (RuntimeException e) { //Ê¡ÂÔ... } } //Ê¡ÂÔ... //¿´¸Ã·½·¨µÄÃû³ÆÊǽ«ºÏ·¨²ÎÊýÌí¼Óµ½ActionContextÖУ¬µ«ÔÚ¸ÃÀ¹½ØÆ÷ÖУ¬¸Ã·½·¨Îª¿ÕʵÏÖ£¬ÎÞÈκδúÂë //¸Ã·½·¨±»ÉùÃ÷Ϊprotected£¬¼´×ÓÀà¿ÉÒÔ¸²¸Ç¸Ã·½·¨ÒԸıäÐÐΪ addParametersToContext(ActionContext.getContext(), acceptableParameters); } |
¸ù¾ÝÉÏÃæµÄ×¢ÊÍ´ó¼ÒÓ¦¸Ã¿ÉÒÔ·¢ÏÖ¸ÃsetParameters·½·¨Âß¼»¹ÊǺÜÃ÷È·µÄ£¬¾ÍÊÇÏÈÅжÏÌá½»¹ýÀ´µÄ²ÎÊýÊÇ·ñºÏ·¨£¬ÒòΪÌá½»¹ýÀ´µÄ²ÎÊý»áÓ°Ïìµ½ÖµÕ»ËùÒÔstruts2Òª¶ÔÌá½»¹ýÀ´µÄ²ÎÊý½øÐкϷ¨ÐÔ¼ì²é£¬ÒÔ·ÀÖ¹¶ñÒâÓû§µÄ¹¥»÷£¬·²ÊÇÇëÇó²ÎÊýÖбí´ïʽÖк¬ÓеȺÅ(=)£¬¶ººÅ(,)£¬#ºÅ(#)µÄ¶¼ÊÇ·Ç·¨±í´ïʽ£¬ÏÖÔÚ¾ÍÈ¥¿´Ò»Ï¾ßÌåÊÇÈçºÎÅжÏÒ»¸ö²ÎÊýÊÇ·ñºÏ·¨µÄ¡£
ÉÏÃæ×¢ÊÍÒ²½²µ½ÁË£¬Èç¹ûActionʵÏÖÁËParameterNameAware£¬¼´ÒªÅжÏParameterNameAware½Ó¿ÚÖÐÉùÃ÷µÄacceptableParameterName(name)·½·¨(Âß¼ÓÉ×Ô¼ºÊµÏÖ)Ò²ÒªÅжϸÃÀ¹½ØÆ÷µÄacceptableName(name)·½·¨£¬ÎÒÃÇÕâÀï¼ÙÉèActionûÓÐʵÏÖParameterNameAware½Ó¿Ú£¬²ÎÊýÊÇ·ñºÏ·¨ÓÉacceptableName(name)·½·¨¾ö¶¨£¬ÏÂÃæÊǸ÷½·¨Ô´Â룺
±í5
protected boolean acceptableName(String name) { //µ÷ÓÃisAcceptedÓëisExcluded·½·¨ÅÐ¶Ï if (isAccepted(name) && !isExcluded(name)) { return true; } return false; } |
isAcceptedÓëisExcluded·½·¨Ô´Â룺
±í6
protectedboolean isAccepted(String paramName) { if (!this.acceptParams.isEmpty()) { for (Pattern pattern : acceptParams) { Matcher matcher = pattern.matcher(paramName); if (matcher.matches()) { returntrue; } } returnfalse; } else return acceptedPattern.matcher(paramName).matches(); }
protectedboolean isExcluded(String paramName) { if (!this.excludeParams.isEmpty()) { for (Pattern pattern : excludeParams) { Matcher matcher = pattern.matcher(paramName); if (matcher.matches()) { returntrue; } } } returnfalse; } |
ÉÏÃæ˵µ½Á˸ÃÀ¹½ØÆ÷ÅäÖÃÁ˲ÎÊý¹ýÂË£¬ÅäÖÃÁËÒ»¸öÃûΪexcludeParamsµÄ²ÎÊý£¬ÓÃÓÚÖ¸¶¨ÄÄЩ²ÎÊýÒªÅųý£¬¼´²»ºÏ·¨£¬ÎÒÃÇ´«µÝµÄʱºòÊÇ×Ö·û´®ÔÚÉèÖøÃ×Ö·û´®µÄʱºò¸ÃÀ¹½ØÆ÷»á¶Ô¸Ã×Ö·û´®½øÐнâÎöת»¯³ÉÏàÓ¦µÄPattern¶ÔÏóÒÔÓÃÓÚÕýÔò±í´ïʽУÑ飬¶øisAcceptedÓëisExcluded·½·¨ÖоÍÊÇÔÚÓÃÕâЩÕýÔò±í´ïʽ½øÐмìÑ飬Âß¼ºÜ¼òµ¥£¬¾Í˵Õâô¶à¡£
¸ÃÀ¹½ØÆ÷»¹ÓÐÒ»¸öorderedÊôÐÔ£¬ÆäֵĬÈÏΪfalse£¬¼´½«²ÎÊýÉèÖõ½ValueStackÖÐÊÇÎÞÐòµÄ£¬Èç¹ûorderedΪtrue£¬Ôò½«ÇëÇó²ÎÊýÉèÖõ½ValueStackÊÇÓÐÏȺó˳ÐòµÄ£¬ËùÒÔÔÚ´´½¨TreeMapµÄʱºò£¬Í¨¹ýgetOrderedComparator()·½·¨´«µÝ½øÁ˱ȽÏÆ÷¶ÔÏó£¬ÏÂÃæÊÇgetOrderedComparator()·½·¨Ô´Â룺
±í7
protected Comparator<String> getOrderedComparator() { return rbCollator; } static final Comparator<String> rbCollator = new Comparator<String>() { public int compare(String s1, String s2) { int l1 = 0, l2 = 0; for (int i = s1.length() - 1; i >= 0; i--) { if (s1.charAt(i) == '.') l1++;//ͨ¹ýÑ»·µÃµ½ÇëÇó²ÎÊýkeyÖÐ'.'·ûºÅµÄ¸öÊý } for (int i = s2.length() - 1; i >= 0; i--) { if (s2.charAt(i) == '.') l2++;//ͨ¹ýÑ»·µÃµ½ÇëÇó²ÎÊýkeyÖÐ'.'·ûºÅµÄ¸öÊý } return l1 < l2 ? -1 : (l2 < l1 ? 1 : s1.compareTo(s2)); }
} |
rbCollator¶ÔÏó¾ÍÊÇÒ»¸ö±È½ÏÆ÷£¬ÊÇÓÃÄäÃûÄÚ²¿ÀàʵÏֵģ¬ÎÒÃÇÔÚÌá½»ÇëÇó²ÎÊýµÄʱºò¾³£»áд³Éxxx.yyy.zzz=value£¬¶øÕâ¸ö±È½ÏÆ÷¾ÍÊǸù¾ÝÇëÇó²ÎÊýkeyÖк¬'.'·ûºÅµÄ¸öÊýÀ´½øÐбȽϵģ¬'.'·ûºÅÔ½ÉÙÅÅÔÚԽǰ£¬¼´'.'·ûºÅÔ½ÉٵĻáÔ½ÏÈÉèÖõ½ValueStackÖС£¹ØÓÚÕâ¸öÔÚ¸ÃÀ¹½ØÆ÷µÄÎĵµÖл¹¾ÙÁËÀý×Ó£¬´ó¼Ò¿ÉÒÔÈ¥¿´Ò»Ï¡£
×îÖÕ½øÐвÎÊý¸³ÖµÊǵ÷ÓõÄValueStackµÄsetValue·½·¨£¬¸Ã·½·¨ÄÚ²¿Ê¹ÓÃÊÇOGNL±í´ïʽÒýÇæ½øÐи³ÖµµÄ£¬ËäÈ»ÄÚ²¿·Ç³£¸´ÔÓ£¬µ«ÎÒÃÇÖ»ÐèÒªÖªµÀOGNL±í´ïʽÒýÇæÔÚ°ÑÇëÇó²ÎÊýÉèÖõ½ValueStackÖÐʱ£¬ÊÇ´ÓÕ»¶¥ÍùÕ»µ×Ñ°ÕÒÓÐÏàÓ¦setter·½·¨µÄ¶ÔÏó£¬Èç¹ûÕýÔÚ¸³ÖµµÄ²ÎÊýÔÚValueStackÕÒµ½ÁËÒ»¸ö¶ÔÏóÓÐsetter·½·¨Ôò°Ñ¸Ã²ÎÊýµÄÖµ¸³¸ø¸Ã¶ÔÏó£¬Èç¹ûûÓÐÕÒµ½Ôò¼Ì³ÐÍùÕ»µ×Ñ°ÕÒ£¬Ö±µ½ÕÒµ½ÎªÖ¹£¬Èç¹ûÕÒµ½Õ»µ×»¹ÊÇûÓÐÕÒµ½Ò²¾ÍûÓи³Öµ³É¹¦¡£
µ½´Ë¸ÃÀ¹½ØÆ÷¾Í½²½âÍê±ÏÁË£¬×îºóµ÷ÓÃinvocation.invoke();µ÷ÓÃÏÂÒ»¸öÀ¹½ØÆ÷......