How receive xml response from SOAP endpoint? - java

My problem is that I have one endpoint url which if I put to the browser I can see the website. When I use this endpoint in postman program with correct request (xml) I am receiving xml response. Which is what I want. But I am trying to receive the same response in my java application but what I am receiving is the website(html).
I am not sure what is wrong
JAXBContext jaxbContext = JAXBContext.newInstance(Envelope.class);
Marshaller jaxbMarshaler = jaxbContext.createMarshaller();
jaxbMarshaler.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
Date now = new Date();
SimpleDateFormat formater = new SimpleDateFormat("ddMMyyhhmmss");
fileName = "EMCS_" + tNumber.trim() + "_" + formater.format(now) + "_" + obtDto.getTransactionIdHost()
+ ".in";
jaxbMarshaler.marshal(envelope, new File("C:\\Temp\\" + fileName));
url = new URL(urlString);
connection = (HttpsURLConnection) url.openConnection();
connection.setUseCaches(false);
connection.setDoOutput(true);
connection.setRequestMethod("POST");
connection.setRequestProperty("Connection", "Keep-Alive");
connection.setRequestProperty("Accept-Encoding", "gzip,deflate");
connection.setRequestProperty("Accept", "*/*");
connection.setRequestProperty("SOAPAction", "");
connection.setRequestProperty("Cache-Control", "no-cache");
connection.setRequestProperty("Authorization",
"Basic " + Base64.encode("USER:PASSWORD".getBytes()));
connection.setRequestProperty("Content-Type", "text/xml");
BufferedOutputStream dos = new BufferedOutputStream(connection.getOutputStream());
File file = new File("C:\\Temp\\" + fileName);
BufferedInputStream fileOutput = new BufferedInputStream(new FileInputStream(file));
byte[] b = new byte[(int) file.length()];
for (int i = 0; i < b.length; i++) {
b[i] = (byte) fileOutput.read();
System.out.printf((char) b[i] + "");
}
dos.write(b);
dos.flush();
dos.close();
fileOutput.close();
System.out.println("RESPONSE: " + connection.getResponseCode());
BufferedOutputStream responseWebsite = new BufferedOutputStream(
new FileOutputStream("C:\\Temp\\response.html"));
InputStream in = url.openStream(); // IMPORTANT TO READ PROPERLY DATA
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
StringBuilder result2 = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
responseWebsite.write(line.getBytes());
result2.append(line + "\n");
}
responseWebsite.close();
By using code above I am posting request and getting HTML response instead of XML. What I am doing wrong?
EDIT
I edited post cause I need give more explanation I think. My problem is that in
'reader' variable bytes which I am receiving are HTML not XML. I want XML.
EDIT2
So I can not give a link to repo cause is not me private project. But when I am using postman and sending request to endpoint with
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:de.aeb.xnsg.emcs.bf" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body><ns2:request>...
body which I genereate with my app I am receiving
<?xml version='1.0' encoding='UTF-8'?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"><S:Body><ns2:response>...
And that is good.
And response in postman is pure XML which I want.
But when I put this endpoint to chrome for example I am receiving website where I can find other endpoints/wsdls to this service but in different language(French, German etc).
EDIT 3
SOLVED
My problem was that I have specified Accept-Encoding
connection.setRequestProperty("Accept-Encoding", "gzip,deflate");
when I removed it I could read proper response from stream.
But also I was able to read this message by using GZIPInputStream, but not sure which solution is better.

Maybe problem is in this line new FileOutputStream("C:\\Temp\\response.html"));?and you should change extension to response.xml

Related

"grant_type parameter is missing" in login Spotify API

