今天学习深入浅出struts2的第十章,Model Driven和Preparable拦截器,结果被表单验证弄的搞了一天才发现问题。
把模型对象从动作类里分离出来,可以借助Model Driven拦截器来创建和填充相关的对象模型。比如我有一个EmployeeAction动作类,Employee模型类,和一个用于隐藏员工管理工作的业务逻辑复杂性的管理类EmployeeManager。
先贴代码
package app10a;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
import java.util.List;
public class EmployeeAction extends ActionSupport
implements ModelDriven {
private Employee employee = new Employee();
private List<Employee> employees;
public Object getModel() {
return employee;
}
public List<Employee> getEmployees() {
employees = EmployeeManager.getEmployees();
return employees;
}
public Employee getEmployee() {
return employee;
}
public void setEmployee(Employee employee) {
this.employee = employee;
}
public void setEmployees(List<Employee> employees) {
this.employees = employees;
}
public String list() {
employees = EmployeeManager.getEmployees();
return SUCCESS ;
}
public String create() {
return SUCCESS;
}
public String submit(){
return SUCCESS;
}
}
package app10a;
public class Employee {
private int id;
private String firstName;
private String lastName;
public Employee() {
}
public Employee(int id, String firstName, String lastName) {
this.id = id;
this.firstName = firstName;
this.lastName = lastName;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
package app10a;
import java.util.ArrayList;
import java.util.List;
public class EmployeeManager {
private static List<Employee> employees;
public static int id;
static {
employees = new ArrayList<Employee>();
employees.add(new Employee(++id, "Rachel", "Greene"));
employees.add(new Employee(++id, "Monica", "Geller"));
employees.add(new Employee(++id, "Phoebe", "Buffay"));
employees.add(new Employee(++id, "Joey", "Tribbiani"));
employees.add(new Employee(++id, "Chandler", "Bing"));
employees.add(new Employee(++id, "Ross", "Geller"));
}
public static List<Employee> getEmployees() {
return employees;
}
public static void create(Employee employee) {
employee.setId(++id);
employees.add(employee);
}
}
现在再贴显示层代码
<%@ taglib prefix="s" uri="/struts-tags" %>
<html>
<head>
<title>Employee List</title>
<style type="text/css">@import url(/css/main.css);</style>
</head>
<body>
<div id="global">
<h3>Add New Employee</h3>
<s:form action="Employee_create" method="POST">
<s:textfield key="firstName"/>
<s:textfield key="lastName"/>
<s:submit/>
</s:form>
<hr/>
<table style="width:100%;text-align:left">
<tr>
<th>Employee Id</th>
<th>First Name</th>
<th>Last Name</th>
</tr>
<s:iterator value="employees" status="rowstatus">
<tr>
<td><s:property value="id"/></td>
<td><s:property value="firstName"/></td>
<td><s:property value="lastName"/></td>
</tr>
</s:iterator>
</table>
</div>
</body>
</html>
struts2.xml配置
<package name="app10a" extends="struts-default">
<action name="Employee_list" method="list" class="app10a.EmployeeAction">
<result>/jsp/Employee.jsp</result>
</action>
<action name="Employee_create" method="create" class="app10a.EmployeeAction">
<result type="redirectAction">Employee_list</result>
<result name="input">/jsp/Employee.jsp</result>
</action>
</package>
现在你看到的页面是这样的
现在你任意输入都可以存储在list中,然后再通过显示层显示,但是我现在要让输入的firstName和lastName不为空怎么办。这就要用到表单验证的方法验证<ActionClassName>-<actionName>-validation.xml。
注意这里的actionName是在struts.xml的name映射。EmployeeAction-Employee_create-validation.xml
<!DOCTYPE validators PUBLIC "-//Apache Struts//XWork Validator 1.0.2//EN"
"http://struts.apache.org/dtds/xwork-validator-1.0.2.dtd">
<validators>
<field name="firstName">
<field-validator type="requiredstring">
<message>Please enter a first name</message>
</field-validator>
</field>
<field name="lastName">
<field-validator type="requiredstring">
<message>Please enter a last name</message>
</field-validator>
</field>
</validators>
注意 field name直接是firstName,而不是Employee.firstName。这是因为当出发EmployeeAction动作的时候,Model Driven拦截器将调用相关的EmployeeAction的getModel方法,并把返回的模型压入Value Stack栈如果你已经提前把defaultStack拦截器配置成在Model Driven拦截器之后切入,Parameters拦截器将把字段映射到Value Stack的栈顶对象的各有关属性。因为此时Value Stack栈的栈顶元素是刚被压入的模型,所以该模型将被填充。
如果你现在提交空表单就会提示你输入了
But IntelliJ IDEA好像是有个BUG,程序能够正确运行,它竟然没有识别出来,显示红色。。。
还有就是深入浅出struts2这本书的头文件竟然过时了,现在是用
<!DOCTYPE validators PUBLIC "-//Apache Struts//XWork Validator 1.0.2//EN" "http://struts.apache.org/dtds/xwork-validator-1.0.2.dtd">
我在看第八章的时候还改了这个bug,结果看到第十章忘了,今天因为这两个原因,直接让我debug了一天。
小生学业不精,跪下了。。