基于Struts2的开发,如果没有足够的经验和规范做支撑,并不能带很多的好处.
1).Action类及Action Name的命名规范
Action类的后缀统一加上"Action",
Action的Name与类的名称保存一致,但不要"Action"的后缀。
这样是为了通过Action的调用url,很方便的找到Action类。
<action name="searchUser"
class="com.demo.search.action.SearchUserAction">
<result name="search">/domain/search.jsp</result>
</action>
2). 每个项目都必须至少有一个公共的Action类,GenericAction
公共的Action类完成如下的功能:
1. 获取、注入request
2. 获取、注入Session
3. 错误页面跳转
4. 获取在线用户和会员的信息(个人信息、权限、角色)
5. 注入类型转换的格式转换类,如日期类型转换:ConvertUtil.register(new DateConverter(),Date.class);
6. 获取系统配置信息,如公用变量
7. 对于request参数的处理等
8. 其他可扩展的操作
3). 擅长使用Dispatch的模式
有人说Action,不就是Dispatch的延伸吗,其实还可以做的更好
典型的模式如下:
1. 页面表单的Hidden参数中,就是一个ID,如queryID="queryUser" Action="/paginate.action"
2. PaginateAction的模板如下
private String queryID;
public String execute(){
//获得Service的接口
//根据queryID调用分页查询方法
return queryID; //这一点,就是动态跳转,在Action不明确注明"success"之类的跳转名称。
}
3. 在Struts.xml中进行配置与queryID向对应:
<action name="paginate" class="com.gehc.util.pagination.PaginateAction">
<result name="queryUser">/demo/userList.jsp</result>
<result name="queryIssue">/pm/issue/allIssue.jsp</result>
</action>
实战代码如下:
public String execute(){
if(queryID != null){
Map params = prepareParams();
int pageSize = RequestUtil.getCurrentRowsDisplayed(request);
PageinatedList results = queryDao.queryByPagination(queryID,params,pageSize);
RequestUtil.initLimit(request,results.getPageSize(),results.size());
request.setAttribute("records",results);
forword = StringUtil.isValidStr(forward) ? forward : queryID;
return forward;
}else{
return forwardError("查询ID号不能为空");
}
}
4)配置文件的目录结构
[img] http://dl.iteye.com/upload/picture/pic/63829/fdacff3f-dd6c-3966-a54c-493f8853ff91.bmp[/img]
5) 不断的提炼公用的Action,并放在一个package中:
如上传、下载、异常处理、excel数据录入、过滤、截取器等等
6) 将一个模块中的Action放置在一起
7) 擅于使用redirect来保持request参数。
使用redirect一样可以将request参数传递到一个页面中,不需要使用session。viewPost?postid=${postid}
public String execute() throws Exception{
name = jiangduxi;//给药传递的参数赋值
return SUCCESS; //默认页面
//return "redirect_1"; //重定向(不带参数)showInfo.do
//return "redirect_2"; //重定向(带固定参数xxx)showInfo.do?name=xxx
//重定向(带动态参数,根据struts.xml的配置将${name}赋值为XXX)最后showInfo.do?name=xxxx
//return "redirect_3";
//return "redirect_4";//这个是重定向到一个action
}
<action name="login" class="LoginAction">
<result name="success" type="velocity">/pages/logok.vm</result>
<result name="redirect_1" type="redirect">showInfo.do</result>
<result name="redirect_2" type="redirect">showInfo.do?name=xxxx</result>
<result name="redirect_3" type="redirect">showInfo.do?name=${name}</result>
<result name="redirect_4" type="redirect">
<param name="actionName">showInfo</param>
<param name="name">${name}</param>
</result>
<action>
8) 灵活使用Chain模式,来编写简短而高度重用的Action,把相关的几个action链接起来,共同完成一个功能。
同一个Chain的多个action间数据的传递非常方便,由于处于chain中的action属于同一个http请求,共享一个ActionContext,故可以在上下文中获取,在页面上可以直接使用,上一个Action的成员变量。
<action name="step1" class="test.Step1Action">
<result name="success" type="chain"> step2.action</result>
</action>
<action name="step2" class="test.Step2Action">
<result name="success">finish.jsp</result>
</action>
9) 编写简洁而高度重用的Action的另一个方法,就是将页面的渲染,格式转换的逻辑,抽取出来,自定义成Result。
官方的Result
1. Chain Result --用于Action Chaining
2. Dispatcher Result -- 用于JSP整合
3. FreeMarker Result -- 用于FreeMarker整合
4. HttpHeader Result - 用于控制特殊的HTTP行为
5. JasperReports Result - 用于 JasperReports 整合
6. Redirect Result - 用于直接跳转到例外的URL
7. Redirect Action Result - 用于直接跳转到另外的action
8. Stream Result - 用于向浏览器返回一个InputStream (一般用于文件下载)
9. Velocity Result - 用于 Velocity 整合
10. XSL Result - 用于 XML/XSLT 整合
11. PlainText Result - 用于显示某个页面的原始的文本 (例如 jsp, html 等)
12. Json Result
13. JFreechart Result
10) 明确Action类不要超长,如不要超过500行代码。