Java HttpURLConnection is not sending a body - java

I'm trying to send a PUT request with a body to my API in my Android app with Java. I'm using the java.net HttpURLConnection and the request gets through. But without the body.
I refactored my code over and over again but it still does not work, at the moment I have following Task:
#Override
protected String doInBackground(String... urls) {
String result = "";
URL url;
HttpURLConnection urlConnection = null;
JSONObject body = new JSONObject();
try {
body.put("title", title);
body.put("content", content);
try {
url = new URL(urls[0]);
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("PUT");
urlConnection.addRequestProperty("username", username);
urlConnection.addRequestProperty("password", password);
urlConnection.addRequestProperty("Content-Type", "application/json; utf-8");
urlConnection.addRequestProperty("Accept", "application/json");
urlConnection.setDoOutput(true);
try(OutputStream os = urlConnection.getOutputStream()){
byte[] input = body.toString().getBytes("utf-8");
os.write(input, 0, input.length);
}
InputStream in = urlConnection.getInputStream();
InputStreamReader reader = new InputStreamReader(in);
int data = reader.read();
while (data != -1){
char current = (char) data;
result += current;
data += current;
data = reader.read();
}
return result;
}catch (Exception e){
e.printStackTrace();
return null;
}
} catch (JSONException e) {
e.printStackTrace();
return null;
}
}
But this code leads always to an empty body.
EDIT
When changing content type to application/x-www-form-urlencoded the server gets the body. But this way I don't get a JSON file for further processing it.

The java code is working correctly. The API wasn't accepting JSON. Other languages worked without problems.
Server Info
Node.js
Express
Body Parser
I didn't add app.use(bodyParser.json());

Related

How to get device Access token and perform multiple HTTP POST Request

I'm currently working on a project using an IoT platform " Thingsboard " where I've have created multiple devices, and I want to send data to each one of the devices from a JSON File, I'm using Rest Api to perform this request, but I've struggling for a while how to get the access token of my devices and parse each one of them in my request as a header param. I was just doing manually by getting them with Curl, but I want now to do it automatically. I know that Thingsboard has a Rest client Api written in java (https://thingsboard.io/docs/reference/rest-client/) so I've tried to use that in my script but I's not working. I'm new to working with Rest Api so if anybody can gie me a clue it would be so helpful.
here's a part of my code for the requests :
private static String token;
public String getToken() {
return token;
}
String paramValue = "param\\with\\backslash";
String yourURLStr = "http://host.com?param=" + java.net.URLEncoder.encode(paramValue, "UTF-8");
URL url2 = new URL("https://demo.thingsboard.io/api/v1/token/telemetry?token=$JWT_TOKEN");
HttpsURLConnection conn = (HttpsURLConnection) url2.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/json");
conn.setRequestProperty("Accept", "application/json");
conn.setRequestProperty(JWT_TOKEN_HEADER_PARAM, "Bearer" +token);
conn.setDoOutput(true);
OutputStream outStream = conn.getOutputStream();
OutputStreamWriter outStreamWriter = new OutputStreamWriter(outStream, "UTF-8");
outStreamWriter.write(list.toString());
outStreamWriter.flush();
outStreamWriter.close();
outStream.close();
String response = null;
System.out.println(conn.getResponseCode());
System.out.println(conn.getResponseMessage());
DataInputStream input1 = null;
input1 = new DataInputStream (conn.getInputStream());
while (null != ((response = input1.readLine()))) {
System.out.println(response);
input1.close ();
}
}
catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ParseException e) {
e.printStackTrace();
}
If you are trying to get the JWT-token to authenticate the following java should work:
Request request = Request.Post("http://THINGSBOARD_URL/api/auth/login");
String body = "{\"username\":\"tenant#thingsboard.org\", \"password\":\"tenant\"}";
request.bodyString(body,ContentType.APPLICATION_JSON);
request.setHeader("Content-Type", "application/json");
request.setHeader("Accept", "application/json");
HttpResponse httpResponse = request.execute().returnResponse();
System.out.println(httpResponse.getStatusLine());
if (httpResponse.getEntity() != null) {
String html = EntityUtils.toString(httpResponse.getEntity());
System.out.println(html);
}
Don't get confused with JWT-Token for tenant authentication and Access-Token for Device Authentication.

Send data(Client_id=1,Staff_id=2) from android application to tomcat server

