Tag Archives: Spring

Spring 3.1 Server side validation for AJAX request using @Valid and @RequestBody

21 Feb

A recent task of mine was to implement server side validation on a REST Web app that saves all of it’s form data via an Ajax POST or PUT request. Many of the form fields in the app are dynamically created so a binding between the jsp form and the Model object could not be easily created.

A general Controller method (pre-validation)  looks like this:

@RequestMapping(value="/user", method = RequestMethod.POST)
@ResponseBody
public User createNewUser(@RequestBody User user) {
    // Logic goes here
}

Step 1: Import the relevant libraries into your app

You’ll need javax.validation and Hibernate Validator. I’ve used Maven to manage my dependencies.

<!-- Server-side Validation -->
<dependency>
    <groupId>javax.validation</groupId>
    <artifactId>validation-api</artifactId>
    <version>1.0.0.GA</version>
</dependency>
    <dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>4.2.0.Final</version>
</dependency>

Step 2: Add the relevant validation rules to your DTO.

Validation rules or “constraints” can be added directly to the relevant field in the form of an annotation.

You can use both:

public class User {

    @NotBlank
    @Size(max = 50)
    private String firstName;

    @Size(max = 50)
    private String lastName;

    @Email
    private String emailAddress;
}

Step 3: Mark your Object as an item that requires validating

Mark the object that needs to be validated with the @Valid annotation in the Controller method signature.

@RequestMapping(value="/user", method = RequestMethod.POST)
@ResponseBody
public User createNewUser(@Valid @RequestBody User user, Model model ) {
    // Logic goes here
}

Now, at this point if you try to trigger server side validation you’ll get a http 400 error, and if you run your application in debug mode you will notice that the error occurs at the method signature of your Controller method. This is how Spring is handling the validation error by default. If you try and handle the validation error within the original Controller method requested, you won’t get the chance to.

So, onto the next step…

Step 4: Add an exception handler so you can add some smarts to redisplay the errors to your user

In this example code, I’ve chosen to use a Set to store the error messages because I don’t want duplicate messages to be returned. However, depending on your app and your current set up, you may choose to handle errors a different way.

@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseBody
public ValidationError handleValidationException(MethodArgumentNotValidExceptionexception) {
    Set<ValidationError> errors = new HashSet<ValidationError>();
    for (ObjectError er : exception.getBindingResult().getAllErrors()) {
        errors.add(new ValidationError(er.getObjectName(), er.getDefaultMessage()));
    }

    return new ValidationErrorResponse(errs);

}

Step 5: Display the error to your user

Now, you might want to get a bit more sophisticated with your errors, but at this point I am just happy to display the validation messages in one go.
I’m using jQuery to handle my Ajax requests.

Assuming the ValidationErrorResponse class has a field “errorMessages”

// Function that Makes Ajax call
function doesSomeStuff() {
    $.ajax({
        type: "POST",
        url: "some/url/in/your/app",
       // ... etc ...
        error: function(data) {
            if (data.errorMessages != null) {
                handleAjaxError(data);
                return;
            }
            // ... etc ...
        }
    });
}

// function that handles ajax error
function handleAjaxError(data) {
        var $errorMessageArea = $("#errorMessageArea");
        for(var i = 0; i < data.errorMessages.length; i++) {
            // append the current error message to the element on the web page
            $errorMessageArea.append($("<li />", { text: data.errorMessages[i] }));
        }
    }
}

Spring MVC 3: Getting a 404 for a mapped static resource

18 Aug

Spring Mvc 3 has introduced a simpler way to map static resources so that you don’t have to handle requests for static content yourself. In it’s simplest form, it looks something like this:

<mvc:resources mapping="/resources/**" location="/resources/" />

Full details in the Spring 3 Documentation: http://static.springsource.org/spring/docs/3.0.x/reference/mvc.html#mvc-static-resources.

It looks like it should be simple to implement, and for the most part it is; however, I did have a bit of trouble figuring out why I was getting a 404 error when trying to access mystylesheet.less (Less Css is awesome, check it out here: http://lesscss.org/).

Turns out that because I was using a file with an extension that you wouldn’t normally be considered as a web resource, I had to add the following configuration to my web.xml:

<mime-mapping>
<extension>less</extension>
<mime-type>text/css</mime-type>
</mime-mapping>

Probably a no-brainer for most, but I’m relatively new to the world of jsp and I would have found a post like this useful, so here I am sharing my new found knowledge!