Alexander Farber
Alexander Farber

Reputation: 22988

How to upload a BufferedImage using Jetty HTTP client and MultiPartContentProvider?

With Jetty 9.4.21.v20190926 I run a custom servlet (a WAR-file), which is able to generate images like this one:

generated image

by the following code:

@Override
protected void doGet(HttpServletRequest httpReq, HttpServletResponse httpResp) throws ServletException, IOException {
    BufferedImage image = new BufferedImage(512, 512, BufferedImage.TYPE_INT_RGB);
    Graphics2D g = image.createGraphics();
    // ...drawing code skipped here...
    g.dispose();
    httpResp.setStatus(HttpServletResponse.SC_OK);
    httpResp.setContentType("image/png");
    ImageIO.write(image, "png", httpResp.getOutputStream());
}

This works well and now I would like to add another feature to my servlet: uploading the same image by HTTP POST to another website (I would trigger the upload by calling an URL on my servlet by a hourly cronjob).

I understand, that I should use MultiPartContentProvider and the following code:

MultiPartContentProvider multiPart = new MultiPartContentProvider();
multiPart.addFilePart("attached_media", "img.png", new PathContentProvider(Paths.get("/tmp/img.png")), null);
multiPart.close();

however I would prefer not to save the generated image as a temporary file.

Instead I would like to use BytesContentProvider or maybe InputStreamContentProvider… but how to marry them with ImageIO.write() call?

Upvotes: 0

Views: 583

Answers (1)

Joakim Erdfelt
Joakim Erdfelt

Reputation: 49462

Have you tried to use a OutputStreamContentProvider instead of a PathContentProvider in your multipart.addFilePart()?

See https://www.eclipse.org/jetty/javadoc/current/org/eclipse/jetty/client/util/OutputStreamContentProvider.html

Then you can just use the ImageIO.write(image, "png", outputStreamContentProvider);

Example:

HttpClient httpClient = ...;

 // the output for the image data
 OutputStreamContentProvider content = new OutputStreamContentProvider();
 MultiPartContentProvider multiPart = new MultiPartContentProvider();
 multiPart.addFilePart("attached_media", "img.png", content, null);
 multiPart.close();
 // Use try-with-resources to autoclose the output stream
 try (OutputStream output = content.getOutputStream())
 {
     httpClient.newRequest("localhost", 8080)
             .content(multipart)
             .send(new Response.CompleteListener()
             {
                 @Override
                 public void onComplete(Result result)
                 {
                     // Your logic here
                 }
             });

     // At a later time...
     ImageIO.write(image, "png", output);
 }

Upvotes: 1

Related Questions