Monday, November 06, 2006

Struts 2: Validation

Update: A new post for validation in struts with annotation is available at: Struts 2 Validation: Annotations.

Struts 2.0 relies on a validation framework provided by XWork input validation. Along with basic validation and client-side Javascript validation offered in Struts 1.x, Struts 2 offers Ajax based validation. The following example demonstrates how to use Struts 2 validation, both basic and ajax validations. For this, the sample page used is shown below.
<s:form action="RegisterUser">
<s:textfield name="userName" size="20" label="User Name" />
<s:textfield name="emailAddress" size="20" label="Email Address" />
<s:textfield name="dateOfBirth" size="20" label="Date Of Birth" />
<s:submit name="submit" value="submit" />
</s:form>
The Action definition is shown below:
<action name="RegisterUser" method="registerUser" class="example.RegisterUser">
<result name="input">/example/Register.jsp</result>
<result>/example/HelloWorld.jsp</result>
</action>
Based on above definition, the Action class must have a method name registerUser.
Basic Validation
For basic validaton, you have to define the validation rules in <ActionClassName>-validation.xml file. The validations for this form are defined in the RegisterUser-validation.xml file as follows
<validators>
<field name="userName">
<field-validator type="requiredstring">
<message key="requiredstring" />
</field-validator>
</field>
<field name="emailAddress">
<field-validator type="email">
<message key="fieldFormat" />
</field-validator>
</field>
<field name="dateOfBirth">
<field-validator type="requiredstring">
<message key="requiredstring" />
</field-validator>
<field-validator type="regex">
<param name="expression">
[0-9][0-9]/[0-9][0-9]/[1-9][0-9][0-9][0-9]
</param>
<message key="fieldFormat" />
</field-validator>
</field>
</validators>
Note that the "date of birth" field has two validators associated with it. The "regex" validator type takes a parameter by the name "expression" which is the regular expression used to validate the field. The message keys used in validation rules must be defined in "package.properties" file as follows:
requiredstring = ${getText(fieldName)} is required.
fieldFormat = ${getText(fieldName)} is not formatted properly.

Client Side Validation
For simple client-side validation without Ajax, just add a validate="true" to the form definition in the JSP, as follows:
<s:form action="RegisterUser" validate="true">
Also note that the message keys do not work(atleast not for me), and you may have to define the error messages directly instead of through the properties file as follows:
<message>Date of birth is not formatted properly</message>

