I try to send post request, but webserver returns that I added no post-values. I spent a lot of time trying to solve this issue, but no result. Here is the code:
public static String post(String url, String postParams)
{
URLConnection connection = null;
try
{
connection = initializeConnection(url);
connection.setDoOutput(true);
((HttpURLConnection) connection).setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "text/xml");
connection.setRequestProperty("Accept", "text/xml");
connection.setUseCaches(false);
connection.setDoInput(true);
DataOutputStream wr = new DataOutputStream(connection.getOutputStream());
wr.write(postParams.getBytes());
wr.flush();
wr.close();
// Get Response
InputStream is = connection.getInputStream();
return inputStreamToString(is);
}
catch (Exception e)
{
e.printStackTrace();
return null;
}
}
protected static HttpURLConnection initializeConnection(String stringUrl)
{
HttpURLConnection connection;
URL url = null;
try
{
url = new URL(stringUrl);
}
catch (MalformedURLException e1)
{
e1.printStackTrace();
}
try
{
connection = (HttpURLConnection) url.openConnection();
connection.setConnectTimeout(5000);
}
catch (Exception e)
{
e.printStackTrace();
return null;
}
return connection;
}
public static String inputStreamToString(InputStream is)
{
BufferedReader r = new BufferedReader(new InputStreamReader(is));
StringBuilder total = new StringBuilder();
String line;
try
{
while ((line = r.readLine()) != null)
{
total.append(line);
}
}
catch (IOException e)
{
e.printStackTrace();
}
return total.toString();
}
I receive a message from webserver where it is told that no post-values are added. As far as I understand from the code, the values are added. I'm stuck.
It turned out that all I had to do was to replace
connection.setRequestProperty("Content-Type", "text/xml");
with
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
So simple and so much time spent to clear it out...
By the way, how could I know that server requires this header? I thought that all the work that is essential to the request would be automatically done by java..
P.S. Installing fiddler helped to solve the issue, thanks for that.
debug the 'postParams' parameter and check what been sent.
Related
I can't understand how to switch to POST method in my HttpsURLConnection. On the debugger the request method is GET also after the setRequestMethod method. Can you tell me where is my mistake?
try {
URL url=new URL("https://smartmates.herokuapp.com");
HttpsURLConnection connection= (HttpsURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setDoInput(true);
connection.setDoOutput(true);
//I'll add some params here
connection.disconnect();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
Thank you very much.
This is a piece of code that I use to POST the String mensaje and receiving rta.ToString(). I think that DoSetInput(true) is a mistake, because you want to send a POST (output) and, eventually, get a response.
`
String urlParametros = "<?xml version=\"1.0\"?>";
urlParametros = urlParametros + mensaje;
byte[] postDatos = urlParametros.getBytes(StandardCharsets.UTF_8);
try {
URL miurl = new URL(url);
con = (HttpURLConnection) miurl.openConnection();
con.setDoOutput(true);
con.setRequestMethod("POST");
//******…………..
con.setRequestProperty("User-Agent", "Java client");
con.setRequestProperty("Content-Type", "text/xml");
try (DataOutputStream datos = new DataOutputStream(con.getOutputStream())) {
datos.write(postDatos);
}
StringBuilder rta;
try (BufferedReader entrada = new BufferedReader(
new InputStreamReader(con.getInputStream()))) {
String linea;
rta = new StringBuilder();
while ((linea = entrada.readLine()) != null) {
rta.append(linea);
rta.append(System.lineSeparator());
}
}
return rta.toString();
} finally {
con.disconnect();
}´
Hope it helps
Daniel
I'm a QA with desire to learn more about Java programming and problem I'm experiencing is this:
I'm trying to POST Employee data to the database of some fake Rest API, but I'm getting
Cannot write to a URLConnection if doOutput=false - call
setDoOutput(true)"
So far, I tried some ideas from StackOverflow, but inexperienced as I am, I could easily fall deeper into a problem.
So URL is: http://dummy.restapiexample.com/api/v1/create and firstly I created an Employee class of json object:
public class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
Employees em = new Employees();
em.setEmployeeName("Alex");
em.setEmployeeSalary("1234");
em.setEmployeeAge("28");
try{
URL url = new URL("http://dummy.restapiexample.com/api/v1/create");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("Accept", "application/json");
if (conn.getResponseCode() != 200) {
throw new RuntimeException("Unsuccessful call: HTTP error : "
+ conn.getResponseCode());
}
// URLConnection urlc = url.openConnection();
// urlc.setDoOutput(true);
PrintWriter pw = new PrintWriter(conn.getOutputStream());
pw.print(new Gson().toJson(em));
pw.close();
pw.flush();
BufferedReader br = new BufferedReader(
new InputStreamReader(conn.getInputStream())
);
String json = "";
String output;
while ((output = br.readLine()) != null) {
json += output;
}
conn.disconnect();
System.out.println("Employee name: " + em.getEmployeeName());
}
catch (MalformedURLException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
}
}
Well, using one of your ideas and added next lines of code (it's commented in above code):
URLConnection urlc = url.openConnection();
urlc.setDoOutput(true);
So the code looks like:
public class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
Employees em = new Employees();
em.setEmployeeName("Alex");
em.setEmployeeSalary("1234");
em.setEmployeeAge("28");
try{
URL url = new URL("http://dummy.restapiexample.com/api/v1/create");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("Accept", "application/json");
if (conn.getResponseCode() != 200) {
throw new RuntimeException("Unsuccessful call: HTTP error : "
+ conn.getResponseCode());
}
URLConnection urlc = url.openConnection();
urlc.setDoOutput(true);
PrintWriter pw = new PrintWriter(urlc.getOutputStream());
pw.print(new Gson().toJson(em));
pw.close();
pw.flush();
BufferedReader br = new BufferedReader(new InputStreamReader(
(urlc.getInputStream())));
String json = "";
String output;
while ((output = br.readLine()) != null) {
json += output;
}
conn.disconnect();
System.out.println("Employee name: " + em.getEmployeeName());
}
catch (MalformedURLException e) {
e.printStackTrace(); }
catch (IOException e) {
e.printStackTrace();
}
}}
With this second code I'm not getting that error, but there is no inserting to the database(checking that using postman, with GET method)...
Well, what am I missing? I guess, I'm missing something basic...
Using url.openConnection twice means you get two different connections. You send the request to the second connection, and try to read the response from the first connection. You should call doOutput on the connection you open originally.
The second problem is you're calling getResponseCode before the request is sent. In http, the request must be sent entirely before the server sends a response. You should move the code that calls doOutput and writes the request body before the code that tries to check the response code.
I'm trying to use HttpURLConnection for connecting to server from Android app which I'm developing. For now, I'm testing the connection code not in an app but as a plain java program with main class. I guess this doesn't make any difference as far as HttpUrlConnection.
Please examine the code snippet. Another issue is even errorStream is throwing null. This I feel is because of malformed URL.
private static String urlConnectionTry() {
URL url; HttpURLConnection connection = null;
try {
String urlParameters = "email=" + URLEncoder.encode("email", "UTF-8") +
"&pwd=" + URLEncoder.encode("password", "UTF-8");
//Create connection
url = new URL("http://example.com/login");
connection = (HttpURLConnection)url.openConnection();
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type",
"application/x-www-form-urlencoded");
connection.setRequestProperty("uuid", getUuid());
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setInstanceFollowRedirects(true);
//Send request
DataOutputStream wr = new DataOutputStream (
connection.getOutputStream ());
wr.writeBytes (urlParameters);
wr.flush ();
wr.close ();
//Get Response
InputStream is = connection.getErrorStream();
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();
}
}
}
private static String getUuid() {
try {
Document doc=Jsoup.connect("http://example.com/getUuid").get();
Elements metaElems = doc.select("meta");
for (Element metaElem : metaElems) {
if(metaElem.attr("name").equals("uuid")) {
return metaElem.attr("content");
}
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
You're probably receiving 401 because the credentials that was sent to the server is not authorized- it's probably not registered or the password is incorrect.
As for the null error stream, take a look at this SO answer.
If the connection was not connected, or if the server did not have an error while connecting or if the server had an error but no error data was sent, this method will return null.
It is probably better if you check first the response code using HttpUrlConnection#getResponseCode(). Decide on whether you'll be checking the contents of the error stream based on the response code you get.
I have problem with connecting to my server. Following code returns -1 as response code and null as response message.
protected Boolean doInBackground(MyTaskParams... params) {
URL url = null;
String load = params[0].jobj.toString();
try {
url = new URL(params[0].serverUrl);
} catch (MalformedURLException e) {
e.printStackTrace();
}
try {
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setConnectTimeout(3000);
urlConnection.setReadTimeout(3000);
urlConnection.setRequestMethod("POST");
urlConnection.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
urlConnection.setChunkedStreamingMode(0);
urlConnection.setDoOutput(true);
urlConnection.setDoInput(true);
urlConnection.connect();
OutputStreamWriter osw = new OutputStreamWriter(urlConnection.getOutputStream());
osw.write(load);
osw.flush();
osw.close();
if(urlConnection.getResponseCode()==200 && urlConnection.getResponseMessage().contains("true") ) return true;
else return false;
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
While debbuging url and body content (which is load in code) are correct. When I try to connect with the server using those params with Fiddler it works perfectly and I get 200 status code. Do you have any ideas what is wrong?
Im passing jData object as the jobj:
JSONObject User=new JSONObject();
JSONObject Mobile=new JSONObject();
JSONObject jData=new JSONObject();
try {
User.put ("UserLogin", "test");
User.put ("UserPassword", "test");
Mobile.put ("MobileIDD", IDD);
Mobile.put("MobileToken", token);
jData.put("Mobile", Mobile);
jData.put("User", User);
} catch (JSONException e) {
e.printStackTrace();
}
#EDIT
Solution with System.setProperty("http.keepAlive", "false") didnt help.
I solved the problem. It was in this line:
if(urlConnection.getResponseCode()==200 && urlConnection.getResponseMessage().contains("true") ) return true;
When I changed it to:
int code = urlConnection.getResponseCode();
if (code==200.....)
It started working.
My android servlet is designed to post request and receive responses with a tomcat servlet on an Apache Tomcat server. For debugging, I have set up the Servlet with identical POST and GET methods so I can try the functionalities and accessability via browsers.
To cut the long story short: When I deploy the app, I can easily access it from the AVD device browser via 10.0.2.2:8080/my_app?request=test and I get a result that's just fine. Same is true for access from my machine with localhost:8080/my_app?request=test.
But when I try it from my app, I always get a java.io.FileNotFoundException: http://10.0.2.2:8080/my_app.
Why?
What did I try so far: The app has internet permissions and they also work, for to get to the Servlet communication point, I have to go through a login procedure via PHP first, and it's on the same server and works normally.
My AsyncTaskconnecting to the servlet looks like this:
AsyncTask<Void,Void,String> getDBdata = new AsyncTask<Void, Void, String>() {
#Override
protected String doInBackground(Void... params) {
URL url = null;
try {
url = new URL("http://10.0.2.2:8080/my_app");
} catch (MalformedURLException e) {
e.printStackTrace();
}
String text;
text = null;
JsonArray js = null;
try {
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoOutput(true);
connection.setRequestMethod("POST");
connection.setRequestProperty("action", "getDBData");
connection.setDoInput(true);
connection.connect();
BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
StringBuilder builder = new StringBuilder();
String aux = "";
while ((aux = in.readLine()) != null) {
builder.append(aux);
}
text = builder.toString();
} catch (IOException e) {
e.printStackTrace();
}
return text;
Alright, of course I've been trying to send params in the header, and this led to BS. Rookie mistake!
bcody's answer from this question helped me a lot with debugging! Also, taking a look at the server protocol from the servlet might have led me to the error earlier.
This is the code that finally worked:
AsyncTask<Void,Void,String> getDBdata = new AsyncTask<Void, Void, String>() {
#Override
protected String doInBackground(Void... params) {
URL url = null;
try {
url = new URL(Constants.SERVER_URL + getDBdataURL);
} catch (MalformedURLException e) {
e.printStackTrace();
}
String text;
text = null;
try {
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestProperty("Accept-Charset", "UTF-8");
connection.setRequestProperty("User-Agent", "Mozilla/5.0 ( compatible ) ");
connection.setRequestProperty("Accept", "*/*");
connection.setChunkedStreamingMode(0);
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
connection.setDoOutput(true);
connection.setRequestMethod("POST");
String request = "action=getDBdata";
PrintWriter pw = new PrintWriter(connection.getOutputStream());
pw.print(request);
pw.close();
BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
StringBuilder builder = new StringBuilder();
String aux = "";
while ((aux = in.readLine()) != null) {
builder.append(aux);
}
text = builder.toString();
} catch (IOException e) {
e.printStackTrace();
}
return text;
}