1、域模型DomainModel
在DomainModel模型中,Struts2的Action对象可以通过直接定义实例对象的引用来调用实例对象进行相关操作,但要求请求参数必须指定参数对应的实体对象,例如在表单中需要指定参数名称为user.name这样的方式。
例:在Action中应用一个User对象,可以使用一下代码
<span style="font-family:SimSun;font-size:14px;">public class UserAction extends ActionSupport{
private User user;</span>
<span style="font-family:SimSun;font-size:14px;"> @Override
public String execute() throws Exception {
return SUCCESS;
}
<span style="white-space:pre"> </span>public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}</span>
那么,在页面中提交注册请求的代码如下
<h2>用户注册</h2>
<s:form action="userAction" method="post">
<s:textfield name="user.name" label="用户名"/>
<s:password name="user.password" label="密码"/>
<s:submit value="注册"/>
</s:form>
2、驱动模型ModelDriven
在Struts2框架的API中,提供了一个名称为ModelDriven接口,Action对象可以通过实现此接口获取指定的实体对象,获取方式是实现ModelDriven接口提供的getModel()方法进行获取,其语法格式如下:
T getModel();
ModelDriven接口应用了泛型,getModel的返回值为所要获取的实体对象。
如果Action实现ModelDriven接口,当表单提交到Action对象后,Struts2首先实例化Action对象,然后判断此Action对象是否是ModelDriven对象(也就是是否实现了ModelDriven接口),如果实现了ModelDriven接口,则会调用getModel()来获取实体对象模型,将实体对象返回。那么,在之后的操作中,就已经存在了明确的实体对象,所以不需要在表单中的元素上添加指定的实例对象的引用名称。
表单中可以设置成一下代码:
<h2>用户注册</h2> <s:form action="userAction" method="post"> <s:textfield name="name" label="用户名"/> <s:password name="password" label="密码"/> <s:submit value="注册"/> </s:form>UserAction类的关键代码如下:
UserAction类中的user属性需要进行初始化操作,否则,在getModel()方法获取实体对象时,将出现空指针异常。<pre name="code" class="html">public class UserAction extends ActionSupport implements ModelDriven{ private static final long serialVersionUID = 1L; private User user = new User(); @Override public String execute() throws Exception{ return SUCCESS; } @Override public Object getModel() { return this.user; } }
3、preparable接口
Preparable 接口定义:
public interface Preparable {
void prepare() throws Exception;
}Struts2的Action在实现com.opensymphony.xwork2.Preparable接口后,就可以重写prepare()方法 此时在Action中,prepare()方法的执行点是在:setXxx()和execute()的执行之前。
使用场景: 如果action针对每次请求都要执行一些相同的业务逻辑, 那么可以实现Preparable接口, 将预处理业务逻辑写在prepare()方法里
比如需求:在执行Action的方法前,接收前台隐藏域传过来的值,再根据该值执行相应逻辑 如前台传过来ID,我们根据ID查找数据库对应的用户信息,再跳转到modify()中修改信息 但实际的运行过程中发现,通过Debug断点调试得知prepare()方法接收到的ID值是零 即前台隐藏域中的ID值没有传过来,事实上问题就出在默认的defaultStack拦截器栈上 其实defaultStack无法接收prepare()需要的数据,而应借助paramsPrepareParamsStack拦截器栈 事实上使用prepare拦截器之前,应先调用params拦截器,prepare()才能接收到表单数据 基于这个思路,于是可以通过各种手段将params拦截器放置在prepare拦截器之前即可 比如将defaultStack中的所有拦截器拷贝到struts.xml的我们自定义的myStack拦截器栈中 再按照paramsPrepareParamsStack拦截器栈中的params和prepare顺序修改二者位置即可。