You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@servicecomb.apache.org by ni...@apache.org on 2017/12/22 03:15:57 UTC

[incubator-servicecomb-java-chassis] 01/11: JAV-548 fix springmvc upload bug, avoid getBytes not closed inputStream

This is an automated email from the ASF dual-hosted git repository.

ningjiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-servicecomb-java-chassis.git

commit 887ab2a6de3732b35e50be73c30b1292a5ddd21d
Author: wujimin <wu...@huawei.com>
AuthorDate: Wed Dec 13 10:45:35 2017 +0800

    JAV-548 fix springmvc upload bug, avoid getBytes not closed inputStream
---
 .../invocation/converter/PartToMultipartFile.java  |  77 +++++++++
 .../converter/SpringMultipartConverter.java        |  47 +-----
 .../converter/TestPartToMultipartFile.java         | 186 +++++++++++++++++++++
 3 files changed, 264 insertions(+), 46 deletions(-)

diff --git a/swagger/swagger-invocation/invocation-springmvc/src/main/java/io/servicecomb/swagger/invocation/converter/PartToMultipartFile.java b/swagger/swagger-invocation/invocation-springmvc/src/main/java/io/servicecomb/swagger/invocation/converter/PartToMultipartFile.java
new file mode 100644
index 0000000..8e83d7c
--- /dev/null
+++ b/swagger/swagger-invocation/invocation-springmvc/src/main/java/io/servicecomb/swagger/invocation/converter/PartToMultipartFile.java
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.servicecomb.swagger.invocation.converter;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.servlet.http.Part;
+
+import org.apache.commons.io.IOUtils;
+import org.springframework.web.multipart.MultipartFile;
+
+public class PartToMultipartFile implements MultipartFile {
+  private Part part;
+
+  public PartToMultipartFile(Part part) {
+    this.part = part;
+  }
+
+  @Override
+  public String getName() {
+    return part.getName();
+  }
+
+  @Override
+  public String getOriginalFilename() {
+    return part.getSubmittedFileName();
+  }
+
+  @Override
+  public String getContentType() {
+    return part.getContentType();
+  }
+
+  @Override
+  public boolean isEmpty() {
+    return part.getSize() == 0;
+  }
+
+  @Override
+  public long getSize() {
+    return part.getSize();
+  }
+
+  @Override
+  public byte[] getBytes() throws IOException {
+    try (InputStream is = getInputStream()) {
+      return IOUtils.toByteArray(is);
+    }
+  }
+
+  @Override
+  public InputStream getInputStream() throws IOException {
+    return part.getInputStream();
+  }
+
+  @Override
+  public void transferTo(File dest) throws IOException, IllegalStateException {
+    part.write(dest.getPath());
+  }
+}
diff --git a/swagger/swagger-invocation/invocation-springmvc/src/main/java/io/servicecomb/swagger/invocation/converter/SpringMultipartConverter.java b/swagger/swagger-invocation/invocation-springmvc/src/main/java/io/servicecomb/swagger/invocation/converter/SpringMultipartConverter.java
index 5e8e0e0..d4618a5 100644
--- a/swagger/swagger-invocation/invocation-springmvc/src/main/java/io/servicecomb/swagger/invocation/converter/SpringMultipartConverter.java
+++ b/swagger/swagger-invocation/invocation-springmvc/src/main/java/io/servicecomb/swagger/invocation/converter/SpringMultipartConverter.java
@@ -17,14 +17,10 @@
 
 package io.servicecomb.swagger.invocation.converter;
 
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
 import java.lang.reflect.Type;
 
 import javax.servlet.http.Part;
 
-import org.apache.commons.io.IOUtils;
 import org.springframework.stereotype.Component;
 import org.springframework.web.multipart.MultipartFile;
 
@@ -46,47 +42,6 @@ class SpringMultipartConverter implements CustomizedConverter {
       return null;
     }
 
-    Part part = (Part) value;
-    return new MultipartFile() {
-      @Override
-      public String getName() {
-        return part.getName();
-      }
-
-      @Override
-      public String getOriginalFilename() {
-        return part.getSubmittedFileName();
-      }
-
-      @Override
-      public String getContentType() {
-        return part.getContentType();
-      }
-
-      @Override
-      public boolean isEmpty() {
-        return part.getSize() == 0;
-      }
-
-      @Override
-      public long getSize() {
-        return part.getSize();
-      }
-
-      @Override
-      public byte[] getBytes() throws IOException {
-        return IOUtils.toByteArray(part.getInputStream());
-      }
-
-      @Override
-      public InputStream getInputStream() throws IOException {
-        return part.getInputStream();
-      }
-
-      @Override
-      public void transferTo(File dest) throws IOException, IllegalStateException {
-        part.write(dest.getPath());
-      }
-    };
+    return new PartToMultipartFile((Part) value);
   }
 }
diff --git a/swagger/swagger-invocation/invocation-springmvc/src/test/java/io/servicecomb/swagger/invocation/converter/TestPartToMultipartFile.java b/swagger/swagger-invocation/invocation-springmvc/src/test/java/io/servicecomb/swagger/invocation/converter/TestPartToMultipartFile.java
new file mode 100644
index 0000000..dc15aaa
--- /dev/null
+++ b/swagger/swagger-invocation/invocation-springmvc/src/test/java/io/servicecomb/swagger/invocation/converter/TestPartToMultipartFile.java
@@ -0,0 +1,186 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.servicecomb.swagger.invocation.converter;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.IOException;
+
+import javax.servlet.http.Part;
+import javax.xml.ws.Holder;
+
+import org.hamcrest.Matchers;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+
+import mockit.Expectations;
+import mockit.Mock;
+import mockit.MockUp;
+import mockit.Mocked;
+
+public class TestPartToMultipartFile {
+  @Mocked
+  Part part;
+
+  PartToMultipartFile multipartFile;
+
+  @Rule
+  public ExpectedException expectedException = ExpectedException.none();
+
+  @Before
+  public void setup() {
+    multipartFile = new PartToMultipartFile(part);
+  }
+
+  @Test
+  public void getName() {
+    String name = "paramName";
+    new Expectations() {
+      {
+        part.getName();
+        result = name;
+      }
+    };
+
+    Assert.assertEquals(name, multipartFile.getName());
+  }
+
+  @Test
+  public void getOriginalFilename() {
+    String submittedFileName = "fileName";
+    new Expectations() {
+      {
+        part.getSubmittedFileName();
+        result = submittedFileName;
+      }
+    };
+
+    Assert.assertEquals(submittedFileName, multipartFile.getOriginalFilename());
+  }
+
+  @Test
+  public void getContentType() {
+    String contentType = "json";
+    new Expectations() {
+      {
+        part.getContentType();
+        result = contentType;
+      }
+    };
+
+    Assert.assertEquals(contentType, multipartFile.getContentType());
+  }
+
+  @Test
+  public void isEmptyTrue() {
+    new Expectations() {
+      {
+        part.getSize();
+        result = 0;
+      }
+    };
+
+    Assert.assertTrue(multipartFile.isEmpty());
+  }
+
+  @Test
+  public void isEmptyFalse() {
+    new Expectations() {
+      {
+        part.getSize();
+        result = 1;
+      }
+    };
+
+    Assert.assertFalse(multipartFile.isEmpty());
+  }
+
+  @Test
+  public void getSize() {
+    long size = 10;
+    new Expectations() {
+      {
+        part.getSize();
+        result = size;
+      }
+    };
+
+    Assert.assertEquals(size, multipartFile.getSize());
+  }
+
+  class ByteArrayInputStreamForTest extends ByteArrayInputStream {
+    boolean closed;
+
+    public ByteArrayInputStreamForTest(byte[] buf) {
+      super(buf);
+    }
+
+    @Override
+    public void close() throws IOException {
+      closed = true;
+    }
+  }
+
+  @Test
+  public void getBytes_normal() throws IOException {
+    byte[] bytes = new byte[] {1, 2, 3};
+    ByteArrayInputStreamForTest is = new ByteArrayInputStreamForTest(bytes);
+    new Expectations() {
+      {
+        part.getInputStream();
+        result = is;
+      }
+    };
+
+    Assert.assertArrayEquals(bytes, multipartFile.getBytes());
+    Assert.assertTrue(is.closed);
+  }
+
+  @Test
+  public void getBytes_exception() throws IOException {
+    new Expectations() {
+      {
+        part.getInputStream();
+        result = new IOException("open stream failed");
+      }
+    };
+
+    expectedException.expect(IOException.class);
+    expectedException.expectMessage(Matchers.is("open stream failed"));
+
+    multipartFile.getBytes();
+  }
+
+  @Test
+  public void transferTo() throws IllegalStateException, IOException {
+    File dest = new File("/dest");
+    Holder<String> destName = new Holder<>();
+    new MockUp<Part>(part) {
+      @Mock
+      void write(String fileName) throws IOException {
+        destName.value = fileName;
+      }
+    };
+
+    multipartFile.transferTo(dest);
+    Assert.assertEquals(dest.getPath(), destName.value);
+  }
+}

-- 
To stop receiving notification emails like this one, please contact
"commits@servicecomb.apache.org" <co...@servicecomb.apache.org>.