http response multipart binary File in java - java

I am not able to read multipart file from the http response. The response contains the MIME Boundary and content transfer encoding - binary. we need to read the date from the response and send the request to another http post method. here we are facing two issues.
Not able to read the binary file properly from the http response.
Not able to form the multipart file to send the request.
when I have send that multipart form data in http post method. I am not receiving proper response. beacuse of the multipart binary encoding file. please provide the sample to read the multipart binary file and how to form and send the multipart file.
private void postLocalRequest(URL url, byte[] requestBody, String contentType, String authHeader)
throws IOException, ProtocolException, Exception {
logger.info("local request URL:::" + url);
logger.info("local request content type:::" + contentType);
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.setRequestMethod("POST");
if (!authHeader.isEmpty()) {
httpURLConnection.setRequestProperty("Authorization", authHeader);
}
httpURLConnection.addRequestProperty("Accept", "application/json; charset=UTF-8");
httpURLConnection.setRequestProperty("Content-Type", contentType);
httpURLConnection.setDoOutput(true);
httpURLConnection.setDoInput(true);
OutputStream outputStream = httpURLConnection.getOutputStream();
outputStream.write(requestBody);
outputStream.flush();
logger.info("waiting for local response");
BufferedReader bufferedReader = null;
logger.info("http response code :::" + httpURLConnection.getResponseCode());
deviceResponse = "";
deviceResponseContentType = httpURLConnection.getContentType();
logger.info("device Response Content Type::" + deviceResponseContentType);
if (httpURLConnection.getResponseCode() == HttpURLConnection.HTTP_OK) {
bufferedReader = new BufferedReader(new InputStreamReader(httpURLConnection.getInputStream()));
deviceResponse = bufferedReader.lines().collect(Collectors.joining("\n"));
XWCConnectorSupplementalLogging.logXML(logger, "plr", "Device Request Output", deviceResponse);
} else {
try {
InputStream ip = httpURLConnection.getInputStream();
String info = new BufferedReader(new InputStreamReader(ip)).lines().collect(Collectors.joining("\n"));
deviceResponse = info;
XWCConnectorSupplementalLogging.logXML(logger, "plr", "Device Request Output", info);
} catch (Exception e) {
try {
InputStream es = httpURLConnection.getErrorStream();
String error = new BufferedReader(new InputStreamReader(es)).lines()
.collect(Collectors.joining("\n"));
if(httpURLConnection.getResponseCode() != HttpURLConnection.HTTP_NOT_FOUND) {
deviceResponse = error;
}
XWCConnectorSupplementalLogging.logXML(logger, "plr", "Device Request Error", error);
} catch (Exception e1) {
logger.severe("Unable to read Request error or output");
}
}
}
}

Related

Java how to send special character is post

Im trying to send a post to a backend API from android and this is what I have but some special characters relating to application/x-www-form-urlencoded content type wont be sent or cause problems. Im wondering if there is a way to send the special characters in this format? (+,&) I'm attempting to send the message "This is a message + a test" but my database is getting "This is a message a test"
I've tried passing JSON but the backend that my co-students wrote doesn't accept JSON and returns a 401 not authorized error.
public void sendMessage() {
if(!mEdit.getText().toString().trim().matches("")) { //Cant send empty strings
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
try {
URL url = new URL(Sendurl); //Create URL
HttpURLConnection conn = (HttpURLConnection) url.openConnection(); //Create a Connector
conn.setRequestMethod("POST"); //Dictate the Method
conn.setRequestProperty("Content-Type", "application/json; utf-8"); //Some other properties
conn.setRequestProperty("Accept", "application/json");
conn.setDoOutput(true);
conn.setDoInput(true);
//This part causes a 401 error because it is the equivalent of passing parameters but our backend uses body formatting
JSONObject jsonParam = new JSONObject();
Date date = new Date();
RequestParams params = new RequestParams();
params.put("username", "admin");
params.put("sessionID", 1);
params.put("cardNum", 111111111);
params.put("sentByStaff", "false");
params.put("message", "This is the message + a test");
params.put("time", date.getTime()/1000);
Log.i("JSON", params.toString());
// OutputStreamWriter os = new OutputStreamWriter(conn.getOutputStream()); //Prepare the connection for output
POST_PARAMS = params.toString(); //Converts post parameters to body type
System.out.println(POST_PARAMS);
try(OutputStream os = conn.getOutputStream()) {
byte[] input = POST_PARAMS.getBytes("utf-8");
os.write(input, 0, input.length);
os.flush();
os.close();
}
//os.write(POST_PARAMS); //Write our parameters to the post
//os.flush(); //Do the thing
//os.close();
Log.i("STATUS", String.valueOf(conn.getResponseCode())); //Debug
Log.i("MSG", conn.getResponseMessage()); //Debug
int responseCode = 0; //get response code
responseCode = conn.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) { //On success
mEdit.setText("");
}
conn.disconnect(); //disconnect after attempting post
getMessage(); //update our messages
} catch (Exception e) { //dirty catch all
e.printStackTrace();
}
}
});
thread.start();
}
}

