用戶登錄 → 點擊註銷 → Session 清空 → **在地址欄直接輸入 Action URL 卻能直接進入歡迎頁**,繞過了表單提交驗證。
<action name="checkUser" class="checkUserAction" method="execute">
<result name="login">/login.jsp</result>
<result name="success">/home.jsp</result>
</action>
<action name="quitUser" class="checkUserAction" method="quitUser">
<result name="success">/login.jsp</result>
</action>
<bean id="administrator" class="pojo.Administrator" /> <!-- 缺省 singleton -->
<bean id="checkUserAction" class="action.checkUserAction" scope="prototype">
<property name="adminer" ref="administrator"/>
<property name="adminUserService" ref="adminUserServiceImpl"/>
</bean>
public class checkUserAction extends ActionSupport implements ModelDriven<Administrator> {
private Administrator adminer; // 模型驅動屬性
private AdminUserService adminUserService;
public String execute() {
String result = adminUserService.findAdministrator(adminer);
if (!"success".equals(result)) { /* 錯誤提示 */ return "login"; }
ActionContext.getContext().getSession().put("adminUser", adminer);
return result;
}
public String quitUser() {
ActionContext.getContext().getSession().clear();
return "success";
}
// getter/setter 省略
}
checkUserAction 為 prototype,每次請求創建新實例 ✓adminer(Administrator)引用的是 **單例 Bean** administrator ✗/checkUser,Struts 再次創建新 Action,注入同一個「髒數據」adminer,驗證直接通過<s:debug/> 查看值棧:每次請求後 Session 中 adminUser 不變將 Administrator 亦改為 prototype 作用域,確保每次請求獲得全新實例:
<bean id="administrator" class="pojo.Administrator" scope="prototype" />
ModelDriven 接口無生命周期回調,需手動置空或改用參數注入