Raging Goblin

5 May 2013

Spring Roo 8: Uploading images 1 (store images as blob in database)

Here is some hard gained knowledge. How to provide the possibility to upload (and view) images to a Spring Roo website. It took me quite a while to understand how to do this and I will describe 2 ways of doing it. In this post I will show a method with storing the image as a byte-array in the database, in the next one I will describe how to store the images on disk. Each method has it’s own benefits so take your pick. The reference is our logbook application introduced in previous posts. For some reason I never have been able to get this working with MySQL, it will generate a tinyblob field which is not capable of storing my images, and using @Lob on the field causes a java.lang.AbstractMethodError: org.apache.commons.dbcp.DelegatingPreparedStatement.setBinaryStream(ILjava/io/InputStream;J). I don’t know how to solve this, so we switch to PostgreSQL. This might be a better choice anyway as I am not a particular fan of dinosaurs like Larry Ellison or Steve Ballmer. Now take care that PostgreSQL is a completely different beast than MySQL. Try to setup your database properly with the proper owner and access rights on the server and the database itself before you continue. I will not tell you how to do that as there is plenty of stuff about this on the internet and I don’t want to deprive you of a fine ‘cursing and banging your head against a wall’ adventure.

Edit 17-05-2013: See comments below, update commons-dbcp to version 1.4 and you will do fine with MySQL as well.

To start with the most simple method, here are the steps needed to store the images as blobs in the database:

Step 1: Add maven dependencies
To handle uploads Spring relies on 2 dependencies: commons-fileupload.jar and commons-io.jar. The first one is already in the pom, so only the latter should be added:


If you use the STS, right click on your project and update the maven dependencies.

Step 2: Add properties to the ‘LogItem’

private byte[] image;
private String contentType;

Take care that the Roo shell is running, you will notice that Roo updates the views and the ApplicationConversionFactoryBean as needed.

Step 3: Update create.jspx to send a MultipartFile
The view for creating a LogItem (~/src/main/webapp/WEB-INF/views/logitems/create.jspx) should be manually adjusted to provide an upload field:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<div xmlns:c="http://java.sun.com/jsp/jstl/core" xmlns:field="urn:jsptagdir:/WEB-INF/tags/form/fields" xmlns:form="urn:jsptagdir:/WEB-INF/tags/form" xmlns:jsp="http://java.sun.com/JSP/Page" xmlns:spring="http://www.springframework.org/tags" version="2.0">
    <jsp:directive.page contentType="text/html;charset=UTF-8"/>
    <jsp:output omit-xml-declaration="yes"/>
    <form:create id="fc_raging_goblin_roo_domain_LogItem" modelAttribute="logItem" multipart="true" path="/logitems" render="${empty dependencies}" z="user-managed">
        <field:input field="message" id="c_raging_goblin_roo_domain_LogItem_message" z="apnKidZldiFISmA4Q9pumki/o6Q="/>
        <field:datetime dateTimePattern="${logItem_creationdate_date_format}" field="creationDate" id="c_raging_goblin_roo_domain_LogItem_creationDate" z="p5GCO6w9q76CIDoEn17xbZPqlT0="/>
        <field:select field="logUser" id="c_raging_goblin_roo_domain_LogItem_logUser" itemValue="id" items="${logusers}" path="/logusers" z="RJfGPnxQnmkMqPwvKANgyfbJA6g="/>
        <field:input field="image" id="c_raging_goblin_roo_domain_LogItem_image" type="file" z="user-managed"/>
        <field:input field="contentType" id="c_raging_goblin_roo_domain_LogItem_contentType" z="user-managed" render="false"/>
    <form:dependency dependencies="${dependencies}" id="d_raging_goblin_roo_domain_LogItem" render="${not empty dependencies}" z="Qbb30wyy/eoxYyR+b/J66Ec1Lxw="/>

Note several changes here: multipart=”true” on the form tag, type=”file” on the field tag for the image and render=”false” on the contentType tag. Spring Roo will adjust the z values to user-managed for us, but you can do this yourself as well. Change the update.jspx in the same way. I also removed the image and contentType from list.jspx by setting render=”false” on those columns.
Edit 17-05-2013: See later post on how to update an image.

Step 4: Update input.tagx to handle type=”file”
In the previous step we added type=”file” to the input fields of the images, but this field actually does nothing with this parameter, so add

<c:when test="${type eq 'file'}">
   <form:input type="file" id="_${sec_field}_id" path="${sec_field}" disabled="${disabled}" />

to this tag (~/src/main/webapp/WEB-INF/tags/form/fields/input.tagx) just above the line ‘<c:when test=”${type eq ‘password’}”>’.

