java Spring MVC中带有文件上传和表单数据的RESTful PUT
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12616928/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
RESTful PUT with file upload and form data in Spring MVC
提问by adarshr
I am using Spring MVC to expose some RESTful web services. One of the operations calls for a RESTful PUT operation when a form is submitted.
我正在使用 Spring MVC 来公开一些 RESTful Web 服务。其中一项操作会在提交表单时调用 RESTful PUT 操作。
However, the form is no ordinary form in that it contains a file input along with regular inputs such as text and checkboxes.
但是,该表单不是普通表单,因为它包含一个文件输入以及诸如文本和复选框之类的常规输入。
I have configured Spring to work with RESTful PUT and DELETE by adding the HiddenHttpMethodFilter
in the web.xml
. In my forms, i have a hidden _method
parameter being sent as well.
我已经通过HiddenHttpMethodFilter
在web.xml
. 在我的表单中,我也_method
发送了一个隐藏参数。
All this works fine for DELETE, PUT without file upload, etc. When I try to do a PUT with file upload and form data, it gives me a 405
.
所有这些都适用于 DELETE、不上传文件的 PUT 等。当我尝试使用文件上传和表单数据执行 PUT 时,它给了我一个405
.
HTTP Status 405 - Request method 'POST' not supported
My controller method looks like this:
我的控制器方法如下所示:
@RequestMapping(value = "/admin/cars/{carId}", method = PUT, headers = "content-type=multipart/form-data")
public String updateCar(@PathVariable("carId") String carId, CarForm form) {
// save and return the right view.
}
My HTML form looks like this:
我的 HTML 表单如下所示:
<form action="<c:url value='/admin/cars/${car.id}'/>" method="POST" enctype="multipart/form-data">
<input type="hidden" name="_method" value="PUT" />
<input type="text" name="carName" value="${car.name}" />
<input type="file" name="photo" />
<input type="submit" />
</form>
Is what I am trying to achieve doable at all using PUT? If so, how to make Spring MVC understand that?
我试图使用 PUT 实现的目标是可行的吗?如果是这样,如何让 Spring MVC 理解这一点?
回答by Xaerxess
Add MultipartFilter
to enable file uploads beforeHiddenHttpMethodFilter
in your web.xml (as written in HiddenHttpMethodFilter
API docs, see NOTE).
添加之前在您的 web.xml 中MultipartFilter
启用文件上传(如API 文档中所述,请参阅注意)。HiddenHttpMethodFilter
HiddenHttpMethodFilter
Also:
还:
Note: This filter is an alternative to using
DispatcherServlet
'sMultipartResolver
support, for example for web applications with custom web views which do not use Spring's web MVC, or for custom filters applied before a Spring MVCDispatcherServlet
(e.g.HiddenHttpMethodFilter
). In any case, this filter should not be combined with servlet-specific multipart resolution.
注:该过滤器是使用替代
DispatcherServlet
的MultipartResolver
支持,例如用于与不使用Spring的web MVC,自定义Web视图的Web应用程序或为Spring MVC的前应用自定义过滤器DispatcherServlet
(如HiddenHttpMethodFilter
)。无论如何,此过滤器不应与特定于 servlet 的多部分解析结合使用。
(from MF's docs, emphasis mine)
(来自 MF 的文档,重点是我的)
Also, MultipartResolver
's bean name must be filterMultipartResolver
in order to MultipartFilter run properly(or must be set via <init-param>
).
此外,MultipartResolver
的 bean 名称必须是filterMultipartResolver
为了 MultipartFilter 正确运行(或必须通过 设置<init-param>
)。
EDIT:
编辑:
As I expected in my last comment, there's an issue with (Actually, The method in the isMultipartContent comes in as POST even though it is a PUT as the MultipartFilter is declared before the HiddenHttpMethodFilter.as OP notes.) Below is extednded class with slighlty modified static method it uses originally:CommonsMultipartResolver
which supports only POST method by default.
正如我在上一条评论中所预期的那样,(实际上,isMultipartContent 中的方法以 POST 形式出现,即使它是 PUT,因为 MultipartFilter 在 HiddenHttpMethodFilter 之前声明。正如 OP 注释。)下面是扩展类,它最初使用的是经过轻微修改的静态方法:CommonsMultipartResolver
默认情况下仅支持 POST 方法存在问题。
public class PutAwareCommonsMultipartResolver extends CommonsMultipartResolver {
private static final String MULTIPART = "multipart/";
@Override
public boolean isMultipart(HttpServletRequest request) {
return request != null && isMultipartContent(request);
}
/**
* Utility method that determines whether the request contains multipart
* content.
*
* @param request The servlet request to be evaluated. Must be non-null.
*
* @return <code>true</code> if the request is multipart; {@code false}
* otherwise.
*
* @see ServletFileUpload#isMultipartContent(HttpServletRequest)
*/
public static final boolean isMultipartContent(HttpServletRequest request) {
final String method = request.getMethod().toLowerCase();
if (!method.equals("post") && !method.equals("put")) {
return false;
}
String contentType = request.getContentType();
if (contentType == null) {
return false;
}
if (contentType.toLowerCase().startsWith(MULTIPART)) {
return true;
}
return false;
}
}
回答by Michael-O
Actually, PUT
receives a binary stream and not multipart data. You can use org.springframework.web.filter.HiddenHttpMethodFilter
to make it work.
实际上,PUT
接收的是二进制流而不是多部分数据。您可以使用org.springframework.web.filter.HiddenHttpMethodFilter
它来使其工作。
回答by Jean-Christophe
If anyone is interested in an alternative solution (MultipartResolver with PUT method), to enforce Restful style for instance, you may have a look at Spring 3.0 FileUpload only with POST?.
如果有人对替代解决方案(带有 PUT 方法的 MultipartResolver)感兴趣,例如强制执行 Restful 风格,您可以查看Spring 3.0 FileUpload only with POST?.