Can't send JSON in a Java HTTP POST request

I'm getting a 'Server returned HTTP response code: 500' error although I have checked what I'm sending (I even tried sending it with an online tool and it worked). The API Key and the JSON are correct. I get this error when trying to read the input stream with 'connection.getInputStream()'. Where could this be comming frome ? Did I forget something ? I am trying to implement this feature from the openrouteservice API : https://openrouteservice.org/dev/#/api-docs/v2/directions/{profile}/post
public static UPSRoute getRoute(Location start, Location end, String language) {
if (language.equals("fr")) {
JSONObject jsonObject = null;
try {
URL url = new URL("https://api.openrouteservice.org/v2/directions/foot-walking");
String payload = "{\"coordinates\":[[" + start.getCoordinates() + "],[" + end.getCoordinates() + "]],\"language\":\"fr\"}";
System.out.println(payload); //{"coordinates":[[1.463478,43.562038],[1.471717,43.560787]],"language":"fr"}
byte[] postData = payload.getBytes(StandardCharsets.UTF_8);
HttpURLConnection connection = (HttpURLConnection)url.openConnection();
connection.setRequestMethod("POST");
connection.setRequestProperty("Authorization", API_KEY);
connection.setRequestProperty("Accept", "application/json, application/geo+json, application/gpx+xml, img/png; charset=utf-8");
connection.setDoOutput(true);
try (DataOutputStream wr = new DataOutputStream(connection.getOutputStream())) {
wr.write(postData);
}
BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream())); // Error is right here
String inputLine;
StringBuffer content = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
content.append(inputLine);
}
in.close();
connection.disconnect();
jsonObject = new JSONObject(content.toString());
} catch (IOException | JSONException e) {
e.printStackTrace();
}
return new UPSRoute(jsonObject);
} else {
return getRoute(start, end);
}
}
Here is the error :
java.io.IOException: Server returned HTTP response code: 500 for URL: https://api.openrouteservice.org/v2/directions/foot-walking/json
at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1913)
at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1509)
at java.base/sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:245)
at UPSRouteService.getRoute(UPSRouteService.java:63)
at Main.main(Main.java:5)
Thanks to Andreas, it was just missing the line :
connection.setRequestProperty("Content-Type", "application/json");
It works fine now.

Using Java (HttpURLConnection) to authenticate to Restheart (for Mongodb)

