Unable to POST, HttpURLConnection defaults to GET - java

I am trying to POST to a certain endpoint, when the GET method isn't allowed for that URL. When using HTTPURLConnection, I set both the request method to be post and doOutput to be true.
However for some reason, when I put a breakpoint on the InputStream (where it fails due to a missing file), the request method is GET, and doOutput is false (with only doInput being true). This leads to a 404, method not allowed not found, saying no matching handler for method [get]. Why is it ignoring my settings and going on as if I entered nothing?
String result = null;
try {
HttpURLConnection connection = (HttpURLConnection)new URL(baseUrl + getTokenPath).openConnection();
connection.setRequestMethod("POST");
connection.setRequestProperty("Accept-Charset", charset);
connection.setRequestProperty("Accept-Language", "en-US,en;q=0.8");
connection.setRequestProperty("Content-Type",
"application/x-www-form-urlencoded");
connection.setRequestProperty("Authorization", "Basic " + Base64.getEncoder().encodeToString((clientid + ":" + secret).getBytes()));
connection.setDoOutput(true);
DataOutputStream wr = new DataOutputStream (
connection.getOutputStream ());
wr.writeBytes ("grant_type=client_credentials");
wr.flush ();
wr.close ();
InputStream is = connection.getInputStream();
BufferedReader rd = new BufferedReader(new InputStreamReader(is));
String line;
StringBuffer response = new StringBuffer();
while((line = rd.readLine()) != null) {
response.append(line);
response.append('\r');
}
result = response.toString();
rd.close();
} catch (Exception e) {
e.printStackTrace();
}

Do not close DataOutputStream until You read all data from InputStream.
wr.close ();
Closing stream causes You dropping the connection. Flush is enough to send POST request.
wr.flush ();

Related

Calling Post request without body in java

I have a post API which doesn't accept any input. I have to get output from API. But it is giving compilation error.
HttpURLConnection connection = null;
String targetUrl="https://idcs-oda-9417f93560b94eb8a2e2a4c9aac9a3ff-t0.data.digitalassistant.oci.oc-test.com/api/v1/bots/"+BotID+"/dynamicEntities/"+dynamicEntityId+"/pushRequests
URL url = new URL(targetUrl);
connection=(HttpURLConnection) url.openConnection();
connection.setUseCaches (false);
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
connection.setRequestProperty("Authorization", "Basic aWRjcy1vZGEtOTQxN2Y5MzU2MGI5NGViOGEyZTJhNGM5YWFjOWEzZmYtdDBfQVBQSUQ6MjQ0YWU4ZTItNmY3MS00YWYyLWI1Y2MtOTExMDg5MGQxNDU2");
connection.setRequestProperty("Accept", "application/json");
OutputStream os = connection.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os, "UTF-8");
**osw.write();** //this line is expecting input in parameter
osw.flush();
osw.close();
os.close();
connection.connect();
If I dont pass any value in osw.write() it gives compilation error. How can I resolve the same.
Look at the following method for the post call. You will need to add the outputstream to the osw.write() as it expects a parameter.
private static void sendPOST() throws IOException {
URL obj = new URL(POST_URL);
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("POST");
con.setRequestProperty("User-Agent", USER_AGENT);
// For POST only - START
con.setDoOutput(true);
OutputStream os = con.getOutputStream();
os.write(POST_PARAMS.getBytes());
os.flush();
os.close();
// For POST only - END
int responseCode = con.getResponseCode();
System.out.println("POST Response Code :: " + responseCode);
if (responseCode == HttpURLConnection.HTTP_OK) { //success
BufferedReader in = new BufferedReader(new InputStreamReader(
con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
// print result
System.out.println(response.toString());
}
else {
System.out.println("POST request not worked");
}
}
For more details on the above code look here.

HttpURLConnection : Unable to retrieve the correct error message

I am calling REST service using java HttpURLConnection object.
When the HTTP server returns any business error, I am not able to retrieve the error properly.
For example, when I call the REST service through SoapUI, I get below error
<exception>
<errors>
<error>
<diagnostic>Matching item with shortCode = 1089992001234 found</diagnostic>
<field>shortCode</field>
<message>The Shortcode/CSG combination must be unique.</message>
<objectFailingValidationClass>com.axiossystems.assyst.dto.organisationConfiguration.SectionDto</objectFailingValidationClass>
<rule>isUniqueShortCodeWithCSG</rule>
</error>
</errors>
<message>A complex validation error has been detected by the application.</message>
<type>ComplexValidationException</type>
</exception>
But in the java code I getting below error, the request message format is correct
java.io.IOException: Server returned HTTP response code: 400 for URL: https://it-test.ihc.eu/assystREST/v2/sections
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
at sun.net.www.protocol.http.HttpURLConnection$6.run(HttpURLConnection.java:1676)
at sun.net.www.protocol.http.HttpURLConnection$6.run(HttpURLConnection.java:1674)
at java.security.AccessController.doPrivileged(Native Method)
at sun.net.www.protocol.http.HttpURLConnection.getChainedException(HttpURLConnection.java:1672)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1245)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:254)
at RestCaller.execute(RestCaller.java:59)
at RestCaller.main(RestCaller.java:18)
Can anyone let me know how to capture business error returned form server? Like the one received in SoapUI
Below is my code
try
{
url = new URL(targetURL);
connection = (HttpURLConnection) url.openConnection();
connection.setRequestProperty("accept", "application/xml");
String userpassword = username + ":" + password;
String authStringEnc = new String(Base64.encodeBase64(userpassword.getBytes()));
connection.setRequestProperty("Authorization", "Basic "+authStringEnc);
if (HttpMethod == "POST")
{
connection.setRequestMethod("POST");
//connection.setRequestProperty("Content-Length","" + Integer.toString(urlParameters.getBytes().length));
connection.setRequestProperty("Content-Type", "application/xml");
connection.setRequestProperty("Content-Language", "en-US");
connection.setUseCaches(false);
connection.setDoInput(true);
connection.setDoOutput(true);
OutputStream os = connection.getOutputStream();
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os, "UTF-8"));
writer.write(payLoad);
writer.flush();
writer.close();
os.close();
}
int statusCode = connection.getResponseCode();
System.out.println("--------000----------" + statusCode);
InputStream is = connection.getInputStream();
System.out.println("--------111----------");
BufferedReader rd = new BufferedReader(new InputStreamReader(is));
System.out.println("--------222----------");
String line;
System.out.println("--------333----------");
StringBuffer response = new StringBuffer();
System.out.println("--------444----------");
while ((line = rd.readLine()) != null)
{
response.append(line);
response.append('\r');
}
rd.close();
return response.toString();
}
catch (Exception e)
{
System.out.println("--------exception----------");
e.printStackTrace();
return "";
}
In case of error (i.e., httpStatusCode other than 200), you might have to read errorStream of HttpUrlConnection as below. After you read errorMessage, you could to deserialize it to the DTO that matches the xml output you pasted. Please note readErrorString() below is incomplete and expect you to use it for reference only
if (statusCode != 200) {
InputStream errorStream = connection.getErrorStream();
String errorMessage = (errorStream != null) ? readErrorString(errorStream) : connection
.getResponseMessage();
}
private void readErrorString(InputStream is) {
String responseString = null;
BufferedInputStream bis = null;
try {
StringBuilder sb = new StringBuilder();
bis = new BufferedInputStream(inputStream);
byte[] byteContents = new byte[4096];
int bytesRead;
String strContents;
while ((bytesRead = bis.read(byteContents)) != -1) {
strContents = new String(byteContents, 0, bytesRead, "UTF-8"); // You might need to replace the charSet as per the responseEncoding returned by httpurlconnection above
sb.append(strContents);
}
responseString = sb.toString();
} finally {
if (bis != null) {
bis.close();
}
}
}
return responseString;
400 error means your response data is malformed, means not in correct format. Please check again with your response api.

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!

