7

I'm developing an HTTP server using HttpServer and HttpHandler.

The server should response to clients with XML data or images.

So far, I have developed HttpHandler implementations which respond to the clients with the XML data but I couldn't implement a HttpHandler which reads the image from file and send it to the client (e.g., a browser).

The image should not be loaded fully into memory so I need some kind of streaming solution.

public class ImagesHandler implements HttpHandler {
    @Override
    public void handle(HttpExchange arg0) throws IOException {
        File file=new File("/root/images/test.gif");
        BufferedImage bufferedImage=ImageIO.read(file);

        WritableRaster writableRaster=bufferedImage.getRaster();
        DataBufferByte data=(DataBufferByte) writableRaster.getDataBuffer();

        arg0.sendResponseHeaders(200, data.getData().length);
        OutputStream outputStream=arg0.getResponseBody();
        outputStream.write(data.getData());
        outputStream.close();
    }
}

This code just sends 512 bytes of data to the browser.

2 Answers 2

12

You're doing way too much work here: decoding the image, and storing it in memory. You shouldn't try to read the file as an image. That is useless. All the browser needs is the bytes that are in the image file. So you should simply send the bytes in the image file as is:

File file = new File("/root/images/test.gif");
arg0.sendResponseHeaders(200, file.length());
// TODO set the Content-Type header to image/gif 

OutputStream outputStream=arg0.getResponseBody();
Files.copy(file.toPath(), outputStream);
outputStream.close();
Sign up to request clarification or add additional context in comments.

2 Comments

With this, the image is downloaded on the browser. What if I need to image to be displayed in the browser (somewhat like having an <img> tag)?
@HarshChiki <img src="/path/to/the/servlet/or/handler/or/action/which/allows/dowloading/the/image" />
0

DataBufferByte stores its data in banks. getData() retrieves only the first bank, so you're declaring a length of only the first bank and then writing only the first bank.

Instead of your current write line, try this instead (untested):

arg0.sendResponseHeaders(200, data.getDataTypeSize(TYPE_BYTE));
OutputStream outputStream=arg0.getResponseBody();
for (byte[] dataBank : data.getBankData()) {
  outputStream.write(dataBank);
}
outputStream.close

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.