2

I have a Product entity, which has a imageUrl String field.

Products images after obtaining from user will be saved in directory:

System.getProperty("user.home") + "shop/data/product/"

And when user wants to see some Product I need to get this image from "user.home"+... to JSP page.

I've tried to read the image into the byte array, convert it to Base64 encoding, and then refer in JSP like this:

<img alt="image from user home" src="data:image/png, base64;${requestScope.image}">

But this solution is not working, and as far as I understand, it has a limitation on image size.

Could you suggest me a way how to do such thing?

Roman C
  • 49,761
  • 33
  • 66
  • 176
marknorkin
  • 3,904
  • 10
  • 46
  • 82
  • why you are reading it as byteSream? why not serve it as static resource. You can set `System.getProperty("user.home") + "shop/data/product/"+imageFileName` as request attribute and just add this path to `src` attribute . Or if is because the image is on the server then give a relative url to the path on server – Amit.rk3 Jun 06 '15 at 14:07
  • @Amit.rk3 yes, I've mention that images store is in server. So the first suggestion wont work. Would you provide some explanations how to do the second one ? – marknorkin Jun 06 '15 at 14:25
  • 1
    See [How to display image in Struts2](http://stackoverflow.com/a/15278402/573032) or [this](http://stackoverflow.com/a/18001916/573032) – Roman C Jun 06 '15 at 14:48
  • 1
    So second one also won't work I guess. You may wan't to check [this answer](http://stackoverflow.com/questions/2000523/how-to-use-the-image-file-located-in-local-drive-for-printing-it-in-jsp-page-or) which talks of creating a separate servlet for serving images dynamically – Amit.rk3 Jun 06 '15 at 14:49
  • @RomanC I will also try the first solution you provide with separate action. Seems more appropriate – marknorkin Jun 06 '15 at 15:07
  • The action/controller replaces servlet in Struts2, and you don't have to write many servlets, but many actions and no servlet. – Roman C Jun 06 '15 at 15:10

3 Answers3

2

Try this ( i think you have some typo )

<img alt="image from user home" src="data:image/png;base64,${requestScope.image}">

Also use this site: http://www.askapache.com/online-tools/base64-image-converter/ to make sure that your output Base64 code is correct.

Alireza Fattahi
  • 42,517
  • 14
  • 123
  • 173
2

There's an example of ImageAction that serves image from the file system. It's called Struts 2 dynamic image example.

Instead of base64 encoding/decoding which increases the content length two times and slows down page loading you can use the action that returnes image bytes from the file. It could be a database, in this way it should fetch bytes from Blob.

In your <img> tag that is using src attribute can contain the URL to the action that returns response with a header Content-Type: image/jpeg and bytes written to the body.

This is the code of the ImageAction:

@Result(type = "stream", params = {"contentType", "${type}"})
public class ImageAction extends ActionSupport implements ServletRequestAware {

    byte[] imageInByte = null;
    String imageId;

    private HttpServletRequest servletRequest;

    private final static String type = "image/jpeg";

    public getInputStream() { return new ByteArrayInputStream(getCustomImageInBytes()); }

    public String getType() { return type; }

    private String getFilename() {
        return this.filename;
    }


    public String getImageId() {
        return imageId;
    }

    public void setImageId(String imageId) {
        this.imageId = imageId;
    }

    public ImageAction() {
        System.out.println("ImageAction");
    }

    public byte[] getCustomImageInBytes() {

        System.out.println("imageId" + imageId);

        BufferedImage originalImage;
        try {
            originalImage = ImageIO.read(getImageFile(this.imageId));
            // convert BufferedImage to byte array
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            ImageIO.write(originalImage, "jpeg", baos);
            baos.flush();
            imageInByte = baos.toByteArray();
            baos.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        return imageInByte;
    }

    private File getImageFile(String imageId) {
        String filePath = servletRequest.getSession().getServletContext().getRealPath("/");
        File file = new File(filePath + "/Image/", imageId);
        System.out.println(file.toString());
        return file;
    }

    @Override
    public void setServletRequest(HttpServletRequest request) {
        this.servletRequest = request;

    }

}    

This action supposed to have configuration created by convention-plugin. So it could be used in HTML like this

<img src="<s:url action='Image?imageId=darksouls.jpg' />" alt=""/>
Roman C
  • 49,761
  • 33
  • 66
  • 176
1

So Alireza Fattahi was right that I had mistakes in my code. The first one is typo in img tag (see answer by Alireza Fattahi), the second one is after reading image to bytes array

byte[] image = ...;

I used

Base64.getEncoder().encode(image);

instead of

Base64.getEncoder().encodeToString(image));

So eventually this method with returning Base64 encoded image works. If there is a better choices - please left comments and answers.

marknorkin
  • 3,904
  • 10
  • 46
  • 82