Struts2学习第四天——全局结果,动态结果及异常映射
1.异常映射的配置
当Action方法出错时Struts会返回异常错误信息页面,这种页面方式是不友好的,可以使用try-catch捕捉异常,然后在catch块中返回对应的错误页面。这种为单个<action>设置异常映射的方式称为局部异常映射。如果要让所有的<action>的各种异常发生时统一跳转到错误页面需要通过 <global-exception-mappings>设置全局异常映射。配置部分:
<global-exception-mappings> <exception-mapping result="error" exception="java.lang.Exception"></exception-mapping>
<exception-mapping result="error2" exception="java.sql.SQLException"></exception-mapping> </global-exception-mappings>
在该配置中,如果该包发生java.lang.Exception异常将寻找<result>name="errror"跳转到对应的页面
2.全局结果的配置
每个Action中都可能遇到错误,此时为使页面友好,都需要跳转到一个公共页面,比较直观的方法是在struts.xml中为每个<action>都配置一个跳转到公共页面的<result>,但是这种做法在<action>多的情况下工作量很大。最好的办法是把<action>中相同的<result>提取出来,设置成全局结果。
代码部分:
<package name="base" abstract="true" extends="struts-default"> <global-results> <result name="login">/page/login.jsp</result> <result name="error">/page/comm/error.jsp</result> <result name="error2">/page/comm/error.jsp</result> </global-results> <global-exception-mappings> <exception-mapping result="error" exception="java.lang.Exception"></exception-mapping> <exception-mapping result="error2" exception="java.sql.SQLException"></exception-mapping> </global-exception-mappings> </package>
上面的<package>base中设置了<global-results>这意味着在base包中所有的<action>中都有一个<result>name="error"。
抽象的包base继承 struts-default下面的包继承本包拥有了struts-default的配置和本包配置,其他包可以继承base包来达到不同页面不同包错误时跳转到相同页面。
1 <package name="default" namespace="/" extends="base"> 2 <action name="*HouserUserAction" class="com.house.action.HouserUserAction" method="{1}"> 3 <result name="register_success">/page/login.jsp</result> 4 <result name="register_err">/page/regs.jsp</result> 5 <!-- 指定Action --> 6 <result name="login_success" type="redirectAction"> 7 <param name="namespace">/house</param> 8 <param name="actionName">listHouserAction</param> 9 </result> 10 <result name="login_err">/page/login.jsp</result> 11 <!-- 动态结果 --> 12 <result name="input">/page/${inputResult}</result> 13 </action> 14 </package> 15 <package name="house" namespace="/house" extends="base"> 16 <action name="*HouserAction" class="com.house.action.HouserAction" method="{1}"> 18 <result>/page/guanli.jsp</result> 19 </action> 20 </package>
3.动态结果
在配置<result>时,如果结果页面在配置时并不能确定,需要在运行时才能确定,例如在登陆和注册时使用数据验证失败时返回各自的初始页面<result>中只有一个name=“input”,这个时候需要使用动态结果来设置。
1 public class HouserUserAction extends ActionSupport{ 2 private User user; 3 private String inputResult; 4 public void validateLogin(){ 5 if(user!=null){ 6 if(user.getUname()==null||user.getUname().equals("")){ 7 super.addFieldError("uname_err","用户名必须填写"); 8 inputResult="login.jsp"; 9 } 10 if(user.getUpwd()==null||user.getUpwd().equals("")){ 11 super.addFieldError("upwd_err","密码必须填写"); 12 } 13 }else{ 14 super.addFieldError("login_err","用户信息不得为空"); 15 } 16 } 17 public void validateReg(){ 18 if(user!=null){ 19 if(user.getUname()==null||user.getUname().equals("")){ 20 super.addFieldError("uname_err","用户名必须填写"); 21 inputResult="regs.jsp"; 22 } 23 if(user.getUpwd()==null||user.getUpwd().equals("")){ 24 super.addFieldError("upwd_err","密码必须填写"); 25 } 26 }else{ 27 super.addFieldError("login_err","用户信息不得为空"); 28 } 29 } 30 31 private UserService uService=new UserServiceImpl(); 32 public User getUser() { 33 return user; 34 } 35 public void setUser(User user) { 36 this.user = user; 37 } 38 39 40 public String getInputResult() { 41 return inputResult; 42 } 43 public void setInputResult(String inputResult) { 44 this.inputResult = inputResult; 45 } 46 /** 47 * 处理login请求 48 * @return 49 */ 50 public String login(){ 51 User users=uService.doLogin(user.getUname(), user.getUpwd()); 52 if(users==null){ 53 return "login_err"; 54 } 55 //request,session,application 56 //获得上下文 57 ActionContext context=ActionContext.getContext(); 58 //保存在session范围 59 Map sessionMap=context.getSession(); 60 sessionMap.put("session_user", users); 61 return "login_success"; 62 } 63 /** 64 * 处理reg请求 65 * @return 66 */ 67 public String reg(){ 68 //制造错误测试exception-mapping 69 //User user=null; 70 int ret=uService.addUser(user); 71 if(ret>0){ 72 return "register_success"; 73 } 74 return "register_err"; 75 } 76 }
在struts.xml配置如下
<!-- 动态结果 --> <result name="input">/page/${inputResult}</result>
配置文件中使用表达式$(),有点类似el标签但是其属于OGNL表达式。
4.数据模块拆分
在大中型项目中,struts.xml文件将会变得非常庞大,难于管理。这时可以把struts.xml按照模块拆分成多个配置文件,并把他们放在rsc下,然后再使用<include>把它们组合在一起。
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" "http://struts.apache.org/dtds/struts-2.3.dtd"> <struts> <package name="base" abstract="true" extends="struts-default"> <global-results> <result name="login">/page/login.jsp</result> <result name="error">/page/comm/error.jsp</result> <result name="error2">/page/comm/error.jsp</result> </global-results> <global-exception-mappings> <exception-mapping result="error" exception="java.lang.Exception"></exception-mapping> <exception-mapping result="error2" exception="java.sql.SQLException"></exception-mapping> </global-exception-mappings> </package> <include file="struts-house.xml"></include> <include file="struts-user.xml"></include> </struts>
1 <?xml version="1.0" encoding="UTF-8" ?> 2 <!DOCTYPE struts PUBLIC 3 "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" 4 "http://struts.apache.org/dtds/struts-2.3.dtd"> 5 6 <struts> 7 <package name="default" namespace="/" extends="base"> 8 <action name="*HouserUserAction" class="com.house.action.HouserUserAction" method="{1}"> 9 <result name="register_success">/page/login.jsp</result> 10 <result name="register_err">/page/regs.jsp</result> 11 <!-- 指定Action --> 12 <result name="login_success" type="redirectAction"> 13 <param name="namespace">/house</param> 14 <param name="actionName">listHouserAction</param> 15 </result> 16 <result name="login_err">/page/login.jsp</result> 17 <!-- 动态结果 --> 18 <result name="input">/page/${inputResult}</result> 19 </action> 20 </package> 21 </struts>
1 <?xml version="1.0" encoding="UTF-8" ?> 2 <!DOCTYPE struts PUBLIC 3 "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" 4 "http://struts.apache.org/dtds/struts-2.3.dtd"> 5 <struts> 6 <package name="house" namespace="/house" extends="base"> 7 <action name="*HouserAction" class="com.house.action.HouserAction" method="{1}"> 8 <!-- name dispatcher请求转发到JSP页面 --> 9 <result>/page/guanli.jsp</result> 10 </action> 11 </package> 12 </struts>