Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 days ago.
Improve this question
This code works perfectly in Java 8 and I am getting a success message. But the exact code does not work in Java 6.
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.io.OutputStreamWriter;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.List;
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.setRequestMethod("POST");
httpConn.setDoOutput(true); // indicates POST method
httpConn.setDoInput(true);
httpConn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
httpConn.setRequestProperty("Cookie","abc=AHGYjGHTTTTTTTTTTTJJJJJHHHHHH; stsservicecookie=estsfd; x-ms-gateway-slice=abcdef");
httpConn.setRequestProperty("Host","login.microsoftonline.com");
outputStream = httpConn.getOutputStream();
writer = new PrintWriter(new OutputStreamWriter(outputStream, charset), true);
}
/**
* Adds a form field to the request
* #param name field name
* #param value field value`your text`
*/
public void addFormField(String name, String value) {
writer.append("--" + boundary).append(LINE_FEED);
writer.append("Content-Disposition: form-data; name=\"" + name + "\"").append(LINE_FEED);
//writer.append("Content-Type: text/plain; charset=" + charset).append(LINE_FEED);
writer.append(LINE_FEED);
writer.append(value).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
*/
public List<String> finish() throws IOException {
List<String> response = new ArrayList<String>();
writer.append(LINE_FEED).flush();
writer.append("--" + boundary + "--").append(LINE_FEED);
writer.close();
// checks server's status code first
int status = httpConn.getResponseCode();
System.out.println(status);
if (status == HttpURLConnection.HTTP_OK) {
BufferedReader reader = new BufferedReader(new InputStreamReader(httpConn.getInputStream()));
String line = null;
while ((line = reader.readLine()) != null) {
response.add(line);
}
reader.close();
httpConn.disconnect();
} else {
throw new IOException("Server returned non-OK status: " + status);
}
return response;
}
public static void main(String[] args) {
String charset = "ISO-8859-1";
String requestURL = "https://login.microsoftonline.com/common/oauth2/token";
try {
MultipartUtility multipart = new MultipartUtility(requestURL, charset);
multipart.addFormField("grant_type", "password");
multipart.addFormField("client_id", "abc");
multipart.addFormField("resource", "abc");
multipart.addFormField("username", "abc");
multipart.addFormField("password", "XXXXXX");
multipart.addFormField("client_secret", "XXXXXXXX");
//multipart.addFilePart("fileUpload", uploadFile1);
List<String> response = multipart.finish();
System.out.println("SERVER REPLIED:");
for (String line : response) {
System.out.println(line);
}
} catch (IOException ex) {
System.out.println("ERROR: " + ex.getMessage());
ex.printStackTrace();
}
}
}
I am getting a 400 response from the server. I also tried printing the request but am not able to.
Related
I am trying to upload an image on discourse using discourse API. I tested it using postman and i works fine.
then i converted the code to java as shown below
HttpPostMultipart.java
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.Iterator;
import java.util.Map;
import java.util.UUID;
public class HttpPostMultipart {
private final String boundary;
private static final String LINE = "\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
* #param headers
* #throws IOException
*/
public HttpPostMultipart(String requestURL, String charset, Map<String, String> headers) throws IOException {
this.charset = charset;
boundary = UUID.randomUUID().toString();
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);
if (headers != null && headers.size() > 0) {
Iterator<String> it = headers.keySet().iterator();
while (it.hasNext()) {
String key = it.next();
String value = headers.get(key);
httpConn.setRequestProperty(key, value);
}
}
outputStream = httpConn.getOutputStream();
writer = new PrintWriter(new OutputStreamWriter(outputStream, charset), true);
}
/**
* Adds a form field to the request
*
* #param name field name
* #param value field value
*/
public void addFormField(String name, String value) {
writer.append("--" + boundary).append(LINE);
writer.append("Content-Disposition: form-data; name=\"" + name + "\"").append(LINE);
writer.append("Content-Type: text/plain; charset=" + charset).append(LINE);
writer.append(LINE);
writer.append(value).append(LINE);
writer.flush();
}
/**
* Adds a upload file section to the request
*
* #param fieldName
* #param uploadFile
* #throws IOException
*/
public void addFilePart(String fieldName, File uploadFile)
throws IOException {
String fileName = uploadFile.getName();
writer.append("--" + boundary).append(LINE);
writer.append("Content-Disposition: form-data; name=\"" + fieldName + "\"; filename=\"" + fileName + "\"").append(LINE);
writer.append("Content-Type: " + URLConnection.guessContentTypeFromName(fileName)).append(LINE);
writer.append("Content-Transfer-Encoding: binary").append(LINE);
writer.append(LINE);
writer.flush();
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);
writer.flush();
}
/**
* Completes the request and receives response from the server.
*
* #return String as response in case the server returned
* status OK, otherwise an exception is thrown.
* #throws IOException
*/
public String finish() throws IOException {
String response = "";
writer.flush();
writer.append("--" + boundary + "--").append(LINE);
writer.close();
// checks server's status code first
int status = httpConn.getResponseCode();
if (status == HttpURLConnection.HTTP_OK) {
ByteArrayOutputStream result = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int length;
while ((length = httpConn.getInputStream().read(buffer)) != -1) {
result.write(buffer, 0, length);
}
response = result.toString(this.charset);
httpConn.disconnect();
} else {
throw new IOException("Server returned non-OK status: " + status);
}
return response;
}
}
and main class Upload.java
import java.net.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import java.util.*;
import java.io.*;
public class Upload {
private final static String BASE_URL = "http://localhost:4200";
private final static String API_KEY = "55acbd478e8b26551240d1b614f3781356541d4ce1fb57c84a672545537f4c92";
static String boundary = "WebKitFormBoundary7MA4YWxkTrZu0gW";
private static final String LINE_FEED = "\r\n";
public static void main(String[] args) {
try {
// Set header
Map<String, String> headers = new HashMap<>();
headers.put("api-key", API_KEY);
headers.put("api-username", "devarshmavani19");
headers.put("content-type", "multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW");
HttpPostMultipart multipart = new HttpPostMultipart("http://localhost:4200/uploads.json", "utf-8", headers);
// Add form field
multipart.addFormField("type", "image");
multipart.addFormField("synchronous", "true");
// Add file
multipart.addFilePart("file", new File("/home/devarsh/Desktop/small.jpeg"));
// Print result
String response = multipart.finish();
System.out.println(response);
} catch (Exception e) {
e.printStackTrace();
}
}
}
when i run this code it gives me 500 internal server error. But the same thing works in postman.
in the postman i used the code generator to generate HTTP structure as shown below
POST /uploads.json HTTP/1.1
Host: localhost:4200
Api-Key: 55acbd478e8b26551240d1b614f3781356541d4ce1fb57c84a672545537f4c92
Api-Username: tester
Cache-Control: no-cache
Postman-Token: 01084a62-6ad2-def1-7a8c-901622c99d21
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="type"
composer
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="synchronous"
true
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="file"; filename="Screenshot from 2022-06-16 22-36-14.png"
Content-Type: image/png
------WebKitFormBoundary7MA4YWxkTrZu0gW--
I am adding postman as tag because In case there is a way i can generate code for java (java.net only) in postman then it will be very helpful
Please help me to accomplish this using java.net package only as i am not allowed to use other libs.
I have a problem calling a webAPI in Java. Basically, I have to upload a file (xml or pdf) but I cannot get it work. I tried in Postman and it works, I had to put in the body the filename and the content of the file
If I declare the filedata as file (see pic. 3) it works. I tried to do it in Java but I cannot find a way to do it. I tried many snippets from the web buut at best when I run them I get error 500.
The code I got so far is
package api_post;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.List;
public class API_POST {
/**
* #param args the command line arguments
*/
public static void main(String[] args) throws IOException {
String charset = "UTF-8";
File uploadFile1 = new File("[fileWithPath]");
String requestURL = "";
requestURL = "[URL]";
try {
MultipartUtility multipart = new MultipartUtility(requestURL, charset);
multipart.addFormField("username", "[user]");
multipart.addFormField("password", "[pwd]");
multipart.addFormField("owner", "[owner]");
multipart.addFormField("destination", "[destination]");
multipart.addFilePart("fileData", uploadFile1);
List<String> response = multipart.finish();
System.out.println("SERVER REPLIED:");
for (String line : response) {
System.out.println(line);
}
} catch (IOException ex) {
System.err.println(ex);
}
}
public static 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;
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);
outputStream = httpConn.getOutputStream();
writer = new PrintWriter(new OutputStreamWriter(outputStream, charset),
true);
}
/**
* Adds a form field to the request
* #param name field name
* #param value field value
*/
public void addFormField(String name, String value) {
writer.append("--" + boundary).append(LINE_FEED);
writer.append("Content-Disposition: form-data; name=\"" + name + "\"")
.append(LINE_FEED);
writer.append("Content-Type: text/plain; charset=" + charset).append(
LINE_FEED);
writer.append(LINE_FEED);
writer.append(value).append(LINE_FEED);
writer.flush();
}
/**
* 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();
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();
}
/**
* Adds a header field to the request.
* #param name - name of the header field
* #param value - value of the header field
*/
public void addHeaderField(String name, String value) {
writer.append(name + ": " + value).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
*/
public List<String> finish() throws IOException {
List<String> response = new ArrayList<String>();
writer.append(LINE_FEED).flush();
writer.append("--" + boundary + "--").append(LINE_FEED);
writer.close();
// checks server's status code first
int status = httpConn.getResponseCode();
if (status == HttpURLConnection.HTTP_OK) {
System.out.println("Entrato");
BufferedReader reader = new BufferedReader(new InputStreamReader(
httpConn.getInputStream()));
String line = null;
while ((line = reader.readLine()) != null) {
response.add(line);
}
reader.close();
httpConn.disconnect();
} else {
throw new IOException("Server returned non-OK status: " + status);
}
return response;
}}}
Can anybody help me please?
I just discovered that in postman I can see the java source code of the call. I used that and now it works.
I want to send to OCR image from local computer, not some remote url with image there (this case working great). But the problem is, I don't know how construct correctly payload of multipart entity. My payload should be looking as it described below.
This's what described in documentation of API. Decode the image data given directly in the multipart/related data. The order is important, and the first part should be the JSON, which tells it which OCR engine to use. The schema for thi JSON is documented in the /ocr endpoint. The img_url parameter of the JSON will be ignored in this case.
The image attachment should be the second part, and it should work with any image content type (eg, image/png, image/jpg, etc).
Request (multipart/related; boundary=---BOUNDARY)
-----BOUNDARY
Content-Type: application/json
{"engine":"tesseract"}
-----BOUNDARY
-----BOUNDARY
Content-Disposition: attachment;
Content-Type: image/png
filename="attachment.txt".
PNGDATA.........
-----BOUNDARY
Here's what I've tried. To perform multipart/related request I am using org.apache.httpcomponents
CloseableHttpClient httpClient = HttpClients.createDefault();
MultipartEntityBuilder multipartEntityBuilder =
MultipartEntityBuilder.create().setBoundary(BOUNDARY).setContentType(ContentType.APPLICATION_JSON).addTextBody("engine", "tesseract")
.setBoundary(BOUNDARY).setBoundary(BOUNDARY);
multipartEntityBuilder.addBinaryBody("file_upload", new File(fileTextPath), ContentType.create(CONTENT_TYPE), fileTextPath).setBoundary(BOUNDARY);
HttpEntity entity = multipartEntityBuilder.build();
HttpPost httpPost = new HttpPost(URL);
httpPost.setHeader(HttpHeaders.CONTENT_TYPE, CONTENT_TYPE_MULTIPART+";boundary="+BOUNDARY);
httpPost.setEntity(entity);
I resolved this problem a few weeks ago and for convenience created a lightweight java web application for both cases (remote and file upload).
You can find the particular answer for the question above here. The source code for a multipart request is shown below:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.UUID;
public class MultipartUtility {
private static final Logger logger = LoggerFactory.getLogger(MultipartUtility.class);
private final String boundary = UUID.randomUUID().toString();
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) {
this.charset = charset;
try {
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/related; boundary=\"" + boundary + "\"");
httpConn.setRequestProperty("Accept-Encoding", "gzip");
outputStream = httpConn.getOutputStream();
//outputStream = System.out;
writer = new PrintWriter(new OutputStreamWriter(outputStream, charset), true);
} catch (IOException ex) {
logger.error("Error during creation of MultiPart: ", ex);
}
}
/**
* Adds a form field to the request
*/
public void addFormField(String jsonBody) {
writer.append("--").append(boundary).append(LINE_FEED);
writer.append("Content-Type: application/json;").append(LINE_FEED);
writer.append(LINE_FEED);
writer.append(jsonBody).append(LINE_FEED);
writer.flush();
}
/**
* Adds a upload file section to the request
*
* #param uploadFile a File to be uploaded
* #throws IOException
*/
public void addFilePart(File uploadFile) {
String fileName = uploadFile.getName();
writer.append("--").append(boundary).append(LINE_FEED);
writer.append("Content-Disposition: attachment;");
writer.append(" filename=\"" + fileName + "\".").append(LINE_FEED);
writer.append("Content-Type: image/*").append(LINE_FEED);
writer.append(LINE_FEED);
writer.flush();
try {
FileInputStream inputStream = new FileInputStream(uploadFile);
//byte[] buffer = new byte[(int) uploadFile.length()];
byte[] buffer = Files.readAllBytes(Paths.get(uploadFile.getPath()));
int bytesRead = -1;
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
outputStream.flush();
inputStream.close();
} catch (IOException ex) {
logger.error("File transformation to bytes went wrong: {}", ex);
}
writer.append(LINE_FEED);
writer.flush();
}
/**
* Adds a header field to the request.
*
* #param name - name of the header field
* #param value - value of the header field
*/
public void addHeaderField(String name, String value) {
writer.append(name + ": " + value).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
*/
public String finish() {
String response = "";
int status = 0;
writer.flush();
writer.append("--").append(boundary).append("--").append(LINE_FEED);
writer.println();
writer.close();
try {
// checks server's status code first
status = httpConn.getResponseCode();
if (status == HttpURLConnection.HTTP_OK) {
BufferedReader reader = new BufferedReader(new InputStreamReader(httpConn.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
response += line;
}
reader.close();
httpConn.disconnect();
} else {
logger.error("OCR API returned error stream: {}", printErrorStream());
throw new IOException("Server returned non-OK status: " + status + " : " + httpConn.getResponseMessage());
//logger.error("Server returned non-OK status: " + status + " : " + httpConn.getResponseMessage());
}
} catch(IOException ex) {
logger.error("Response message in Multipart finish has been received with problems: ", ex);
}
return response;
}
private String printErrorStream() throws IOException {
//System.out.print("DEBUG System out ocr API error stream: ");
InputStream errorStream = httpConn.getErrorStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(errorStream));
String errLine = "", tempLine;
while ((tempLine = reader.readLine()) != null) {
errLine += tempLine;
}
return errLine;
}
private void getRequestHeaders(HttpURLConnection httpURLConnection) {
for (Map.Entry<String, List<String>> entries : httpURLConnection.getRequestProperties().entrySet()) {
String values = "";
for (String value : entries.getValue()) {
values += value + ",";
}
System.out.println("Request" + " " + entries.getKey() + " - " + values );
}
}
}
I am currently reading a file from then writing it to an HTTP connection which saves the file locally to disk - it's working fine.
However, because of the environment I'm working within I cannot read files from disk, rather they are pulled from a database and stored in a ByteArrayOutputStream in my java code.
So instead of starting by reading a file from disk, I need to use a ByteOutputArrayStream and write that to an http connection instead.
I need an efficient method to do this - If I can modify my current code (bloew) that's fine - I'm willing to scrap it all if necessary...
// 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;
}
}
}
The contents of a ByteArrayOutputStream can be written to another OutputStream using the writeTo method, like this:
byteArrayOutputStream.writeTo(outputStream);
Another option would be to create a new InputStream:
InputStream inputStream = new ByteArrayInputStream(
byteArrayOutputStream.toByteArray());
but calling toByteArray makes a copy of the byte array, so is more expensive.
Let me see if I can explain this. The front-end provides me with a spreadsheet that I need to pass to my central server via an api call to do the processing. I use the following code to pull out the spreadsheet and create my work book,
Part spreadsheet = request.getPart(SPREADSHEET);
Workbook workbook = WorkbookFactory.create(spreadsheet.getInputStream());
Where 'request' is an incoming HttpServletRequest object. I know that it works and I can manipulate the spreadsheet, but I need to pass it along to my other server to do the processing and I can't figure out how to do that. Here is what I have so far.
#Path("/uploadSpreadsheet")
#POST
public String uploadSpreadsheet(#Context final HttpServletRequest request,#Context final HttpHeaders httpHeaders) throws IOException, ServletException, InvalidFormatException, JSONException {
return uploadUtil(request, "rest/memberService/uploadSpreadsheet");
}
Here is the util that I can't get right.
private String uploadUtil(HttpServletRequest request, String serviceUrl) throws MalformedURLException, ProtocolException, IOException, ServletException {
String baseUrl = "http://localhost:8084/centralservices/";
String urlString = baseUrl.concat(serviceUrl);
URL url = new URL(urlString);
String boundary = "===" + System.currentTimeMillis() + "===";
HttpURLConnection httpCon = (HttpURLConnection) url.openConnection();
httpCon.setDoOutput(true);
httpCon.setRequestMethod("POST");
httpCon.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
httpCon.setRequestProperty("Key", "SOMEKEYHERE");
httpCon.setRequestProperty("clientAddress", request.getRemoteAddr());
//I know this is wrong but I'm not sure what goes here:
httpCon.setRequestProperty("file", request.getPart(SPREADSHEET));
int responseCode;
StringBuilder resp = new StringBuilder();
BufferedReader in = null;
try {
in = new BufferedReader(new InputStreamReader(httpCon.getInputStream(), "UTF-8"));
String inputLine;
while ((inputLine = in.readLine()) != null) {
resp.append(inputLine);
}
} finally {
if (in != null) {
in.close();
}
httpCon.disconnect();
}
return resp.toString();
}
Hopefully that makes sense. I mean all I really need to do is transfer the request identically(with all the formparts and everything) to a different url. Once it gets there I have no issue processing it. Let me know if I am unclear on something. I'm pretty new to this stuff. We already have a rest utility that I've always used for everything else, but it doesn't work for this scenario so I need to create a new one.
If you are using the Servlet-Api 3.0, then the below approach gives you on how to read the stream and write back the stream to the subsequent URL.
http://balusc.omnifaces.org/2009/12/uploading-files-in-servlet-30.html
From your code above , once you get the Part , convert the obtained file/workbook to bytebuffer and then write it to Output stream.
connection.getOutputStream().write(filebuff);
Because adding to request property will not help in this case.
Thanks
Maruthi
I was too unfamiliar with some of the options presented so I just converted the spreadsheet into a json string and sent that over with my existing rest utility.
I think there's a lot of stuff missing in the multipart request. See this link
Sending files using POST with HttpURLConnection.
Also it's probably better to use some API to do this for you, probably easiest would be apache httpclient
See the example usage in this SO post
If you do need to use URLConnection for this then you can use this multipart utility from codejava.net
I'm posting the code from there here for backup in case original link goes down.
MultipartUtility
package net.codejava.networking;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.List;
/**
* 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");
/*Following line has no significance for the task this utility performs*/
/*httpConn.setRequestProperty("Test", "Bonjour");*/
outputStream = httpConn.getOutputStream();
writer = new PrintWriter(new OutputStreamWriter(outputStream, charset),
true);
}
/**
* Adds a form field to the request
* #param name field name
* #param value field value
*/
public void addFormField(String name, String value) {
writer.append("--" + boundary).append(LINE_FEED);
writer.append("Content-Disposition: form-data; name=\"" + name + "\"")
.append(LINE_FEED);
writer.append("Content-Type: text/plain; charset=" + charset).append(
LINE_FEED);
writer.append(LINE_FEED);
writer.append(value).append(LINE_FEED);
writer.flush();
}
/**
* 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();
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();
}
/**
* Adds a header field to the request.
* #param name - name of the header field
* #param value - value of the header field
*/
public void addHeaderField(String name, String value) {
writer.append(name + ": " + value).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
*/
public List<String> finish() throws IOException {
List<String> response = new ArrayList<String>();
writer.append(LINE_FEED).flush();
writer.append("--" + boundary + "--").append(LINE_FEED);
writer.close();
// checks server's status code first
int status = httpConn.getResponseCode();
if (status == HttpURLConnection.HTTP_OK) {
BufferedReader reader = new BufferedReader(new InputStreamReader(
httpConn.getInputStream()));
String line = null;
while ((line = reader.readLine()) != null) {
response.add(line);
}
reader.close();
httpConn.disconnect();
} else {
throw new IOException("Server returned non-OK status: " + status);
}
return response;
}
}
Test Program
package net.codejava.networking;
import java.io.File;
import java.io.IOException;
import java.util.List;
/**
* This program demonstrates a usage of the MultipartUtility class.
* #author www.codejava.net
*
*/
public class MultipartFileUploader {
public static void main(String[] args) {
String charset = "UTF-8";
File uploadFile1 = new File("e:/Test/PIC1.JPG");
File uploadFile2 = new File("e:/Test/PIC2.JPG");
String requestURL = "http://localhost:8080/FileUploadSpringMVC/uploadFile.do";
try {
MultipartUtility multipart = new MultipartUtility(requestURL, charset);
multipart.addHeaderField("User-Agent", "CodeJava");
multipart.addHeaderField("Test-Header", "Header-Value");
multipart.addFormField("description", "Cool Pictures");
multipart.addFormField("keywords", "Java,upload,Spring");
multipart.addFilePart("fileUpload", uploadFile1);
multipart.addFilePart("fileUpload", uploadFile2);
List<String> response = multipart.finish();
System.out.println("SERVER REPLIED:");
for (String line : response) {
System.out.println(line);
}
} catch (IOException ex) {
System.err.println(ex);
}
}
}