有没有人知道像Apache Commons FileUpload这样的产品或库会处理PUT文件上传?
非常感谢任何友好的建议或指示!
全文:
我们开始为我们的java webapp实现文件上传休息(如)服务,但似乎没有任何“简单”的解决方案来处理通过HTTP PUT方法上传文件。
我们希望找到像Apache Commons FileUpload项目这样的库,但不仅要处理“基于表单的HTML文件上传”和/或“multipart / form-data”。
我们非常希望FileUpload能够临时存储文件,在询问时移动这些文件,然后在不再使用后清理临时文件。我们还喜欢这样一个事实,即Spring会自动将MultipartFile List绑定到我们的命令对象,并且当它进入我们的其他基于html表单的文件上传控制器时,我们可以使用它。
完整堆栈背景:
感谢您的时间!
以下网址是一个示例,显示了从请求的InputStream上传文件的功能。代码完成了工作,但生产质量不高。
https://boplicity.nl/confluence/display/spring/Using+HTTP+PUT+and+Spring+MVC+to+upload+files
我们使用以下curl命令来测试我们的web服务:
curl -v -k -X PUT --data-binary @"c:/java/files/tempfilename.txt" https://localhost:8443/api/file/tempfilename.txt
然后,xwoker给出了以下很好的卷曲示例:
curl -v -X PUT -T "myfile" http://localhost:8080/mytargetfilename
答案 0 :(得分:7)
很容易让Spring能够正确响应HTTP PUT方法的文件上传请求。
只需覆盖自定义isMultipart()课程中的MultipartResolver方法。
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's Javadoc页面上有文档说明如何为您的应用程序正确定义自定义MultipartResolver(重点是我的):
没有用于Spring的默认解析器实现 DispatcherServlets ,作为应用程序可能会选择解析它 multipart请求自己。要定义实现,请创建一个bean 在DispatcherServlet的应用程序中使用id“multipartResolver” 上下文。这样的解析器将应用于由此处理的所有请求 DispatcherServlet的。
对于xml配置的应用程序,它将看起来接近以下内容:
<bean id="multipartResolver" class="<package>.<name>.PostAndPutCommonsMultipartResolver"/>
对于注释配置的应用程序,它将看起来接近以下内容:
@Bean(name = "multipartResolver")
public CommonsMultipartResolver createMultipartResolver() {
return new PostAndPutCommonsMultipartResolver();
}
More information on Annotation configuration of MultipartResolver
答案 1 :(得分:1)
我不知道有任何库满足您的要求。但是如果你不介意做一些编码,我认为创造类似东西的好方法就是编写你自己的
public class FileMessageConverter extends AbstractHttpMessageConverter<File>
将请求主体转换为tmp目录中的File:
@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;
}
在控制器中,您可以使用以下方法定义方法:
@RequestMapping(value="/{fileName}", method = RequestMethod.PUT)
public ResponseEntity uploadFile(@PathVariable(value="fileName") String fileName, @RequestBody File tmpFile) throws IOException {
// .. process tmpFile, e.g. tmpFile.renameTo(new File(fileName);
return new ResponseEntity<String>(HttpStatus.CREATED);
}
不要忘记注册FileMessageConverter,例如
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = {"my.controller.package"})
public class WebConfig extends WebMvcConfigurerAdapter {
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(new FileMessageConverter());
}
}
调用上传的curl命令:
curl -v -X PUT -T "myfile" http://localhost:8080/mytargetfilename