5.定义一个动作:
属性:
- name: 必须的. 动作名称, 用户用于发起请求, 在包中要唯一.
- class: 指定动作类的全名. 框架会通过反射机制去实例化. 不写默认是 com.opensymph ony.xwork2.ActionSupport
- method: 指定动作类中的动作方法. 框架会执行该方法. 默认是 execute(). execute () 默认返回 success
例如:
<package name="actions" extends=“AllDefault" namespace="/demo">
<action name="demo1" class="com.XXX.struts.actions.DemoAction1" method="demo1">
<result name="success">/success.jsp</result>
<result name="error">/error.jsp</result>
</action>
</package>
上面首先定义了一个包,包的名字是actions,继承于之前的AllDefault,也就是如果没写class,会将默认的class地址改为指定的.名称空间为/demo,那么也就是说如果JSP想访问这个action,那么在超链接的地址里应该这样写${pageContext.request.contextPath}/demo/demo1.action
也就是要在demo1.action前面加上命名空间的值.之后的action名字为demo1,执行的是位于actions文件夹下的DemoAction1类里面的demo1方法,在结果方面,这个方法会返回两种结果”SUCCESS”与”ERROR”.这两种结果都默认执行的是dispatcher,也就是转发.
6.关于动作类,拿上面的DemoAction1举例,动作类继承于ActionSupport,所以它可以复写ActionSupport的所有方法.
package com.xxx.struts.actions;
import com.opensymphony.xwork2.ActionSupport;
public class DemoAction1 extends ActionSupport {
// 动作方法:
public String demo1() {
int a = 3, b = 5;
if (a > b) {
return "success";
} else {
return ERROR;
}
}
}
7.关于返回值,可以使用接口中的常量:
- String SUCCESS : success 动作执 正常
- String NONE : none 动作方法执行后不转向任何视图. 或者在动作方法后 null
- String ERROR : error. 有错误
- String INPUT : input. 验证, 转换失败,转入输入页面
- String LOGIN : login. 检测用户是否登录, 没有登录转向次视图.
8.关于动作类方法的要求:必须返回String类型
public String XXX(){
return SUCCESS;
}
9.关于使用通配符,比如说我要写数据库方面,涉及到增,删,改,查四个跳转,那么如果我们按照以前的写法是
大量的冗余代码沉淀,而且这四种方法有规律可循,所以这时候可以使用通配符来代替它们
<package name="wildcard" extends="AllDefault" namespace="/">
<action name="*_Customer" class="com.lanou.struts.wildcard.CustomerAction" method="{1}Customer">
<result name="success">/{1}Customer.jsp</result>
</action>
</package>
或者
<package name="wildcard" extends="AllDefault" namespace="/">
<action name="*_*" class="com.lanou.struts.wildcard.{2}Action" method="{1}{2}">
<result name="success">/{1}{2}.jsp</result>
</action>
</package>
这是两种使用通配符的写法,第二种比第一种更加简便
10.Action访问 ServletAPI 使用action的最终目的也是处理一下请求的数据
两种方法:
(1).ServletActionContext
如果整个类只有这一次使用到request,那么我们可以通过ServletActionContext来直接获取HttpServletRequest request = ServletActionContext.getRequest();
(2)如果这个类里面的许多方法都需要用到request,那么我建议通过实现XXXAware接口来实现.在执行动作之前有拦截器给你注入这些实例 interceptor — servletcofig
现在展示ResultAction类的实现代码
package com.xxx.struts.result;
import com.opensymphony.xwork2.ActionSupport;
import org.apache.struts2.interceptor.ServletRequestAware;
import javax.servlet.http.HttpServletRequest;
//这里的ResultAction不仅继承了ActionSupport,而且还实现了ServletRequestAware
public class ResultAction extends ActionSupport implements ServletRequestAware{
private HttpServletRequest request;
//这里需要将HttpServletRequest作为成员变量,并且有set/get方法才可以使用
public HttpServletRequest getRequest() {
return request;
}
//通过实现ServletRequestAware,需要复写方法
@Override
public void setServletRequest(HttpServletRequest httpServletRequest) {
this.request = httpServletRequest;
}
public void setRequest(HttpServletRequest request) {
this.request = request;
}
//这里定义了三个动作方法,第二个是自定义返回值,那么在xml中的action里面的result里的name就需要有一个为suc
public String result1(){
return SUCCESS;
}
public String result2(){
return "suc";
}
public String result3(){
return SUCCESS;
}
}
11.关于结果集
(1).result 元素的配置
- name: 指定配置逻辑视图名, 对应着动作方法的返回值. Name 默认值: success
type: 到达目标的形式. 默认值: dispatcher 转发
(2).结果集类型
chain : 用户转发到另外一个动作
- dispatcher: 转发到 jsp页面
- redirect: 用于重定向到另外一个 JSP页面
- redirectAction: 用于重定向到另外一个action
- stream: 用于向浏览器返回一个InputStream的结果类型.用于文件下载
- plainText: 用于显示某个页面原始代码的结果类型 [直接访问页面]
(3).自定义结果集
随机验证码图片:
<form action="">
username: <input><br>
password: <input><br>
验证码: <input name="code" size="4"><img src="${pageContext.request.
contextPath}/codeImg.action"><br> <input type="submit" value="登录">
</form>
每当页面加载的时候,图片就需要加载,也就自动访问了这个方法.间接或直接实现 com.opensymphony.xwork2.Result接口的 doExecute 方法
public class CodeImgResult implements Result {
@Override
public void execute(ActionInvocation actionInvocation) throws Excep
tion {
VerifyCode code = new VerifyCode();
BufferedImage img = code.getImage();
System.out.println("code: " + code.getText());
VerifyCode.output(img, ServletActionContext.getResponse().getOu
tputStream());
}
}
声明结果类型.这个是在包中可以使用,若想全局,使用包继承
<package name="customresult" extends="struts-default"> <!-- 声明结果集类型-->
<result-types>
<result-type name="codeimg" class="com.lanou.customresult.CodeImg
Result"></result-type>
</result-types>
<action name="codeImg">
<!--使用自定义的结果集类型-->
<result type="codeimg" name="success"></result>
</action>
</package>
(4).关于result->param
12.(1)通过OGNL表达式来封装数据
JSP:
<form action="${pageContext.request.contextPath}/login2.action” method="post">
用户名: <input type="text" name="person.username"><br>
密码: <input type="password" name="person.password"><br>
性别: <input type="text" name="person.gender"><br>
<input type="submit" value="登录">
</form>
action:
public class PersonAction extends ActionSupport {
private Person person;
public Person getPerson() {
return person;
}
public void setPerson(Person person) {
this.person = person;
}
public String login(){
return null;
} }
在jsp页面中的 person.username 和person.password 其实就是ognl表达式,代表着往根 (root,值栈valueStack)中存放值,而值栈中的栈顶元素也就是为当前action,我们在 action中设置person的get、set属性,即可以让存进来的值匹配到,进而将对应属性赋 值成功。
(2)实现 ModelDriven 接口,提供一个方法getModel(),初始化对象实例。 modelDriven 拦截器将getModel方法返回的结果压入值栈,而我们的表单参数会从值栈中从上往下进行查找,自然就直接将参数封装到对象中了。
在使用的时候implements ModelDriven<Student>
实现ModelDriven的时候需要将所要封装的类名写进去,比如说我从表单获取学生信息,那么ModelDriven里面写的就是Student,同时我还要创建一个Student的类,里面有所有我需要获取数据的set/get方法,并且定义实例化成员对象private Student stu = new Student();
之后我们就可以直接用stu.getXXX()来获取对应的值了.