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 執(zhí)行execute
??@Override
??
public
?String?execute()?
throws
?Exception?{
????
this
.addActionError(
"
系統(tǒng)錯誤
"
);
????
return
?INPUT;
??}
Sxt_DaoHang_XianShiAction.java 執(zhí)行execute
??@Override
??
public
?String?execute()?
throws
?Exception?{
????ActionContext?ctx?
=
?ActionContext.getContext();
????ctx.put(
"
listDaoHangLieBiao
"
,?
new
?ArrayList());
????
return
?SUCCESS;
??}
這個時候執(zhí)行代碼 freemarker會提示“<pre>Expression listDaoHangLieBiao is undefined</pre>”為什么會這樣了?
仔細查找了相關資料 發(fā)現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的正常執(zhí)行,這個時候應該實現Preparable接口中的prepare()方法,這個方法中的操作不會因為validation錯誤而不執(zhí)行。
聯(lián)想到上面的錯,會不會也是因為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);
??}
}
再執(zhí)行==成功。
總結 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個小時