I am using restheart to provide a restful interface to mongodb. The interface is set up and running and provides the correct answer if a GET request is sent through Chrome. However if I use the following java code using a HttpURLConnection I get a 201 response with no content.
try {
videos = new URL("http://www.example.com:8080/myflix/videos");
} catch (Exception et) {
System.out.println("Videos URL is broken");
return null;
}
HttpURLConnection hc = null;
try {
hc = (HttpURLConnection) videos.openConnection();
String login="admin:admin";
final byte[] authBytes = login.getBytes(StandardCharsets.UTF_8);
final String encoded = Base64.getEncoder().encodeToString(authBytes);
hc.addRequestProperty("Authorization", "Basic "+encoded);
hc.setDoInput(true);
hc.setDoOutput(true);
hc.setUseCaches(false);
hc.setRequestMethod("GET");
hc.setRequestProperty("Accept-Encoding", "gzip, deflate, sdch");
hc.setRequestProperty("Content-Type", "application/json");
hc.setRequestProperty("Accept", "application/json,text/html,application/hal+json,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*");
} catch (Exception et) {
System.out.println("Can't prepare http URL con");
return (null);
}
BufferedReader br = null;
try {
OutputStreamWriter writer = new OutputStreamWriter(
hc.getOutputStream());
} catch (Exception et) {
System.out.println("Can't get reader to videos stream");
}
String inputLine;
String sJSON = null;
try {
int rc = hc.getResponseCode();
What is the correct way to authenticate using Java to the resthert interface? (Details on the restheart authentication is here Restheart authentication
I made few changes (look for inline comments starting with <==) and it works:
The way you generate the authentication request header is correct. When I run your code I actually got 415 Unsupported Media Type, that went away commenting out hc.setDoOutput(true). A GET is a input operation, in fact you were also trying to get an OutStream from the connection: you need to get an InputStream actually.
URL url;
try {
url = new URL("http://127.0.0.1:8080/test/huge");
} catch (Exception et) {
System.out.println("Videos URL is broken");
Assert.fail(et.getMessage());
return;
}
HttpURLConnection hc = null;
try {
hc = (HttpURLConnection) url.openConnection();
String login = "admin:admin";
final byte[] authBytes = login.getBytes(StandardCharsets.UTF_8);
final String encoded = Base64.getEncoder().encodeToString(authBytes);
hc.addRequestProperty("Authorization", "Basic " + encoded);
System.out.println("Authorization: " + hc.getRequestProperty("Authorization"));
hc.setDoInput(true);
//hc.setDoOutput(true); <== removed, otherwise 415 unsupported media type
hc.setUseCaches(false);
hc.setRequestMethod("GET");
hc.setRequestProperty("Accept-Encoding", "gzip, deflate, sdch");
hc.setRequestProperty("Accept", "application/json,text/html,application/hal+json,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*");
} catch (Exception et) {
System.out.println("Can't prepare http URL con");
}
System.out.println(hc.toString());
BufferedReader br = null;
try {
InputStreamReader reader = new InputStreamReader(hc.getInputStream()); // <== the request is a GET, data is in input
} catch (Exception et) {
System.out.println("Can't get reader to videos stream");
}
int rc = hc.getResponseCode();
System.out.println("response code: " + rc);
System.out.println("response message: " + hc.getResponseMessage());
Assert.assertEquals(200, rc);

Send image from Android client to AppEngine Cloud Endpoint

I am developing an Android applicaiton with AppEngine backend. I am creating the server part with Google Cloud Endpoints in Java. My problem is that I cannot send a Bitmap from the client to the server.
I used the answer from this question but even if the client part does not seem to have any problems at all, the server part does not receive the data at all. I also think this solution might be a bit complicated and that it might work a different, easier way, however this is my first time implementing a server and first time sending a picture to it so I accept any good tips on this. Thanks!
Here is my code:
String boundary = Long.toHexString(System.currentTimeMillis()); // Just generate some unique random value.
String CRLF = "\r\n"; // Line separator required by multipart/form-data.
String charset = "UTF-8";
HttpURLConnection connection = (HttpURLConnection) new URL("https://path_to_my_app/_ah/api/registration/v1/uploadImage").openConnection();
connection.setDoOutput(true);
connection.setReadTimeout(60000);
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
PrintWriter writer = null;
try {
OutputStream output = connection.getOutputStream();
writer = new PrintWriter(new OutputStreamWriter(output, charset), true); // true = autoFlush, important!
// Send text file.
writer.append("--" + boundary).append(CRLF);
writer.append("Content-Disposition: form-data; name=\"textFile\"; filename=\"" + somename + "\"").append(CRLF);
writer.append("Content-Type: text/plain; charset=" + charset).append(CRLF);
writer.append(CRLF).flush();
BufferedReader reader = null;
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
photo.compress(Bitmap.CompressFormat.PNG, 100, outputStream);
byteArray = stream.toByteArray();
try {
reader = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(byteArray), charset));
for (String line; (line = reader.readLine()) != null;) {
writer.append(line).append(CRLF);
}
} finally {
if (reader != null) try { reader.close(); } catch (IOException logOrIgnore) {}
}
writer.flush();
// End of multipart/form-data.
writer.append("--" + boundary + "--").append(CRLF);
}
finally
{
if (writer != null)
{
writer.close();
}
}
The server part:
#ApiMethod(name = "uploadImage", httpMethod = "POST")
public void uploadImage(HttpServletRequest request, HttpServletResponse response) throws IOException
{
ServletFileUpload fileUpload = new ServletFileUpload();
try
{
FileItemIterator iterator = fileUpload.getItemIterator(request);
while(iterator.hasNext()){
FileItemStream itemStream = iterator.next();
String fieldName = itemStream.getFieldName();
log.info("field name:"+fieldName);
InputStream stream = itemStream.openStream();
String result = getStringFromInputStream(stream);
log.info("result: "+result);
stream.close();
}
}
catch (FileUploadException e)
{
e.printStackTrace();
}
}
I am getting 204 no Content type now.
I did it!
I think this is not the best way of doing it but it´s working so I am fine until I get a better solution.
So I take the Bitmap image and convert it to String:
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream);
byte[] bitmapByte = outputStream.toByteArray();
String stringEncodedImage = Base64.encodeToString(bitmapByte, Base64.DEFAULT);
Then I create a httpPostRequest and set a JsonObject to it with the image converted to String in it.
HttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost("https://my_app_path/_ah/api/registration/v1/uploadImage");
JSONObject jsonObject = new JSONObject();
jsonObject.put("image",stringEncodedImage);
StringEntity stringEntity = new StringEntity(jsonObject.toString());
httpPost.addHeader("Content-Type", "application/json");
httpPost.setEntity(stringEntity);
HttpResponse response = httpClient.execute(httpPost);
On the server side, in my Endpoint, I do this:
#ApiMethod(name = "uploadImage", httpMethod = "POST")
public JSONObject uploadImage(JSONObject request) throws IOException
{
String imageInString = (String) request.get("image");
Blob blob = new Blob(imageInString.getBytes());
....save blob and do whatever you want...
}
The same goes the other way. I pack Blob into JsonObject and send it over.

