📄 第一章:struts2入门.txt
字号:
十一、Action介绍
每个请求的动作都对应于一个相应的Action,excute()方法是Action类里最重要的部分,它执行返回String类型的值,与xwork配置文件里result标签name的值是相对应的。
字符常量的含义如下:
SUCCESS:Action正确的执行完成,返回相应的视图;
NONE:表示Action正确的执行完成,但并不返回任何视图;
ERROR:表示Action执行失败,返回到错误处理视图;
INPUT:Action的执行,需要从前端界面获取参数,INPUT就是代表这个参数输入的界面,一般在应用中,会对这些参数进行验证,如果验证没有通过,将自动返回到该视图; LOGIN:Action因为用户没有登陆的原因没有正确执行,将返回该登陆视图,要求用户进行登陆验证。
在WebWork中,一般Action类需要实现Action接口,或者直接继承基础类com.opensymphony.xwork.ActionSupport。如果用户输入的数据验证没有通过,我们需重新返回输入页面,并给出错误信息提示。拦截器栈“validationWorkflowStack”为我们实现了这个功能。它首先验证用户输入的数据,如果验证没有通过将不执行我们Action的execute()方法,而是将请求重新返回到输入页面。通过接口ValidationAware,我们可以获得类级别或字段级别的验证错误信息,这个错误信息也就是我们验证文件中标签里的数据。ActionSupport类已实现了此接口,这样在应用中我们的Action只要继承ActionSupport类就可以了。
根据FormBean的不同可以分为二类,
1. 一类是Field-Driven(字段驱动的)Action
Action将直接用自己的字段来充当FormBean的功能,我们的例子就是使用这种方式。它一般用在页面表单比较简单的情况使用,而且可以直接用域对象作为Action的字段,这样就不用在另写FormBean,减少了重复代码。
每个action有处理请求的方法,也可以封装前台的业务表单字段。当然也可可以将字段封装成对应的vo,即FormBean,如User对象,是一个普通的JavaBean,它可以包含用户注册的字段信息,并对每个字段提供相应的set和get方法。如“user.userid”将去分别调用Action类的getUser()和User类的getUserid()方法,即:getUser().getUsername(),取得的数据就是前面注册页面输入的用户名。而不封装时就调用action的getUid()和setUid().
1) login.jsp
<body>
<font color="red"><s:property value="message" /></font>
<s:form action="login2">
<table>
<tr><td><s:textfield label="用户名" name="user.uid"/></td></tr>
<tr><td><s:password label="密 码" name="user.pwd"/></td></tr>
<tr><td><s:submit/></td></tr>
</table>
</s:form>
</body>
2) LoginAction2
public class LoginAction2 extends ActionSupport{
private UserVO user;
private String message;
public UserVO getUser() {
return user;
}
public void setUser(UserVO user) {
this.user = user;
}
public String execute() throws Exception{
if(!user.getUid().equals(user.getPwd())) {
setMessage("用户名或密码错误");
return this.INPUT;
}
return this.SUCCESS;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
3) User
public class UserVO {
private String uid;
private String pwd;
public String getUid() {
return uid;
}
public void setUid(String uid) {
this.uid = uid;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
}
4) main.jsp
<body>
<h1 style="align:center;color:blue"><s:property value="user.uid" />,欢迎登陆!</h1>
</body>
5) struts.xml
<action name="login2" class="org.accp.struts2.action.LoginAction2">
<result>/main.jsp</result>
<result name="input">/index.jsp</result>
</action>
2. 另一类是Model-Driven(模型驱动的)Action 它很像Struts的FormBean,但在WebWork中,只要普通Java对象就可以充当模型部分。Model-Driven(模型驱动的)Action要求我们的Action实现com.opensymphony.xwork. ModelDriven接口,它有一个方法:Object getModel();当我们采用Model-Driven(模型驱动的)Action时,它将取得模型对象保存在值堆栈中。“name="username"”就是代表直接调用模型对象的setUsername()方法 我们Action的在配置文件中,也要给它指定一个拦截器model-driven,它的作用就是将模型对象保存到值堆栈中。其缺省的拦截器已有,不用再指定model-driven
1) index.jsp
<body>
<font color="red"><s:property value="message" /></font>
<s:form action="login2">
<table>
<tr><td><s:textfield label="用户名" name="uid"/></td></tr>
<tr><td><s:password label="密 码" name="pwd"/></td></tr>
<tr><td><s:submit/></td></tr>
</table>
</s:form>
</body>
2) LoginAction2
public class LoginAction2 extends ActionSupport implements ModelDriven<UserVO> {
private UserVO user = new UserVO();
private String message;
public String execute() throws Exception {
if (!user.getUid().equals(user.getPwd())) {
setMessage("用户名或密码错误");
return this.INPUT;
}
return this.SUCCESS;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public UserVO getModel() {
return user;
}
}
3) main.jsp
<body>
<h1 style="align:center;color:blue"><s:property value="uid" />,欢迎登陆!</h1>
</body>
3. ActionContext
?????????????
十二、OGNL
我们把“user.username”这样的语句叫做表达式语言(Expression Language,简称为EL)。它由XWork框架提供,XWork表达式语言的核心是OGNL(Object Graph Notation Language),通过它简单一致的表达式语法,可以存取对象的任意属性,调用对象的方法,遍历整个对象的结构图,实现字段类型转化等功能。
我们输入框的name用到的名字就是OGNL的表达式,比如:用户名的输入框:“
<input type="text" name="user.username">”,
在用户注册成功之后我们要显示用户注册的信息,用了“
<ww:property value="user.username"/>”。
Input输入框里的“user.username”,它解析成Java语句为:getUser().setUsername();,property标签里的“user.username”解析为Java语句:getUser.getUsername();。
十三、ValueStack
OGNL将对象存放在哪里呢?--OgnlValueStack,即值堆栈。
1、ValueStack其实就是一个放置Java对象的堆栈而已,唯一特别的是可以使用EL来获得值堆栈中对象属性的数据,并可以为值堆栈的对象属性赋值。
2、 WebWork的ValueStack底层有第三方开源项目OGNL实现。所以EL也都遵循OGNL的规范。我们在开发中,几乎不需要知道OGNL的细节。
3、 WebWork为每一次请求构建一个ValueStack,并将所有相关的数据对象(例如:Action对象、Model对象等)放到ValueStack中。再将ValueStack暴露给视图页面,这样页面就可以直接访问后台处理生成的数据。
1)、 所有存取操作的目标对象都是已放入ValueStack中的对象。所以在使用之前,必须要先将对象入栈。例如我们在setup方法中的语句:valueStack.push(employee)。
2)、 每一次WebWork请求,在创建Action对象之前都会先生成一个ValueStack对象,再将Action对象入栈。这样我们就可以通过表达式语言来直接存取action对象的数据,所以在WebWork中,action具有数据模型的功能。
3)、 在对ValueStack进行存取操作时,我们的操作指令(表达式语言)并不知道它是对哪个对象进行操作。例如,我们在获取员工姓名时,我们给的操作指令是”name”,这时,并不知道ValueStack里面的对象一定就是employee。ValueStack会从上而下,遍历栈里面的对象,并试图调用当前遍历对象的getName方法,当它找到了这个方法,并执行之后,就会将执行得到的数据返回。这就是那神秘的ValueStack。
4、 关于值堆栈的context map,它是一个放置值堆栈上下文数据的对象。通过符号“#“再加上对象的名称,可以访问这些数据(只可以访问)。一些JavaServlet相关的数据都放在这个容器中。这个对webwork的标签库特别有用,这样我们可以直接通过表达式语言去访问request、attribute、session、application里的数据。例如:用property标签库打印出所有请求参数的数据,代码如下:<ww:property value="%{#request}"/>。
5、 其它。“top”是ValueStack里面的关键字,通过它可以找到ValueStack中最上面的那个对象。可以试着打印一下valueStack.findValue("top"))看看。表达式语言除了可以调用基于JavaBean规范的get和set方法之外,还可以调用一般的Java方法(这是需要使用方法的全名,并传入需要的参数),也可以直接访问Java类的静态字段和静态方法。具体的使用,可以查看WebWork的官方文档。
十四、多视图支持
1、velocity模板
1) 改xwork.xml
<action name="testVM" class="org.accp.struts2.action.InterceptorAction">
<result type="velocity">/login.vm</result>
</action>
2) login.vm
<html>
<head>
<title>Velocity</title>
#shead()
</head>
<body>
#sform ("action=testVM" "method=post")
#stextfield ("label=username" "name=name")
#sdatetimepicker ("label=userbirth" "name=birthday")
#stextarea ("label=memo" "name=bio" "cols=20" "rows=3")
#sselect ("label=color" "list={'Red', 'Blue', 'Green'}" "name=favouriteColor" "emptyOption=true" "headerKey=None" "headerValue=None")
#sselect ("label=Favourite Language" "list=favouriteLanguages" "name=favouriteLanguage" "listKey=key" "listValue=description" "emptyOption=true" "headerKey=None" "headerValue=None")
#scheckboxlist ("label=Friends" "list={'Patrick', 'Jason', 'Jay', 'Toby', 'Rene'}" "name=friends")
#scheckbox ("label=Age 18+" "name=legalAge")
#sdoubleselect ("label=State" "name=region" "list={'North', 'South'}" "value='North'" "doubleValue='Florida'" "doubleList=top == 'North' ? {'Oregon', 'Washington'} : {'Texas', 'Florida'}" "doubleName=state" "headerKey=-1" "headerValue=---------- Please Select ----------" "emptyOption=true" )
#sfile ("label=Picture" "name=picture")
#soptiontransferselect ("label=Favourite Cartoons Characters" "name=leftSideCartoonCharacters" "leftTitle=Left Title" "rightTitle=Right Title" "list={'Popeye', 'He-Man', 'Spiderman'}" "multiple=true" "headerKey=headerKey" "headerValue=--- Please Select ---" "emptyOption=true" "doubleList={'Superman', 'Mickey Mouse', 'Donald Duck'}" "doubleName=rightSideCartoonCharacters" "doubleHeaderKey=doubleHeaderKey" "doubleHeaderValue=--- Please Select ---" "doubleEmptyOption=true" "doubleMultiple=true" )
#ssubmit()
#sreset()
#end
</body>
</html>
2、freemarker模板
1). 改xwork.xml
<action name="testFM" class="org.accp.struts2.action.InterceptorAction">
<result type="freemarker">/login.ftl</result>
</action>
2). login.ftl
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=gbk"/>
</head>
<body>
<@s.form action="testFM">
<@s.textfield label="username" name="user.uid"/>
<@s.textfield label="password" name="user.pwd"/>
<@s.submit value="login"/>
</@s.form>
</body>
</html>
十五、导入的jar包
antlr-2.7.2.jar
commons-beanutils-1.6.jar
commons-beanutils-1.7.0.jar
commons-chain-1.1.jar
commons-codec-1.3.jar
commons-collections-3.1.jar
commons-digester-1.6.jar
commons-el-1.0.jar
commons-fileupload-1.1.1.jar
commons-fileupload.jar
commons-io-1.1.jar
commons-lang-2.1.jar
commons-logging-1.0.4.jar
commons-logging-api-1.1.jar
commons-validator-1.3.0.jar
freemarker-2.3.8.jar
log4j-1.2.9.jar
ognl-2.6.11.jar
oro-2.0.8.jar
struts2-core-2.0.11.jar
struts-core-1.3.5.jar
velocity-1.4.jar
velocity-dep-1.4.jar
velocity-tools-1.1.jar
xwork-2.0.4.jar
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -