如何从 Servlet3SecurityContextHolderAwareRequestWrapper 中获取 MultipartRequest
Posted
技术标签:
【中文标题】如何从 Servlet3SecurityContextHolderAwareRequestWrapper 中获取 MultipartRequest【英文标题】:How do I get a MultipartRequest out of a Servlet3SecurityContextHolderAwareRequestWrapper 【发布时间】:2014-11-02 08:49:11 【问题描述】:我正在使用 Grails 2.4.3,我有一个 <g:uploadForm>
方法设置为发布,但我的控制器操作中没有收到 MutlipartRequest。相反,我得到了一个没有 getFile()
方法的 Servlet3SecurityContextHolderAwareRequestWrapper 。我尝试过强制转换,我尝试使用request.request
将请求从包装器中取出,并且我尝试了许多其他我看到的其他类似问题的建议,但仍然没有骰子。我确定我错过了一些简单的东西。我倾向于这样做,但如果有人能指出我正确的方向,我将不胜感激。
这是我的表格:
<g:uploadForm method="POST" action="uploadSupplemental" >
<div class="modal-header">
<h3 class="modal-title" id="myModalLabel">Upload Supplemental Data File</h3>
</div>
<div class="modal-body">
<label for="fileInput">Choose file to upload:</label>
<input type="file" id="fileInput" name="supplementalData" />
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
<input type="submit" class="btn btn-primary" />
</div>
</g:uploadForm>
这是我的控制器操作:
def uploadSupplemental()
MultipartRequest multipartRequest = request as MultipartRequest
def file = multipartRequest.getFile('supplementalData')
if (file)
flash.message = "File found!!"
else
flash.message = "File NOT found. :-( "
redirect action:'list'
这是我得到的错误:
URI /app/upload/upload 补充类 groovy.lang.MissingMethodException 消息没有方法签名: org.springframework.security.web.servletapi.HttpServlet3RequestFactory$Servlet3SecurityContextHolderAwareRequestWrapper.getFile() 适用于参数类型:(java.lang.String) 值: [supplementalData] 可能的解决方案:getXML(), getPart(java.lang.String), getAt(java.lang.String), getAt(java.lang.String), getLocale(), getJSON()
【问题讨论】:
更多信息:我第一次访问请求时,在我的控制器操作中,请求的类型为:org.springframework.security.web.servletapi.HttpServlet3RequestFactory$Servlet3SecurityContextHolderAwareRequestWrapper。如果我对此调用 getRequest(),我会得到一个 org.springframework.security.web.context.HttpSessionSecurityContextRepository$Servlet3SaveToSessionRequestWrapper。仍然是一个包装器,所以我调用 getRequest 并获得一个 org.springframework.security.web.firewall.RequestWrapper,另一个包装器。 (续...) 再调用一次 org.springframework.security.web.firewall.RequestWrapper.getRequest 给我一个 org.apache.catalina.core.ApplicationHttpRequest。所以我终于有了一个请求对象,但它不是应该的 MultipartRequest。还是被难住了。Config.groovy
中设置的grails.web.disable.multipart
的值是多少?这是一个相关的JIRA issue 和一个duplicate question in SO 报告相同的异常。还要确保在上传操作之前对用户进行身份验证。控制器中使用@Secured
是肯定的。
@dmahapatro,成功了。谢谢!你能把这个变成答案吗?
完成。很高兴挖掘很有帮助。 :)
【参考方案1】:
为了启用多部分请求,必须在Config.groovy
中将以下配置属性设置为true
。
grails.web.disable.multipart=true
这是一个 related JIRA issue 和 a duplicate question in SO 报告相同的异常。
还要确保在上传操作之前用户已通过身份验证(使用@Secured
)。
【讨论】:
这个解决方案对我不起作用,但我没有安全注释,但我也得到了 HttpServlet3RequestFactory$Servlet3SecurityContextHolderAwareRequestWrapper。一个想法如何解决这个问题?注意:上传适用于桌面设备,但不适用于移动设备【参考方案2】:我在我的 grails 应用程序中遇到了完全相同的错误,并提出了以下解决方案:
我的应用程序中请求实例的类型与到达服务器的 HTTP 帖子中的内容类型属性有关。所以,如果我在一个带有 enctype 属性设置的表单中有一个文件输入......
<form enctype="multipart/form-data" action="upload" method="POST">
...我收到了预期的 MutlipartRequest,并且可以调用request.getFile()
获取上传的文件。
但是,如果 HTTP 帖子的内容类型为“application/octet-stream”(就像我们使用 Valum 的 AJAX File-Uploader 上传单个文件时一样),那么请求本身就是一个二进制文件,并且可以通过调用 request.getInputStream()
将其转换为 InputStream。
因此,如果您不确定您的应用中使用的是什么内容类型,我建议您使用诸如 firebug 之类的浏览器工具进行检查,并尝试使用request.getInputStream()
直接从请求中获取文件。
See the diference between content-type and enctype
【讨论】:
以上是关于如何从 Servlet3SecurityContextHolderAwareRequestWrapper 中获取 MultipartRequest的主要内容,如果未能解决你的问题,请参考以下文章
如何将数据从回收器适配器发送到片段 |如何从 recyclerview 适配器调用片段函数
如何从服务器获取和设置 android 中的 API(从服务器获取 int 值)?如何绑定和实现这个