Categories
Computing Java Web Development

Spring Bean Validation: Error code list for Custom Error Message

In my charge to regain my coding skills, I am using Spring MVC and trying to run it on Google's App Engine.

As with any web application, I have a form which I was looking to validate. Spring appears to be very high on its integration of Hibernate's implementation of a budding Java standard, JSR-303, In essence that means annotating a POJO bean file and then having your Spring MVC Controller (@Controller is the annotation) use another annotation (@Valid) to trigger validation. If errors are found, the form is returned with error messages. Pretty awesome. Yet JSR-303 has a rather big omission: if you have to fields in a form that must be identical – as in the case of password a password confirmation field, you need to write custom code. Luckily, that capability is covered by *the other* Spring-related validation framework – The Spring Modules project's Validation library.

Configuring Spring Modules' validation is covered insanely well by Willie Wheeler. Spring Modules Validation (SMV hereafter) has the ability to compare fields to each other as a validation condition and also apply a validation rule based on prior validation success (look here for table 17.11). Very very cool powerful stuff. 

Where his article needs a bit of help is in how to set up custom error messages. See, SMV detects a validation error, it looks to create an error message that your Spring MVC form will display to the user. The default error messages are intentionally lacking, as you *are* expected to provide your own version for an error. And while the Wheeler article talks about how to set the errors up in a Properties file, he does not (nor is he expected – again thank you) cover all possible validation error codes that are necessary for you to define the error messages. This is why I am writing this post.

So, your custom error message properties file will consist of lines like the following:

SimpleClassName.propertyBeingValidated[validationRuleViolated]=your custom error message

So if you had a class called ApplicationUser with a field called email, your annotated class code will look this:

@Email private String email;

And your error message properties file will have a line like:

ApplicationUser.email[email]=Please enter a valid email address

You need to ensure that your class name (no package needed) is correctly capitalized. What's not clear – and drove me nuts, is what exactly are the error codes you put within the brackets – for example – [email].

Thanks to this incredibly useful post on the SpringFramework discussion boards, the error codes are based on default strings that are embedded in each one of the validation classes inside the org.springmodules.validation.bean.rule package.

To spare you digging through the source, here are the validation rules and the default error code strings associated with them:

Validation Rule Error Code Description
@NotNull [not.null] This rule validates that the validated value is not null.
@NotBlank [not.blank] This rule checks that a string value is not blank (that is, it holds some characters).
@InTheFuture [in.future] This validation rule checks that the validated date/calendar/instant occurs in the future (relative to the time of validation).
@InThePast [in.past] This validation rule checks that the validated date/calendar/instant occurred in the past (relative to the time of validation).Attributes are value that"Specifies the condition expression " and optionally, expressionScope. Defines the evaluation scope of the condition expression. global will define the validated object as the scope, while property will define the property value as the scope. Using the property scope enables the definition of conditions that apply directly on the property value (e.g. "length > 5"). The global scope enables the definition of conditions that apply on other properties of the validated object (e.g. "equals some_other_property")
@Email [email] This rule validates that a string value holds a valid email address.
@Expression [expression] This annotation represents an expression based validation rule. See Table 17.11
@Length [length] This rule checks that the range of a string's length is within specific bounds.See Table 17.13 for extra attributes
@MaxLength [max.length] This rule checks that the range of a string's length is less than or equals a specific upper bound. Must have a max attribute that "Specifies the maximum length the string value can have"
@MinLength [min.length] This rule checks that a string's length is greater than or equals a specific lower bound. Must have a value attribute that "Specifies the minimum length the string value can have"
@NotEmpty [not.empty] This rule checks that a collection/array is not empty (that is, it holds at least one element).
@size [size] This rule checks that the size of a collection/array is within specific bounds. See Table 17.16. Essentially, min and max attributes
@MinSize [min.size] This rule checks that the size of a collection/array is greater than or equals a specific lower bound. Must have a value attribute that "Specifies the minimum size of the collection or array ".
@MaxSize [max.size] This rule checks that a java.lang.Comparable value is within a specific range. Must have a value attribute that "Specifies the maximum size of the collection or array".
@Range [range] This rule checks that the size of a collection/array is less than or equals a specific bound. Must define either a min or a max attributes or both. Specify the lower and upper bounds of the range, respectively.
@Min [range] This rule checks that a java.lang.Comparable value is greater than or equals a specific lower bound. Must define a value attribute that "Specifies the lower bound of the range"
@Max [range] This rule checks that a java.lang.Comparable value is less than or equals a specific upper bound. Must define a value attribute that "Specifies the upper bound of the range"
@RegExp [regexp] This rule checks that a string value matches a specific regular expression. Must define a value attribute that "Specifies the regular expression"
@Expressions [expression] This annotation enables defining multiple @Expression annotations on a property.
@ConditionRef [spring.condition] This rule uses a condition that is defined in the application context to perform the validation check. Must define a value attribute that "Specifies the name of the condition bean as defined in the application context."

Hope this is of help to others.

Share
Categories
General

Charter school vs. Old school

Great story from the Wall Street Journal about the diverging paths of two Oklahoma City students. The article aldiscusses the effect their choice of high school had on their future. A great read.
http://online.wsj.com/article/SB10001424052748704717004575268752238805736.html

Share
Categories
General

The Motorola Dilemma; do agencies have a lesson there?

A Wall Street Journal story about Motorola's relationship with Verizon and Google yesterday made me think of the tough situation mobile phone makers are in. The company is betting on partnerships with Verizon and Google for its future. Verizon as a carrier is important, but Verizon will go wherever the next iPhone wannabe is, not caring who makes it. Google, on the other hand, is where the risk lies.

Using a common operating system is nothing new. Nokia's Symbian was used by many manufacturers successfully for almost a decade. But this common foundation, while breeding a 3rd party app developer ecosystem, drastically increases the demand to produce great hardware. If your device cannot cut it, consumers will reject it. The alternative is to ditch the common operating system and create a combined, premium software/hardware combination. Apple succeeded, Palm did not, Samsung dreams it can. In Motorola's case, its own old basic operating system survives on low-end phones, while it realizes savings from avoiding its own Linux-based operating system's development costs.

In a way Motorola has something a reason for optimism. It DID produce excellent designs in the StarTac and Razr series. But now, if the hardware is not compelling enough, it will be toast. Worse, it is relegated the ranks of generic hardware manufacturers like HTC (well, they wish they were HTC at this point), LG, Samsung and Pantech. So the key here is design. And design translates to a unique proprietary flavor. The gist of 'why would I buy this phone as opposed to the others'.

Is this a unique business situation in a specific marketplace? Not really. Retailers compete to sell the same product on shelves they think are better organized, in stores they hope are cleaner and providing service that excels beyond that offered by their competitors. Technology offers a level playing filed in creating something that a brand can say is unequivocally superior. Snappier operating system experience is one; better video playback, a great keyboard or camera, remarkable call quality and stability are others. Again – proprietary flavor, a unique business proposition, the differentiator.

Working in an agency we operate in a miasma where beloved clients who love you have 6-18 months on average in a job. The next guy will bring his own agency and you're gone. Interchangeability is the name of the game and being on par with your peers is a good and common place to be. That is the core of why the problem is similar: if your agency lacks differentiation, you will be considered, invited, known, but nothing will pop to people's minds when they think of you. If you have a good idea that services the client well, great; you might get the assignment. What is missing is that differentiator, and I look right back at that concept of 'proprietary'. Proprietary is the hook. Proprietary is what you can do, only you have access too, and is a factual advantage to you. And when the client likes that proprietary capability/service/offering – they have no choice but stick with you.

For an agency that might mean having creative that knocks the ball out of the ballpark every single time. But that's difficult to achieve and can be draining. I am a technologist. I care about building stuff. And I think an agency needs to invest (!) in building technology that is the differentiator, maybe even the foundation, for its relationship with clients. That's really challenging, and may be expensive, but can simplify customer relationship lifecycle – acquisition, retention, expansion – from the current rat race. It is a very steep slope to crawl upon. You need to discover a need, do it once, and bet on repeating it. Worse yet, the agency suddenly needs to support technology, not only customer needs. Having a product is an entirely complex ball of wax all by itself.

Do agencies have a choice to avoid it? I am not sure. You can still partner with vendors – like Motorola does with Google – but your competitors can do so too and come up with a better offering that you will. Brands are not stupid either. They are happy to go straight to startups to get their own edge and to avoid paying agency overhead. 

Therefore, agency folk, the choice is yours: become more of a startup, get your proprietary flavor, or remain adrift in a very flashy variety of a sea of gray.

Share
Share