动态方法调用和通配符
一、动态方法调用
- Action执行的时候并不一定要执行execute方法,也可以在配置文件中配置Action的时候用method=”name”来指定执行哪个方法;
Login.jsp
<form action="log.action"> <font color="red">${loginError }</font> <table align="center"> <tr><td>用户名:<input type="text" name="uname"></td></tr> <tr><td>密 码:<input type="password" name="upass"></td></tr> <tr><td><input type="submit" value="登录"></td></tr> </table> </form> |
Struts.xml
<action name="log" class="com.inspur.action.LoginAction" method="login"> <result name="success">/success.jsp</result> <result name="error">/error.jsp</result> </action> |
LoginAction.java
public String login(){ if("ross".equals(this.uname) && "111".equals(this.upass)){ return SUCCESS; }else{ return ERROR; } } |
- 也可以在URL地址中动态指定(动态方法调用DMI)(推荐)
动态调用案例
Login.jsp
<form action="log!login"> <font color="red">${loginError }</font> <table align="center"> <tr><td>用户名:<input type="text" name="uname"></td></tr> <tr><td>密 码:<input type="password" name="upass"></td></tr> <tr><td><input type="submit" value="登录"></td></tr> </table> </form> |
Struts.xml
<action name="log" class="com.inspur.action.LoginAction"> <result name="success">/success.jsp</result> <result name="error">/error.jsp</result> </action> |
LoginAction.java
public String login() { // 模拟用户登录处理(登录正确) if ("ross".equals(uname) && "111".equals(upass)) { session.put("uname", uname); // 返回逻辑视图名 return SUCCESS; // 登录失败 } else { request.put("loginError", "登录名称或者密码错误"); // 返回逻辑视图名 return ERROR; } } |
- 如果action中存在多个方法时,可以使用“!方法名”的方式调用指定方法
- 默认情况下,Struts的动态方法调用处于激活状态,若想禁用该功能,可以在struts.xml文件中添加如下常量元素:
<constant name="struts.enable.DynamicMethodInvocation" value="false"/>
二、通配符
- 一个Web应用可能有成千上万个action声明,可以利用Struts提供的通配符映射机制把多个彼此相似的映射关系简化为一个映射关系
反面案例
Login.jsp
<form action="login_add.action"> <font color="red">${loginError }</font> <table align="center"> <tr><td>用户名:<input type="text" name="uname"></td></tr> <tr><td>密 码:<input type="password" name="upass"></td></tr> <tr><td><input type="submit" value="登录"></td></tr> </table> </form> </body> |
Struts.xml
<package name="struts2" extends="struts-default"> <action name="login_add" class="com.inspur.action.LoginAction" method="add"> <result name="success">/login_add_success.jsp</result> </action> <action name="login_upd" class="com.inspur.action.LoginAction" method="upd"> <result name="success">/login_upd_success.jsp</result> </action> </package> |
loginAction.xml
public String add(){ //第一种方式:actioncontext类 ActionContext context = ActionContext.getContext(); Map<String, String> requestMap = (Map<String, String>) context.get("request");
requestMap.put("msg", "add success!"); return SUCCESS; } public String upd(){ //第一种方式:actioncontext类 ActionContext context = ActionContext.getContext(); Map<String, String> requestMap = (Map<String, String>) context.get("request");
requestMap.put("msg", "upd success!"); return SUCCESS; } |
Struts.xml中add和upd可以用*代替,这样每个action都只配置一次就好了,但是在系统里面很多模块的时候action依然会比较多,不利于配置。同理将action名称也用通配符进行配置。
最终Struts.xml配置样式:
<action name="*_*" class="com.inspur.action.{1}Action" method="{2}"> <result name="success">/{1}_{2}_success.jsp</result> </action> |
- 通配符的映射规则
- 若找到多个匹配,没有通配符的那个胜出
- 若指定的动作不存在,Struts会尝试把这个uri与任何一个包含着通配符*的动作名进行匹配
- 若Struts找到的带有通配符的匹配不止一个,最后一个匹配将胜出
- 被通配符匹配到的uri字符串的子串可以用{1},{2}来引用。{1}匹配第一个子串,{2 }匹配第二个子串……
- {0}匹配整个uri
- *可以匹配零个或多个字符,但不包括/字符,如果想把/字符包括在内,需要使用**,如果需要对某个字符进行转义,需要使用\。