GWT FileUpload 问题:Content-Type 是 'multipart/form-data;预期的“文本/x-gwt-rpc”

Posted

技术标签:

【中文标题】GWT FileUpload 问题:Content-Type 是 \'multipart/form-data;预期的“文本/x-gwt-rpc”【英文标题】:GWT FileUpload issue: Content-Type was 'multipart/form-data; Expected 'text/x-gwt-rpc'GWT FileUpload 问题:Content-Type 是 'multipart/form-data;预期的“文本/x-gwt-rpc” 【发布时间】:2012-10-30 00:34:59 【问题描述】:

我在将文件上传到服务器时遇到了一些问题。我使用了这个教程:http://code.google.com/p/gwtupload/wiki/GwtUpload_GettingStarted,一切都很顺利,但是当我选择一个文件时,进度条没有显示任何进度,在 Eclipse 中我得到:

[WARN] 调度传入 RPC 调用时出现异常 javax.servlet.ServletException: Content-Type 是 'multipart/form-data;边界=----webkitformboundaryfafzb7tzbpq9rkjl'。预期为“文本/x-gwt-rpc”。 在 com.google.gwt.user.server.rpc.RPCServletUtils.checkContentTypeIgnoreCase(RPCServletUtils.java:476) ....

我开始在 GWT 的 HelloWorld 初始项目之上添加教程中的代码。

这是我的 web.xml 文件

<context-param>
    <!-- max size of the upload request -->
    <param-name>maxSize</param-name>
    <param-value>3145728</param-value>
</context-param>
<context-param>
    <!-- Useful in development mode to slow down the uploads in fast networks. 
        Put the number of milliseconds to sleep in each block received in the server. 
        false or 0, means don't use slow uploads -->
    <param-name>slowUploads</param-name>
    <param-value>200</param-value>
</context-param>

<!-- Servlets -->
<servlet>
    <servlet-name>greetServlet</servlet-name>
    <servlet-class>webapp.server.GreetingServiceImpl</servlet-class>

    <servlet-name>uploadServlet</servlet-name>
    <!-- This is the default servlet, it puts files in session -->
    <servlet-class>webapp.server.CustomizedUploadServlet</servlet-class>

</servlet>

<servlet-mapping>
    <servlet-name>greetServlet</servlet-name>
    <url-pattern>/singlefileuploadsample/greet</url-pattern>

    <servlet-name>uploadServlet</servlet-name>
    <url-pattern>*.gupld</url-pattern>

    <servlet-name>uploadServlet</servlet-name>
    <url-pattern>/upload</url-pattern>

</servlet-mapping>

<!-- Default page to serve -->
<welcome-file-list>
    <welcome-file>SingleFileUploadSample.html</welcome-file>
</welcome-file-list>

对于 servlet,我创建了一个新类并在其中添加了代码。 有一些与内容类型有关的东西,但我不知道如何解决这个问题。

更新:

当我尝试在 Jetty 上部署项目时,只会在 Eclipse 中发生这种情况。一旦在 Tomcat 上部署为 war 文件,我就可以正常工作了。

【问题讨论】:

【参考方案1】:

您不能发布包含要上传到 RPC 服务的文件的表单。扩展 RPC servlet 的服务不能接收表单,只能接受适当的对象。

【讨论】:

【参考方案2】:

我使用gwtupload 上传文件

import gwtupload.server.UploadAction;
import gwtupload.server.exceptions.UploadActionException;

import java.io.File;
import java.util.Hashtable;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.fileupload.FileItem;

public class CWTUploadServlet extends UploadAction 

  private static final long serialVersionUID = 1L;

  Hashtable<String, String> receivedContentTypes = new Hashtable<String, String>();
  /**
   * Maintain a list with received files and their content types. 
   */
  Hashtable<String, File> receivedFiles = new Hashtable<String, File>();

  /**
   * Override executeAction to save the received files in a custom place
   * and delete this items from session.  
   */
  @Override
  public String executeAction(HttpServletRequest request, List<FileItem> sessionFiles) throws UploadActionException 
    String response = "";
    int cont = 0;
    for (FileItem item : sessionFiles) 
      if (false == item.isFormField()) 
        cont++;
        try 

           //Create a new file based on the remote file name in the client
           String saveName = item.getName().replaceAll("[\\\\/><\\|\\s\"'()\\[\\]]+", "_");
           System.out.println("Save name : "+saveName);
           File file =new File("/Users/Spirit/hob/" + saveName);

          item.write(file);
          /// Save a list with the received files
          receivedFiles.put(item.getFieldName(), file);
          receivedContentTypes.put(item.getFieldName(), item.getContentType());

          /// Compose a xml message with the full file information
          response += "<file-" + cont + "-field>" + item.getFieldName() + "</file-" + cont + "-field>\n";
          response += "<file-" + cont + "-name>" + item.getName() + "</file-" + cont + "-name>\n";
          response += "<file-" + cont + "-size>" + item.getSize() + "</file-" + cont + "-size>\n";
          response += "<file-" + cont + "-type>" + item.getContentType() + "</file-" + cont + "type>\n";
         catch (Exception e) 
          throw new UploadActionException(e);
        
      
    

    /// Remove files from session because we have a copy of them
    removeSessionFileItems(request);

    /// Send information of the received files to the client.
    return "<response>\n" + response + "</response>\n";
  

