I've been trying to get this work for a while now. Im working on an app where the user signs in with a username and password which uses a httppost request to post to the server. i get the correct response, and during the post i store the session cookie that the server gives me. (I store it in a cookie store)
But when i try to click a link on the menu ( which does a second http post) after i logged in, the servers gives me a message saying that i am not logged in. But i send the cookie that i recieved in the first post to the server in the second post, yet the server does not recognize that i am logged in. To test this more easily i used the chrome plug in "Postman" which lets you post to websites easily. The only time it worked was when i log in to the website using chrome then use Postman to do the second post, which successfully gives me a response. however, when i use Postman to log in, then also use postman to attempt the second post , again, "Not logged in". Im guessing that the cookie is not being stored properly in the app. How could i go about fixing this? I read some stuff about storing the cookies in something called "Shared Preferences", is that possibly a fix? If so, what is it and how could i store the cookies there?
public static String executeHttpPost(String url, ArrayList<NameValuePair> postParameters) throws Exception {
BufferedReader in = null;
try {
LoginLayout.httpClient = new DefaultHttpClient();
HttpPost request = new HttpPost(url);
UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(postParameters);
request.setEntity(formEntity);
CookieStore cookiestore = LoginLayout.httpClient.getCookieStore();
HttpResponse response = LoginLayout.httpClient.execute(request);
List<Cookie> cookies = LoginLayout.httpClient.getCookieStore().getCookies();
cookiestore.addCookie(cookie);
cookie = cookies.get(0);
cookieValue = "ASPSESSIONIDCQTCRACT=" + cookiestore.getCookies();
System.out.println("The cookie" + cookieValue);
List<Cookie> cookiess = cookiestore.getCookies();
cookiee = cookies.get(0);
Header[] headers = response.getAllHeaders();
System.out.println("length" + headers.length);
for (int i=0; i < headers.length; i++) {
Header h = headers[i];
System.out.println( "Header names: "+h.getName());
System.out.println( "Header Value: "+h.getValue());
}
in = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
StringBuffer sb = new StringBuffer("");
String line = "";
String NL = System.getProperty("line.separator");
while ((line = in.readLine()) != null) {
sb.append(line + NL);
}
in.close();
// System.out.println( mCookie);
String result = sb.toString();
return result;
}
finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
} }
Here is the getter so i can access the cookie from the cookie store in the next activity
public static String getCookie(){
return cookiee.getName() +"="+cookiee.getValue();
}
Here is the second post where i try to retrieve the stored cookie, which it seems to do sucessfully, however the server doesnt recognize i am logged in
public static String executeHttpPost(String url, ArrayList<NameValuePair> postParameters) throws Exception {
BufferedReader in = null;
try {
HttpPost request = new HttpPost(url);
request.setHeader("Cookie", LoginLayout.getCookie());
UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(postParameters);
request.setEntity(formEntity);
HttpResponse response = LoginLayout.httpClient.execute(request);
Header[] headers = response.getAllHeaders();
System.out.println("length" + headers.length);
for (int i=0; i < headers.length; i++) {
Header h = headers[i];
System.out.println( "Header names: "+h.getName());
System.out.println( "Header Value: "+h.getValue());
}
in = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
StringBuffer sb = new StringBuffer("");
String line = "";
String NL = System.getProperty("line.separator");
while ((line = in.readLine()) != null) {
sb.append(line + NL);
}
in.close();
//System.out.println( mCookie);
String result = sb.toString();
return result;
}
finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
You have to make sure that your HttpClient is using the same HttpContext on each request.
The CookieStore is associated with the HttpContext so create a new instance of HttpContext will create a new CookieStore as well.
The best way I found is to create a static instance of HttpContext and use it on every request.
Below I added an part of a class I'm using in my apps:
public class ApiClient {
// Constants
private final static String TAG = "ApiClient";
private final static String API_URL = "your-url";
// Data
private static ApiClient mInstance;
private HttpClient mHttpClient;
private ThreadSafeClientConnManager mConnectionManager;
private HttpPost mPost;
/*
* we need it static because otherwise it will be recreated and the session
* will be lost
*/
private static HttpContext mHttpContext;
private HttpParams mParams;
private Context mContext;
public ApiClient(Context pContext) {
mParams = new BasicHttpParams();
mContext = pContext;
if (null == mHttpContext) {
CookieStore cookieStore = new BasicCookieStore();
mHttpContext = new BasicHttpContext();
mHttpContext.setAttribute(ClientContext.COOKIE_STORE, cookieStore);
}
ConnManagerParams.setMaxTotalConnections(mParams, 300);
HttpProtocolParams.setVersion(mParams, HttpVersion.HTTP_1_1);
SchemeRegistry schemeRegistry = new SchemeRegistry();
schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
mConnectionManager = new ThreadSafeClientConnManager(mParams, schemeRegistry);
mHttpClient = new DefaultHttpClient(mConnectionManager, mParams);
}
public static ApiClient getInstance(Context pContext) {
if (null == mInstance) {
return (mInstance = new ApiClient(pContext));
} else {
return mInstance;
}
}
public void testPOST() {
List<NameValuePair> requestParams = new ArrayList<NameValuePair>();
requestParams.add(new BasicNameValuePair("param1", "value1"));
requestParams.add(new BasicNameValuePair("param2", "value2"));
mPost = new HttpPost(API_URL);
try {
mPost.setEntity(new UrlEncodedFormEntity(requestParams, HTTP.UTF_8));
HttpResponse responsePOST = mHttpClient.execute(mPost, mHttpContext);
HttpEntity resEntity = responsePOST.getEntity();
String result = EntityUtils.toString(resEntity);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
To test it try setting the correct API_URL and
ApiClient api = ApiClient.getInstance(somContext);
api.testPOST();
Related
I am knew to java, azure ad and power bi and I want to test pushing data into power bi using the azure ad java library (ADAL) here : http://innerdot.com/azure/authenticating-to-azure-resource-manager-using-java
I've created a netbeans project and used this code : http://innerdot.com/azure/authenticating-to-azure-resource-manager-using-java and tested it so that I know I have all rights to access my azure ad application.
In the Power BI documentation, we tell you to register your app and get the authentication token which will help you use the API to send GET/POST.. requests
I used a sample code I found on Github. However, following the examples in the power bi apiary docs I get a "403" or "404" http reponse status.
public class ApplicationAuthExample {
private final static String AUTHORIZATION_ENDPOINT = "https://login.microsoftonline.com/";
private final static String ARM_ENDPOINT = "https://management.azure.com/";
private static final boolean DEV_MODE = true;
public static void main(String[] args) throws Exception {
String username = null;
String credential = null;
String tenantId = null;
String clientId = null;
String subscriptionId = null;
if (DEV_MODE) {
username = "name.name#entity.com";
credential = "******";
clientId = "50xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
tenantId = "bbexxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
subscriptionId = "16bxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
} else {
if ((!args[0].equals("service-principal") && !args[0].equals("user"))
|| (args[0].equals("user") && args.length != 6)
|| (args[0].equals("service-principal") && args.length != 5)) {
System.out.println("Usage:");
System.out.println(" user <username> <password> <client id> <tenant id> <subscription id>");
System.out.println(" service-principal <password> <client id> <tenant id> <subscription id>");
System.exit(1);
}
int idx = 1;
if (args[0].equals("user")) {
username = args[idx++];
}
credential = args[idx++];
clientId = args[idx++];
tenantId = args[idx++];
subscriptionId = args[idx++];
}
// use adal to Authenticate
AuthenticationContext context = null;
AuthenticationResult result = null;
ExecutorService service = null;
try {
service = Executors.newFixedThreadPool(1);
String url = AUTHORIZATION_ENDPOINT + tenantId + "/oauth2/authorize";
context = new AuthenticationContext(url,
false,
service);
Future<AuthenticationResult> future = null;
if (username == null) {
System.out.println("username = null");
ClientCredential cred = new ClientCredential(clientId, credential);
future = context.acquireToken(ARM_ENDPOINT, cred, null);
} else {
future = context.acquireToken(ARM_ENDPOINT, clientId,
username, credential, null);
}
result = future.get();
} catch (Exception ex) {
System.out.println("Exception occurred:");
ex.printStackTrace();
System.exit(1);
} finally {
service.shutdown();
}
// make a request to list available providers
String url = ARM_ENDPOINT
+ "subscriptions/" + subscriptionId
+ "/providers"
+ "?api-version=2014-04-01-preview";
// String url = "https://api.powerbi.com/v1.0/myorg/datasets";
String body = null;
try {
//final HttpClient httpClient = new DefaultHttpClient();
final HttpClient httpClient = HttpClientBuilder.create().build();
//HttpConnectionParams.setConnectionTimeout(httpClient.getParams(), 10000);
RequestConfig requestConfig = RequestConfig.custom()
.setSocketTimeout(5000)
.setConnectTimeout(5000)
.setConnectionRequestTimeout(5000)
.build();
HttpGet httpGet = new HttpGet(url);
httpGet.setConfig(requestConfig);
System.out.println("url : "+url);
httpGet.addHeader("Authorization", "Bearer " + result.getAccessToken());
// httpGet.setHeader("Authorization", "Bearer " + result.getAccessToken());
// System.out.println("token : "+result.getAccessToken());
HttpResponse response = httpClient.execute(httpGet);
int statusCode = response.getStatusLine().getStatusCode();
System.out.println("status : "+statusCode);
if(statusCode == 403){
System.out.println(statusCode+": acces denied");
}
HttpEntity entity = response.getEntity();
InputStream instream = entity.getContent();
StringBuilder sb = new StringBuilder();
BufferedReader r = new BufferedReader(new InputStreamReader(instream), 1000);
for (String line = r.readLine(); line != null; line = r.readLine()) {
sb.append(line);
}
instream.close();
body = sb.toString();
} catch (Exception ex) {
System.out.println(ex.toString());
System.exit(1);
}
System.out.println("body : "+body);
}
}
Thank you for your help.
As I known, the endpoints in your code are only for service on Azure, not for PowerBI. Please follow the PowerBI offical document to set the endpoints for authenticating, and see the document Push data into a Power BI Dashboard to know how to get started.
For authenticating to PowerBI service, please according to your needs to register a client app or a web app that needs different authentication.
There is a sample which I searched in GitHub, that includes the code for getting access token for PowerBI authentication using Java, please see https://github.com/satalyst/powerbi-rest-java/blob/master/src/main/java/com/satalyst/powerbi/impl/Office365Authenticator.java.
Hope it helps.
Any concern, please feel free to let me know.
After testing it in C# and going back to java, I finally managed to establish the connexion and get a valid token:
public class ApplicationAuth {
public static void main(String[] args) throws Exception {
String username = null;
String credential = null;
String clientId = null;
username = "xxxx.xxxxx#company.com";
credential = "************";
clientId = "50xxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";
// use adal to Authenticate
AuthenticationContext context = null;
AuthenticationResult result = null;
ExecutorService service = null;
try {
service = Executors.newFixedThreadPool(1);
String url = "https://login.windows.net/common/oauth2/authorize";
context = new AuthenticationContext(url,
false,
service);
Future<AuthenticationResult> future = null;
if (username==null) {
System.out.println("username = null");
ClientCredential cred = new ClientCredential(clientId, credential);
future = context.acquireToken("https://analysis.windows.net/powerbi/api", cred, null);
} else {
future = context.acquireToken("https://analysis.windows.net/powerbi/api", clientId,
username, credential, null);
}
result = future.get();
} catch (Exception ex) {
System.out.println("Exception occurred:");
ex.printStackTrace();
System.exit(1);
} finally {
service.shutdown();
}
String body = null;
String token = result.getAccessToken();
try {
DatasetsHandler datasetH = new DatasetsHandler();
String data = "{\"name\": \"JavaDatasetTest\", \"tables\": " +
"[{\"name\": \"Product\", \"columns\": " +
"[{ \"name\": \"ProductID\", \"dataType\": \"Int64\"}, " +
"{ \"name\": \"Name\", \"dataType\": \"string\"}, " +
"{ \"name\": \"Category\", \"dataType\": \"string\"}," +
"{ \"name\": \"IsCompete\", \"dataType\": \"bool\"}," +
"{ \"name\": \"ManufacturedOn\", \"dataType\": \"DateTime\"}" +
"]}]}";
//datasetH.CreateDataset(data, token);
System.out.println("after creating dataset");
body = datasetH.GetDatasets(token);
String datasetID = datasetH.GetDatasetID(token);
System.out.println("dataset ID: "+datasetID);
String rows = "{\"rows\":" +
"[{\"ProductID\":1,\"Name\":\"Adjustable Race\",\"Category\":\"Components\",\"IsCompete\":true,\"ManufacturedOn\":\"07/30/2014\"}," +
"{\"ProductID\":2,\"Name\":\"LL Crankarm\",\"Category\":\"Components\",\"IsCompete\":true,\"ManufacturedOn\":\"07/30/2014\"}," +
"{\"ProductID\":3,\"Name\":\"HL Mountain Frame - Silver\",\"Category\":\"Bikes\",\"IsCompete\":true,\"ManufacturedOn\":\"07/30/2014\"}]}";
String resu = datasetH.AddRows( datasetID, token, "Product", rows);
}catch (Exception ex) {
System.out.println(ex.toString());
System.exit(1);
}
// System.out.println("body : "+body); //{"value":[]}
}
}
Here are the methods I use:
public class DatasetsHandler {
public String powerBIDatasetsApiUrl = "https://api.powerbi.com/v1.0/myorg/datasets";
public String GetDatasets(String token) throws IOException{
HttpRequests httpRequest = new HttpRequests();
HttpResponse response = httpRequest.HttpHeaderParams(token, powerBIDatasetsApiUrl, "GET", "");
HttpEntity entity = response.getEntity();
InputStream instream = entity.getContent();
StringBuilder sb = new StringBuilder();
BufferedReader r = new BufferedReader(new InputStreamReader(instream), 1000);
for (String line = r.readLine(); line != null; line = r.readLine()) {
sb.append(line);
}
instream.close();
String body = sb.toString();
return body;
}
public void CreateDataset(String data, String token) throws IOException{
HttpRequests httpRequest = new HttpRequests();
HttpResponse response = httpRequest.HttpHeaderParams(token, powerBIDatasetsApiUrl, "POST", data);
System.out.println("createDataset response: "+response.getStatusLine().getStatusCode());
HttpEntity entity = response.getEntity();
System.out.println("entity: "+entity);
InputStream instream = entity.getContent();
StringBuilder sb = new StringBuilder();
BufferedReader r = new BufferedReader(new InputStreamReader(instream), 1000);
for (String line = r.readLine(); line != null; line = r.readLine()) {
sb.append(line);
}
instream.close();
String body = sb.toString();
System.out.println("created dataset");
}
public String GetDatasetID(String token) throws IOException{
int id_count = 0;
DatasetsHandler DatasetH = new DatasetsHandler();
String result = DatasetH.GetDatasets(token);
JSONObject jObject = new JSONObject(result);
JSONArray geodata = jObject.getJSONArray("value");
for (int i = 0; i<geodata.length(); i++){
try{
JSONObject cdataset = geodata.getJSONObject(i);
id_count = id_count +1;
}catch (JSONException e) {
// If id doesn't exist, this exception is thrown
}
}
JSONObject cdataset = geodata.getJSONObject(id_count -1);
String Id = cdataset.getString("id");
System.out.println("get dataset name : "+cdataset.getString("name"));
System.out.println("get dataset id : "+cdataset.getString("id"));
return Id;
}
public String AddRows(String DatasetID, String token, String TableName, String rows) throws IOException{
String url = "https://api.powerbi.com/v1.0/myorg/datasets/"+DatasetID+"/tables/"+TableName+"/rows";
HttpRequests httpRequest = new HttpRequests();
HttpResponse response = httpRequest.HttpHeaderParams(token, url, "POST", rows);
System.out.println("Rows Added");
return response.getEntity().toString();
}
}
And the HttpHandelr:
public class HttpRequests {
public HttpRequestBase httpRequest;
public static Gson gson = new Gson();
public HttpResponse HttpHeaderParams (String token, String powerBIApiUrl, String method, String body) throws IOException {
final HttpClient httpClient = HttpClientBuilder.create().build();
//JSONObject jsonObj = new JSONObject(body);
StringEntity dataset = new StringEntity(body);
RequestConfig requestConfig = RequestConfig.custom()
.setSocketTimeout(5000)
.setConnectTimeout(5000)
.setConnectionRequestTimeout(5000)
.build();
if("GET".equals(method)){
httpRequest = new HttpGet(powerBIApiUrl);
}else if("POST".equals(method)){
System.out.println("===POST METHOD");
httpRequest = new HttpPost(powerBIApiUrl);
((HttpPost)httpRequest).setEntity(dataset);
System.out.println("get entity: "+((HttpPost)httpRequest).getEntity());
}
System.out.println("TOKEN: "+token);
httpRequest.setConfig(requestConfig);
httpRequest.addHeader("Authorization", "Bearer " + token);
httpRequest.setHeader("Content-Type", "application/json");
httpRequest.setHeader("ContentLength", "\""+body.length()+"\"");
HttpResponse response = httpClient.execute(httpRequest);
System.out.println("response: "+Arrays.toString(response.getAllHeaders()));
System.out.println("response: "+response.getStatusLine().getStatusCode());
return response;
}
}
I hope It helps :)
I can't seem to get my PHP page to display the data I have sent using a http client in Android. All I need now is displaying it in PHP which seems to be a challenge, I know I have done something wrong.
Any guidance would be much appreciated. I have tried everything from var_dump($_SERVER) to json_decode to display it in PHP. Is it even possible to display it on a PHP page?
private class Connection extends AsyncTask{
#Override
protected Object doInBackground(Object[] objects){
try{
PostData(R.id.fullscreen_content, 3);
}
catch(IOException exception){
exception.printStackTrace();
}
return null;
}
}
protected void PostData(Integer Question_ID,Integer ResponseChosen_ID) {
URL url = new URL("http://10.0.2.2:443/SwlLogin.php");
HttpURLConnection conn =(HttpURLConnection)url.openConnection();
conn.setDoOutput(true);
HttpClient httpClient = new DefaultHttpClient();
HttpGet post = new HttpGet(conn.getURL().toString());
post.setHeader("Content-type","application/json");
conn.connect();
Date date = new Date();
SimpleDateFormat dt = new SimpleDateFormat("yyyy-MM-dd", Locale.UK);
SimpleDateFormat time = new SimpleDateFormat("HH:mm:ss",Locale.UK);
String nowDate = dt.format(date);
String nowTime = time.format(date);
String phpDate = nowDate;
String phpTime = nowTime;
ArrayList<NameValuePair> params = new ArrayList<>();
params.add(new BasicNameValuePair("Question ID", Question_ID.toString()));
params.add(new BasicNameValuePair("Response_Chosen_ID", ResponseChosen_ID.toString()));
params.add(new BasicNameValuePair("TimestampDate", phpDate));
params.add(new BasicNameValuePair("time", phpTime));
JSONArray array = new JSONArray();
array.put(params);
post.setHeader("postData", params.toString());
post.getParams().setParameter("JSON", params);
HttpParams var = httpClient.getParams();
var.setParameter("GET",params);
HttpResponse response = httpClient.execute(post);
OutputStreamWriter write = new OutputStreamWriter(conn.getOutputStream());
BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
StringBuilder builder = new StringBuilder();
String line = null;
while((line = reader.readLine()) != null){
builder.append(line);
}
Log.d("Response:", builder.toString());
builder.toString();
reader.close();
public void happy_click(View view) throws IOException {
try{
new Connection().execute();
report_success();
}
catch(Exception exception){
messageBox("Response was not successful","Failed to process response" + exception.getMessage());
}
}
you can not run this code on the UI thread or you will get a NetworkRequestOnUIThread exception. you have to do this on a different thread.
try using AsyncTask via
private class Uploader extends AsyncTask<Void,Void,Void>{
protected void doInBackground(){
// do network request here
}
private void onPostExecute(){
// handle UI updates here as is on ui Thread
}
}
or you could look at using OkHTTP library which I recommend highly. to do this download the jar from okHttp. add it to you libs folder then you can do network call like this
MediaType JSON = MediaType.parse("application/json; charset=utf-8");
JSONObject parcel = new JSONObject();
try{
parcel.put("email", emailEdit.getText().toString());
parcel.put("password", passwordEdit.getText().toString());
parcel.put("device", "Android");
parcel.put("hash", "1234");;
}catch (JSONException e ){
e.printStackTrace();
}
RequestBody body = RequestBody.create(JSON, parcel.toString());
Request request = new Request.Builder()
.header("Content-Type", "application/json")
.url("YOURURL")
.post(body)
.build();
client.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(Call call, IOException e) {
if (null != e) {e.printStackTrace();}
}
#Override
public void onResponse(Call call, Response response) throws IOException {
if (null != response && response.message().equals(Constants.KEY_OK)) {
JSONObject serverResponse;
try{
serverResponse = new JSONObject(response.body().string());
if(serverResponse.getBoolean(Constants.KEY_SUCCESS)){
Constants.getInstance().setToken(serverResponse.getString(Constants.KEY_TOKEN));
moveToHomePage();
}else{
showLoginFail();
}
}catch (JSONException e ){
e.printStackTrace();
}
response.body().close();
} else {
showLoginFail();
}
}
});
also make sure you have
<uses-permission android:name="...permision.INTERNET">
in your manifest file
I want to create a restful web service in java using jersey API and consume it in android application. I got this question on SO but it talks about java client whereas I have android client.
My service looks like this:
#Path("/no")
public class CheckNumber {
#POST
#Produces("application/json")
#Consumes("application/json")
public String getDetails(#PathParam("cNo") String cNo) {
String CardNo="";
try {
JSONObject jsonObj = new JSONObject(cNo);
CardNo=jsonObj.getString("CardNo");
} catch (ParseException e1) {
e1.printStackTrace();
}
//Do something
return "someValue";
}
}
Now comes the client side:
public class MainActivity extends Activity {
JSONObject json = new JSONObject();
String wsdl = "http://192.168.1.105:8080/restdemo/check/no/";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new RequestTask().execute("1234567890");
}
class RequestTask extends AsyncTask<String, String, String> {
#Override
protected String doInBackground(String... uri) {
HttpClient httpclient = new DefaultHttpClient();
HttpResponse response;
String add = "{\"CardNo\":\"" + uri[0] + "\"}";
HttpPost postMethod = new HttpPost(wsdl);
String responseString = null;
try {
postMethod.addHeader("Content-Type", "application/json");
HttpEntity entity = new StringEntity(add);
postMethod.setEntity(entity);
response = httpclient.execute(postMethod);
StatusLine statusLine = response.getStatusLine();
if (statusLine.getStatusCode() == HttpStatus.SC_OK) {
ByteArrayOutputStream out = new ByteArrayOutputStream();
response.getEntity().writeTo(out);
out.close();
responseString = out.toString();
} else {
response.getEntity().getContent().close();
throw new IOException(statusLine.getReasonPhrase());
}
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return responseString;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
}
}
}
I'm just starting with rest web services. I successfully created a sample rest service which consumes string and returns string and used this service in android app.
But when I try to pass json string using POST method. It's giving following errorin log:
java.io.IOException: Internal Server Error
at com.example.restclient.MainActivity$RequestTask.doInBackground(MainActivity.java:85)
where MainActivity.java:85 is throw new IOException(statusLine.getReasonPhrase()); which implies that statusLine.getStatusCode() is not returning HttpStatus.SC_OK. Instead it's returning status code = 500.
Any help appreciated.
It will be good to see the server side log to understand better.
Try creating the entity with UTF8 and set the content-type in the string entity rather than in the postMethod
StringEntity stringEntity = new StringEntity(myJsonDocStr, HTTP.UTF_8);
stringEntity.setContentType("application/json");
Try this code, It works for me
Boolean NetworkLostFlag = false;
HttpParams httpParameters = new BasicHttpParams();
int timeoutConnection = 10000;
HttpConnectionParams.setConnectionTimeout(httpParameters,
timeoutConnection);
int timeoutSocket = 12000;
HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);
HttpClient httpclient = new DefaultHttpClient(httpParameters);
HttpPost httppost = new HttpPost(strUrl");
try {
httppost.setEntity(new UrlEncodedFormEntity(new BasicNameValuePair(arg1, val1), "UTF-8"));
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
if (entity != null) {
InputStream instream = entity.getContent();
try {
// do something useful
StringBuffer buffer = new StringBuffer();
byte[] b = new byte[4096];
for (int n; (n = instream.read(b)) != -1;) {
buffer.append(new String(b, 0, n));
}
result = buffer.toString();
} catch (Exception e) {
NetworkLostFlag = true;
// TODO: handle exception
} finally {
instream.close();
}
}
} catch (Exception e) {
NetworkLostFlag = true;
e.printStackTrace();
}
In my app, I need to send all sorts of POST requests to a server. some of those requests have responses and others don't.
this is the code I'm using to send the requests:
private static final String TAG = "Server";
private static final String PATH = "http://10.0.0.2:8001/data_connection";
private static HttpResponse response = null;
private static StringEntity se = null;
private static HttpClient client;
private static HttpPost post = null;
public static String actionKey = null;
public static JSONObject sendRequest(JSONObject req) {
try {
client = new DefaultHttpClient();
actionKey = req.getString("actionKey");
se = new StringEntity(req.toString());
se.setContentEncoding(new BasicHeader(HTTP.CONTENT_ENCODING, "application/json"));
se.setContentType(new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));
post = new HttpPost(PATH);
post.setEntity(se);
Log.d(TAG, "http request is being sent");
response = client.execute(post);
Log.d(TAG, "http request was sent");
if (response != null) {
InputStream in = response.getEntity().getContent();
String a = convertFromInputStream(in);
in.close();
return new JSONObject(a);
}
} catch (UnsupportedEncodingException e) {
Log.d(TAG, "encoding request to String entity faild!");
e.printStackTrace();
} catch (ClientProtocolException e) {
Log.d(TAG, "executing the http POST didn't work");
e.printStackTrace();
} catch (IOException e) {
Log.d(TAG, "executing the http POST didn't work");
e.printStackTrace();
} catch (JSONException e) {
Log.d(TAG, "no ActionKey");
e.printStackTrace();
}
return null;
}
private static String convertFromInputStream(InputStream in)
throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(in));
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = br.readLine()) != null) {
sb.append(line);
}
return (sb.toString());
}
This is the code for the AsyncTask class that sends the request:
class ServerRequest extends AsyncTask<JSONObject, Void, JSONObject> {
#Override
protected JSONObject doInBackground(JSONObject... params) {
JSONObject req = params[0];
JSONObject response = Server.sendRequest(req);
return response;
}
#Override
protected void onPostExecute(JSONObject result) {
// HANDLE RESULT
super.onPostExecute(result);
}
}
my problem starts when the server doesn't return a response. the AsyncTask thread stays open even after the work is done because the HTTPClient never closes the connection.
Is there a way to not wait for a response? this is something that will definitely add a lot of overhead to the server since all the Android apps trying to connect to it will keep the connection alive, and will probably cause many problems on the app itself.
Basically, what I'm looking for is a method that will allow me to send to POST message and kill the connection right after the sending of the request since there is no response coming my way.
Just, Set ConnectionTimeOut with HttpClient Object, (Code is for your understanding in your case it may be different)
int TIMEOUT_MILLISEC = 30000;
HttpParams httpParams = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(httpParams, TIMEOUT_MILLISEC);
HttpConnectionParams.setSoTimeout(httpParams, TIMEOUT_MILLISEC);
HttpClient httpclient = new DefaultHttpClient(httpParams);
HttpPost httppost = new HttpPost(url);
httppost.addHeader("Content-Type", "application/json");
Now, It will terminate the Connection after TimeoOut you defined. But be sure this will throw TimeOutException so You have to handle this exception in your HttpRequest.. (Use Try -catch)
EDIT: Or you can use HttpRequestExecutor class.
From class HttpRequestExecutor of package org.apache.http.protocol
protected boolean canResponseHaveBody (HttpRequest request, HttpResponse response)
Decide whether a response comes with an entity. The implementation in this class is based on RFC 2616. Unknown methods and response codes are supposed to indicate responses with an entity.
Derived executors can override this method to handle methods and response codes not specified in RFC 2616.
I have tried different methods to upload and retrieve a link via imgur but none have been successfull despite looking at the imgur api.
http://api.imgur.com/examples#uploading_java
But the following methods partly works..
im trying to retrieve,
errors: if any errors occured.
link to image: the link to the image hosted
delete link: the link to delete the image hosted
But i only end up with the "delete link", as the others are blank,
check it out:
public void post(String path) {
List<NameValuePair> postContent = new ArrayList<NameValuePair>(2);
postContent.add(new BasicNameValuePair("key", DEV_KEY));
postContent.add(new BasicNameValuePair("image", path));
String url = "http://api.imgur.com/2/upload";
HttpClient httpClient = new DefaultHttpClient();
HttpContext localContext = new BasicHttpContext();
HttpPost httpPost = new HttpPost(url);
try {
MultipartEntity entity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);
for(int index=0; index < postContent.size(); index++) {
if(postContent.get(index).getName().equalsIgnoreCase("image")) {
// If the key equals to "image", we use FileBody to transfer the data
entity.addPart(postContent.get(index).getName(), new FileBody(new File (postContent.get(index).getValue())));
} else {
// Normal string data
entity.addPart(postContent.get(index).getName(), new StringBody(postContent.get(index).getValue()));
}
}
httpPost.setEntity(entity);
HttpResponse response = httpClient.execute(httpPost, localContext);
mImgurResponse = parseResponse (response);
Iterator it = mImgurResponse.entrySet().iterator();
while(it.hasNext()){
HashMap.Entry pairs = (HashMap.Entry)it.next();
Log.i("INFO",pairs.getKey().toString());
if(pairs.getValue()!=null){
reviewEdit.setText(pairs.getValue().toString());
Log.i("INFO",pairs.getValue().toString());
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
private Map<String,String> parseResponse(HttpResponse response) {
String xmlResponse = null;
try {
xmlResponse = EntityUtils.toString(response.getEntity());
} catch (ParseException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
if (xmlResponse == null) return null;
HashMap<String, String> ret = new HashMap<String, String>();
ret.put("error", getXMLElementValue(xmlResponse, "error_msg"));
ret.put("delete", getXMLElementValue(xmlResponse, "delete_page"));
ret.put("original", getXMLElementValue(xmlResponse, "original_image"));
return ret;
}
private String getXMLElementValue(String xml, String elementName) {
if (xml.indexOf(elementName) >= 0)
return xml.substring(xml.indexOf(elementName) + elementName.length() + 1,
xml.lastIndexOf(elementName) - 2);
else
return null;
}
All i get back in the end is a hashmap mImageResponse with only the delete link...
any ideas on what im doing wrong?
The fix to this was merely to change the URL to: imgur.com/api/upload.xml