Spring : Using HTTP PUT and Spring MVC to upload files

This page last changed on Nov 13, 2008 by Kees de Kooter

Intro

In the days of RESTful buzz I decided to give file uploading using the proper verb a shot. Googling did not give any useful spring/java related information. But maybe that is because the word "put" is so common.

So I ended up digging through javadocs and went back to the raw servlet basics. It turned out that just flushing the body of the request to disk did the trick.

The Spring MVC controller

@Controller
@RequestMapping(value = "/put/**/*", method = RequestMethod.PUT)
public class PutController {

    private final Log log = LogFactory.getLog(getClass());

    @Autowired
    private UrlParser urlParser;

    @RequestMapping
    public void put(HttpServletRequest request, HttpServletResponse response) {

        try {
            InputStream inputStream = request.getInputStream();

            if (inputStream != null) {
                String filePath = urlParser.getFilePath(request.getRequestURI());
                FileOutputStream outputStream = new FileOutputStream(new File(filePath));

                byte[] buffer = new byte[1024];
                int bytesRead;

                while ((bytesRead = inputStream.read(buffer)) > 0) {
                    outputStream.write(buffer, 0, bytesRead);
                }

                outputStream.flush();

                log.info("Put file " + filePath);
            }
        } catch (FileNotFoundException e) {
            log.error(e.toString(), e);
        } catch (IOException e) {
            log.error(e.toString(), e);
        } catch (UrlParseException e) {
            log.error(e.toString(), e);
        }
    }
}

The client code

The client consuming this service uses commont-httpclient to call the put method. The code is even simpler than the server side code.

    public void put(String targetDirectory, File file) {

        PutMethod method = new PutMethod("/updateserver/put/" + targetDirectory + "/" + file.getName());

        method.setRequestEntity(new FileRequestEntity(file, "application/octet-stream"));

        try {
            httpClient.executeMethod(method);
        } catch (IOException e) {
            log.error(e.toString(), e);
        } catch (Exception e) {
            log.error(e.toString(), e);
        }
    }