1. 程式人生 > >Struts2輸入驗證(--validation.xml,深入淺出struts2第十章)

Struts2輸入驗證(--validation.xml,深入淺出struts2第十章)

今天學習深入淺出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了一天。

小生學業不精,跪下了。。