Push data into power bi using java azure ad library - java

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 :)

Related

Getting response code 400 when trying to get access token from Azure AD

I am implementing azure for my web application and trying to get access token by following there openId connect tutorial
https://learn.microsoft.com/en-us/azure/active-directory/develop/active-directory-protocols-oauth-code
And when i am requesting to get the access token, i am always getting bad request 400
Request to get access token :
POST /{tenant}/oauth2/token HTTP/1.1
Host: https://login.microsoftonline.com
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code
&client_id=2d4d11a2-f814-46a7-890a-274a72a7309e
&code=AwABAAAAvPM1KaPl.......
&redirect_uri=https%3A%2F%2Flocalhost%2Fmyapp%2F
&resource=https%3A%2F%2Fservice.contoso.com%2F
&client_secret=p#ssw0rd
here is my code :
public static String post( String endpoint,
Map<String, String> params) {//YD
StringBuffer paramString = new StringBuffer("");
//if(!Utilities.checkInternetConnection(context)){
// return XMLHandler.getXMLForErrorCode(context, JSONHandler.ERROR_CODE_INTERNET_CONNECTION);
//}
Iterator<Entry<String, String>> iterator = params.entrySet().iterator();
StringBuffer tempBuffer = new StringBuffer("");
String paramval;
while (iterator.hasNext()) {
Entry<String, String> param = iterator.next();
if (param != null) {
if (paramString.length() > 0) {
paramString.append("&");
}
System.out.println( "post key : " + param.getKey());
String value;
try {
paramval = param.getValue();
if(paramval!=null)
value = URLEncoder.encode(paramval, "UTF-8");
else
value = "";
} catch (UnsupportedEncodingException e) {
value = "";
e.printStackTrace();
}
paramString.append(param.getKey()).append("=")
.append(value);
}
}
try {
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(endpoint);
String data = "";
try {
// Add your data
// httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs))
//httppost.addHeader("Host", host);
httppost.addHeader("Content-Type",
"application/x-www-form-urlencoded");
if (!paramString.equals("")) {
if (tempBuffer.length() > 0) {
data = data + tempBuffer.toString();
}
data = data + paramString.toString();
if (data.endsWith("&")) {
data = data.substring(0, data.length() - 1);
}
httppost.setEntity(new ByteArrayEntity(data.getBytes()));
}
System.out.println( "post Stringbuffer : " + data);
// Execute HTTP Post Request
HttpResponse response = httpclient.execute(httppost);
int statuscode = response.getStatusLine().getStatusCode();
System.out.println("Response code : " + statuscode);
if (statuscode != 200) {
return null;
}
HttpEntity entity = response.getEntity();
InputStream in = null;
if (entity != null) {
in = entity.getContent();
}
if (in != null) {
StringBuilder builder = new StringBuilder();
String line;
try {
BufferedReader reader = new BufferedReader(
new InputStreamReader(in, "UTF-8"));
while ((line = reader.readLine()) != null) {
builder.append(line);
}
} finally {
in.close();
}
String response2 = builder.toString();
System.out.println("response :" + response2);
retrycount = 0;
return response2;
}
}
catch(UnknownHostException e){
e.printStackTrace();
return null;
}
catch (EOFException eof) {
if (retrycount < max_retry) {
eof.printStackTrace();
post( endpoint, params);
retrycount = 1;
}
} catch (Throwable th) {
throw new IOException("Error in posting :" + th.getMessage());
}
retrycount = 0;
return null;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
Please help me with this
Thanks in Advance
Have you ensured the redirect uri passed to /token is the same as the one you passed to /authorize
I believe, it will help if you can test the OAuth auth code flow with your current client id, secret and scope using Postman tool in order to rule out bad configuration.
Please refer to the code below to request AuthorizationCode.
public static void getAuthorizationCode() throws IOException {
String encoding = "UTF-8";
String params = "client_id=" + clientId
+ "&response_type=" + reponseType
+ "&redirect_uri=http%3A%2F%2Flocalhost%2Fmyapp%2F"
+ "&response_mode=query"
+ "&resource=https%3A%2F%2Fgraph.windows.net"
+ "&state=12345";
String path = "https://login.microsoftonline.com/" + tenantId + "/oauth2/authorize";
byte[] data = params.getBytes(encoding);
URL url = new URL(path);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setDoOutput(true);
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
conn.setRequestProperty("Content-Length", String.valueOf(data.length));
conn.setConnectTimeout(5 * 1000);
OutputStream outStream = conn.getOutputStream();
outStream.write(data);
outStream.flush();
outStream.close();
System.out.println(conn.getResponseCode());
System.out.println(conn.getResponseMessage());
BufferedReader br = null;
if (conn.getResponseCode() != 200) {
br = new BufferedReader(new InputStreamReader((conn.getErrorStream())));
} else {
br = new BufferedReader(new InputStreamReader((conn.getInputStream())));
}
System.out.println("Response body : " + br.readLine());
}
Then you could get access token using the AuthorizationCode you got and get refresh code using the code below.
public static void getToken(String refreshToken) throws IOException {
String encoding = "UTF-8";
String params = "client_id=" + clientId + "&refresh_token=" + refreshToken
+ "&grant_type=refresh_token&resource=https%3A%2F%2Fgraph.windows.net";
String path = "https://login.microsoftonline.com/" + tenantId + "/oauth2/token";
byte[] data = params.getBytes(encoding);
URL url = new URL(path);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setDoOutput(true);
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
conn.setRequestProperty("Content-Length", String.valueOf(data.length));
conn.setConnectTimeout(5 * 1000);
OutputStream outStream = conn.getOutputStream();
outStream.write(data);
outStream.flush();
outStream.close();
System.out.println(conn.getResponseCode());
System.out.println(conn.getResponseMessage());
BufferedReader br = null;
if (conn.getResponseCode() != 200) {
br = new BufferedReader(new InputStreamReader((conn.getErrorStream())));
} else {
br = new BufferedReader(new InputStreamReader((conn.getInputStream())));
}
System.out.println("Response body : " + br.readLine());
}
Hope it helps you.

How to get json response data using facebook graph api 2.5?

I have a code that brings the json response from the twitter api. I want to use same code for facebook graph api to get json response from the Facebook but facebook doesn't provide any consumer keys as twitter. I can change this code to get the facebook json response. Can any of you help to modify the code.
public class TwitterResponse {
static String AccessToken = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
static String AccessSecret = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
static String ConsumerKey = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
static String ConsumerSecret = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
/**
* #param args
*/
public static void main(String[] args) throws Exception
{
OAuthConsumer consumer = new CommonsHttpOAuthConsumer(ConsumerKey,ConsumerSecret);
String twitterUrl="https://api.twitter.com/1.1/statuses/user_timeline.json?screen_name=heymailme143&count=1&include_rts=true&contributors=true";
consumer.setTokenWithSecret(AccessToken, AccessSecret);
//HttpGet request = new HttpGet("https://api.twitter.com/1.1/friends/list.json");
HttpGet request = new HttpGet(twitter);
consumer.sign(request);
HttpClient client = new DefaultHttpClient();
HttpResponse response = client.execute(request);
int statusCode = response.getStatusLine().getStatusCode();
String m=IOUtils.toString(response.getEntity().getContent());
System.out.println(m);
System.out.println(statusCode + ":" + response.getStatusLine().getReasonPhrase());
}
}
This is a sample code I used to get the twitter response. Could you help me in changing it to get the facebook response using fb graph api?
Have a look at
http://facebook4j.org/en/index.html
which also has some examples.
I'm Looking for this :)
public String getUserInfo(String access_token) throws MalformedURLException, ProtocolException, IOException {
try {
String connection = connectionGet("https://graph.facebook.com/me?access_token=" + access_token, "");
System.out.println("done");
return connection;
} catch (Exception e) {
System.out.println("null value");
return null;
}
}
public static String connectionGet(String url, String parameter) throws MalformedURLException, ProtocolException, IOException {
URL url1 = new URL(url);
HttpURLConnection request1 = (HttpURLConnection) url1.openConnection();
request1.setRequestMethod("GET");
request1.connect();
String responseBody = convertStreamToString(request1.getInputStream());
return responseBody;
}
private static String convertStreamToString(InputStream is) {
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuilder sb = new StringBuilder();
String line = null;
try {
while ((line = reader.readLine()) != null) {
sb.append(line).append("\n");
}
} catch (IOException e) {
} finally {
try {
is.close();
} catch (IOException e) {
}
}
System.out.println(sb.toString());
return sb.toString();
}}

AccountManager hanging on GetAuthToken()

So I am using the AccountManager from Android to store OAuth2 credentials. These credentials are then used in the getAuthToken method, as any other account manager works. Here is my getAuthToken method:
#Override
public Bundle getAuthToken(AccountAuthenticatorResponse response, final Account account, String authTokenType, Bundle options) throws NetworkErrorException {
Log.d(TAG, "onGetAuthToken");
final AccountManager am = AccountManager.get(context);
String storeToken = am.peekAuthToken(account, authTokenType);
final String password = am.getPassword(account);
if (TextUtils.isEmpty(storeToken) && password != null) {
storeToken = new OAuth2Client(account.name, password, "test", "test", Constants.getServerUrlBase() + "token.php").getAccessToken().getAccessToken();
} else {
if (password != null) {
final Bundle result = new Bundle();
String authToken = null;
// Network stuff
JSONObject JSONResult;
DefaultHttpClient httpClient = new DefaultHttpClient(new BasicHttpParams());
HttpPost httppost = new HttpPost(Constants.SERVER_URL_BASE + "verify.php");
List<NameValuePair> pairs = new ArrayList<>();
pairs.add(new BasicNameValuePair("access_token", storeToken));
try {
httppost.setEntity(new UrlEncodedFormEntity(pairs));
} catch (UnsupportedEncodingException e) {
Log.e(TAG, "onFailed Posting\n" + e);
}
InputStream inputStream = null;
try {
HttpResponse httpResponse = httpClient.execute(httppost);
HttpEntity entity = httpResponse.getEntity();
inputStream = entity.getContent();
// json is UTF-8 by default
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"), 8);
StringBuilder sb = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
sb.append(line).append("\n");
}
Log.d(TAG + "." + this.getClass().getEnclosingMethod(), "onReceivedData " + sb.toString());
JSONResult = new JSONObject(sb.toString());
if (JSONResult.getBoolean("success"))
authToken = storeToken;
} catch (JSONException | IOException e) {
Log.e(TAG, "onCrashed\n", e);
} finally {
if (inputStream != null) try {
inputStream.close();
} catch (IOException e) {
Log.e(TAG, "Failed on inputStream!\n", e);
}
}
if (authToken == null) {
authToken = new OAuth2Client(account.name, password, "corentec_logistics_application", "corentec123", Constants.getServerUrlBase() + "token.php").getAccessToken().getAccessToken();
am.invalidateAuthToken(Constants.ACCOUNT_TYPE, storeToken);
am.setUserData(account, AccountManager.KEY_AUTHTOKEN, authToken);
}
result.putString(AccountManager.KEY_ACCOUNT_NAME, account.name);
result.putString(AccountManager.KEY_ACCOUNT_TYPE, account.type);
result.putString(AccountManager.KEY_AUTHTOKEN, authToken);
Log.d(TAG, "onPostExecute with String: " + authToken);
return result;
}
}
final Intent intent = new Intent(context, AuthenticatorActivity.class);
intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE, response);
intent.putExtra(AuthenticatorActivity.ARG_ACCOUNT_TYPE, account.type);
intent.putExtra(AuthenticatorActivity.ARG_AUTH_TYPE, authTokenType);
final Bundle bundle = new Bundle();
bundle.putParcelable(AccountManager.KEY_INTENT, intent);
return bundle;
}
Basically, this gains the user credentials, checks with the server if the token is still valid or expired. If the token is expired, it gains a new one from the server and returns that. If the token was still good, then it just returns the given token. All of this is obviously in a bundle, as required by the overridden class. This method I am having called from my application class for a more centralized approach. Here is the important part of the application class:
public String getAuthToken() {
String token = null;
final String[] authToken = {null};
GetToken getToken = new GetToken();
getToken.execute();
try {
authToken[0] = getToken.get();
return authToken[0];
} catch (InterruptedException | ExecutionException e) {
Log.e(TAG, "onCrashed\n", e);
}
return null;
}
And ...
private class GetToken extends AsyncTask<Void, Void, String> {
String token = null;
#Override
protected String doInBackground(Void... params) {
Log.d(TAG, "onDoInBackgroundExecute");
try {
token = accountManager.getAuthToken(getCurrentAccount(), Constants.TOKEN_TYPE, null, null, null, null).getResult().getString(AccountManager.KEY_AUTHTOKEN);
Log.d(TAG, "Finished getting token: " + token);
} catch (OperationCanceledException | IOException | AuthenticatorException e) {
Log.e(TAG, "onCrashed getting token\n", e);
}
return token;
}
}
I then have an activity calling this by means of:
application.setCurrentAccount(new Account(intent.getStringExtra(AccountManager.KEY_ACCOUNT_NAME), Constants.ACCOUNT_TYPE));
String token = application.getAuthToken();
With application being an instance of the Application class.
However, this hangs the activity. Logcat and Thread Snapshots say it is due to this line:
token = accountManager.getAuthToken(getCurrentAccount(), Constants.TOKEN_TYPE, null, null, null, null).getResult().getString(AccountManager.KEY_AUTHTOKEN);
inside of the ASyncTask GetToken. I cannot figure out why this is hanging and going ANR. Can anyone help?