Ajax Validation
Struts implements Ajax Validation by using DWR. For a quick start of DWR read Ajax in Java with DWR. Coming to Struts validation, follow these steps to setup DWR
  1. Download DWR from here.
  2. Add DWR servlet mapping in the web deployment descriptor as shown below
    <servlet>
    <servlet-name>dwr</servlet-name>
    <servlet-class>uk.ltd.getahead.dwr.DWRServlet</servlet-class>
    <init-param>
    <param-name>debug</param-name>
    <param-value>true</param-value>
    </init-param>
    </servlet>
    <servlet-mapping>
    <servlet-name>dwr</servlet-name>
    <url-pattern>/dwr/*</url-pattern>
    </servlet-mapping>
  3. In your WEB-INF directory, create a dwr.xml file and declare the struts validator as follows
    <!DOCTYPE dwr PUBLIC
    "-//GetAhead Limited//DTD Direct Web Remoting 1.0//EN"
    "http://www.getahead.ltd.uk/dwr/dwr10.dtd">

    <dwr>
    <allow>
    <create creator="new" javascript="validator">
    <param name="class"
    value="org.apache.struts2.validators.DWRValidator" />
    </create>
    <convert converter="bean"
    match="com.opensymphony.xwork2.ValidationAwareSupport" />
    </allow>

    <signatures>
    <![CDATA[
    import java.util.Map;
    import org.apache.struts2.validators.DWRValidator;

    DWRValidator.doPost(String, String, Map<String, String>);
    ]]>
    </signatures>
    </dwr>
  4. Change the form declaration in your JSP file to include "theme=ajax" as shown below
    <s:form action="RegisterUser" validate="true" theme="ajax">
This example was tested using Tomcat 5.5 on Java 1.5.

27 comments:

  1. Hi abhi
    Its a very good example
    but i need your help that i need validation in struts 2.
    But i dont want to do Validation in the first page
    e.g
    That i have one class like Jurisdiction in this class i have 4 method for creating deleting updating ok
    and i have to put validation in the method say updating ok
    and my first page is like craeting ok i dont want to put Validation on Craeting
    i think you can understand my problem Can you help me
    my emai Id is
    akif.waseem@gamil.com

    ReplyDelete
  2. I followed the steps you had mentioned. I get a message in Firefox as 'ReferenceError: validateForm_[formId] is not defined'

    Here formId is the id of the form I submit.

    In IE, Its nots working and I don even get any message on the browser screen.

    I am using Tomact 5.5 and Java 1.6

    ReplyDelete
  3. Hi,

    I'm trying to compare the value of the textfield witha String using field expression.But it isnt working.Any clue?

    thanks
    AN

    ReplyDelete
  4. Hi,
    I am using struts 2.
    I have written my customised java class to do the form validation within
    the action class.
    I want to render the validation error messages from a property file and not
    hard coding it into the code.

    What i understand is the struts ActionSupport class has
    addActionError(String msg) which takes a error messages,
    Can anyone help me how can I set the error key in the validation class?

    Manoj.

    ReplyDelete
  5. Maybe this will help someone else.

    I had this (validation) setup from when I was using WebWork 2.2.5 and I am now upgrading to Struts 2.0.9 from WebWork. After making all my other changes and testing my site, I received the following error:

    org.xml.sax.SAXParseException: Document is invalid: no grammar found.

    I searched the net but didn't find a direct solution, just a few links about other people having similar issues and that the DTD must be missing. I opened the xwork-2.0.4.jar that comes with Struts 2.0.9 and found the file xwork-validator-config-1.0.dtd. Inserting the string documented in that file fixed my problem.

    ReplyDelete
  6. Hello all,

    I have search for a similar solution as in struts 1.X ({0} is required and {0} filled in xml validation file), but I haven't found its equivalence.

    Suppose we have, as you mentioned:

    requiredstring = ${getText(fieldName)} is required.
    fieldFormat = ${getText(fieldName)} is not formatted properly.

    and this validator:
    <validators>
    <field name="userName">
    <field-validator type="requiredstring">
    <message key="requiredstring" />
    </field-validator>
    </field>

    userName would be an input field:
    <input type="text" name="userName" ..... />

    An error after the for is submitted will be displayed as:
    userName is required.

    What about if the desirable output is another entry in bundle? Such as:
    User name is required.

    Where "User name" is not the field name in the <input type="text" name="userName"...> tag.

    Even worse, if the application uses internationalization, we would have in a second resource bundle, in spanish for instance:
    ${getText(fieldName)} es requerido.

    and still the output will be:
    userName es requerido.

    Can this be done in struts/webwork?

    Regards,
    OO

    ReplyDelete
  7. Some one fix this error:


    Anonymous said...

    I followed the steps you had mentioned. I get a message in Firefox as 'ReferenceError: validateForm_[formId] is not defined'

    Here formId is the id of the form I submit.

    In IE, Its nots working and I don even get any message on the browser screen.

    I am using Tomact 5.5 and Java 1.6
    1:05 AM

    ReplyDelete
  8. hi, Abhi,
    any way you are doing a very great service.

    ReplyDelete
  9. hi abhi,

    can i know how do i create search criteria using ajax and struts..
    can i get the sample codding

    thanx

    ReplyDelete
  10. hi,
    i'm trying to do validation using Struts2-validation interceptor and had some confusing about certain things...
    1) may i know which directory should i put ActionClassName-validation.xml?
    2) how to configure ActionClassName-validation.xml with other related files so that my validation can work properly?
    plz reply my ques ASAP. i really need ur help.
    thanks in advance ;)
    -azu-

    ReplyDelete
  11. Try the following link...
    http://struts.apache.org/2.x/docs/bootstrap.html

    San.

    ReplyDelete
  12. Hi Abhi.. What if you have two text fields on the page from which you can enter a value in either one. When i use the requiredstring type validation on the page, and provide a value to one, the validation kicks in for the other one. can you guide me with this. Do i need to use a different validation type ?

    ReplyDelete
  13. i did the configurations exactly as mentioned. But hte page is not getting validated by ajax. My page has custom client side js and when i clink on any check box (conneted with custom -js) i get an alert with 'null' string in it and in the backend i see exceptions:
    1113743 [http-8080-Processor23] WARN uk.ltd.getahead.dwr.impl.ExecuteQuery - Method execution failed:
    java.lang.NullPointerException
    at org.apache.struts2.validators.DWRValidator.doPost(DWRValidator.java:85)
    at sun.reflect.GeneratedMethodAccessor97.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:585)
    at uk.ltd.getahead.dwr.impl.ExecuteQuery.execute(ExecuteQuery.java:233)
    at uk.ltd.getahead.dwr.impl.DefaultExecProcessor.handle(DefaultExecProcessor.java:48)
    at uk.ltd.getahead.dwr.impl.DefaultProcessor.handle(DefaultProcessor.java:83)
    at uk.ltd.getahead.dwr.AbstractDWRServlet.doPost(AbstractDWRServlet.java:162)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:709)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:252)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
    at admin.util.UTF8Filter.doFilter(UTF8Filter.java:27)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:178)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:432)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:126)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:105)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:107)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:148)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:868)
    at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:663)
    at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:527)
    at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:80)
    at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:684)
    at java.lang.Thread.run(Thread.java:595)


    any idea what went wrong?

    ReplyDelete
  14. hai i am using client-side validation in struts 2.but when i submit the error message display each time.
    and if i enter data to validating field then the error will not go and the action didnot work.

    can u help me

    ReplyDelete
  15. Hi everybody,
    great post Abhi!
    Do you know how to check if two dates submitted are greater and less than today?? in other words that today is between "dateStart" and "dateEnd".

    I need something like that:

    field name="todayDate"
    field-validator type="date" param name="min" ${dateStart} /param
    param name="max" ${dateEnd} /param
    message key ="error.field.invalid_format" /
    /field-validator
    /field


    where dateStart and dateEnd are two others field name declared as date.

    Note: If I do that I get a java.lang.NoSuchMethodException: setMin(java.lang.String) and the same about max

    Thanks a lot for your help

    ReplyDelete
  16. Hi evry
    M working on struts2 validation using XML. M using a custom tag instead of datetimepicker for date selection since i was facing problems in making the textfield of the datetimepicker readonly.
    My problem is dat the first validation is displayed below the field. wat shud i do to get it above the field? need ur help in this rgrd.
    Thanx in advance
    Joslin

    ReplyDelete
  17. This comment has been removed by the author.

    ReplyDelete
  18. Hi evry1!
    M working on struts2 validation using XML. M using a custom tag (instead of datetimepicker) for date selection ,since i was facing problems in making the textfield of the datetimepicker readonly.
    My problem is dat the first validation is displayed below the field. wat shud i do to get it above the field? need ur help in this rgrd.
    Thanx in advance
    Joslin

    ReplyDelete
  19. Hi all,
    I found out that you need to extend ActionSupport class in order to support validation. Also after some wrong input while showing the messages css is not applied can anyone tell how to do that
    Also enable javascript

    ReplyDelete
  20. well.. i saw the example but i could not figure out where u have used DWR functionality.. cause I believe just mapping does not means that u r using DWR. Though I am not very much familiar with DWR but i can still understand that there is only mapping not implementation

    ReplyDelete
  21. can u give me solution for ajax submit. i am struggling with this code below.

    login.jsp
    --------
    div id="id1"
    s:form id="myform" action="login"
    s:textfield name="username"/
    s:submit type="submit" theme="ajax" targets="id1"/
    /div
    /code
    In struts.xml, result type="success"login.jsp/result

    (I left out the > & < tag symbol, please regret for this.)

    i am getting field error validation message.

    Please help me.

    ReplyDelete
  22. hi abhi,
    i am new to Struts2 so please help me to execute a HelloWorld program.

    when i delete the filter and filter-mapping tags from the web.xml file then the project get deployed successfully....and otherwise i am not able to deploy it....whats the problem......
    ....can u mail me on my email id

    ReplyDelete
  23. Hi
    I am Deepak
    I am using Struts2 and xml validation
    in action i had given 2 methods fetch and insert
    insert method works fine with validation when action submitted
    but for fetch when i m going to call action validations are performed and and return to page with out excuting the fetch method

    how should i diable validation for fetch method

    my mail id
    deepak.mule@lntinfotech.com

    ReplyDelete
  24. Hi Abhi I am new to struts2.1.6 when I use client side validation by making validate="true" in form tag It works fine but if any error message was present previously It is shown as it is and other error messages are repating. So what is the solution? Any help is appriciated well in advance....

    ReplyDelete
  25. Nice information, I really appreciate the way you presented.Thanks for sharing..

    http://www.w3cvalidation.net/

    ReplyDelete

Popular Posts