通过HTTP PUT请求上传文件

有没有人知道任何产品或库,如Apache Commons FileUpload将处理PUT文件上传?

任何友好的建议或方向将非常感谢!

全文:

我们开始为我们的java webapp实现文件上传rest(如)服务,但似乎没有任何“简单”的解决方案来处理通过HTTP PUT方法上传文件。

我们希望找到像Apache Commons FileUpload项目这样的库,但不仅要处理“基于表单的HTML文件上传”和/或“multipart / form-data”。

我们非常希望FileUpload能够临时存储文件,在询问时移动这些文件,然后在不再使用后清理临时文件。 我们还喜欢这样一个事实,即Spring会自动将MultipartFile List绑定到我们的命令对象,并且当它进入我们的其他基于html表单的文件上传控制器时,我们可以使用它。

全栈背景:

  • Spring MVC(3.2.3.RELEASE)
  • 雄猫7
  • 我们正在尝试遵循分层架构(UI,服务/业务逻辑,持久性)

感谢您的时间!


以下url是一个示例,显示了从请求的InputStream上载文件的function。 代码完成了工作但是生产质量不高。

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


我们使用以下curl命令来测试我们的webservice:

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

然后xwoker给出了以下漂亮的curl示例:

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

让弹簧正确响应HTTP PUT方法的文件上载请求非常容易。

只需重写自定义MultipartResolver类中的isMultipart()方法即可。

 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; } } 

真正重要的是扩展默认的MultipartResolver ,以便isMultipart()方法对POST或PUT请求返回true。

通常,有两个默认的MultipartResolver实现: CommonsMultipartResolver (与Apache Commons FileUpload一起使用)和StandardServletMultipartResolver (与Servlet 3.0+ Part API一起使用)。

由于我们使用的是Apache Commons FileUpload ,因此扩展了CommonsMultipartResolver类。

MultipartResolver的Javadoc页面上有文档说明如何为您的应用程序正确定义自定义MultipartResolver(重点是我的):

Spring DispatcherServlets没有使用默认的解析器实现 ,因为应用程序可能会选择解析其多部分请求本身。 要定义实现,请在DispatcherServlet的应用程序上下文中创建一个id为“multipartResolver”的bean。 这样的解析器将应用于该DispatcherServlet处理的所有请求。

对于xml配置的应用程序,它将看起来接近以下内容:

  

对于注释配置的应用程序,它将看起来接近以下内容:

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

有关MultipartResolver的注释配置的更多信息 。

我不知道有任何库满足您的要求。 但是如果你不介意做一些编码,我认为创造类似的东西的好方法就是自己写

 public class FileMessageConverter extends AbstractHttpMessageConverter 

将请求主体转换为tmp目录中的File:

 @Override protected File readInternal(Class 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; } 

在控制器中,您将使用以下方法定义方法:

 @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(HttpStatus.CREATED); } 

不要忘记注册FileMessageConverter,例如

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

curl命令用于调用上传:

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