【问题标题】:GWT's getResults() of SubmitCompleteEvent returns null after submitting form with FileUpload使用 FileUpload 提交表单后,GWT 的 SubmitCompleteEvent 的 getResults() 返回 null
【发布时间】:2017-11-24 01:03:31
【问题描述】:

在一个应用程序中使用GWT 成功实现文件上传后,我尝试将其传输到另一个应用程序,但无法在提供的SubmitCompleteHandler 中检索从上传servlet 返回的字符串。 SubmitCompleteEvent.getResults() 只是返回 null。

返回 null 的一个典型原因似乎是上传的 servlet 位于不同的域中。但由于 GWT 和上传 servlet 在相同的上下文中运行,它不应该是跨域问题。

FileUpload 小部件包含在 FormPanel 中。单击按钮时,将提交表单。这会调用一个 servlet(实际上,在调试期间会到达一个断点)。在现实世界中,它将文件存储在服务器端并返回文件名。在这个简化的示例中,它只是将一个字符串写入响应 Writer。

FormPanelFileUpload sn-p:

final FormPanel form = new FormPanel();
form.setAction("upload"); // results "upload" directly below context
form.setEncoding(FormPanel.ENCODING_MULTIPART);
form.setMethod(FormPanel.METHOD_POST);
VerticalPanel panel = new VerticalPanel();
form.setWidget(panel);
FileUpload upload = new FileUpload();
upload.setName("uploadFormElement");
panel.add(upload);

panel.add(new Button("Submit", new ClickHandler() {
    public void onClick(ClickEvent event) {
        form.submit();
    }
}));
form.addSubmitCompleteHandler(new FormPanel.SubmitCompleteHandler() {
    public void onSubmitComplete(SubmitCompleteEvent event) {
        Window.alert("===> " + event.getResults() + " <==="); // shows "===> null <==="
    }
});

web.xmlsn-p:

<servlet> 
    <servlet-name>FileUploadServlet</servlet-name>
    <servlet-class>mypackage.FileUploadServlet</servlet-class> 
</servlet> 
<servlet-mapping>
    <servlet-name>FileUploadServlet</servlet-name>
    <url-pattern>/upload</url-pattern> 
</servlet-mapping>

FileUploadServletsn-p:

public class FileUploadServlet extends HttpServlet {

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse response)
            throws ServletException, IOException {

        response.setContentType("text/html");
        response.getWriter().write("OK");
        response.getWriter().flush();
    }

}

是否有任何已知与 GWT 的 SubmitCompleteHandler 冲突的库或库版本?

任何想法都值得赞赏...

更新:在将属于 spring-security 的所有工件从 4.0.4.RELEASE 降级到 3.2.4.RELEASE 之后,它就可以工作了。将它们升级到 4.1.2.RELEASE 它也不起作用。

【问题讨论】:

  • 1.我不认为这是 GWT 问题。只需尝试在带有表单的简单平面页面上使用此 servlet。还要查看浏览器开发控制台中的原始响应。 2. 可能你有一些过滤器,包装了 HttpServletResponse 和 Writer。尝试通过从 servlet 中的断点跳出调用堆栈帧来进行调试,以查看将响应发送给调用者之前的最后一点。
  • 1. servlet 在不同的应用程序中工作,响应返回到那里的浏览器。在其他应用程序中并非如此......在将属于 spring-security 的所有工件从 4.0.4.RELEASE 降级到 3.2.4.RELEASE 之后,它就可以工作了。将它们升级到 4.1.2.RELEASE 它也不起作用。 2. 在调试时,我看到所有过滤器仍然携带来自 servlet 的响应。但它不再出现在浏览器的原始响应中。
  • 可能是 X-Frame-Options 标头问题。 spring-security 4.x 默认为响应附加此标头。尝试禁用此标头进行检查。
  • @AlexanderLeshkin 在我的applicationContext.xml 中添加&lt;s:headers&gt;&lt;s:frame-options policy="SAMEORIGIN" /&gt;&lt;/s:headers&gt;&lt;s:http&gt; 使其工作。非常感谢。您想添加一个我接受的答案还是希望我这样做?
  • 我已经添加了答案。

标签: java file-upload gwt


【解决方案1】:

此问题与 X-Frame-Options: DENY 标头有关,spring-security 4.x 附加到响应 [1]。由于 GWT 应用程序通常在 iframe 中加载,因此此标头无法正确处理来自在框架中执行的客户端代码的表单提交。

要修复问题框架选项策略,应禁用或切换到SAMEORIGIN。 例如。将 xml 配置为 &lt;s:http&gt;:

<s:headers>
  <s:frame-options policy="SAMEORIGIN" />
</s:headers>

或者使用org.springframework.security.config.annotation.web.configurers.HeadersConfigurer.frameOptions()进行Java配置:

 HttpSecurity cfg = ...;
 cfg.headers().frameOptions().sameOrigin();

[1]https://docs.spring.io/spring-security/site/docs/current/reference/html/headers.html#headers-frame-options

【讨论】:

  • 这不是因为客户端代码在 iframe 中执行,而是因为表单提交到 iframe,所以结果页面“显示”在 iframe 中(标题禁止)
【解决方案2】:

为了更改 x 帧选项,您可以在响应标头中添加 X-Frame-Options 作为 SAMEORIGIN。 赞response.setHeader("X-Frame-Options","SAMEORIGIN");

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多