title: smartgwt spring servlet and uploading files
body: <p>I've seen this question here before, but none of the solutions work for me.
  I have a SmartGWT app with Spring MVC.  This all works great, and I have working RESTful web-services.</p>
  
  <p>I have a form to upload not only the file, but also some meta data as well.
  There is an associated DataSource with this form:</p>
  
  <pre><code>private final String DEFAULT_FILE_UPLOAD_SERVICE_PATH = "upload";
  private final String TARGET = "uploadTarget";
  
   public FileUploadForm()
  {
      setEncoding(Encoding.MULTIPART);
      setMethod(FormMethod.POST);
  
      setAutoFetchData(false);
      setDataSource(fileUploadDS);
  
      setTitleOrientation(TitleOrientation.TOP);
      setNumCols(1);
      setColWidths("*");
  
      uploadFileIdItem.setRequired(true);
      uploadFileIdItem.setDefaultValue(0);
      uploadFileIdItem.setVisible(false);
      uploadFileIdItem.setShowTitle(false);
  
      // ==========================================================================
  
      fileUploadTypeSelectItem.setShowTitle(false);
      fileUploadTypeSelectItem.setName(Constants.FILE_UPLOAD_UPLOADTYPE);
      fileUploadTypeSelectItem.setPickListWidth(TEXT_SIZE);
      fileUploadTypeSelectItem.setTitle(Constants.TITLE_FILE_UPLOAD_UPLOADTYPE);
      fileUploadTypeSelectItem.setOptionDataSource(fileUploadTypeDS);
      fileUploadTypeSelectItem.setRequired(true);
      fileUploadTypeSelectItem.setDisplayField(Constants.FILE_UPLOAD_UPLOADTYPE_NAME);
      fileUploadTypeSelectItem.setValueField(Constants.FILE_UPLOAD_UPLOADTYPE_ID);
      fileUploadTypeSelectItem.setDataPath("fileUploadType/fileUploadTypeId");
  
      // ==========================================================================
  
      setAction(GWT.getHostPageBaseURL() + "rest/" + DEFAULT_FILE_UPLOAD_SERVICE_PATH);
  
      ButtonItem uploadButton = new ButtonItem("Upload");
  
      uploadButton.addClickHandler(new com.smartgwt.client.widgets.form.fields.events.ClickHandler()
      {
          @Override
          public void onClick(com.smartgwt.client.widgets.form.fields.events.ClickEvent event)
          {
              submitForm();
          }
      });
  
      FileItem uploadItem = new FileItem(Constants.FILENAME);
      uploadItem.setTitle(Constants.FILENAME);
  
      setFields(uploadFileIdItem, fileUploadTypeSelectItem, uploadItem, uploadButton);
  }
  </code></pre>
  
  <p>So, I don't know if I need to use:
  setAction(GWT.getHostPageBaseURL() + "rest/" + DEFAULT_FILE_UPLOAD_SERVICE_PATH);
  or
  setAction(GWT.getHostPageBaseURL() + DEFAULT_FILE_UPLOAD_SERVICE_PATH);
  or
  setAction(GWT.getHostPageBaseURL() + DEFAULT_FILE_UPLOAD_SERVICE_PATH);</p>
  
  <p>None of these seem to work, I submit my data to upload the filename, and I constantly get the HTTP 404 error.</p>
  
  <p>I did not define anything extra special in the web.xml file for servlets.
  Instead, the springmvc-servlet contains:</p>
  
  <pre><code>&lt;context:component-scan base-package="com.myself.products.app.server.controller" /&gt;
  </code></pre>
  
  <p>And the servlet is actually defined like:</p>
  
  <pre><code>@SuppressWarnings("serial")
  @Controller
  @RequestMapping("/upload")
  public class FileUploadServlet extends HttpServlet
  {
      private final Logger logger = LoggerFactory.getLogger(FileUploadServlet.class);
  
      @Override
      public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
  {
      this.process(request, response);
  }
  
  @Override
  public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
  {
      this.process(request, response);
  }
  
  private void process(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
  {
      // check that we have a file upload request
      if (ServletFileUpload.isMultipartContent(request))
      {
          processFiles(request, response);
      }
  }
  
  private File tmpDir;
  private static final String DESTINATION_DIR_PATH = "/files/upload";
  private File destinationDir;
  
  public void init(ServletConfig config) throws ServletException
  {
      super.init(config);
  
      tmpDir = new File(((File) getServletContext().getAttribute("javax.servlet.context.tempdir")).toString());
  
      if (!tmpDir.isDirectory())
      {
          throw new ServletException(tmpDir.toString() + " is not a directory");
      }
  
      logger.debug("tmpDir: " + tmpDir.toString());
  
      String realPath = getServletContext().getRealPath(DESTINATION_DIR_PATH);
      destinationDir = new File(realPath);
  
      if (!destinationDir.isDirectory())
      {
          throw new ServletException(DESTINATION_DIR_PATH + " is not a directory");
      }
  }
  
  private void processFiles(HttpServletRequest request, HttpServletResponse response) throws ServletException,
      IOException
  {
  
      // create a factory for disk-based file items
      DiskFileItemFactory factory = new DiskFileItemFactory();
  
      // set the size threshold, above which content will be stored on disk
      factory.setSizeThreshold(1 * 1024 * 1024); // 1 MB
  
      // set the temporary directory (this is where files that exceed the threshold will be stored)
      factory.setRepository(tmpDir);
  
      // create a new file upload handler
      ServletFileUpload upload = new ServletFileUpload(factory);
  
      try
      {
          // parse the request
          List&lt;?&gt; items = upload.parseRequest(request);
  
          // process the uploaded items
          Iterator&lt;?&gt; itr = items.iterator();
  
          while (itr.hasNext())
          {
              FileItem item = (FileItem) itr.next();
  
              // write the uploaded file to the application's file staging area
              File file = new File(destinationDir, item.getName());
              item.write(file);
          }
  
      }
      catch (FileUploadException e)
      {
          logger.error("Error encountered while parsing the request", e);
      }
      catch (Exception e)
      {
          logger.error("Error encountered while uploading file", e);
      }
  }
  </code></pre>
  
  <p>You've seen this code before along this web-site, and several others.</p>
  
  <p>I'd like to submit the file, AND data if possible, but if not, then how can I submit the form, and then metadata for it?</p>
  
  <p>Any help would be much appreciated.</p>