i want to send data from android application to tomcat java server.
Data is just one is client_id which is 1 and second is staff_id which is 2.
after authenticate the client id and staff id from tomcat show me a toast of success....please help...
Code is here
public class MyAsyncTasks extends AsyncTask<String, String, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
// display a progress dialog for good user experiance
}
#Override
protected String doInBackground(String... params) {
// implement API in background and store the response in current variable
String current = "";
try {
URL url;
HttpURLConnection urlConnection = null;
try {
url = new URL("http://192.168.1.13:8080/digitaldisplay/s/m/data");
urlConnection = (HttpURLConnection) url
.openConnection();
InputStream in = urlConnection.getInputStream();
InputStreamReader isw = new InputStreamReader(in);
int data = isw.read();
while (data != -1) {
current += (char) data;
data = isw.read();
System.out.print(current);
}
// return the data to onPostExecute method
return current;
} catch (Exception e) {
e.printStackTrace();
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
}
} catch (Exception e) {
e.printStackTrace();
return "Exception: " + e.getMessage();
}
return current;
}
#Override
protected void onPostExecute(String s) {
Toast.makeText(Register.this, "success", Toast.LENGTH_SHORT).show();
Log.d("data", s.toString());
// dismiss the progress dialog after receiving data from API
try {
// JSON Parsing of data
JSONArray jsonArray = new JSONArray(s);
JSONObject oneObject = jsonArray.getJSONObject(0);
// Pulling items from the array
client = Integer.parseInt(oneObject.getString("client"));
staff = Integer.parseInt(oneObject.getString("staff"));
} catch (JSONException e) {
e.printStackTrace();
}
} }}
The logic in your code looks off to me. This is the pattern I usually follow when making a REST call from an activity using HttpURLConnection:
try {
String endpoint = "http://192.168.1.13:8080/digitaldisplay/s/m/data";
URL obj = new URL(endpoint);
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("POST"); // but maybe you want GET here...
con.setConnectTimeout(10000);
con.setDoInput(true);
con.setDoOutput(true);
JSONObject inputJSON = new JSONObject();
inputJSON.put("Client_id", 1);
inputJSON.put("Staff_id", 2);
con.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
OutputStream os = con.getOutputStream();
BufferedWriter writer = new BufferedWriter(
new OutputStreamWriter(os, "UTF-8"));
writer.write(inputJSON.toString());
writer.flush();
writer.close();
os.close();
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
System.out.println(response);
} catch (SocketTimeoutException se) {
// handle timeout exception
responseCode = -1;
} catch (Exception e) {
// handle general exception
responseCode = 0;
}
The only major change in adapting the above code for GET would be that you wouldn't write your input data to the connection. Instead, you would just append query parameters to the URL. I am possibly guessing that you need POST here, since your URL doesn't have any query parameters in it.

Call httpconnection with encoding not working

