如何从 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 适配器调用片段函数

如何从 Firebase 获取所有设备令牌?

如何直接从类调用从接口继承的方法?

如何从服务器获取和设置 android 中的 API(从服务器获取 int 值)?如何绑定和实现这个

如何从Mac从android studio中的fabric注销? [复制]

如何从设备中获取 PDF 文件以便能够从我的应用程序中上传?