1

Question: how to validate the elements of an array?

I want to write a simple application that asks a user to enter 10 numbers using struts2.

enter.jsp

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%@ taglib prefix="s" uri="/struts-tags" %>    

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Enter 10 numbers!</title>
</head>
<body>
<h3>Please enter 10 numbers</h3>
<s:form action="next.action" method="post" validate="true">
    <s:iterator var="i" begin="0" end="9">
        <s:label value="Number %{#i+1}"/>
        <s:textfield name="number" key="label.number" size="20"/>   
    </s:iterator>
    <s:submit method="execute" key="label.next" align="center" />
</s:form>
</body>
</html>

I used a iterator to generate 10 textarea for the user to enter the numbers. And I want all the fields to be required.

NextAction.java

import com.opensymphony.xwork2.ActionSupport;
import java.util.ArrayList;

public class NextAction extends ActionSupport{



    private Integer[] number;

    public Integer[] getNumber() {
        return number;
    }
    public void setNumber(Integer[] number) {
        this.number = number;
    }


    public String execute(){
        return "success";
    }

}

The only property this class has is number. Note that because I generated 10 textarea with the same name "number", the "number" I'll get in this class will be an Integer array of length 10. And when I am not using the validation below, I can easily get the numbers the user entered (i.e. number[i]), and display them after in another jsp.

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
  <display-name>Number</display-name>
  <welcome-file-list>
    <welcome-file>enter.jsp</welcome-file>
  </welcome-file-list>

    <filter>
    <filter-name>struts2</filter-name>
    <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
  </filter>

  <filter-mapping>
    <filter-name>struts2</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

</web-app>

struts.xml

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE struts PUBLIC 
    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" 
    "http://struts.apache.org/dtds/struts-2.0.dtd">

<struts>

 <constant name="struts.custom.i18n.resources" value="ApplicationResources" />

    <package name="default" extends="struts-default" namespace="/">
        <action name="forward" class="NextAction">
            <result name="success">success.jsp</result>
            result name="input">enter.jsp</result>

        </action>
    </package>
</struts>

NextAction-validation.xml

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE validators PUBLIC 
    "-//OpenSymphony Group//XWork Validator 1.0.2//EN" 
    "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">

<validators>

<field name="number">   <!-- The field 'number' here is actually holding an array -->
    <field-validator type="required">
        <message key="errors.required"/>
    </field-validator>
    <field-validator type="int">
        <param name="min">1</param>
    <param name="max">100</param>
        <message key="errors.number"/>
    </field-validator>
</field>

</validators>

But when I added this validation, because the field "number" is array, then this validation will not work.(if there were only one textarea named 'number', this validation would have been fine. But we have 10 )

My question is how to validate each element of the array, which we get from the submitted form? Hope my question is clear.

Thank you

shane716
  • 145
  • 2
  • 14

1 Answers1

3

It is unlikely you are going to reuse this validator, so just use validate within the action:

import com.opensymphony.xwork2.ActionSupport;
import java.util.ArrayList;

public class NextAction extends ActionSupport{
    private Integer[] number;

    public Integer[] getNumber() {
        return number;
    }
    public void setNumber(Integer[] number) {
        this.number = number;
    }
    //Following is default behaviour so it is not worth writing
    //public String execute(){
    //    return "success";
    //}

    //add validation in action (_not tested_)
    public void validate(){
        if (number.length > 10){
          this.addActionError("Error: More than ten numbers supplied.");
        }else if (number.length < 10){
          this.addActionError("Error: Less than ten numbers supplied.");
        }
        for (int i = 0; i < number.length; i++){
           if(number[i] < 0){
             this.addActionError("Error: Number " + (i + 1) + " is less than zero.");
           }else if(number[i] > 100){
             this.addActionError("Error: Number " + (i + 1) + " is greater than 100.");
           }
        }
    }
}

Then display the field errors in the jsp with <s:actionerror /> or rewrite the above to specifically name fields (with indexes) in which case you can use , and you'll use the addFieldError method. For details on these tags see http://struts.apache.org/2.3.1.2/docs/tag-reference.html

Quaternion
  • 10,380
  • 6
  • 51
  • 102
  • Thank you for your reply. What happens if the user enters some strings instead of numbers. @Quaternion – shane716 Apr 02 '12 at 04:07
  • I'm not sure... type conversion would fail to set the values, what I don't know is how the array size is calculated when array subscripts are not used in the name. A simple test would show this but I'll leave it till tomorrow unless someone else gets back. Intuition tells me to use array notation in the field names and then I would check in validate if each element is null... if it is validation failed for that element (an integer was not entered). – Quaternion Apr 02 '12 at 04:39