如何通过 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
会复制字节数组,因此成本更高。
我目前正在读取一个文件,然后将其写入一个 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
会复制字节数组,因此成本更高。