Android HttpUrlConnection not working - java

Basically, I'm trying to connect to a web interface through an Android App.
I managed to send commands to the form successfully using HttpClient. However, I want to accomplish this using HttpUrlConnection as recommended here http://android-developers.blogspot.com/2011/09/androids-http-clients.html with the intention of having a faster and more energy efficient connection.
URL url = new URL("http://" + mIpAddress + ":" + mPort + "/command.html");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setReadTimeout(10000);
connection.setConnectTimeout(15000);
connection.setRequestMethod("POST");
connection.setDoInput(true);
connection.setDoOutput(true);
OutputStream os = connection.getOutputStream();
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os, "UTF-8"));
writer.write(URLEncoder.encode("parameter=" + value, "UTF-8");
writer.flush();
writer.close();
os.close();
connection.connect();
Edit: No exceptions are being thrown since the code is executing just fine, the request is just probably not in the expected format by the server?

connnection.getInputStream() was required for the POST to work. Fixed.

Here is what I use to send http requests using HttpURLConnection, notice that the connection.connect() is right after setting up the HttpURLConnection not at the end, also the setDoInput makes the request POST instead of the default get,
URL url = new URL(urlString);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
//conn.setReadTimeout(10000 /* milliseconds */);
// conn.setConnectTimeout(15000 /* milliseconds */);
//conn.setRequestMethod("GET");
//conn.setDoInput(true); //* uses POST
// Starts the query
conn.connect();
InputStream stream = conn.getInputStream();
//String data = convertStreamToString(stream);
int sz = stream.available();
byte[] b = new byte[sz];
stream.read(b);
stream.close();
String data = new String(b);

Just add one line
connection.getRequestMethod();
and it will work.
I dont know why but this works for me after I have spent a whole day on it!

Could you provide more information, like Exceptions, or the servers response? Does the server receives a your request?
However, I recommend you to use okhttp which has been build on top of HttpUrlConnection

To share Data using HttpUrlConnection class
Here is Simple Connection class this Will Help you to Connect With WS , and to pass data using JSON parsing ..
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
public class CommonConnectionClass {
JSONObject jsonObject;
public JSONObject getConnection(String u,JSONObject object){
try {
//URL url=new URL("https://e-gurukulam.000webhostapp.com/public_html/project/login.php"+u+".php");
URL url=new URL("http://"+new Connection_Url_Setter().urlIp+"/classroom/"+u+".php");
// URL url=new URL("http://192.168.43.120/classroom/"+u+".php");
HttpURLConnection httpURLConnection=(HttpURLConnection)url.openConnection();
httpURLConnection.setRequestMethod("POST");
httpURLConnection.setRequestProperty("Content-Type","application/json; charset=utf-8");
httpURLConnection.setRequestProperty("Accept","application/json; charset=utf-8");
httpURLConnection.setDoInput(true);
httpURLConnection.setDoOutput(true);
httpURLConnection.connect();
if(object!=null) {
DataOutputStream dataOutputStream = new DataOutputStream(httpURLConnection.getOutputStream());
dataOutputStream.write(object.toString().getBytes());
}
int code=httpURLConnection.getResponseCode();
if(code== HttpURLConnection.HTTP_OK){
String inputLine;
StringBuilder stringBuilder=new StringBuilder();
BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(httpURLConnection.getInputStream()));
while((inputLine=bufferedReader.readLine())!=null){
stringBuilder.append(inputLine);
}
jsonObject=new JSONObject(stringBuilder.toString());
}
} catch (Exception e) {
e.printStackTrace();
}
return jsonObject;
}
}
To use this class i use the Asyn class Like,...
class userNameFetchTask extends AsyncTask<Void, Void, JSONObject> {
JSONObject object, jsonObject, json;
JSONArray jsonArray;
ArrayList<CreateGroupModel> lidList = new ArrayList<>();
String lid, name;
#Override
protected void onPreExecute() {
jsonObject = new JSONObject();
try {
jsonObject.put("lid", sp.getString("lid", null));
} catch (JSONException e) {
e.printStackTrace();
}
super.onPreExecute();
}
#Override
protected JSONObject doInBackground(Void... voids) {
object = new JSONObject();
CommonConnectionClass commonConnectionClass = new CommonConnectionClass();
object = commonConnectionClass.getConnection("selectUserForGroup", jsonObject);
return object;
}
#Override
protected void onPostExecute(JSONObject jsonObject) {
super.onPostExecute(jsonObject);
jsonArray = new JSONArray();
try {
jsonArray = jsonObject.getJSONArray("response");
for (int i = 0; i < jsonArray.length(); i++) {
CreateGroupModel model = new CreateGroupModel();
json = jsonArray.getJSONObject(i);
model.setLid(json.getString("relative_lid"));
model.setName(json.getString("name"));
model.setEmail(json.getString("email"));
model.setImage(json.getString("image"));
lidList.add(model);
}
viewstudentsadapterForCreateGroup viewstudentsadapterForCreateGroup = new viewstudentsadapterForCreateGroup(getApplicationContext(), lidList, createGroup_Activity.this);
listView.setAdapter(viewstudentsadapterForCreateGroup);
} catch (JSONException e) {
e.printStackTrace();
}
}
}