I'm building a little application and i need to use the spoify API, when I try to login I have
400 ERROR:{"error":"unsupported_grant_type","error_description":"grant_type parameter is missing"}
when I make the POST request
String urlString = "https://accounts.spotify.com/api/token?";
URL website = new URL(urlString);
HttpURLConnection connection = (HttpURLConnection) website.openConnection();
connection.setRequestMethod("POST");
// Headers
String toEncode = Test.CLIENT_ID + ":" + Test.CLIEN_SECRET_ID;
String encodedString = Base64.getEncoder().encodeToString(toEncode.getBytes());
connection.setRequestProperty("Authorization", encodedString);//client id + secret
connection.setRequestProperty("Accept", "application/json");
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
connection.setDoOutput(true);
// Add parameters to the body
String jsonInputString = "{" +
"grant_type: authorization_code,\n" +
"\"redirect_uri\": \"" + Test.REDIRECT_URI + "\",\n" +
"\"code\": \"" + code +
"\"\n}";
System.out.println("json input string " +jsonInputString);
byte[] input = jsonInputString.getBytes(StandardCharsets.UTF_8);
connection.setFixedLengthStreamingMode(input.length);
connection.connect();
try (OutputStream os = connection.getOutputStream()) {
os.write(input);
}
I read a lot about this error but I cannot find who to correct it, I also asked other people to look at my code and check if I did something wrong they don't find it either.
Please tell me you see what's wrong and how I can correct it
As far as I see you are trying to do the authorization with OAuth2.
I recommend, you to read https://datatracker.ietf.org/doc/html/rfc6749, which explains what you are doing.
Besides, if possible use some libraries, which are doing the OAuth2 flows for you.
Furthermore from what I see in your code, you should try to pass the values in your JSON as form parameters. See also https://stackoverflow.com/a/13486223/17832003
List<NameValuePair> formParams = new ArrayList<NameValuePair>();
formParams.add(new BasicNameValuePair("grant_type", "authorization_code"));
formParams.add(new BasicNameValuePair("redirect_uri", Test.REDIRECT_URI));
formParams.add(new BasicNameValuePair("code", code));
OutputStream os = conn.getOutputStream();
BufferedWriter writer = new BufferedWriter(
new OutputStreamWriter(os, "UTF-8"));
writer.write(getQuery(params));
writer.flush();
writer.close();
os.close();
conn.connect();

Getting java.io.IOException: Server returned HTTP response code: 400

I am trying to convert my POST request for multipart/form-data into java program and I am receiving java.io.IOException: Server returned HTTP response code: 400
// Connect to the web server endpoint
URL serverUrl =
new URL("http://testurl/start-date/2017-01-01/upload");
HttpURLConnection urlConnection = (HttpURLConnection) serverUrl.openConnection();
//String boundaryString = "----SomeRandomText";
String fileUrl = "C:/Users/V70070/Documents/ALL FILES/Rates/MAC2291_RATES.csv";
String encodedCredentials = "Basic dGVzdDpwYXNzd29yZA==";
File logFileToUpload = new File(fileUrl);
// Indicate that we want to write to the HTTP request body
urlConnection.setDoOutput(true);
urlConnection.setRequestProperty ("Authorization", encodedCredentials);
urlConnection.setRequestMethod("POST");
urlConnection.addRequestProperty("Content-Type", "multipart/form-data");
OutputStream outputStreamToRequestBody = urlConnection.getOutputStream();
BufferedWriter httpRequestBodyWriter =
new BufferedWriter(new OutputStreamWriter(outputStreamToRequestBody));
// Include value from the myFileDescription text area in the post data
httpRequestBodyWriter.write("Content-Disposition: form-data; name=\"fileData\"; Content-Type: text/plain; filename=\"MAC2291_RATES.csv\"");
// Include the section to describe the file
// httpRequestBodyWriter.write("Content-Disposition: form-data;"
// + "name=\"myFile\";"
// + "filename=\"" + logFileToUpload.getName() + "\""
// + "\nContent-Type: text/plain\n\n");
// httpRequestBodyWriter.flush();
// Write the actual file contents
FileInputStream inputStreamToLogFile = new FileInputStream(logFileToUpload);
int bytesRead;
byte[] dataBuffer = new byte[1024];
while ((bytesRead = inputStreamToLogFile.read(dataBuffer)) != -1) {
outputStreamToRequestBody.write(dataBuffer, 0, bytesRead);
}
outputStreamToRequestBody.flush();
// Mark the end of the multipart http request
//httpRequestBodyWriter.write("\n--" + boundaryString + "--\n");
httpRequestBodyWriter.flush();
// Read response from web server, which will trigger the multipart HTTP request to be sent.
BufferedReader httpResponseReader =
new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
String lineRead;
while((lineRead = httpResponseReader.readLine()) != null) {
System.out.println(lineRead);
}
// Close the streams
outputStreamToRequestBody.close();
httpRequestBodyWriter.close();
}
I am getting the Exception while Reading response from web server
BufferedReader httpResponseReader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
Any help highly appreciated. TIA

