4

I am trying out Validations in SpringMVC using annotations...

I used 2 annotations for a field to validate

@NotEmpty(message="required")

@Size(min="3" max="8" message="Out of range")

private String password;

The issue i'm facing is, when the field is left blank it shows both error messages (*required as well as Out of Range). But I want to display either one of those error message not both...

Is it possible to restrict with one message? If so what are the possibilities for this scenario?

Any suggestions and guidance is appreciated.. Thanks in advance...

sree
  • 535
  • 4
  • 12
  • 26

2 Answers2

4

I've faced the same problem, so I created custom errors tag that displays the first error only - feel free to use it:

a] Create custom tag class

package cz.devmint.springext.web.tags.form;

import javax.servlet.jsp.JspException;

import org.apache.commons.lang.StringUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.web.servlet.tags.form.ErrorsTag;
import org.springframework.web.servlet.tags.form.TagWriter;

public class ErrorsTagExt extends ErrorsTag {

private boolean firstErrorOnly = true;

public boolean isFirstErrorOnly() {
    return firstErrorOnly;
}

public void setFirstErrorOnly(boolean firstErrorOnly) {
    this.firstErrorOnly = firstErrorOnly;
}

@Override
protected void renderDefaultContent(TagWriter tagWriter) throws JspException {
    tagWriter.startTag(getElement());
    writeDefaultAttributes(tagWriter);
    String delimiter = ObjectUtils.getDisplayString(evaluate("delimiter", getDelimiter()));
    String[] errorMessages = getBindStatus().getErrorMessages();
    for(int i = 0; i < errorMessages.length; i++) {
        String errorMessage = errorMessages[i];
        if (i > 0) {
            tagWriter.appendValue(delimiter);
        }
        tagWriter.appendValue(getDisplayString(errorMessage));
        if (firstErrorOnly) break;
    }
    tagWriter.endTag();
}

b] To use the custom tag you have to create tag library descriptor - you can simply copy ErrorsTag declaration from spring's tag library descriptors (spring-webmvc-3.2.1.RELEASE.jar in META-INF directory under name spring-form.tld) and add your own attribute firstErrorOnly. Below is the complete example extracted from my library - see comments in the code what can be changed and customized:

<?xml version="1.0" encoding="UTF-8"?>
<taglib xmlns="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"
    version="2.0">