Send POST data from JSP page to remote PHP server (and get an answer)

I'm trying to send some data from a JSP page to a PHP one (which should execute some code and return a success message).
I'm using this java function to make some tests:
public String excutePost(String targetURL, String urlParameters)
{
URL url;
HttpURLConnection connection = null;
try {
//Create connection
url = new URL(targetURL);
connection = (HttpURLConnection)url.openConnection();
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type",
"application/x-www-form-urlencoded");
connection.setRequestProperty("Content-Length", "" +
Integer.toString(urlParameters.getBytes().length));
connection.setRequestProperty("Content-Language", "en-US");
connection.setUseCaches (false);
connection.setDoInput(true);
connection.setDoOutput(true);
//Send request
DataOutputStream wr = new DataOutputStream (
connection.getOutputStream ());
wr.writeBytes (urlParameters);
wr.flush ();
wr.close ();
//Get Response
InputStream is = connection.getInputStream();
BufferedReader rd = new BufferedReader(new InputStreamReader(is));
String line;
StringBuffer response = new StringBuffer();
while((line = rd.readLine()) != null) {
response.append(line);
response.append('\r');
}
rd.close();
return response.toString();
} catch (Exception e) {
e.printStackTrace();
return null;
} finally {
if(connection != null) {
connection.disconnect();
}
}
}
String urlParameters =
"var=" + URLEncoder.encode("varcontent", "UTF-8");
out.println(excutePost("remoteurl",urlParameters));
Now if i run the page i get the response "null" and none of the code in the php page is executed.
Am I doing something wrong? How can I allow the php page to run the code in it?
Isn't a simple echo $_POST['var'] enough to send the data back to the jsp page?
EDIT: I tried to see if the php page is receiving something by writing the posted variable in a file. But nothing is written in it.
$file = 'debug.txt';
echo file_put_contents($file, $_POST['var']);
and here is the exception i'm getting..
java.net.SocketException: Connection reset
No, an echo is not enough. Put $_POST['var'] in say a text file and serve the updated text file (Edit the text file each time you need to keep track of $_POST['var']). Alternatively you can put it in some DB and check for changes.

return StringBuffer array

I'm using StringBuffer to send and receive variables from a web service.
My code is:
// Create connection
url = new URL(urlSCS + "/login");
connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type",
"application/x-www-form-urlencoded");
connection.setRequestProperty("Content-Length",
"" + Integer.toString(urlParameters.getBytes().length));
connection.setRequestProperty("Content-Language", "pl-PL");
connection.setUseCaches(false);
connection.setDoInput(true);
connection.setDoOutput(true);
// Send request
DataOutputStream wr = new DataOutputStream(
connection.getOutputStream());
wr.writeBytes(urlParameters);
wr.flush();
wr.close();
// Get Response
InputStream is = connection.getInputStream();
BufferedReader rd = new BufferedReader(new InputStreamReader(is));
String line;
StringBuffer response = new StringBuffer();
while ((line = rd.readLine()) != null) {
response.append(line);
response.append('\r');
}
rd.close();
How can I change this code to be able to receive Array instead of String?
The request which I get from the web service is like this: {"var", "var"}.
This might help
http://www.coderanch.com/t/393008/java/java/explode-Java
Remember to cut the response from {} using response.substring()!
look at:
String partsColl = "A,B,C";
String[] partsCollArr;
String delimiter = ",";
partsCollArr = partsColl.split(delimiter);
you will have your responses in "" so substring them then.
Good luck!

Categories