Parse upload to a class using REST java

I want to upload file to a class myclass in parse.com .Now, when I use the URL as https://api.parse.com/1/files/hello, I get the response message Created and the location of the file in the header. But, when I try to upload it to the class, I get the response message :- Bad Request and the header says that it is a 400 request. What am I doing wrong?
String name = "file.txt";
URL url = new URL("https://api.parse.com/1/classes/myclass/hello");
HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
httpConn.setDoOutput(true);
httpConn.setRequestMethod("POST");
httpConn.setRequestProperty("X-Parse-Application-Id", "App_Id");
httpConn.setRequestProperty("X-Parse-REST-API-Key", "APp_KeY");
httpConn.setRequestProperty("Content-type", "text/plain");
OutputStream outputStream = httpConn.getOutputStream();
File uploadFile = new File("F:\\file.txt");
InputStream inputStream = new FileInputStream(uploadFile);
byte[] buffer = new byte[4096];
int bytesRead = -1;
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
outputStream.close();
inputStream.close();
System.out.println("Response message : " + httpConn.getResponseMessage());
You can't upload using your class name I guess. What I do is first upload the file and then insert it into the class. I will be using Java since you have used java. So, first upload your file using https://api.parse.com/1/files/hello. Then you will get the location of the file in the header received. You can get it using httpConn.getResponseHeader("Location");. Now that will give you the entire url of the file. But you need only the name. You can extract it by this code:-
String ar[] = location.split("[/]");
String name = ar[ar.length - 1];
Now, insert it into your class. But before inserting, you have to make sure that you have a column that has data type of File in your class. Now, insert it into your class using this code :-
httpConn.setDoOutput(true);
httpConn.setRequestMethod("POST");
httpConn.setRequestProperty("X-Parse-Application-Id", "App_Id");
httpConn.setRequestProperty("X-Parse-REST-API-Key", "APp_KeY");
httpConn.setRequestProperty("Content-type", "application/json");
String json = "{\"myclass\":"
+ "{ "
+ "\"name\":\"" + name + "\","
+ "\"__type\": \"File\""
+ "}"
+ "}";
httpConn.getOutputStream().write(json.getBytes());
So, you have to make 2 requests in total.

Manually hitting a SOAP Service in Java, getting IO.FileNotFound exception

