3

I've got a legacy application that writes to an OutputStream, and I'd like to have the contents of this stream uploaded as a file to a Servlet. I've tested the Servlet, which uses commons-fileupload, using JMeter and it works just fine.

I would use Apache HttpClient, but it requires a File rather than just an output stream. I can't write a file locally; if there was some in-memory implementation of File perhaps that might work?

I've tried using HttpURLConnection (below) but the server responds with "MalformedStreamException: Stream ended unexpectedly".

        URL url = new URL("http", "localhost", 8080, "/upload");
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        connection.setDoOutput(true);
        String boundary = "---------------------------7d226f700d0";
        connection.setRequestProperty("Content-Disposition", "form-data; name=\"file\""); 
        connection.setRequestProperty("Content-Type", "multipart/form-data; boundary="+boundary);
        connection.setRequestProperty("Accept", "application/json");
        connection.setRequestMethod("POST");   
        connection.setChunkedStreamingMode(0);
        connection.connect();           

        OutputStream out = connection.getOutputStream();
        byte[] boundaryBytes =("--" + boundary + "\r\n").getBytes();
        out.write(boundaryBytes);


        //App writes to outputstream here

        out.write("\r\n".getBytes());
        out.write(("--"+boundary+"--").getBytes());
        out.write("\r\n".getBytes());

        out.flush();
        out.close();
        connection.disconnect();
1
  • By definition, there is no in-memory implementation of File. You can, however, replicate the HttpClient method and pass your bytes or stream directly, as that API most likely loads the file's bytes via a stream. Commented Sep 27, 2012 at 14:24

1 Answer 1

1

The PostMethod allows you to set a RequestEntity, which is an interface which you can implement. you just need to implement the RequestEntity.writeRequest method appropriately.

Or, if you want HttpClient to handle the multi-part stuff for you, you could use MultipartRequestEntity with a custom Part.

Sign up to request clarification or add additional context in comments.

2 Comments

Excellent - looks like I could even just implement PartSource. The legacy app takes OutputStream as an argument, and then writes to it, so I'm in control of what OutputStream goes in there. I'm guessing I could use a ByteArrayOutputStream, have the legacy code write to that, generate the byte array, and then implement a PartSource that takes a byte array instead of a file, and then provides an ByteArrayInputStream from that?
@Deejay - you could do that, but it wouldn't scale very well if you have large streams.

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.