Step 5: Add a method to the controller to send the actual image
In order to send the actual image to the browser we need to add an extra REST mapping to the LogItemController. Add the following method:

@RequestMapping(value = "/{id}/image", method = RequestMethod.GET)
	public String showImage(@PathVariable("id") Long id, HttpServletResponse response, Model model) {
		LogItem logItem = LogItem.findLogItem(id);
		if (logItem != null) {
			byte[] image = logItem.getImage();
			if (image != null) {
				try {
					OutputStream out = response.getOutputStream();
					IOUtils.copy(new ByteArrayInputStream(image), out);
				} catch (Exception e) {
		return null;

This will take care of sending the image when you browse to an url like http://localhost:8080/logbook/logitems/1/image. Note that I just added /image to the standard url mapping of a LogItem.

Step 6: Change create and update methods of LogItemController to set contentType
Copy the create method from the aspect to the java file and wait to let Roo update the aspect. Than add a parameter and store the contentType:

    @RequestMapping(method = RequestMethod.POST, produces = "text/html")
    public String create(@Valid LogItem logItem, BindingResult bindingResult, Model uiModel, 
    		@RequestParam("image") MultipartFile multipartFile,
    		HttpServletRequest httpServletRequest) {
        if (bindingResult.hasErrors()) {
            populateEditForm(uiModel, logItem);
            return "logitems/create";
        return "redirect:/logitems/" + encodeUrlPathSegment(logItem.getId().toString(), httpServletRequest);

You will have to edit the update method in a similar fashion.

Step 7: Add a PropertyEditor to the LogItemController
At this moment Spring will send a CommonMultipartFile to the controller, but the type of the image is a byte-array. Spring will fail with a IllegalArgumentException (Failed to convert property value of type org.springframework.web.multipart.commons.CommonsMultipartFile to required type byte[] for property image). Spring however comes very conveniently with a PropertyEditor to handle this conversion. Register this in the LogItemController:

	protected void initBinder(HttpServletRequest request,
			ServletRequestDataBinder binder) throws ServletException {
				new ByteArrayMultipartFileEditor());

Step 8: Update show.jspx to display the image
To display an image add a standard HTML img tag to show.jspx:

<img src="${logitem.id}/image" height="256px"/>


Good luck!


  1. http://viralpatel.net/blogs/spring-roo-save-read-blob-object-spring-roo-tutorial/
  2. http://gadgets.coolman.ca/multipart-file-upload-spring-roo/
  3. http://whyjava.wordpress.com/tag/spring-roo/


  1. […] the previous blog it is pretty easy to guess how to do this, but here is the recipe as promised to upload images and […]

    Pingback by Spring Roo 9: Uploading images 2 (store images on filesystem) | Raging Goblin — 16 May 2013 @ 20:39 | Reply

  2. I found an issue when I generate project used spring roo, it generate a dbcp1.3 jar file to me, so when I use @Lob mapping field, I took a exception:org.apache.commons.dbcp.DelegatingPreparedStatement.setBinaryStream(ILjava/io/InputStream;J)V
    I took one day find the reason, but google have pool information on it, finally I find some useful information on apache dbcp project page:
    DBCP 1.4 binaries should be used by applications running under JDK 1.6.
    DBCP 1.3 should be used when running under JDK 1.4 or 1.5.
    so I change the version to 1.4, everything working ok.

    Comment by Gustavo Matias — 17 May 2013 @ 06:23 | Reply

  3. Hi, Thanks for the Tutorial.
    I run it successfully. Here I have question about update Blob in DB by Spring Roo. You disable the update in above code. Bu I am interested in how to update Blob in DB by Spring Roo. DO you have any investigation on update?

    Comment by karen85 — 17 July 2013 @ 14:28 | Reply

  4. what about list? how to add custom column of type image?

    Comment by dit j. — 15 July 2014 @ 16:05 | Reply

    • Unfortunately this is not supported, you will have to create the table yourself from scratch. Then you can do something like this:

      <img alt="${imageItemName} ${item.id}" src="/application/items/${item.id}/image" style="max-height:16px;" />

      Comment by raginggoblin — 19 July 2014 @ 10:32 | Reply

  5. […] (参考)https://raginggoblin.wordpress.com/2013/05/05/spring-roo-8-uploading-images/ […]

    Pingback by SpringRoo開発(1) | 読書と開発人生 — 9 August 2014 @ 09:28 | Reply

  6. It works properly to create and show LogItem, but I have issue to update the entity!
    org.hibernate.PersistentObjectException: detached entity passed to persist

    Comment by Mohammad Namvar — 11 September 2014 @ 23:28 | Reply

RSS feed for comments on this post. TrackBack URI

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Create a free website or blog at WordPress.com.

%d bloggers like this: