Upload files via HTTP PUT request

Does anyone know of any products or libraries, such as Apache Commons FileUpload, that will handle PUT file downloads?

Any friendly advice or recommendations would be greatly appreciated!

Full story:

We are starting to implement a file upload service (for example) for our java webapp, but there seems to be no β€œsimple” solution for working with file uploads using the HTTP PUT method.

We hope to find a library, for example, Apache Commons FileUpload , but something that concerns not only the "form-based file Upload to HTML" and / or "multipart / form-data".

We really like the ability of FileUpload to temporarily store files, move them on demand, and then clean up temporary files after they are no longer used. We also like the fact that Spring will automatically bind the MultipartFile list to our command object and it is just available for us to use when it gets into our other html-based file upload controllers.

Full Screen Background:

  • Spring MVC (3.2.3.RELEASE)
  • Tomcat 7
  • We try to follow a multi-level architecture (user interface, service / business logic, persistence)

Thank you for your time!


The following URL is an example that shows the ability to load a file from an InputStream request. The code does the job, but it’s not quite a quality quality.

https://boplicity.nl/confluence/display/spring/Using+HTTP+PUT+and+Spring+MVC+to+upload+files


We use the following curl command to test our web service:

curl -v -k -X PUT --data-binary @"c:/java/files/tempfilename.txt" https://localhost:8443/api/file/tempfilename.txt 

xwoker then gave the following good example of twisting:

 curl -v -X PUT -T "myfile" http://localhost:8080/mytargetfilename 
+5
source share
2 answers

It's pretty painless to get Spring to respond correctly to the file upload request for the HTTP PUT method.

All you need to do is to override the isMultipart () method in the custom MultipartResolver class.

 import org.apache.commons.fileupload.FileUploadBase; import org.apache.commons.fileupload.servlet.ServletRequestContext; import javax.servlet.http.HttpServletRequest; public class PostAndPutCommonsMultipartResolver extends CommonsMultipartResolver { private static final String POST_METHOD = "POST"; private static final String PUT_METHOD = "PUT"; @Override public boolean isMultipart(HttpServletRequest request) { boolean isMultipartRequest = false; if (request != null) { if (POST_METHOD.equalsIgnoreCase(request.getMethod()) || PUT_METHOD.equalsIgnoreCase(request.getMethod())) { isMultipartRequest = FileUploadBase.isMultipartContent(new ServletRequestContext(request)); } } return isMultipartRequest; } } 

What really matters is that MultipartResolver is extended by default, so the isMultipart () method will return true for a POST or PUT request.

In general, there are two default implementations of MultipartResolver: CommonsMultipartResolver (used with Apache Commons FileUpload) and StandardServletMultipartResolver (used with Servlet 3. 0+ Part API).

Since we are using Apache Commons FileUpload , we have expanded the CommonsMultipartResolver class.

The MultipartResolver Javadoc page has documentation that explains how to correctly define the custom MultipartResolver for your application (selection added):

For Spring, there is no default DispatcherServlets recognizer implementation , since an application can parse it. Multipart asks for itself. To define an implementation, create a component with the identifier "multipartResolver" in the DispatcherServlet application context. Such a resolver applies to all requests processed by this DispatcherServlet.

For an application configured for XML, it will look something like this:

 <bean id="multipartResolver" class="<package>.<name>.PostAndPutCommonsMultipartResolver"/> 

For an application configured for annotations, it will look like this:

 @Bean(name = "multipartResolver") public CommonsMultipartResolver createMultipartResolver() { return new PostAndPutCommonsMultipartResolver(); } 

Additional configuration information for MultipartResolver annotations .

+8
source

I do not know which libraries meet your requirements. But if you don't mind doing some kind of coding, I think a good way to create something like this is to write your own

 public class FileMessageConverter extends AbstractHttpMessageConverter<File> 

which converts the request body to a file in the tmp directory:

 @Override protected File readInternal(Class<? extends File> clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException { InputStream inputStream = inputMessage.getBody(); File tmpFile = File.createTempFile("upload","tmp"); if (inputStream != null) { FileOutputStream outputStream = new FileOutputStream(tmpFile); byte[] buffer = new byte[1024]; int bytesRead; while ((bytesRead = inputStream.read(buffer)) > 0) { outputStream.write(buffer, 0, bytesRead); } outputStream.flush(); outputStream.close(); } return tmpFile; } 

In the controller, you define your method with:

 @RequestMapping(value="/{fileName}", method = RequestMethod.PUT) public ResponseEntity uploadFile(@PathVariable(value="fileName") String fileName, @RequestBody File tmpFile) throws IOException { // .. process tmpFile, eg tmpFile.renameTo(new File(fileName); return new ResponseEntity<String>(HttpStatus.CREATED); } 

Remember to register your FileMessageConverter, for example

 @Configuration @EnableWebMvc @ComponentScan(basePackages = {"my.controller.package"}) public class WebConfig extends WebMvcConfigurerAdapter { @Override public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { converters.add(new FileMessageConverter()); } } 

The curl command to invoke the boot:

 curl -v -X PUT -T "myfile" http://localhost:8080/mytargetfilename 
+1
source

Source: https://habr.com/ru/post/1501553/


All Articles