IOException when trying to read http connection response - java

I'm submitting the request below in Java via a Websphere Portlet.
It works fine when I submit manually using postman (chrome extension) but cannot get it to succeed via java.
What am I missing?
I imported the SSL cert from remote host into Websphere, so SSL connections are not the issue.
Exception in logs ..
[7/15/14 23:06:39:993 BST] 00000170 ServletWrappe E com.ibm.ws.webcontainer.servlet.ServletWrapper service CWSRV0014E: Uncaught service() exception root cause MyApp: java.io.IOException: Server returned HTTP response code: 500 for URL: https://server.com/msg
This is the java code invoking the request and trying to read the response ..
URL url = new URL("https://server.com/msg");
URLConnection connection = url.openConnection();
connection.setRequestProperty("Content-Type", "application/json");
connection.setDoOutput(true);
String body = URLEncoder.encode("{\"x\": \"hello\"}", "UTF-8");
OutputStreamWriter out = new OutputStreamWriter(connection.getOutputStream());
out.write(body);
out.close();
// Exception occurs here ..
BufferedReader rd2 = new BufferedReader(new InputStreamReader(connection.getInputStream()));
while ((line = rd2.readLine()) != null) {
result += line;
}
rd2.close();

This was solution, to not URLEncoder.encode() the POST body ..
URL url = new URL(queries.getQuery(sessionBean.getSelectedQuery()));
URLConnection connection = url.openConnection();
connection.setRequestProperty("Content-Type", "application/json");
connection.setDoOutput(true);
String json = "{\"x\": \"hello\"}";
OutputStreamWriter out = new OutputStreamWriter(connection.getOutputStream());
out.write(json);
out.close();
BufferedReader rd2 = new BufferedReader(new InputStreamReader(connection.getInputStream()));
while ((line = rd2.readLine()) != null) {
result += line;
}
rd2.close();

Related

Spring Boot : POST request returns 401 HttpUrlConnection

I'm using HttpURLConnection to send a POST request to get the access token. However, I get the error says
java.io.IOException: Server returned HTTP response code: 401 for URL: https://xyz.auth0.com/oauth/token
Note: I'm able to get the access token via Postman.
Can someone please help me? Thanks in advance!
public String requestToken() throws Exception{
StringBuilder response = new StringBuilder();
URL url = new URL("https://xyz.auth0.com/oauth/token");
//open a connection
HttpURLConnection connection = (HttpURLConnection)url.openConnection();
//set the request method
connection.setRequestMethod(TokenConstant.METHOD_POST);
//set the request content-type header parameter
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
connection.setRequestProperty("charset", "utf-8");
//set response format type
connection.setRequestProperty("Accept", "application/json");
connection.setDoOutput(true);
//create request parameter
String jsonInputString = "grant_type=client_credentials&client_id=xyz&client_secret=abc&audience=https://xyz.abc.com}";;
// we need to write it
try(OutputStream outputStream = connection.getOutputStream()){
byte[] input = jsonInputString.getBytes("utf-8");
outputStream.write(input, 0, input.length);
}
//Read the response from Input Stream
//get the input stream to read the response content
try(BufferedReader br = new BufferedReader(
new InputStreamReader(
connection.getInputStream(),"utf-8"))){
String responseLine = null;
while((responseLine = br.readLine()) != null){
response.append(responseLine.trim());
}
}
return response.toString();
}
Sample curl facebook oauth access token generation (GET request) - To generate an app access token:
curl -X GET "https://graph.facebook.com/oauth/access_token
?client_id={your-app-id}
&client_secret={your-app-secret}
&grant_type=client_credentials"
Commented few headers - Not required. Changed request to GET.
NOTE: if it works fine with curl, then your code might work fine, with few modifications.
public static String requestToken() throws Exception{
StringBuilder response = new StringBuilder();
URL url = new URL("https://graph.facebook.com/oauth/access_token");
//open a connection
HttpURLConnection connection = (HttpURLConnection)url.openConnection();
//set the request method
connection.setRequestMethod("GET");
//set the request content-type header parameter
// Commented - not required
/*connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
connection.setRequestProperty("charset", "utf-8");*/
//set response format type
connection.setRequestProperty("Accept", "application/json");
connection.setDoOutput(true);
//create request parameter
String jsonInputString = "client_id=<your-app-id>&client_secret=<your-app-secret>&grant_type=client_credentials";;
// we need to write it
try(OutputStream outputStream = connection.getOutputStream()){
byte[] input = jsonInputString.getBytes("utf-8");
outputStream.write(input, 0, input.length);
}
//Read the response from Input Stream
//get the input stream to read the response content
try(BufferedReader br = new BufferedReader(
new InputStreamReader(
connection.getInputStream(),"utf-8"))){
String responseLine = null;
while((responseLine = br.readLine()) != null){
response.append(responseLine.trim());
}
}
return response.toString();
}