i need to call a service get using http connection, the response contains arabic characters, but when i call it using the code below
try {
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
InputStream in = new BufferedInputStream(conn.getInputStream());
response = IOUtils.toString(in, "UTF-8");
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
the reponse is
1|U|����� ������|$2|L|���� �������|$3|S|����
I tried another solution not using Commons-io but also not working
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
connection.setConnectTimeout(5000);
connection.setRequestMethod("GET");
connection.connect();
int statusCode = connection.getResponseCode();
//Log.e("statusCode", "" + statusCode);
if (statusCode == 200) {
sb = new StringBuilder();
reader = new BufferedReader(new InputStreamReader(connection.getInputStream(),"UTF-8"));
char[] tmp = new char[1024];
int l;
while((l = reader.read(tmp)) != -1) {
sb.append(tmp, 0, l);
}
//sb = buffer.toString();
}
connection.disconnect();
if (sb != null)
serverResponse = sb.toString();
Do i need to change anything from web service??? but when i call it from browser all characters show clearly with no problem
any suggestion?
Maybe the server is not using UTF-8, your code is trying to use UTF-8 to decode the data but that will only work if the server is using the same encoding.
The browser works because maybe it is using the HTTP header "Content-Encoding" which should indicate the encoding used for the data.
Please decode your string response
String dateStr = URLDecoder.decode(yourStringResponse, "utf-8");

HTTP post call from android to PHP?

I am new working with Android Studio.
Here in the below code i am trying to send data from java to the backend server (in PHP). The call is being made but NULL is returned from the server side which shouldn't happen. So I think input sent from the java side is not interpreted properly at the PHP side i guess. Could you tell what is wrong with the code (and PHP code is perfectly all right and it should not return NULL).
HttpURLConnection httpURLConnection = null;
JSONObject Student_det = stu_det.getJSONObject(i);
String stu_GUID = Student_det.getString("StuGUID");
String visit_GUID = Student_det.getString("VisitGUID");
String value = "Rec="+(tableRow+1)+"&SchGUID="+schoolGUID.trim()+"&StuGUID="+stu_GUID.trim()+"&VisitGUID="+visit_GUID.trim()+"&role="+role;
URL url = new URL("http://52.66.25.82/api/download_student.php");
String enc_val = URLEncoder.encode(value,"UTF-8");
httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.setDoOutput(true);
httpURLConnection.setDoInput(true);
httpURLConnection.setRequestMethod("POST");
OutputStreamWriter wr = new OutputStreamWriter(httpURLConnection.getOutputStream());
wr.write( enc_val );
wr.flush();
InputStream responseStream = new BufferedInputStream(httpURLConnection.getInputStream());
BufferedReader responseStreamReader =
new BufferedReader(new InputStreamReader(responseStream));
// Read Server Response
String output = responseStreamReader.readLine();
As you said new to android, start with best possible way
Try to implement with volley library or
RetroFit lib,its easy and simple
volley example
OR
RetroFit example
To make REST full Api's call from Android App use Retrofit by Square.inc which is the fastest and best way to call web services in android app
Check out this Easy Retrofit Sample app to call Api's -
https://github.com/TheSeasApps/Easy-Retrofit
HTTP post call from android to PHP. Start with best possible way.
http://www.androidcode.in/php-full-code-with-login-and-registration-in-android
public class LoginAsy extends AsyncTask <String, Void, String > {
Context myContext;
String result;
public LoginAsy(Context c) {
myContext = c;
}
#Override
protected String doInBackground(String... params) {
String myurldata = "name=" + params[0] + "&email=" + params[1] + "&mobile=" + params[2] + "&username=" + params[3] + "&password=" + params[4];
try {
URL url = new URL("http://192.168.2.3/Android/jnuproject.php");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.getOutputStream().write(myurldata.getBytes());
int responce = connection.getResponseCode();
Log.d("Responce code ", "" + responce);
if (responce == HttpURLConnection.HTTP_OK) {
String line;
StringBuilder builder = new StringBuilder();
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
while ((line = reader.readLine()) != null) {
builder.append(line);
}
result = builder.toString();
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
if (result.equals("success")) {
login = true;
} else {
login = false;
}
return null;
}
}

Java: read data sent by HTTP POST (Android AVD)

I use a simple WebServer from http://www.java2s.com/Code/Java/Network-Protocol/AverysimpleWebserverWhenitreceivesaHTTPrequestitsendstherequestbackasthereply.htm
and Android code from Sending json object via http post method in android
In my main Activity:
AsyncT asyncT = new AsyncT();
asyncT.execute();
Class:
class AsyncT extends AsyncTask<Void,Void,Void>{
#Override
protected Void doInBackground(Void... params) {
try {
URL url = new URL(""); //Enter URL here
HttpURLConnection httpURLConnection = (HttpURLConnection)url.openConnection();
httpURLConnection.setDoOutput(true);
httpURLConnection.setRequestMethod("POST"); // here you are telling that it is a POST request, which can be changed into "PUT", "GET", "DELETE" etc.
httpURLConnection.setRequestProperty("Content-Type", "application/json"); // here you are setting the `Content-Type` for the data you are sending which is `application/json`
httpURLConnection.connect();
JSONObject jsonObject = new JSONObject();
jsonObject.put("para_1", "arg_1");
DataOutputStream wr = new DataOutputStream(httpURLConnection.getOutputStream());
wr.writeBytes(jsonObject.toString());
wr.flush();
wr.close();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
}
The connection is established without any errors ("HostConnection::get() New Host Connection established"). However, I am not able to get in my Java server any information from the request. When I read from input stream
BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));
System.out.println(in);
I get java.io.BufferedReader#4d7hge12
And this outputs nothing:
String line;
while ((line = in.readLine()) != null) {
if (line.length() == 0)
break;
System.out.println(line);
}
Don't re-invent the wheel and use a library for this.
For example okhttp:
public static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");
OkHttpClient client = new OkHttpClient();
String post(String url, String json) throws IOException {
RequestBody body = RequestBody.create(JSON, json);
Request request = new Request.Builder()
.url(url)
.post(body)
.build();
Response response = client.newCall(request).execute();
return response.body().string();
}
If you want to call a REST-API you can use retrofit (which is build ontop of okhttp)
Assuming you're doing this as a learning exercise, so using another library isn't what you're looking for, I would suggest a couple of things:
(1) install Wireshark and see what the actual response coming back the server is, does it look sensible?
(2) break that line of code out into separate lines, is the InputStream / InputStreamReader null?

Categories