In my case, it was actually NetworkOnMainThreadException thrown but not shown clearly in Logs

Related

How to change a HttpsURLConnection GET to be a POST request?

I'm really new to android (programming in general), but I'm inherit a project that was created by another person, I know this may be simple for a lot of you guys but Im lost with trying to change the below piece of code.
What I need to do is to change the type of request from a GET to a POST, and send some values with the request.
The request needs to have the following syntax.
type=active
data={"json here with all info"} ------> mRequestStringEncoded
String RequestString = ((myrequest) request).getJson();
String mRequestStringEncoded = URLEncoder.encode( RequestString, "utf-8" );
mURL = defautlUrl+ mRequestStringEncoded;
Log.e( TAG, "Request URL: " + mURL );
try
{
HttpsURLConnection mUrlConnection = (HttpsURLConnection) new URL( mURL ).openConnection();
mUrlConnection.setRequestProperty( "charset", "utf-8" );
mUrlConnection.setRequestMethod( "GET" );
mUrlConnection.setConnectTimeout( 12000 );
mUrlConnection.setReadTimeout( 30000 );
mUrlConnection.connect();
I know that I need to change:
mUrlConnection.setRequestProperty( "charset", "utf-8" );
mUrlConnection.setRequestMethod( "GET" );
To:
mUrlConnection.setRequestProperty("Content-Type", "application/json; utf-8");
mUrlConnection.setRequestMethod( "POST" );
But how can I pass the paramenter?
Try something like this:
String post_data="type=active&data=" + data;
HttpsURLConnection mUrlConnection = (HttpsURLConnection) new URL( tURL ).openConnection();
mUrlConnection.setRequestMethod( "POST" );
mUrlConnection.setRequestProperty("type", "active");
mUrlConnection.setRequestProperty("data", "data");
mUrlConnection.setDoOutput(true);
//Adding Post Data
OutputStream outputStream = mUrlConnection.getOutputStream();
outputStream.write(post_data.getBytes());
outputStream.flush();
outputStream.close();
mUrlConnection.setConnectTimeout( 22000 );
mUrlConnection.setReadTimeout( 30000 );
mUrlConnection.connect();
You almost got it. Try this, it should work. I used Jackson for getting json format from a Map:
package com.http;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Map;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
public class FormSubmitService {
public void doSubmit(String url, Map<String, String> data) throws IOException {
URL siteUrl = new URL(url);
HttpURLConnection conn = (HttpURLConnection) siteUrl.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/json; utf-8");
conn.setUseCaches (true);
conn.setDoOutput(true);
conn.setDoInput(true);
DataOutputStream out = new DataOutputStream(conn.getOutputStream());
String content = getJsonFromMap(data);
System.out.println(content);
out.writeBytes(content);
out.flush();
out.close();
BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String line = "";
while ((line=in.readLine())!=null) {
System.out.println(line);
}
in.close();
}
private String getJsonFromMap(Map<String, String> map) {
ObjectMapper objectMapper = new ObjectMapper();
String json = null;
try {
json = objectMapper.writeValueAsString(map);
} catch (JsonProcessingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return json;
}
}
Well, in the POST method you can pass the parameters by converting them into JSON using Gson.
Step 1: Add gson dependency in the Gradle file.
dependencies {
implementation 'com.google.code.gson:gson:2.8.8'
}
Step 2: Create a model class of your parameter/key.
public class ApiModel {
public String type,data;
public ApiModel(String type, String data) {
this.type = type;
this.data = data;
}
public String getType() {
return type;
}
public String getData() {
return data;
}
}
Step 3: Create Object of Model class and add the values.
//add data into model to create json
ApiModel ObjApi = new ApiModel(type_value, data_value);
Step 4: Now, convert the ObjApi into JSON using Gson.
Gson gson = new Gson();
String json = gson.toJson(ObjApi);
Step 5: Add json string into BufferedWriter.
OutputStream stream = httpURLConnection.getOutputStream();
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(stream, "UTF-8"));
bufferedWriter.write(json);
bufferedWriter.flush();
bufferedWriter.close();
stream.close();
Example: sample with httpurlConnection.
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.setRequestMethod(REQUEST_METHOD);
httpURLConnection.setRequestProperty("Content-Type", "application/json");
httpURLConnection.setDoOutput(true);
httpURLConnection.setDoInput(true);
httpURLConnection.setConnectTimeout(TimeOut);
httpURLConnection.setReadTimeout(TimeOut);
OutputStream stream = httpURLConnection.getOutputStream();
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(stream, "UTF-8"));
bufferedWriter.write(json);
bufferedWriter.flush();
bufferedWriter.close();
stream.close();
httpURLConnection.disconnect();

