Struts2使用通配符完成方法和action的调用
2013-03-31 09:04
423 查看
官网对struts2通配符使用的介绍:
Wildcard Mappings
<action name="*_*" class="com.netshuai.action.{1}Action" method="{2}">
<result name="success">/{2}_{1}Success.jsp</result>
</action>
如上所示,所有文件都采用统一的命名规范,第一个*为分类名称,第二个*为操作名,{1}和{2}分别代表第一个和第二个*的替换值,所有action实现类都命名为分类名称+Action。
如分类名称为User,操作名为add,则访问的action名为User_add.action,action实现类名为UserAction,返回页面的名为add_UserSuccess.jsp
另:{0}代表显示所有通配符内容,如<result name="success">/{2}_{1}Success.jsp</result>改为<resultname="success">/{0}Success.jsp</result>,则返回的名为User_addSuccess.jsp
下面我们来介绍struts2的通配符方面的实现的内部原理
AbstractMatcher类是主要的匹配和计算通配符的类,下面我们来学习他的match方法
下面我们来关注下convert方法:我们关注它的子类,ActionConfigMatcher
在进行convert方法的时候,传递了一个map,下面我们通过一个模拟WildCardMatcher类的方法,给我们看下,这个map
到底是什么:
运行这段模拟的java代码:
结果:
现在终于知道了这个map的作用了,这个map存放的值是为了在取如下配置中的
{1}和{2}中的值,另外,struts2对这个{下标}的这个下标的最大值进行了限定,最大的值为9,请看下面的官网的介绍
In the action mapping and action results, the wildcard-matched values can be accessed with the token {N} where N is a number from 1 to 9 indicating which wildcard-matched value to substitute. The whole request URI can be accessed with the {0} token.{0代表struts2的请求全路径},
下面我们学习下convertParam方法:
-end
Wildcard Mappings
<action name="*_*" class="com.netshuai.action.{1}Action" method="{2}">
<result name="success">/{2}_{1}Success.jsp</result>
</action>
如上所示,所有文件都采用统一的命名规范,第一个*为分类名称,第二个*为操作名,{1}和{2}分别代表第一个和第二个*的替换值,所有action实现类都命名为分类名称+Action。
如分类名称为User,操作名为add,则访问的action名为User_add.action,action实现类名为UserAction,返回页面的名为add_UserSuccess.jsp
另:{0}代表显示所有通配符内容,如<result name="success">/{2}_{1}Success.jsp</result>改为<resultname="success">/{0}Success.jsp</result>,则返回的名为User_addSuccess.jsp
下面我们来介绍struts2的通配符方面的实现的内部原理
AbstractMatcher类是主要的匹配和计算通配符的类,下面我们来学习他的match方法
/** * <p> Matches the path against the compiled wildcard patterns. </p> * * @param potentialMatch The portion of the request URI for selecting a config. * @return The action config if matched, else null */ public E match(String potentialMatch) { E config = null; 所有已经编译好的通配符的list,即已经将表达式的字符串转换为整形数组 if (compiledPatterns.size() > 0) { if (log.isDebugEnabled()) { log.debug("Attempting to match '" + potentialMatch + "' to a wildcard pattern, "+ compiledPatterns.size() + " available"); } 在这里,我们的match方法中传递的map(vars)终于派上了用场,它是用来存储匹配成功的字符, Map<String,String> vars = new LinkedHashMap<String,String>(); for (Mapping<E> m : compiledPatterns) { if (wildcard.match(vars, potentialMatch, m.getPattern())) { if (log.isDebugEnabled()) { log.debug("Value matches pattern '" + m.getOriginalPattern() + "'"); } config = convert(potentialMatch, m.getTarget(), vars); break; } } } return config; }
下面我们来关注下convert方法:我们关注它的子类,ActionConfigMatcher
在进行convert方法的时候,传递了一个map,下面我们通过一个模拟WildCardMatcher类的方法,给我们看下,这个map
到底是什么:
运行这段模拟的java代码:
public static void main(String[] args) throws URISyntaxException { WildcardHelper w = new WildcardHelper(); int[] a = w.compilePattern("*_*"); for (int i = 0; i < a.length; i++) { int j = a[i]; System.out.print(j + ","); } Map<String,String> vars = new LinkedHashMap<String,String>(); //User_add.action,页面请求的action,请求通过struts2的处理后,他会把后缀action给截取掉 //所以,我们模拟的时候,将action给去掉 w.match(vars, "User_add", a); System.out.println(); System.out.println(vars); }
结果:
-4,-1,95,-1,-5, {0=User_add, 1=User, 2=add}
现在终于知道了这个map的作用了,这个map存放的值是为了在取如下配置中的
<action name="*_*" class="com.netshuai.action.{1}Action" method="{2}"> <result name="success">/{2}_{1}Success.jsp</result> </action>
{1}和{2}中的值,另外,struts2对这个{下标}的这个下标的最大值进行了限定,最大的值为9,请看下面的官网的介绍
In the action mapping and action results, the wildcard-matched values can be accessed with the token {N} where N is a number from 1 to 9 indicating which wildcard-matched value to substitute. The whole request URI can be accessed with the {0} token.{0代表struts2的请求全路径},
/** * <p> Clones the ActionConfig and its children, replacing various * properties with the values of the wildcard-matched strings. </p> * * @param path The requested path * @param orig The original ActionConfig * @param vars A Map of wildcard-matched strings * @return A cloned ActionConfig with appropriate properties replaced with * wildcard-matched values */ @Override public ActionConfig convert(String path, ActionConfig orig, Map<String, String> vars) { String className = convertParam(orig.getClassName(), vars);转换类名 String methodName = convertParam(orig.getMethodName(), vars);转换方法名 String pkgName = convertParam(orig.getPackageName(), vars);转换包名 替换参数 Map<String,String> params = replaceParameters(orig.getParams(), vars); 替换result配置 Map<String,ResultConfig> results = new LinkedHashMap<String,ResultConfig>(); for (String name : orig.getResults().keySet()) { ResultConfig result = orig.getResults().get(name); name = convertParam(name, vars); ResultConfig r = new ResultConfig.Builder(name, convertParam(result.getClassName(), vars)) .addParams(replaceParameters(result.getParams(), vars)) .build(); results.put(name, r); } List<ExceptionMappingConfig> exs = new ArrayList<ExceptionMappingConfig>(); for (ExceptionMappingConfig ex : orig.getExceptionMappings()) { String name = convertParam(ex.getName(), vars); String exClassName = convertParam(ex.getExceptionClassName(), vars); String exResult = convertParam(ex.getResult(), vars); Map<String,String> exParams = replaceParameters(ex.getParams(), vars); ExceptionMappingConfig e = new ExceptionMappingConfig.Builder(name, exClassName, exResult).addParams(exParams).build(); exs.add(e); } 重新的构造针当前action的配置:config return new ActionConfig.Builder(pkgName, orig.getName(), className) .methodName(methodName) .addParams(params) .addResultConfigs(results) .addInterceptors(orig.getInterceptors()) .addExceptionMappings(exs) .location(orig.getLocation()) .build(); }
下面我们学习下convertParam方法:
/** * <p> Inserts into a value wildcard-matched strings where specified * with the {x} syntax. If a wildcard-matched value isn't found, the * replacement token is turned into an empty string. * </p> * * @param val The value to convert * @param vars A Map of wildcard-matched strings * @return The new value */ protected String convertParam(String val, Map<String, String> vars) { if (val == null) { return null; } int len = val.length(); StringBuilder ret = new StringBuilder(); char c; String varVal; for (int x=0; x<len; x++) { c = val.charAt(x); if (x < len - 2 && c == '{' && '}' == val.charAt(x+2)) { varVal = (String)vars.get(String.valueOf(val.charAt(x + 1))); if (varVal != null) { ret.append(varVal); } x += 2;在这里,将类似于{1}的值进行了替换,替换为解析好的map中的值,替换后进行+2,向后叠加 } else { ret.append(c); } } return ret.toString(); }
-end
相关文章推荐
- struts2学习笔记--------动态方法调用和使用通配符定义action
- Struts2 Action中动态方法调用、通配符的使用
- 第三章Struts2 Action中动态方法调用、通配符的使用
- struts2-10动态方法调用和使用通配符定义action
- Struts2动态方法调用和使用通配符定义action
- struts2中动态方法调用和使用通配符定义Action
- struts2教程:10、动态方法调用和使用通配符定义action
- struts2中动态方法调用和使用通配符定义Action
- struts2动态方法调用和使用通配符定义action
- Struts2_动态方法调用和使用通配符定义action
- struts2动态方法调用和使用通配符定义action
- Struts2 Action中动态方法调用、通配符的使用
- Struts2一个Action内包含多个请求处理方法的处理,method的使用方法,struts2中的路径问题,通配符映射
- struts2的action方法匹配以及通配符的使用
- Struts2中Action有很多方法 使用通配符
- struts2:使用通配符的方法进行动态方法调用
- 动态方法调用和使用通配符定义action
- Struts2-Action-4-系列问题(路径、调用Action的自定义方法、通配符)
- struct2动态方法调用和使用通配符定义action
- struts2中使用DMI(动态调用方法)方式配置action