Announcement Announcement Module
Collapse
No announcement yet.
Spring 2 Breaks my File Upload Unit test Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Spring 2 Breaks my File Upload Unit test

    I have written (Based on some code Matt Raible posted) some test cases to test my controller. It requires a file tobe uploaded to it. The test case ran ok with Spring 1.2.8 but when I updated to Spring 2 it fails with the following error.

    Anyone know what might be going on?

    Code:
    org.springframework.web.multipart.MultipartException: Could not parse multipart servlet request; nested exception is org.apache.commons.fileupload.FileUploadBase$UnknownSizeException: the request was rejected because its size is unknown
    Caused by: org.apache.commons.fileupload.FileUploadBase$UnknownSizeException: the request was rejected because its size is unknown
    	at org.apache.commons.fileupload.FileUploadBase.parseRequest(FileUploadBase.java:305)
    	at org.apache.commons.fileupload.servlet.ServletFileUpload.parseRequest(ServletFileUpload.java:116)
    	at org.springframework.web.multipart.commons.CommonsMultipartResolver.resolveMultipart(CommonsMultipartResolver.java:117)
    	at com.benshort.catalog.web.admin.CategoryFormControllerTests.testCreateWithoutParent(CategoryFormControllerTests.java:163)

    The test case

    Code:
    byte[] originalImageData = ImageFactory.createJpeg(1524, 2032);
    
            MockFileItem fileItem = new MockFileItem("image", "image/jpeg", "test.jpg", new String(originalImageData));
    
            Category categoryThatWillBeSaved = new Category();
            categoryThatWillBeSaved.setId(null);
            categoryThatWillBeSaved.setName("Saved Category");
    
            Image originalImage =  new Image();
            originalImage.setData(originalImageData);
            originalImage.setImageType("jpg");
            originalImage.setMimeType("image/jpeg");
            originalImage.setLength(originalImage.getData().length);
            originalImage.setLastModified(new Date().getTime());
    
            Image imageThatWillBeSaved = new Image();
            imageThatWillBeSaved.setData(ImageUtils.resize(150, 200, originalImageData, "jpg"));
            imageThatWillBeSaved.setImageType("jpg");
            imageThatWillBeSaved.setMimeType("image/jpeg");
            imageThatWillBeSaved.setLength(imageThatWillBeSaved.getData().length);
            imageThatWillBeSaved.setLastModified(originalImage.getLastModified());
    
            categoryThatWillBeSaved.setImage(imageThatWillBeSaved);
            categoryThatWillBeSaved.setImageName("null.jpg");
    
            // called by onSubmit()
            mMockCatalogRepository.expects(once()).method("saveCategory").with(eq(categoryThatWillBeSaved));
            mMockImageRepository.expects(once()).method("saveImage").with(eq(imageThatWillBeSaved));
    
            MockHttpServletRequest httpServletRequest = new MockHttpServletRequest("POST", "/createCategory.html");
            httpServletRequest.setContentType("multipart/form-data");
            httpServletRequest.addHeader("Content-type", "multipart/form-data");
    
            httpServletRequest.addParameter("name", categoryThatWillBeSaved.getName() );
            httpServletRequest.addParameter("parent", "-1");
    
            List<MockFileItem> fileItems = new ArrayList<MockFileItem>();
            fileItems.add(fileItem);
    
            MockCommonsMultipartResolver resolver = new MockCommonsMultipartResolver(fileItems);
            assertTrue(resolver.isMultipart(httpServletRequest));
            MultipartHttpServletRequest multipartRequest = resolver.resolveMultipart(httpServletRequest);
    
            mMockHttpImageUtil.expects(once()).method("validateAndCreateImage").with(eq("image"), eq(multipartRequest),   isA(BindException.class) , eq(true)).will(returnValue(originalImage));
    
            mModelAndView = mController.handleRequest(multipartRequest, new MockHttpServletResponse());
    
            // verify expectations
            mMockCatalogRepository.verify();
            mMockImageRepository.verify();
    The MockFileItem class

    Code:
    public class MockFileItem implements FileItem
        {
    
        private String fieldName;
        private String contentType;
        private String name;
        private String value;
    
        private File writtenFile;
        private boolean deleted;
    
        public MockFileItem(String fieldName, String contentType, String name, String value)
            {
            this.fieldName = fieldName;
            this.contentType = contentType;
            this.name = name;
            this.value = value;
            }
    
        public InputStream getInputStream() throws IOException
            {
            return new ByteArrayInputStream(value.getBytes());
            }
    
        public String getContentType()
            {
            return contentType;
            }
    
        public String getName()
            {
            return name;
            }
    
        public boolean isInMemory()
            {
            return true;
            }
    
        public long getSize()
            {
            return value.length();
            }
    
        public byte[] get()
            {
            return value.getBytes();
            }
    
        public String getString(String encoding) throws UnsupportedEncodingException
            {
            return new String(get(), encoding);
            }
    
        public String getString()
            {
            return value;
            }
    
        public void write(File file) throws Exception
            {
            this.writtenFile = file;
            }
    
        public File getWrittenFile()
            {
            return writtenFile;
            }
    
        public void delete()
            {
            this.deleted = true;
            }
    
        public boolean isDeleted()
            {
            return deleted;
            }
    
        public String getFieldName()
            {
            return fieldName;
            }
    
        public void setFieldName(String s)
            {
            this.fieldName = s;
            }
    
        public boolean isFormField()
            {
            return (this.name == null);
            }
    
        public void setFormField(boolean b)
            {
            throw new UnsupportedOperationException();
            }
    
        public OutputStream getOutputStream() throws IOException
            {
            throw new UnsupportedOperationException();
            }
        }
    The MockCommonsMultipartResolver class

    Code:
    public class MockCommonsMultipartResolver extends CommonsMultipartResolver
        {
        private boolean empty;
        private List<MockFileItem> mFileItem;
        private MockFileItem mEmptyFileITem = new MockFileItem("file", "text/html", empty ? "" : "test.xml", empty ? "" : "<root/>");
    
        public MockCommonsMultipartResolver(List<MockFileItem> fileItem)
            {
            mFileItem = fileItem;
            }
    
        public void setEmpty(boolean empty)
            {
            this.empty = empty;
            }
    
        protected DiskFileUpload newFileUpload()
            {
            return new DiskFileUpload()
            {
            public List parseRequest(HttpServletRequest request)
                {
                if (request instanceof MultipartHttpServletRequest)
                    {
                    throw new IllegalStateException("Already a multipart request");
                    }
                List fileItems = new ArrayList();
    
                if ( empty )
                    fileItems.add(mEmptyFileITem);
                else
                    fileItems.addAll(mFileItem);
    
                return fileItems;
                }
            };
            }
    
    
        }

  • #2
    I'm not sure why it is throwing that exception, but I've had problems in the past with CommonsMultipartResolver messing up the last few bytes when uploading images so the images would have digital blocks at the very bottom. I messed around with it for a long time and finally switched to CosMultipartResolver and it worked fine.

    Granted that was over two years ago with a CMS system I made, but I've always used the CosMultipartResolver since then and it works for me.

    Comment


    • #3
      Thanks whipshaw, I will keep an eye out for that.

      I fixed the problem by refactoring my MockCommonsMultipartResolver class as shown below.

      Code:
      public class MockCommonsMultipartResolver extends CommonsMultipartResolver
          {
          private boolean empty;
          private List<MockFileItem> mFileItem;
          private MockFileItem mEmptyFileITem = new MockFileItem("file", "text/html", empty ? "" : "test.xml", empty ? "" : "<root/>");
      
          public MockCommonsMultipartResolver(List<MockFileItem> fileItem)
              {
              mFileItem = fileItem;
              }
      
          public void setEmpty(boolean empty)
              {
              this.empty = empty;
              }
      
      
          protected FileUpload newFileUpload(FileItemFactory fileItemFactory)
              {
              return new MockFileUpload(fileItemFactory);
              }
      
          class MockFileUpload extends ServletFileUpload
              {
              public MockFileUpload(FileItemFactory fileItemFactory)
                  {
                  super(fileItemFactory);
                  }
      
              public List /* FileItem */ parseRequest(HttpServletRequest request) throws FileUploadException
                  {
                  List fileItems = new ArrayList();
      
                      if ( empty )
                          fileItems.add(mEmptyFileITem);
                      else
                          fileItems.addAll(mFileItem);
      
                      return fileItems;
                  }
              }
      
          }

      Comment


      • #4
        new to file uploading

        Hi Jamin,
        I'm new to uloading file.
        please tell me how to upload the file to server and how to download it.
        I'm using struts at my view and spring for business layer.
        Thanks in advance.

        Comment


        • #5
          Hi,

          The first place to visit would be the manual [1] that will show you how to upload files with spring mvc.

          But from reading your post you want to use struts, so maybe you should google fot a struts based solution?


          [1] http://static.springframework.org/sp...#mvc-multipart

          Comment

          Working...
          X