struts.xml配置文件
<
action
name
="*_*_*"
class
="{0}Action"
>
<
result
name
="input"
type
="freemarker"
>
/WEB-INF/template/strong/{1}/{1}_{2}_XianShi.ftl
</
result
>
<
result
name
="success"
type
="freemarker"
>
/WEB-INF/template/strong/{1}/{0}.ftl
</
result
>
</
action
>
登录操作Action 对应Action名为sxt_DengLu_CaoZuo 对应的input result为/WEB-INF/template/strong/sxt/sxt_DengLu_XianShi.ftl
Sxt_DengLu_CaoZuoAction.java
@Component(
"
sxt_DengLu_CaoZuoAction
"
)
//
使用了Spring 这里的意思是将本Action装配为一个ID为sxt_DengLu_CaoZuoAction的Bean
@Scope(
"
prototype
"
)
//
作用域为prototype 即每次都使用新的对象
public
class
Sxt_DengLu_CaoZuoAction
extends
ActionSupport
implements
ModelDriven
<
MYh
>
{
导航列表Action 对应Action名为sxt_DaoHang_XianShi 对应的success result为/WEB-INF/template/strong/sxt/sxt_DaoHang_XianShi.ftl
Sxt_DaoHang_XianShiAction.java
@Component(
"
sxt_DaoHang_XianShiAction
"
)
//
同上
@Scope(
"
prototype
"
)
//
同上
public
class
Sxt_DaoHang_XianShiAction
extends
ActionSupport
implements
Preparable{
sxt_DengLu_XianShi.ftl // 使用action标签将导航列表导入到本页面
<@s.action name="sxt_DaoHang_XianShi" namespace="/ht" executeResult=true ignoreContextParams=true />
<@s.form action="sxt_DengLu_CaoZuo" id="form_login" theme="simple">
<table align="CENTER" id="table_login">
<tr>
<td class="td_label">登录名</td>
<td class="td_input"><@s.textfield label="${action.getText('TYH_YHDLM')}" id="yhDlm" name="yhDlm" /></td>
</tr>
<tr>
<td class="td_label">密码</td>
<td class="td_input"><@s.password label="${action.getText('TYH_YHMM')}" id="yhMm" name="yhMm" /></td>
</tr>
<tr>
<td class="td_label"> </td>
<td class="td_input"><p id="p_submit">
<@s.submit value="${action.getText('PAGE_DENG_LU')}" />
<input type="button" value="${action.getText('PAGE_TUI_CHU')}">
</p></td>
</tr>
</table>
</@s.form>
sxt_DaoHang_XianShi.ftl
<ul>
<#list listDaoHangLieBiao as nav>
<li>
${nav}
</li>
</#list>
</ul>
Sxt_DengLu_CaoZuoAction.java 执行execute
@Override
public
String execute()
throws
Exception {
this
.addActionError(
"
系统错误
"
);
return
INPUT;
}
Sxt_DaoHang_XianShiAction.java 执行execute
@Override
public
String execute()
throws
Exception {
ActionContext ctx
=
ActionContext.getContext();
ctx.put(
"
listDaoHangLieBiao
"
,
new
ArrayList());
return
SUCCESS;
}
这个时候执行代码 freemarker会提示“<pre>Expression listDaoHangLieBiao is undefined</pre>”为什么会这样了?
仔细查找了相关资料 发现apache的文档 http://struts.apache.org/2.x/docs/how-do-we-repopulate-controls-when-validation-fails.html中写道
When validation fails, we typically forward back to the same server
page, so that the errors can be presented, and so that the client can
fix the problem and resubmit the form. Of course, aside from the
errors, we may also need to present rich controls, like drop down
lists.
If we try to populate rich controls in an Action method, like input or execute,
and validation fails, the method will not be invoked, and the controls
are not populated. Two alternative ways to populate controls are the Preparable interface and the action tag.
大致的意思是但出现validation错误的时候会影响到Action的正常执行,这个时候应该实现Preparable接口中的prepare()方法,这个方法中的操作不会因为validation错误而不执行。
联想到上面的错,会不会也是因为addActionError而导致不能正常使用action标签了。为此在Sxt_DaoHang_XianShiAction中实现Preparable接口并在prepare()方法中put listDaoHangLieBiao。修改代码如下
Sxt_DaoHang_XianShiAction.java
@Component(
"
sxt_DaoHang_XianShiAction
"
)
@Scope(
"
prototype
"
)
public
class
Sxt_DaoHang_XianShiAction
extends
ActionSupport
implements
Preparable{
@Override
public
String execute()
throws
Exception {
return
SUCCESS;
}
public
void
prepare()
throws
Exception {
ActionContext ctx
=
ActionContext.getContext();
ctx.put(
"
listDaoHangLieBiao
"
, Constants.DAO_HANG_LIE_BIAO);
}
}
再执行==成功。
总结 Struts2目前的资料相对Struts1来说是非常少的,尤其是研究的很深的资料,看来现在想学好Struts2还必须从Apache的原始资料中寻找。
另外上面使用action标签的时候是这样写的
<
@s.action name
=
"
sxt_DaoHang_XianShi
"
namespace
=
"
/ht
"
executeResult
=
true
ignoreContextParams
=
true
/>
注意和Struts2的标签写法略有不同,因为这里使用了Freemarker做模板,所以使用的freemarker的写法,特别的是executeResult=true ignoreContextParams=true而按照Struts2的标签应该是executeResult="true" ignoreContextParams="true"
哈哈 小小两个引号 害我折腾N个小时