Java HttpURLConnection is not sending a body

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());

How to get and use HTTPResponse message from a DJANGO server

How can I get the response message returned from my DJANGO view and place it into a textview? Most of the answers talk about using Httpresponse but as I've read, it has be deprecated. I'm using SDK v28.
Java code in Android Studio:
private class HTTPAsyncTask_wdgt extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... urls) {
try {
try {
return HttpPost_wdgt(urls[0]);
} catch (JSONException e) {
e.printStackTrace();
return "Error!";
}
} catch (IOException e) {
return "Unable to retrieve web page. URL may be invalid.";
}
}
}
private String HttpPost_wdgt(String myUrl) throws IOException, JSONException {
URL url = new URL(myUrl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setDoOutput(true);
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/json; charset=utf-8");
JSONObject jsonObject = buildJsonObject_wdgt(); //Just takes some data from the app and returns JSON to be posted.
setPostRequestContent_wdgt(conn, jsonObject);
conn.connect();
return conn.getResponseMessage()+"";
}
private void setPostRequestContent_wdgt(HttpURLConnection conn,
JSONObject jsonObject) throws IOException {
OutputStream os = conn.getOutputStream();
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os, "UTF-8"));
writer.write(jsonObject.toString());
writer.flush();
writer.close();
os.close();
}
Django view: (Right now it just returns 'mac' from the posted JSON)
#csrf_exempt
def req_exec(request):
ret = request.POST
data = json.loads(request.body)
return HttpResponse(data['mac'])
I normally use OKHttp for getting and processing requests, here is a Vogella tutorial helping to get start.

Inserting JSON data to mLab database using Android application

I am new to android and mongodb.
I have problem with inserting data to my mLab database using my android application.
My code is this:
final class MongoLabSaveData extends AsyncTask<Object, Void, Boolean> {
#Override
protected Boolean doInBackground(Object... params) {
SignupData signupData = (SignupData) params[0];
Log.d("Sign_Up", ""+signupData);
try {
SupportDataAPI sd = new SupportDataAPI();
URL url = new URL(sd.buildSignupSaveURL());
HttpURLConnection connection = (HttpURLConnection) url
.openConnection();
connection.setRequestMethod("PUT");
connection.setDoOutput(true);
connection.setRequestProperty("Content-Type",
"application/json");
connection.setRequestProperty("Accept", "application/json");
OutputStreamWriter osw = new OutputStreamWriter(connection.getOutputStream());
osw.append(sd.createSignupData(signupData));
osw.flush();
osw.close();
if(connection.getResponseCode() <205)
{
return true;
}
else
{
return false;
}
} catch (Exception e) {
e.getMessage();
Log.d("Got error", e.getMessage());
return false;
}
}
}
Here, the data gets inserted to every 0th index of json data due to this line:
SignupData signupData = (SignupData) params[0];
How can I make this in such a way that it appends my json data with the existing data. Not in the 0th index.

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