I need to access a .Net SOAP Service manually. All the importers have issues with its WSDL, so I'm just manually creating the XML message, using HttpURLConnection to connect, and then parsing the results. I've wrapped the Http/SOAP call into a function that is supposed to return the results as a string. Here's what I have:
//passed in values: urlAddress, soapAction, soapDocument
URL u = new URL(urlAddress);
URLConnection uc = u.openConnection();
HttpURLConnection connection = (HttpURLConnection) uc;
connection.setDoOutput(true);
connection.setDoInput(true);
connection.setRequestMethod("POST");
connection.setRequestProperty("SOAPAction", soapAction);
connection.setRequestProperty("User-Agent","Mozilla/5.0 ( compatible ) ");
connection.setRequestProperty("Accept","[star]/[star]");
connection.setRequestProperty("Content-Type", "text/xml; charset=utf-8");
OutputStream out = connection.getOutputStream();
Writer wout = new OutputStreamWriter(out);
//helper function that gets a string from a dom Document
String xmldata = XmlUtils.GetDocumentXml(soapDocument);
wout.write(xmldata);
wout.flush();
wout.close();
// Response
int responseCode = connection.getResponseCode();
BufferedReader rd = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String responseString = "";
String outputString = "";
//Write the SOAP message response to a String.
while ((responseString = rd.readLine()) != null) {
outputString = outputString + responseString;
}
return outputString;
My problem is on the line BufferedReader rd = new BufferedReader(new InputStreamReader(connection.getInputStream())); I get a "java.io.FileNotFoundException" with the address that I'm using (i.e. urlAddress). If I paste that address into a browser, it pulls up the Soap Service webpage just fine (address is http://protectpaytest.propay.com/API/SPS.svc). From what I've read, the FileNotFoundException is if the HttpURLConnection returns a 400+ error message. I added the line getResponseCode() just to see what the exact code was, and it's 404. I added the User-Agent and Accept headers from some other pages saying they were needed, but I'm still getting 404.
Are there other headers I'm missing? What else do I need to do to get this call to work (since it works in a browser)?
-shnar

How to POST in Java

I have something that looks like this:
POST /o/oauth2/token HTTP/1.1
Host: accounts.google.com
Content-Type: application/x-www-form-urlencoded
grant_type=assertion&assertion_type=http%3A%2F%2Foauth.net%2Fgrant_type%2Fjwt%2F1.0%2Fbearer&assertion=eyJhbGciOiJSUzI1NiIs
How would I go about using this in Java? I have all the information already so I wouldn't need to parse it.
Basically I need to POST with 3 different data and using curl has been working for me but I need to do it in java:
curl -d 'grant_type=assertion&assertion_type=http%3A%2F%2Foauth.net%2Fgrant_type%2Fjwt%2F1.0%2Fbearer&assertion=eyJhbGciOiJSUzI1NiIsInR5i' https://accounts.google.com/o/oauth2/token
I cut off some data so its easier to read so it wont work.
So a big problem is that the curl would work while most tutorials I try for Java would give me HTTP response error 400.
Like should I be encoding the date like this:
String urlParameters = URLEncoder.encode("grant_type", "UTF-8") + "="+ URLEncoder.encode("assertion", "UTF-8") + "&" + URLEncoder.encode("assertion_type", "UTF-8") + "=" + URLEncoder.encode("http://oauth.net/grant_type/jwt/1.0/bearer", "UTF-8") + "&" + URLEncoder.encode("assertion", "UTF-8") + "=" + URLEncoder.encode(encodedMessage, "UTF-8");
or not:
String urlParameters ="grant_type=assertion&assertion_type=http://oauth.net/grant_type/jwt/1.0/bearer&assertion=" + encodedMessage;
Using this as the code:
URL url = new URL(targetURL);
URLConnection conn = url.openConnection();
conn.setDoOutput(true);
OutputStreamWriter writer = new OutputStreamWriter(conn.getOutputStream());
writer.write(urlParameters);
writer.flush();
String line;
BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
writer.close();
reader.close();
Use something like HttpClient or similar.
It can post pre-URL-encoded data to a URI, although I don't know if you could just throw a complete request body at it--might need to parse it out, but there are likely libraries for that as well.
Here's a simple example of Apache HttpClient with request body from their docs (slightly modified to show how the execute works):
HttpClient client = new HttpClient();
PostMethod post = new PostMethod("http://jakarata.apache.org/");
NameValuePair[] data = {
new NameValuePair("user", "joe"),
new NameValuePair("password", "bloggs")
};
post.setRequestBody(data);
int returnCode = client.execute(post);
// check return code ...
InputStream in = post.getResponseBodyAsStream();
See the Apache HttpClient site for more info, examples and tutorials. This link might help you too.

Categories