用ActionForm截获登录表单数据
原登录模块用bookstoreUser描述loginjsp登录页面表单的数据在switchjsp程序中通过<jsp:useBean>标签获取loginjsp表单的数据其实User类相当于Struts框架中的模型我们将通过一个ActionForm更好地实现这个功能
ActionForm和Bean一样以属性名匹配的映射机制从HTTP请求中填充对象数据但ActionForm比一般的Bean提供了更多的功能Struts允许ActionForm通过validate()方法进行自校验当数据不合法时自动转向到输出界面此外还可以通过reset()方法在数据填充前复位属性值
下面我们就来创建UserActionForm替换User的功能建立起Struts框架中的数据模型
.指定ActionForm的Web模块及类信息
File>New>Web>在Web页中双击ActionForm图标弹出如图 所示的对话框
图 创建UserActionForm
·Struts config我们前面有提到Struts支持多个配置文件所以你在这儿可以选择使用哪个Struts配置文件因为我们现在还没有定义多个Struts配置文件所以只得使用strutsconfigxml在开发新增图书的功能时我们将定义另一个配置文件
·ActionFormActionForm的类名这里我们填入UserActionForm
按Next到下一步
.定义ActionForm属性
图 定义ActionForm属性
通过Add按钮为UserActionForm增加个属性如图 所示特别的如果这个ActionForm所对应的入口页面已经创建你也可以直接通过Add from JSP按钮选择一个JSP页面JBuilder会分析这个页面的表单并将表单的数据组件名抽取为ActionForm的属性
按Next到下一步
.一些附加功能的定义
图 附加功能定义
在FormBeanName中为UserActionForm指定一个名字一般接受JBuilder所提供的默认名即可这个名字将在strutsconfigxml文件用来命名UserActionForm
ActionForm比一般JavaBean强大的地方在于它可以进行数据检验还可以进行数据复位如果这个ActionForm最终要放到session中的那么最好实现reset()方法以复位ActionForm的数据否则属性可能不会反映最新的值这里 UserActionForm无需进行数据有效性校验但由于UserActionForm最终需要放到session中所以我们需要实现reset()方法故此我们勾选Create/replace reset() method body选项
直接按Finish创建UserActionForm再将User类的代码拷贝过来整改后的最终代码如下所示
代码清单 以ActionForm实现的User类
package bookstore;
import javasql*;
import javatext*;
import javautilDate;
import javaxservlethttp*;
import orgapachestrutsaction*;
public class UserActionForm
extends ActionForm
{
private String userId;
private String password;
private String userName;
private String loginDatetime;
public String getPassword() {
return password;
}
…
//复位所有属性值
public void reset(ActionMapping actionMappingHttpServletRequest servletRequest) {
thisuserId = null;
thisuserName = null;
thispassword = null;
thisloginDatetime = null;
}
此外JBuilder自动在strutsconfxml文件中通过<formbean>描述ActionFormUserActionForm必须和一个Action相关联因为HTTP请求通过Struts总控制器转发给ActionStruts控制器一旦发现Action有一个对应的ActionForm时就用HTTP请求的数据填充这个ActionForm
用Action代替switchjsp的控制转换功能
我们在前面已经数落用switchjsp实现请求转换控制的缺点Struts框架的Action是实现请求转换控制的最适合替代者
在这节里我们就来创建一个名为LoginAction的Action让其完美的接替switchjsp的工作
File>New>Web>在Web页中双击Action图标启动创建Action的向导
.指定Action名字及Web模块
图 指定Web模块及Action名字
在Action中键入LoginAction作为Action的类名其中Base class的下拉框中有许多Action基类可供选择它们用于不同的场合这些选项是
·orgapachestrutsactionAction标准的Action
·orgapachestrutsactionsForwardAction相当于JSP的<jsp:forward>方便Struts控制器进行预处理此外从学究的角度上来说在JSP页面直接通过<jsp:forward>违反了MVC的分层原则控制器无法干预
·orgapachestrutsactionsIncludeAction出于ForwardAction相似的原因Struts推荐用IncludeAction代替JSP的<jsp:include>
·orgapachestrutsactionsLookupDispatchAction如果一个表单有多个提交按钮不同的提交按钮执行不同的业务操作用DispatchAction最为合适
·orgapachestrutsactionsSwitchAction用SwitchAction可在不同的Struts模块间转换
由于我们的Action需要完成用户密码验证的业务并根据结果转换到不同的页面中所以这个LoginAction是一个普通的Action故我们选择orgapachestrutsactionAction
按Next到下一步
.设置Action的配置信息
图 设置LoginAction的配置信息
·Action path访问这个Action的URI接受默认的/loginAction这样我们将通过类似这样的URL来访问这个Action
·FormBean name下拉框中列出Web模块中所有的ActionForm我们选择前一小节中所创建的userActionForm这样客户端的HTTP请求访问LoginAction时HTTP请求所带的数据就会被Struts总控制器自动填充到userActionForm中了
·ScopeAction有两个选择request和session表示ActionForm在填充后将放在request对象中还是session对象中由于我们需要在通过密码验证后才使用户登录系统这样就不能使userActionForm在数据填充时就放入session中而应该在通过密码验证后手工将其绑定到session中(UserActionForm一旦绑定到session中其valueBound()方法就会被调用记录用户登录日志)故此我们选择request
·input JSP输入的JSP页面在ActionForm需要进行数据有效性自校验的情况下如果校验失败Struts框架总控制器将请求返回到这个输入页面上因为UserActionForm无需进行有效性校验(在的第步我们没有为UserActionForm实现自校验功能)所以无需指定输入的JSP
按Finish按钮直接创建LoginActionJBuilder自动打开Struts Config Editor生动形象地展现用户登录模块Struts框架下的处理流程如图 所示
图 Struts Config Editor
位于中心的/loginAction是访问LoginAction的URI它是登录业务的控制器Struts总控制器创建一个UserActionForm实例并用HTTP请求的数据填充UserActionForm实例然后将其传给LoginAction的execute()方法
.定义访问入口
现在我们需要调整loginjsp表单的提交地址使用LoginAction来处理用户登录的请求调整后的代码如所示
代码清单 loginjsp 使用LoginAction处理用户登录
<%@page contentType=text/html; charset=GBK import=bookstoreUserList %>
…
<form name=form method=post action=/webModule/loginActiondo>用户名
<select name=userId>
<option value= selected>登录用户</option>
<%=UserListgetUserListHTML()%>
</select>
密 码
<input name=password type=password>
<input type=submit name=Submit value=登录>
</form>
</body>
</html>
如第行所示将原来action=switchjsp改为/webModule/loginActiondo由于我们需要将整个应用部署于/webModule的URI下所以需要在Action访问的地址前加上/webModule如果通过Struts的<html:form>标签来指定表单提交的地址则无需添加/webModule标签将自动进行转换你将在本专题后续内容中学习到这种方法
注意
Struts框架总控制器Servlet通过路径匹配的方式截获HTTP请求其匹配串是*do表示URL以do结束的HTTP请求才会被Struts框架处理否则Struts忽略之所以在写链接地址时千万不要忘了调用地址后加一个do的后缀