如何通过 http post ByteArrayOutputStream

How to post ByteArrayOutputStream via http

我目前正在读取一个文件,然后将其写入一个 HTTP 连接,该连接将文件本地保存到磁盘 - 它工作正常。

但是,由于我工作的环境,我无法从磁盘读取文件,而是从数据库中提取文件并存储在我的 java 代码中的 ByteArrayOutputStream 中。

因此,我需要使用 ByteOutputArrayStream 并将其写入 http 连接,而不是从磁盘读取文件开始。

我需要一种有效的方法来执行此操作 - 如果我可以修改我当前的代码 (blow) 那很好 - 如有必要,我愿意将其全部废弃...

        // This is the primary call from jsp
        public String postServer(String[] args)throws Exception{
            System.out.println("******* HTTPTestJPO  inside postServer");

            String requestURL = "http://MyServer:8080/TransferTest/UploadServlet";
            String charset = "UTF-8";
            String sTest=args[0];
            String sResponse="";

            System.out.println("******* HTTPTestJPO incoming file string sTest:"+sTest);

            MultipartUtility multipart = new MultipartUtility(requestURL, charset);
            StringTokenizer inFiles=new StringTokenizer(sTest,",");
            while(inFiles.hasMoreTokens()){
                String tmpFileName=inFiles.nextToken();
                System.out.println("*******  tokenized tmpFileName:"+tmpFileName);
                File uploadFile1 = new File(tmpFileName);
                try {
                    multipart.addFilePart("fileUpload", uploadFile1);
                } catch (IOException ex) {
                    System.err.println("******* HTTPTestJPO  EXCEPTION: "+ex);
                }
            }

            sResponse = multipart.handleFinish();
            System.out.println("******* HTTPTestJPO   SERVER REPLIED:"+sResponse);
            return sResponse;
        }

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // Multipart utility
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        /**
         * This utility class provides an abstraction layer for sending multipart HTTP
         * POST requests to a web server.
         * @author www.codejava.net
         *
         */
        public class MultipartUtility {
            private final String boundary;
            private static final String LINE_FEED = "\r\n";
            private HttpURLConnection httpConn;
            private String charset;
            private OutputStream outputStream;
            private PrintWriter writer;

            /**
             * This constructor initializes a new HTTP POST request with content type
             * is set to multipart/form-data
             * @param requestURL
             * @param charset
             * @throws IOException
             */
            public MultipartUtility(String requestURL, String charset)throws IOException {
                this.charset = charset;

                // creates a unique boundary based on time stamp
                boundary = "===" + System.currentTimeMillis() + "===";

                URL url = new URL(requestURL);
                httpConn = (HttpURLConnection) url.openConnection();
                httpConn.setUseCaches(false);
                httpConn.setDoOutput(true); // indicates POST method
                httpConn.setDoInput(true);
                httpConn.setRequestProperty("Content-Type","multipart/form-data; boundary=" + boundary);
                //httpConn.setRequestProperty("User-Agent", "CodeJava Agent");
                //httpConn.setRequestProperty("Test", "Bonjour");
                outputStream = httpConn.getOutputStream();
                writer = new PrintWriter(new OutputStreamWriter(outputStream, charset),true);
            }

            /**
             * Adds a upload file section to the request
             * @param fieldName name attribute in <input type="file" name="..." />
             * @param uploadFile a File to be uploaded
             * @throws IOException
             */

            public void addFilePart(String fieldName, File uploadFile)throws IOException {
                String fileName = uploadFile.getName();
                writer.append("--" + boundary).append(LINE_FEED);
                writer.append("Content-Disposition: form-data; name=\"" + fieldName + "\"; filename=\"" + fileName + "\"").append(LINE_FEED);
                writer.append("Content-Type: "+ URLConnection.guessContentTypeFromName(fileName)).append(LINE_FEED);
                writer.append("Content-Transfer-Encoding: binary").append(LINE_FEED);
                writer.append(LINE_FEED);
                writer.flush();

   // HOW CAN I MODIFY THIS TO SEND AN EXISTING BYTEARRAYOUTPUTSTREAM INSTEAD OF A DISK FILE??
                FileInputStream inputStream = new FileInputStream(uploadFile);
                byte[] buffer = new byte[4096];
                int bytesRead = -1;
                while ((bytesRead = inputStream.read(buffer)) != -1) {
                    outputStream.write(buffer, 0, bytesRead);
                }
                outputStream.flush();
                inputStream.close();

                writer.append(LINE_FEED);
                writer.flush();     
            }

            /**
             * Completes the request and receives response from the server.
             * @return a list of Strings as response in case the server returned
             * status OK, otherwise an exception is thrown.
             * @throws IOException
             */
            private String handleFinish() throws IOException {
                String sResponse = "";

                //close out the multipart send
                writer.append(LINE_FEED).flush();
                writer.append("--" + boundary + "--").append(LINE_FEED);
                writer.close();

                // checks server's status code first
                int status = httpConn.getResponseCode();
                sResponse=Integer.toString(status);
                System.out.println("******* HTTPTestJPO http response code:"+status);
                // if (status == HttpURLConnection.HTTP_OK) {
                    // BufferedReader reader = new BufferedReader(new InputStreamReader(
                            // httpConn.getInputStream()));
                    // String line = reader.readLine();
                    // while ((line = reader.readLine()) != null) {
                        // sResponse+=line;
                    // }
                    // reader.close();
                     httpConn.disconnect();
                // } else {
                    // throw new IOException("Server returned non-OK status: " + status);
                // }

                return sResponse;
            }
        }
    }

可以使用 writeTo 方法将 ByteArrayOutputStream 的内容写入另一个 OutputStream,如下所示:

byteArrayOutputStream.writeTo(outputStream);

另一种选择是创建一个新的 InputStream:

InputStream inputStream = new ByteArrayInputStream(
        byteArrayOutputStream.toByteArray());

但调用 toByteArray 会复制字节数组,因此成本更高。