今天學習深入淺出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了一天。
小生學業不精,跪下了。。