Showing posts with label Spring MVC. Show all posts
Showing posts with label Spring MVC. Show all posts

Wednesday, March 6, 2013

Custom internationalized error messages in Spring MVC + JSR303

A very common thing to do when building an application, is using JSR303 validation annotations on your domain classes. In a Spring MVC controller, those annotated fields will get validated when calling a ResuestMapping method with an @Valid parameter. You can then easily show the generated errors in your Spring MVC form.

So far so good. Only drawback is that Spring has some default messages. Which are clear, but usually not what you want in your frontend pages. Luckily, there's an easy way to override the defaults with custom messages!

NOTE: This small guide assumes you're using Spring MVC's Internationalization in a correct way, as described here

Ok, so overriding the messages. Actually, it's fairly easy. If you want to override each and every message for @NotEmpty, you add 1 entry to your messages.properties file:

NotEmpty = This is the new default message for all NotEmpty annotations

Easy huh? Now if you want to be more specific, you can override the message for (for example) every firstname that is @NotEmpty:

NotEmpty.firstname = This is the new default message for NotEmpty annotations on firstname-fields

This will override the default message for every field named firstname. But you can even be more specific! You can define an error message for a specific field in a specific class. If you have an Employee class, with a firstname field that is annotated with @NotEmpty, you can specify a default message like this:

NotEmpty.employee.firstname = This is the new default message for the NotEmpty annotation on the firstname-field in our Employee class

There's one huge point of attention, though. The pattern of your message has to resemble the SPeL-pattern you'd use to access the field. Usually, the @Valid annotation will be on a command object. That means that in this case, our command object has to be named "employee" on the Model. If, however, you have named your command "command", you'll have to change the message key to this:

NotEmpty.command.firstname = This is the new default.

It's a pitfall, and one you can lose a lot of time with!

Monday, March 12, 2012

How to use Uploadify in Spring MVC

What is Uploadify?

www.uploadify.com
"Uploadify is a jQuery plugin that integrates a fully-customizable multiple file upload utility on your website. It uses a mixture of Javascript, ActionScript, and any server-side language to dynamically create an instance over any DOM element on a page."

So, Uploadify is a JQuery lib which allows you to upload multiple files at once onto your webpage. Uses flash for fancy animations!

Implementation

Integration

You start by downloading Uploadify and integrate it into your project. Put them in a folder and add thaty folder to mvc:resources in je servlet-context.xml.

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

Further, you need to tell Spring thatMultiPartFiles are possible:

<bean class="org.springframework.web.multipart.commons.CommonsMultipartResolver" id="multipartResolver">
  <property name="maxUploadSize" value="500000"/>
</bean>


In a Maven project, get the required libraries by adding this to your POM:

<dependency>
 <groupid>commons-fileupload</groupid>
 <artifactid>commons-fileupload</artifactid>
 <version>1.2</version>
</dependency>


Upload page

Your upload page looks like this:

<link href="../resources/uploadify/uploadify.css" rel="stylesheet" type="text/css"></link>
<script src="../resources/js/jquery16.js"></script>
<script src="../resources/uploadify/jquery.uploadify.js"></script>
<script src="../resources/uploadify/swfobject.js"></script>

<script type="text/javascript">
$(document).ready(function() {
var myFiles = new Array();
var myFileCnt = 0;
$('#file-upload').uploadify({
'swf': '../resources/uploadify/uploadify.swf',
'cancelImage': '../resources/uploadify/cancel.png',
'multi' : true,
'auto' : true,
'fileObjName' : 'filedata',
'checkExisting' : false
});
});
</script>

<input id="file-upload" name="file-upload" type="file" />


Handling

If you set auto to true, an automatic POST-request will be executed. We need to catch and handle it!

@Controller public class FileUploadController {

 @RequestMapping(method=RequestMethod.POST)
 public String handleFile(MultipartHttpServletRequest request)
 {
  MultipartFile file = request.getFile("filedata");
  //some code here
  return "fileupload/success";
 }
}


Extra parameters in request

You can add extra parameters to your request. This is not as easy as it sounds, because Uploadify creates and manages its own form. This is how I did it:
Add function to your JSP page
In Uploadify, there are a few events available that are triggered throughout the process. onSelect is one of them. It gets called every time files are selected.

onSelect : function(){
$('#file-upload').uploadifySettings(
'postData',
{'season':$('#season').val()}
);
}


Your entire script now looks as follows:

$(document).ready(function() {
var myFiles = new Array();
var myFileCnt = 0;
$('#file-upload').uploadify({
'swf': '../resources/uploadify/uploadify.swf',
'uploader': '',
'cancelImage': '../resources/uploadify/cancel.png',
'multi' : true,
'auto' : true,
'fileObjName' : 'filedata',
'checkExisting' : false,
onSelect : function(){
$('#file-upload').uploadifySettings(
'postData',
{'myParamName':$('#myFieldId').val()}
);
}
});
});


Get parameter in Controller
When you've added the parameter to the postData, as described above, you can easily get it in your Controller. Its value is now in the parametermap of your request.

String s = request.getParameter("myParamName");

If you have followed this guide and stumbled upon problems, please let me know. I'll try to keep it as correct and up-to-date as possible!