Raging Goblin

16 May 2013

Spring Roo 9: Uploading images 2 (store images on filesystem)

Filed under: Java,Spring Roo — Raging Goblin @ 20:39
Tags: ,

From the previous blog it is pretty easy to guess how to do this, but here is the recipe as promised to upload images and store them on the file system. As the images are not stored in the database you can use MySQL for this as well.

Step 1: Add maven dependencies
Same as previous.

Step 2: Add properties to the ‘LogItem’

private String contentType;
private String path;
@Transient
private CommonsMultipartFile image;

Note here that the image is added as a CommonsMultipartFile, exactly as it is received by Spring, but it is marked @Transient which will prevent it from entering the database. Besides this a path is added to enable us to retrieve the image later.

Step 3: Update create.jspx to send a MultipartFile
Like in step 3 of the previous post, the form to create a LogItem is adjusted to our needs:

<?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: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" render="false" z="user-managed"/>
        <field:input field="path" id="c_raging_goblin_roo_domain_LogItem_path" z="P0zJQZkpJ19wRptpdaKLWSTr/BU=" render="false"/>
    </form:create>
    <form:dependency dependencies="${dependencies}" id="d_raging_goblin_roo_domain_LogItem" render="${not empty dependencies}" z="Qbb30wyy/eoxYyR+b/J66Ec1Lxw="/>
</div>

Edit 17-07-2013: See next post how to handle updates to an image.

Step 4: Update input.tagx to handle type=”file”
If you have not done so yet, adjust it as described in step 4 earlier.

Step 5: Add a method to the controller to send the actual image
Images are now loaded from the filesystem, to be precise from the path field:

@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 && logItem.getPath() != null) {
		try {
			OutputStream out = response.getOutputStream();
			response.setContentType(logItem.getContentType());
			Files.copy(FileSystems.getDefault().getPath(logItem.getPath()),
					out);
			out.flush();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	return null;
}

Step 6: Change create and update methods of LogItemController to save image to the filesystem
The create and update methods now should store the image on the filesystem. With the new file-io of Java 7 this has never been easier.

@RequestMapping(method = RequestMethod.POST, produces = "text/html")
public String create(@Valid LogItem logItem, BindingResult bindingResult,
		Model uiModel, HttpServletRequest httpServletRequest) {
	if (bindingResult.hasErrors()) {
		populateEditForm(uiModel, logItem);
		return "logitems/create";
	}
	uiModel.asMap().clear();

	CommonsMultipartFile image = logItem.getImage();
	if (image != null) {
		File file = new File(image.getOriginalFilename());
		try {
			image.transferTo(file);
			logItem.setContentType(image.getContentType());
			logItem.setPath(file.getAbsolutePath());
		} catch (Exception e) {
			e.printStackTrace();
			return "logitems/create";
		}
	}
	logItem.persist();
	return "redirect:/logitems/"
			+ encodeUrlPathSegment(logItem.getId().toString(),
					httpServletRequest);
}

Note that the images will end up in the same directory where your webapp is running. This is something you probably wouldn’t do on a production system.

Step 7: Give webserver write access to the filesystem
Take care that the directory where you want to save the images is write-enabled for the webserver. Ok, I admit this is not really a decent step, but I just wanted to keep the numbering the same as in the previous post and this is the best I could come up with ;).

Step 8: Update show.jspx to display the image
The artificial step 7 allows me now to just redirect you to the previous step 8.

Advertisements

4 Comments »

  1. Hello, in step 5 ” Files.copy(FileSystems.getDefault().getPath(logItem.getPath()),out);” as I can do it con java 6 ?

    Comment by Jean — 20 June 2013 @ 17:05 | Reply

  2. IOUtils.copy or other method?? would greatly appreciate your response

    Comment by Jean — 20 June 2013 @ 18:57 | Reply

    • Yes, I would certainly go for IOUtils from Apache or Guave from Google. Otherwise you have to read bytes from inputstream and write them to ouputstream which is very cumbersome, verbose and ugly.

      Comment by raginggoblin — 28 June 2013 @ 13:52 | Reply

  3. […] my previous blog about uploading images I left it to the reader to come up with a solution for updating an image […]

    Pingback by Spring Roo 10: Update images | Raging Goblin — 17 July 2013 @ 20:23 | 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 )

Twitter picture

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

Facebook photo

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

Google+ photo

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

Connecting to %s

Create a free website or blog at WordPress.com.

%d bloggers like this: