-2

I have a project based on Spring Web model-view-controller (MVC) framework. The version of the Spring Web model-view-controller (MVC) framework is 3.2.8. I am reading an image

public static void main(String[] args) {

    BufferedImage img = null;
    try {
        img = ImageIO.read(new File("C:/tmp/device.jpg"));
    } catch (IOException e) {
    }       
    System.out.println  ("img -> " + img);
}

and It is working fine with this result:

img -> BufferedImage@18e8541: type = 5 ColorModel: #pixelBits = 24 numComponents = 3 color space = java.awt.color.ICC_ColorSpace@1ce85c4 transparency = 1 has alpha = false isAlphaPre = false ByteInterleavedRaster: width = 480 height = 640 #numDataElements 3 dataOff[0] = 2

But when I upload the same image in my Spring-MVC app:

 MultipartFile file = productForm.getAttachment();  

System.out.println ("productForm.getAttachment() ------------------> " + productForm.getAttachment());
        System.out.println ("productForm.getAttachment().getContentType() -> " + productForm.getAttachment().getContentType());
        System.out.println ("productForm.getAttachment().getSize() --------> " + productForm.getAttachment().getSize());

    byte[] result = new byte[(int) file.getSize()];
    Image img = new Image();
    img.setContent(result);
    ByteArrayInputStream in = new ByteArrayInputStream(img.getContent());
    BufferedImage img2 = null;
                try {
                    img2 = ImageIO.read(in);
                    System.out.println ("IMAGE CONTENT2 ------> " + img2);
                } catch (IOException e) {
                }

    productForm.getAttachment() ------------------> org.springframework.web.multipart.commons.CommonsMultipartFile@1f1bc67
    productForm.getAttachment().getContentType() -> image/jpeg
    productForm.getAttachment().getSize() --------> 28704

, I have faced img2 is NULL !!!

Here the class Image

public class Image implements java.io.Serializable {

    private Long id;
    private byte[] content;

    public Image() {
    }

    public Image(Image image) {
        this.id = image.getId();
        this.content = image.getContent();
    }

    public Image(byte[] content) {
        this.content = content;
    }

    @Id
    @Column(name = "ID", unique = true, nullable = false, precision = 38, scale = 0)
    public Long getId() {
        return this.id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    @Column(name = "CONTENT", nullable = false)
    @Lob
    @Basic(fetch = FetchType.LAZY)
    public byte[] getContent() {
        return this.content;
    }

    public void setContent(byte[] content) {
        this.content = content;
    }

}
Amadeu Cabanilles
  • 913
  • 3
  • 19
  • 47
  • Have you checked that file, result and img is not null, to make sure that the problem does not lie there. – Magic-Mouse Jan 26 '17 at 13:15
  • maybe you have an... `IOException`? :D – fantaghirocco Jan 26 '17 at 13:19
  • No, I see IMAGE CONTENT2 ------> – Amadeu Cabanilles Jan 26 '17 at 13:24
  • @AmadeuCabanilles You should probably add that line to your output then, to avoid confusion. Anyway, what class is `Image`? What does the `setContent(..)/getContent()` methods do? It seems to me, you are passing an empty array and forgot to copy the actual data from `file`. If not, most likely, something is corrupting the image data in the upload process. Try just writing the content of `in` directly to disk, and see what it looks like in a hex editor. – Harald K Jan 27 '17 at 08:28
  • @AmadeuCabanilles As I thought, the problem is that you never copy any bytes into `result`. You only initialize `result` to an empty array of length `file.getSize()`. You then pass this empty array to your `Image` instance and back to the `ByteArrayInputStream`. You probably meant to initialize `result`to `file.getBytes()` instead. – Harald K Jan 27 '17 at 08:46
  • @haraldK, please convert to answer than – Amadeu Cabanilles Jan 27 '17 at 08:49

1 Answers1

0

The problem is simple, the result array is empty. If you change the code as follows, you should probably be good.

From:

MultipartFile file = productForm.getAttachment();  
...
byte[] result = new byte[(int) file.getSize()]; // Bug: Empty array
Image img = new Image();
img.setContent(result);
ByteArrayInputStream in = new ByteArrayInputStream(img.getContent());

To:

MultipartFile file = productForm.getAttachment();  
...
byte[] result = file.getBytes(); // Good: The content of the uploaded file
Image img = new Image();
img.setContent(result);
ByteArrayInputStream in = new ByteArrayInputStream(img.getContent());

PS: I'm still not sure what the Image class is doing in all this, it should work just as fine with simply:

MultipartFile file = productForm.getAttachment();  
...
ByteArrayInputStream in = new ByteArrayInputStream(file.getBytes());

Or, even better, you could pass file.getInputStream() directly to ImageIO.read(...), to avoid caching the file contents in memory:

MultipartFile file = productForm.getAttachment();  
...
InputStream in = file.getInputStream();

All this is unless you use img for something later, but just left it out of the question for brevity, of course.

Harald K
  • 26,314
  • 7
  • 65
  • 111