Convert cURL to Java for SOAP Call

Im implementing a SOAP web service and it is working with a cURL call. I implemented following this tutorial. The service is working with the following command:
curl --header "content-type: text/xml" -d #request.xml http://localhost:8080/ws
But of course this action has to be free from command prompt and be able to be called whenever necessary, so I want to relate this service to an action when a method is called for example.
So far I found from internet
String url = "http://localhost:8080/ws";
URL obj = new URL(url);
HttpURLConnection conn = (HttpURLConnection) obj.openConnection();
conn.setRequestProperty("Content-Type", "text/xml");
conn.setDoOutput(true);
conn.setRequestMethod("POST");
I assume it should be a POST method but how do I add the "request.xml" and "--header"? What command will finalize the cURL call? Or am I doing this totally wrong and the long way, is there an easier way?
PS: I already have a web service running and Im using Eclipse Oxygen.
Add below lines to your code at the end, it will do the JOB.
OutputStream wr = new DataOutputStream(conn.getOutputStream());
BufferedReader br = new BufferedReader(new FileReader(new File("request.xml")));
//reading file and writing to URL
System.out.println("Request:-");
String st;
while ((st = br.readLine()) != null) {
System.out.print(st);
wr.write(st.getBytes());
}
//Flush&close the writing to URL.
wr.flush();
wr.close();
BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String output;
StringBuffer response = new StringBuffer();
while ((output = in.readLine()) != null) {
response.append(output);
}
in.close();
// printing result from response
System.out.println("Response:-" + response.toString());
While HttpURLConnection can be used for this purpose, SOAPConnection was designed for situations where there is not a WSDL.
The code below is much simpler:
SOAPConnection conn = SOAPConnectionFactory.newInstance().createConnection();
SOAPMessage msg =
MessageFactory.newInstance()
.createMessage(null, Files.newInputStream(Paths.get("request.xml")));
SOAPMessage resp = conn.call(msg, "http://localhost:8080/ws");
resp.writeTo(System.out);

how to do an online xml request in java to a url that require authentication

I want to do an online xml request in java but the server responds with 401 error that means that there is an authentication that is need to access the server. I have the certfile.cer that i can use to do the authentication but i dont know how to load it in java.How can I achieve this in java? Here is part of my code.
StringBuilder answer = new StringBuilder();
URL url = new URL("www.myurl.com");
URLConnection conn = url.openConnection();
OutputStreamWriter writer = new OutputStreamWriter(conn.getOutputStream());
writer.write(xml);
writer.flush();
String line;
while ((line = reader.readLine()) != null)
{
answer.append(line);
}

HttpURLConnection always return error 500

i'm trying to run a soap request in a basic http request...naturally i tried with external tools the message and is correct, like the endpoint i'm using as targetUrl, the wsdl is in something like
http://00.00.00.00/a-ws/services/basic?wsdl
and my actual end point is
http://00.00.00.00/a-ws/services/basic.targetservice
and i'm using this last as target url
URL url = new URL(targetUrl);
connection = (HttpURLConnection)url.openConnection();
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "text/xml;charset=UTF-8");
connection.setRequestProperty("SOAPAction", action);
connection.setRequestProperty("User-Agent", "myagent");
connection.setRequestProperty("Host", "localhost");
//connection.setRequestProperty("Content-Length", "" + Integer.toString(message.getBytes().length));
connection.setUseCaches (false);
connection.setDoInput(true);
connection.setDoOutput(true);
//Send request
OutputStream wr = connection.getOutputStream ();
wr.write (message.getBytes());
wr.flush ();
wr.close ();
//Get Response
InputStream is = connection.getInputStream();
BufferedReader rd = new BufferedReader(new InputStreamReader(is));
String line=null;
StringBuffer response = new StringBuffer();
while( (line = rd.readLine()) != null) {
if (line!=null)
response.append(line);
}
rd.close();
return response.toString();
the raw message is tested with chrome plugin, the only thing i can't test is headers but the result is always an exception on getInputStream
java.io.IOException: Server returned HTTP response code: 500 for URL:
why?
It was a very stupid issue of encoding (like I was supposing)...i didn't escape double quote inside the message.
The evidence of problem was visible using a fake http server that just echo contents.
UPDATE:
Another thing nobody already pointed out is that is useful in case of exception to retrieve
connection.getErrorStream()
that contains the response in case of error!

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

Categories