还有你的 web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    version="2.5">

    <display-name>CWTMVP</display-name>

    <!-- Default page to serve -->
    <welcome-file-list>
        <welcome-file>CWTMVP.html</welcome-file>
    </welcome-file-list>

    <!--
        This Guice listener hijacks all further filters and servlets. Extra
        filters and servlets have to be configured in your
        ServletModule#configureServlets() by calling
        serve(String).with(Class<? extends HttpServlet>) and
        filter(String).through(Class<? extends Filter)
    -->
    <listener>
        <listener-class>com.db.cawt.clientzonedesign.server.guice.GuiceServletConfig</listener-class>
    </listener>

    <filter>
        <filter-name>guiceFilter</filter-name>
        <filter-class>com.google.inject.servlet.GuiceFilter</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>guiceFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>


      <context-param>
        <param-name>maxSize</param-name>
        <param-value>102400000</param-value>
      </context-param>

      <context-param>
        <param-name>slowUploads</param-name>
        <param-value>true</param-value>
      </context-param>

      <servlet>
        <servlet-name>uploadServlet</servlet-name>
        <servlet-class>xxx.yyy.server.CWTUploadServlet</servlet-class>
      </servlet>

      <servlet-mapping>
        <servlet-name>uploadServlet</servlet-name>
        <url-pattern>*.gupld</url-pattern>
      </servlet-mapping>


</web-app>

【讨论】:

感谢您的帮助,但还是不行。问题与内容类型有关。我不断收到此错误:Content-Type 是 'multipart/form-data;预期为“文本/x-gwt-rpc”。【参考方案3】:

您的错误跟踪表明收到您发送的请求的 servlet 是 gwt-rpc servlet。

看来您的 web.xml 配置正确,并且应该根据您的 webapp.server.CustomizedUploadServlet 处理请求的文件,所以我看到的错误的唯一可能原因是:

您的 webapp.server.CustomizedUploadServlet 正在扩展 RPCServlet 而不是 UploadAction。 或者您的部署错误并且您的应用没有读取正确的 web.xml

【讨论】:

我的 CustomizedUploadServlet 正在扩展 UploadAction。你能更具体地谈谈第二点吗?我做错了什么或者我应该寻找什么?如果您认为可以给出答案,我可以发布其余代码,但正如我在问题中所说,我只是将教程中的代码复制粘贴到 HelloWorld 初始项目中,Eclipse 将其添加到新的 Web 应用程序中。 如您所知,当您在开发模式下部署应用程序时,它会将 web.xml 从源文件夹复制到部署文件夹,因此这些 web.xml 可能会不同步。 您可以尝试查看 gwtupload 请求中使用了哪个 url(查看 firebug 网络输出),他们尝试手动请求浏览器的 url,gwtupload servlet 应该以类似的方式响应listener 为 null,否则另一个 servlet 正在响应您的请求 感谢您的想法。具有讽刺意味的是,这只发生在 Eclipse on Jetty 中。一旦部署在 Tomcat 上,它就会按预期工作。这很不寻常,因为大多数抱怨这个问题的人都遇到了相反的问题。仍然不知道如何让它在 devmode 下工作 在开发模式下,它的工作方式应该与生产环境中完全相同。您是否尝试过从谷歌代码下载示例项目并在您的 Eclipse 中运行?它对我有用【参考方案4】:

mP 是正确的,您不能将带有文件的表单发布到 RPC servlet。因此,不要扩展 RemoteServiceServlet,而是创建一个扩展 javax.servlet.http.HttpServlet 的 servlet。 我自己做了这个改变(使用this问题中的代码)并成功上传了一个文件。

【讨论】:

以上是关于GWT FileUpload 问题:Content-Type 是 'multipart/form-data;预期的“文本/x-gwt-rpc”的主要内容,如果未能解决你的问题,请参考以下文章

GWT FileUpload OnClick

如何使用 fileUpload 在 GWT 中将文件从客户端传输到服务器

GWT文件上传表单提交POST请求无法读取文件

GWT - 从 FormPanel 上传文件后返回对象?

jmeter-fileupload操作使用说明

commons-fileupload处理plupload多文件上传