How can I call HTTP POST request with multiple parameters?

how can i call http post requst with multiple parameter.
like this
WebClient webClient = new WebClient();
webClient.Headers["Content-type"] = "application/json";
webClient.Encoding = Encoding.UTF8;
webClient.UploadStringCompleted += new UploadStringCompletedEventHandler(wc_UploadStringCompleted);
webClient.UploadStringAsync(new Uri(URL), "POST", JSON);
this one in c#. but i want in android
i have already try this
public String postServiceCall(String paraURL,JSONArray jsonParams, String usrId, String syncDt){
TAG = "makeHttpRequestJSONObject";
Log.d(MODULE, TAG + " called");
String json = "";
InputStream is = null;
try{
HttpParams httpParams = new BasicHttpParams();
int timeoutConnection = 3000;
HttpConnectionParams.setConnectionTimeout(httpParams, timeoutConnection);
int timeoutSocket = 5000;
HttpConnectionParams.setSoTimeout(httpParams, timeoutSocket);
DefaultHttpClient httpClient = new DefaultHttpClient(httpParams);
String params = "UserId="+ usrId +"&SyncDate="+syncDt;
String encodedUrl = URLEncoder.encode (params,"UTF-8");
HttpPost httpPost = new HttpPost(paraURL+encodedUrl);
httpPost.setHeader( "Content-Type", "application/json" );
Log.v(MODULE, TAG + ", POST paraURL " + (paraURL+encodedUrl));
Log.v(MODULE, TAG + ", POST paraURL jsonParams.toString() " + (jsonParams.toString()));
httpPost.setEntity(new ByteArrayEntity(jsonParams.toString().getBytes("UTF8")));
HttpResponse httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
is = httpEntity.getContent();
BufferedReader reader = new BufferedReader(new InputStreamReader(is, "iso-8859-1"), 8);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
is.close();
json = sb.toString().trim();
json = json.substring(1,3);
Log.v(MODULE, TAG + ", json data " + json);
} catch (Exception e){
Log.e(MODULE, TAG + "Exception Occurs " + e);
json = "";
}
return json;
}
}
this code not work properly. this code post only the json. here userid and syncdate not send to server side
please check this
String encodedUrl = URLEncoder.encode (params,"UTF-8");
example
your code returns the url like this
input "http://test.com/ttttt?query=jjjj test"
output "http://test.com/ttttt?query=jjjj+test"
but your need url like this
output "http://test.com/ttttt?query=jjjj%20test"
so you can try this function for url encoding
public String parseUrl(String surl) throws Exception
{
URL u = new URL(surl);
return new URI(u.getProtocol(), u.getAuthority(), u.getPath(), u.getQuery(), u.getRef()).toString();
}
OR
This may help you to comfortable with higher versions
public String parseURL(String url, Map<String, String> params)
{
Builder builder = Uri.parse(url).buildUpon();
for (String key : params.keySet())
{
builder.appendQueryParameter(key, params.get(key));
}
return builder.build().toString();
}

Storing session cookie to maintain log in session

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

Categories