Posting Data using HttpURLConnection

I need to post data to server using HttpURLConnection. Data contains Thai character as well. Server which accept post request accept encoding UTF-8 and TIS-620 both. When I directly post data from rest client it works fine, but when I send same request from java code it is not working properly, I mean when I send UTF-8 format data it gives parse exception and when I use TIS-620 instead thai text in server I am getting some speial character square etc.( I do not any have handle on server which accept data )
I am setting same header property for HttpURLConnection which I set for rest client in browser.Please let me know what could be going wrong here
As per my requirement I have to write this code in servlet , and servlet is called from browser AJAX call. In JQUERY AJAX call while sending data I am setting
beforeSend: function(xhr) {
xhr.setRequestHeader( "Content-type", "application/json; charset=UTF-8" );
},
I changed UTF-8 to TIS-620 All places but no luck
Some finding :
when I set
connection.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
and Print connection.getContentType() it is only printing application/json
If I send only English text it works fine. I am giving servlet code below which accept post request and POST it to server
protected void doPost(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {
System.err.println("************** POST CALLED **************");
//PRINT SERVLET REQUEST PROPERTY
System.err.println("CharacterEncoding : "+ request.getCharacterEncoding());
System.err.println("ContentType : "+request.getContentType());
//SEND GET REQUEST AND FETCH XCSRF TOKEN
String dummyServiceUrl = "GET_LOT_SRV/get_lot";
String xcsrfToken = null;
HttpURLConnection connection = null;
String requestURL = httpPrefix + hostName + semiColon + portNumber + forwardSlash + dummyServiceUrl;
List<String> cookies = null;
try {
URL gatewayServiceUrl = new URL(requestURL);
connection = (HttpURLConnection) gatewayServiceUrl.openConnection();
connection.setRequestMethod("GET");
connection.setRequestProperty("Authorization", this.getBasicAuth());
connection.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
connection.setRequestProperty("x-csrf-token", "fetch");
connection.connect();
if (HttpURLConnection.HTTP_OK == connection.getResponseCode()) {
//ON SUCCESS GET XCSRF TOKEN AND IN SAME SESSION POST DATA
requestURL = httpPrefix + hostName + semiColon + portNumber + forwardSlash + request.getQueryString();
gatewayServiceUrl = new URL(requestURL);
connection = (HttpURLConnection) gatewayServiceUrl.openConnection();
//SET CONNECTION PROPERTY
connection.setRequestMethod("POST");
xcsrfToken = connection.getHeaderField("x-csrf-token");
cookies = connection.getHeaderFields().get("set-cookie");
// SET COOKIES
for (String cookie : cookies) {
String tmp = cookie.split(";", 2)[0];
connection.addRequestProperty("Cookie", tmp);
}
//SET HEADERS
connection.setRequestProperty("Authorization", this.getBasicAuth());
connection.setRequestProperty("x-csrf-token", xcsrfToken);
connection.setRequestProperty("Content-Type", "application/json; charset=utf-8");
connection.setRequestProperty("Accept", "application/json");
connection.setRequestProperty("DataServiceVersion", "2.0");
connection.setRequestProperty("X-Requested-With", "XMLHttpRequest");
connection.setRequestProperty("Accept-Encoding", "gzip, deflate");
connection.setRequestProperty("Accept-Charset", "UTF-8");
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setUseCaches(false);
//SET USERS INPUT DATA TO OUTPUT STREAM
String payload = this.getDataFromStreamPost(request.getInputStream());
DataOutputStream dataOutputStream = new DataOutputStream(connection.getOutputStream());
dataOutputStream.write(payload.getBytes());
dataOutputStream.flush();
dataOutputStream.close();
//POST DATA AND CHECK RESPONSE
connection.connect();
response.setStatus(HttpURLConnection.HTTP_CREATED);
response.setContentType("application/json; charset=TIS-620");
response.getWriter().println(this.getDataFromStream(connection.getInputStream()));
} else {
System.err.println("XCSRF GET FAILURE "+connection.getResponseCode());
response.setStatus(connection.getResponseCode());
response.setContentType("application/json; charset=TIS-620");
response.getWriter().println(this.getDataFromStream(connection.getInputStream()));
}
} catch (Exception e) {
System.err.println("EXCEPTION OCCURED IN POST : "+e.getMessage());
response.setStatus(connection.getResponseCode());
response.setContentType("application/json; charset=TIS-620");
response.getWriter().println(this.getDataFromStream(connection.getErrorStream()));
}
}
private String getBasicAuth() {
String userpass = userName + ":" + password;
return "Basic "
+ javax.xml.bind.DatatypeConverter.printBase64Binary(userpass
.getBytes());
}
private String getDataFromStream(InputStream stream) throws IOException {
StringBuffer dataBuffer = new StringBuffer();
BufferedReader inStream = new BufferedReader(new InputStreamReader(
stream));
String data = "";
while ((data = inStream.readLine()) != null) {
dataBuffer.append(data);
}
inStream.close();
return dataBuffer.toString();
}
private String getDataFromStreamPost(InputStream stream) throws IOException {
StringBuffer dataBuffer = new StringBuffer();
BufferedReader inStream = new BufferedReader(new InputStreamReader(
stream,"UTF-8"));
String data = "";
while ((data = inStream.readLine()) != null) {
dataBuffer.append(data);
}
inStream.close();
return dataBuffer.toString();
}

Categories

Resources