<description>Custom extension to Spring Framework JSP Tag Library</description>
<tlib-version>3.0</tlib-version>
<short-name>tags</short-name>
<!-- use your own uri -->
<uri>http://cz.devmint.spring-ext/tags</uri>
<tag>
    <description>Renders field errors in an HTML 'span' tag.</description>
    <name>errors</name>
    <!-- use your own package - fully qualified name of your tag class  -->
    <tag-class>cz.devmint.springext.web.tags.form.ErrorsTagExt</tag-class>
    <body-content>JSP</body-content>
    <variable>
        <name-given>messages</name-given>
        <variable-class>java.util.List</variable-class>
    </variable>
    <!-- this attribute declaration is the only change when compare with spring's original tag definition -->   
    <attribute>
        <description>Whether to render the first error for given field only</description>
        <name>firstErrorOnly</name>
        <required>false</required>
        <rtexprvalue>false</rtexprvalue>
    </attribute>
    <attribute>
        <description>Path to errors object for data binding</description>
        <name>path</name>
        <required>false</required>
        <rtexprvalue>true</rtexprvalue>
    </attribute>
    <attribute>
        <description>HTML Standard Attribute</description>
        <name>id</name>
        <required>false</required>
        <rtexprvalue>true</rtexprvalue>
    </attribute>
    <attribute>
        <description>Enable/disable HTML escaping of rendered values.</description>
        <name>htmlEscape</name>
        <required>false</required>
        <rtexprvalue>true</rtexprvalue>
    </attribute>
    <attribute>
        <description>Delimiter for displaying multiple error messages. Defaults to the br tag.</description>
        <name>delimiter</name>
        <required>false</required>
        <rtexprvalue>true</rtexprvalue>
    </attribute>
    <attribute>
        <description>Equivalent to "class" - HTML Optional Attribute</description>
        <name>cssClass</name>
        <required>false</required>
        <rtexprvalue>true</rtexprvalue>
    </attribute>
    <attribute>
        <description>Equivalent to "style" - HTML Optional Attribute</description>
        <name>cssStyle</name>
        <required>false</required>
        <rtexprvalue>true</rtexprvalue>
    </attribute>
    <attribute>
        <description>HTML Standard Attribute</description>
        <name>lang</name>
        <required>false</required>
        <rtexprvalue>true</rtexprvalue>
    </attribute>
    <attribute>
        <description>HTML Standard Attribute</description>
        <name>title</name>
        <required>false</required>
        <rtexprvalue>true</rtexprvalue>
    </attribute>
    <attribute>
        <description>HTML Standard Attribute</description>
        <name>dir</name>
        <required>false</required>
        <rtexprvalue>true</rtexprvalue>
    </attribute>
    <attribute>
        <description>HTML Standard Attribute</description>
        <name>tabindex</name>
        <required>false</required>
        <rtexprvalue>true</rtexprvalue>
    </attribute>
    <attribute>
        <description>HTML Event Attribute</description>
        <name>onclick</name>
        <required>false</required>
        <rtexprvalue>true</rtexprvalue>
    </attribute>
    <attribute>
        <description>HTML Event Attribute</description>
        <name>ondblclick</name>
        <required>false</required>
        <rtexprvalue>true</rtexprvalue>
    </attribute>
    <attribute>
        <description>HTML Event Attribute</description>
        <name>onmousedown</name>
        <required>false</required>
        <rtexprvalue>true</rtexprvalue>
    </attribute>
    <attribute>
        <description>HTML Event Attribute</description>
        <name>onmouseup</name>
        <required>false</required>
        <rtexprvalue>true</rtexprvalue>
    </attribute>
    <attribute>
        <description>HTML Event Attribute</description>
        <name>onmouseover</name>
        <required>false</required>
        <rtexprvalue>true</rtexprvalue>
    </attribute>
    <attribute>
        <description>HTML Event Attribute</description>
        <name>onmousemove</name>
        <required>false</required>
        <rtexprvalue>true</rtexprvalue>
    </attribute>
    <attribute>
        <description>HTML Event Attribute</description>
        <name>onmouseout</name>
        <required>false</required>
        <rtexprvalue>true</rtexprvalue>
    </attribute>
    <attribute>
        <description>HTML Event Attribute</description>
        <name>onkeypress</name>
        <required>false</required>
        <rtexprvalue>true</rtexprvalue>
    </attribute>
    <attribute>
        <description>HTML Event Attribute</description>
        <name>onkeyup</name>
        <required>false</required>
        <rtexprvalue>true</rtexprvalue>
    </attribute>
    <attribute>
        <description>HTML Event Attribute</description>
        <name>onkeydown</name>
        <required>false</required>
        <rtexprvalue>true</rtexprvalue>
    </attribute>
    <attribute>
        <description>Specifies the HTML element that is used to render the enclosing errors.</description>
        <name>element</name>
        <required>false</required>
        <rtexprvalue>true</rtexprvalue>
    </attribute>
    <dynamic-attributes>true</dynamic-attributes>
</tag>
</taglib>

Put this xml file in WEB-INF/tld/spring-ext.tld

On jsp page add declaration:

<%@taglib prefix="spring-ext" uri="http://cz.devmint.spring-ext/tags" %>    

Instead of spring's ErrorsTag use custom tag:

<spring-ext:errors path="dummy" firstErrorOnly="true" /> 
Pavla Nováková
  • 796
  • 4
  • 11
  • Hi I can able understand the code you have given but I'm sorry I don't know where to use this code and how to map it with errors tag in view.. I'm really sorry I'm new to Spring... Can you explain little bit how to use this code please... – sree Feb 26 '13 at 06:26
  • Ok, I've add complete code and explanation of particular steps. – Pavla Nováková Feb 26 '13 at 18:37
  • Thanks a lot you made my day happy and you have done great work its working in the same way i expected.. Thanks again for your knowledge share... – sree Feb 27 '13 at 06:07
  • I'm really sorry user2003170, I'm not able to vote for your answer. I don't have number of reputations to vote... – sree Feb 27 '13 at 06:10
  • user2003170 how to guarantee the order of the property validation if we don't define the GroupSequence? If we don't do that, every time the order of property validation is random. – Rocky Hu Nov 24 '14 at 14:23
  • The order of validation related annotations / constraints cannot be specified at time of writing this comment. I've submitted order related issue to Hibernate Validator team a time ago, the issue was was accepted and probably will be solved in a next Bean Validation specification release - see more details here: http://beanvalidation.org/proposals/BVAL-248/ Btw, in simple cases you can avoid "order conflict" by using "non conflicting" combinations of annotations, e.g. NotNull and Size- Size will evaluate to true for null value. – Pavla Nováková Feb 07 '15 at 22:40
0

There is a question about that. You can check the following link:

In Spring MVC validation, Is it possible to show only one error message per field at a time?

Community
  • 1
  • 1
ahmetdursun
  • 83
  • 1
  • 6
  • Thanks for your answer ahmetdursun... I saw the link you posted, in that case they used interface and own validation so they used '@ReportAsSingleViolation' but in my case i'm using predefined exception annotation in class where i cannot place the '@ReportAsSingleViolation' annotation... Is there any other way? – sree Feb 25 '13 at 12:55