I'm creating an application for our Android devices. The aim of this section is to post a username and password (currently just assigned as a string) to a web service and to receive a login token. When running the code, at the getOutputStream() line, my code terminates and will no progress any further.
I have assigned the android emulator GSM access and also set the proxy and DNS server within Eclipse. I'm not sure where to go with it now!
This is within my onHandleIntent():
protected void onHandleIntent(Intent i) {
try{
HttpURLConnection http_conn = (HttpURLConnection) new URL("http://www.XXXXX.com").openConnection();
http_conn.setRequestMethod("POST");
http_conn.setDoInput(true);
http_conn.setDoOutput(true);
http_conn.setRequestProperty("Content-type", "application/json; charset=utf-8");
String login = URLEncoder.encode("XXXXX", "UTF-8") + "=" + URLEncoder.encode("XX", "UTF-8");
login += "&" + URLEncoder.encode("XXXXX", "UTF-8") + "=" + URLEncoder.encode("XX", "UTF-8");
OutputStreamWriter wr = new OutputStreamWriter(http_conn.getOutputStream());
//TERMINATES HERE
wr.write(login);
wr.flush();
BufferedReader rd = new BufferedReader(new InputStreamReader(http_conn.getInputStream()));
String line = rd.toString();
wr.close();
rd.close();
http_conn.disconnect();
}
catch (IOException e){
}
}
This is my first go at java and have only been writing it for a few days so bear with me if I've missed something obvious.
Thanks
If you want to POST something using HTTP, why not use HTTP POST? ;-)
Here is an example snippet:
public void postData() {
// Create a new HttpClient and Post Header
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://www.yoursite.com/script.php");
try {
// Add your data
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
nameValuePairs.add(new BasicNameValuePair("id", "12345"));
nameValuePairs.add(new BasicNameValuePair("stringdata", "AndDev is Cool!"));
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
// Execute HTTP Post Request
HttpResponse response = httpclient.execute(httppost);
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
} catch (IOException e) {
// TODO Auto-generated catch block
}
}
Source: http://www.androidsnippets.com/executing-a-http-post-request-with-httpclient
This may not be the appropriate answer, but will certainly be helpful to you. I have used this code for sending and receiving the request and reply resp, to a webservice.
This code is working, but will need some Refactoring, as i have used some extra variable, which are not needed.
I have used the NameValuePair here for Post
public String postData(String url, String xmlQuery) {
final String urlStr = url;
final String xmlStr = xmlQuery;
final StringBuilder sb = new StringBuilder();
Thread t1 = new Thread(new Runnable() {
public void run() {
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(urlStr);
try {
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(
1);
nameValuePairs.add(new BasicNameValuePair("xml", xmlStr));
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = httpclient.execute(httppost);
Log.d("Vivek", response.toString());
HttpEntity entity = response.getEntity();
InputStream i = entity.getContent();
Log.d("Vivek", i.toString());
InputStreamReader isr = new InputStreamReader(i);
BufferedReader br = new BufferedReader(isr);
String s = null;
while ((s = br.readLine()) != null) {
Log.d("YumZing", s);
sb.append(s);
}
Log.d("Check Now",sb+"");
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} /*
* catch (ParserConfigurationException e) { // TODO
* Auto-generated catch block e.printStackTrace(); } catch
* (SAXException e) { // TODO Auto-generated catch block
* e.printStackTrace(); }
*/
}
});
t1.start();
try {
t1.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Getting from Post Data Method "+sb.toString());
return sb.toString();
}
String line = rd.toString();
should be
String line = rd.readLine();
that might do the trick. rd.toString() gives you a String representation of your BufferedReader. It does not trigger the HTTP operation. I did not test your code, so there might be other errors as well, this was just the obvious one.
Related
I am having problems calling a simple JSON web service from an Android app. The .execute() completes successfully with an 200-OK Status however I am unable to read any JSON output or text.
For the record, if I HttpPost a regular webpage, like Google.com, I can read and parse all the markup. Also, I am able to call the complete urlWithParams string from the device's browser and I see JSON output in the browser. This works in device's browser:
http://maps.googleapis.com/maps/api/distancematrix/json?origins=Seattle&destinations=San+Francisco&mode=bicycling&language=fr-FR&sensor=false
When the code runs, the reader is always blank and reader.readLine() never runs. Returns an empty string. If I change the URL to Google.com, it works and returns 17,000 characters. Thanks!
protected String doInBackground(String... uri) {
String responseString = null;
try {
//String urlGoogle = "http://google.com";
//String urlWithParams = "http://maps.googleapis.com/maps/api/distancematrix/json?origins=Seattle&destinations=San+Francisco&mode=bicycling&language=fr-FR&sensor=false";
String urlOnly = "http://maps.googleapis.com/maps/api/distancematrix/json";
HttpClient httpclient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(urlOnly);
httpPost.setHeader("Accept", "application/json");
httpPost.setHeader("Content-type", "application/json");
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
nameValuePairs.add(new BasicNameValuePair("origins", "Seattle"));
nameValuePairs.add(new BasicNameValuePair("destinations", "Cleveland"));
nameValuePairs.add(new BasicNameValuePair("sensor", "false"));
httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = httpclient.execute(httpPost);
int status = response.getStatusLine().getStatusCode();
HttpEntity entity = response.getEntity();
InputStream is = entity.getContent();
BufferedReader reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
StringBuilder sb = new StringBuilder();
String line = null;
try {
while ((line = reader.readLine()) != null) {
sb.append((line + "\n"));
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
responseString = sb.toString();
}}
catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
catch (ClientProtocolException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
return responseString;
}
Maybe you should test other mime types instead of application/json.
1 - Check in your manifest file having INTENET Permission or not.
2 - Use this code its returning data
BufferedReader reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
try {
String inputLine;
while ((inputLine = reader.readLine()) != null) {
responseString += inputLine;
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
Solved! The blank return when calling the JSON page was due to not having the proxy settings defined. Proxy settings were setup on the device however per this post, HttpClient does NOT inherit them.
Adding the following line resolved my issue. The code is now returning JSON.
HttpHost proxy = new HttpHost("172.21.31.239", 8080);
httpclient.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, proxy);
I have an application in Android, in which I were reading files from the remote server, code for reading file is given below;
URI uri = null;
try {
uri = new URI("http://192.168.1.116/Server1/Users.xml");
} catch (URISyntaxException e) {
e.printStackTrace();
}
HttpGet httpget = new HttpGet(uri);
httpget.setHeader("Content-type", "application/json; charset=utf-8");
httpget.setHeader("host", "192.168.1.116");
HttpResponse response = null;
try {
response = httpClient.execute(httpget);
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
HttpEntity responseEntity = response.getEntity();
String result = null;
try {
result = EntityUtils.toString(responseEntity);
Log.d("SERVER1", result);
} catch (ParseException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
Now all the remote files are behind proxy (Microsoft ISA Server) which required authentication to access the files. Please guide me how I can pass authentication parameters from android to access the files.
I have tried the following codes but useless,
URL uri = null;
try {
uri = new URI("http:// 192.168.1.116/CookieAuth.dll?Logon");
} catch (URISyntaxException e) {
e.printStackTrace();
}
DefaultHttpClient httpclient = new DefaultHttpClient();
httpclient.getCredentialsProvider()
.setCredentials(
AuthScope.ANY,
new NTCredentials(username, password, deviceIP,
domainName));
HttpPost httppost = new HttpPost(uri);
httppost.setHeader("Content-type",
"application/x-www-form-urlencoded");
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("curl", "Z2FServer1/users.xmlZ2F"));
params.add(new BasicNameValuePair("formdir", "3"));
params.add(new BasicNameValuePair("username", "test"));
params.add(new BasicNameValuePair("password", "test"));
UrlEncodedFormEntity ent = null;
try {
ent = new UrlEncodedFormEntity(params, HTTP.UTF_8);
} catch (UnsupportedEncodingException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
httppost.setEntity(ent);
try {
response = httpclient.execute(httppost);
Log.i("Test", response.getStatusLine().toString());
HttpEntity entity = response.getEntity();
if (entity != null) {
InputStream instream = entity.getContent();
result = convertStreamToString(instream);
Log.d("ISA Server", result);
instream.close();
}
} catch (Exception e) {
e.printStackTrace();
}
But it’s giving HTTP1.1 500 Internal Server Error. I have also tried following link but same error
https://stackoverflow.com/a/10937857/67381
In my case i use
public static DefaultHttpClient getClient(String username, String password,
Integer timeOut) {
HttpParams httpParams = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(httpParams, timeOut);
HttpConnectionParams.setSoTimeout(httpParams, timeOut);
DefaultHttpClient retHttpClient = new DefaultHttpClient(httpParams);
if (username != null) {
retHttpClient.getCredentialsProvider().setCredentials(
new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT),
new UsernamePasswordCredentials(username, password));
}
return retHttpClient;
}
Try, may be works.
P.S.
It's not for ISA, for MS C# WebService Application, but maybe...
I'm trying to let my users be able to report small errors my android application automatically catches to my server. It's nothing big, just a small text box and send button.
It's supposed to send 3 strings (error, optional user description, and time) to a file on my website made specifically to capture those errors. The thing is, I have absolutely no idea how to do so. I only know how to let my application read info from my website but not the other way around.
Do I have to have a special script on my website? Are JSON Strings necessary? I need the string to be saved there. (Not temporarily)
I'm a bit of a newbie so any help is appreciated. Thanks!
- There has to be a script running on your server, eg: php script.
- Its actually a web-service published on the server so that a client can access it.
- Then you will need to do a HTTP Post to the Server, its better to use NameValuePair along with it to send the data.
This is my code for doing HTTP POST:
public String postData(String url, String xmlQuery) {
final String urlStr = url;
final String xmlStr = xmlQuery;
final StringBuilder sb = new StringBuilder();
Thread t1 = new Thread(new Runnable() {
public void run() {
HttpClient httpclient = MySSLSocketFactory.getNewHttpClient();
HttpPost httppost = new HttpPost(urlStr);
try {
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(
1);
nameValuePairs.add(new BasicNameValuePair("xml", xmlStr));
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = httpclient.execute(httppost);
Log.d("Vivek", response.toString());
HttpEntity entity = response.getEntity();
InputStream i = entity.getContent();
Log.d("Vivek", i.toString());
InputStreamReader isr = new InputStreamReader(i);
BufferedReader br = new BufferedReader(isr);
String s = null;
while ((s = br.readLine()) != null) {
Log.d("YumZing", s);
sb.append(s);
}
Log.d("Check Now", sb + "");
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} /*
* catch (ParserConfigurationException e) { // TODO
* Auto-generated catch block e.printStackTrace(); } catch
* (SAXException e) { // TODO Auto-generated catch block
* e.printStackTrace(); }
*/
}
});
t1.start();
try {
t1.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Getting from Post Data Method " + sb.toString());
return sb.toString();
}
//////////////////////////// Edited Part ///////////////////////////////////
Server side php code:
<?php
require_once(ROOT.'/lab/lib/xyz_api_int.php');
try {
//setup the sdk
$api = YumzingApiInt::_get(
Config::get('api_int','url'),
Config::get('api_int','key'),
Config::get('api_int','secret')
);
//connect to the api
$api->connect();
//check our token
echo $api->getToken();
} catch(Exception $e){
sysError($e->getMessage());
}
You just need to post values by http to a php script on your server that will save those values in your file or a database.
I have looked at the following links, but nothing seems concrete.
Secure HTTP Post in Android
This one does not work anymore, I have tested it and there are comments from other people saying it does not work.
I also checked this out: DefaultHttpClient, Certificates, Https and posting problem! This seems it could work but the blogger just leaves you hanging. More step by step instructions would be helpful. I managed to get my certificate by I have not been able to follow through his second step.
http://www.makeurownrules.com/secure-rest-web-service-mobile-application-android.html This one seem good, but again, I loose the author at the last step: "Back to our original rest client code." He too is all over the place, I have no clue which libraries he is using. He is not explaining his code and with the
RestTemplate restTemplate = new RestTemplate();
it's another cliffhanger. Because that class has not been provided. So, if someone could explain how to do HTTPS post request in detail that would be great. I do need to accept the self signed certificate.
I hope it would help. This is the code i used and worked perfectly fine.
private HttpClient createHttpClient()
{
HttpParams params = new BasicHttpParams();
HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
HttpProtocolParams.setContentCharset(params, HTTP.DEFAULT_CONTENT_CHARSET);
HttpProtocolParams.setUseExpectContinue(params, true);
SchemeRegistry schReg = new SchemeRegistry();
schReg.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
schReg.register(new Scheme("https", SSLSocketFactory.getSocketFactory(), 443));
ClientConnectionManager conMgr = new ThreadSafeClientConnManager(params, schReg);
return new DefaultHttpClient(conMgr, params);
}
Then create an HttpClient like this: -
HttpClient httpClient = createHttpClient();
and use it with HttpPost.
Cheers!!
EDIT
And i did not used RestTemplate in my code. I made a simple post request. If you need more help just let me know. It seems like i recently have done something similar to what you are looking for.
This is the method i used for HTTPS Post and Here i used Custom Certificate, So change the HttpClient assignment with yours own...
public String postData(String url, String xmlQuery) {
final String urlStr = url;
final String xmlStr = xmlQuery;
final StringBuilder sb = new StringBuilder();
Thread t1 = new Thread(new Runnable() {
public void run() {
HttpClient httpclient = MySSLSocketFactory.getNewHttpClient();
HttpPost httppost = new HttpPost(urlStr);
try {
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(
1);
nameValuePairs.add(new BasicNameValuePair("xml", xmlStr));
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = httpclient.execute(httppost);
Log.d("Vivek", response.toString());
HttpEntity entity = response.getEntity();
InputStream i = entity.getContent();
Log.d("Vivek", i.toString());
InputStreamReader isr = new InputStreamReader(i);
BufferedReader br = new BufferedReader(isr);
String s = null;
while ((s = br.readLine()) != null) {
Log.d("YumZing", s);
sb.append(s);
}
Log.d("Check Now",sb+"");
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} /*
* catch (ParserConfigurationException e) { // TODO
* Auto-generated catch block e.printStackTrace(); } catch
* (SAXException e) { // TODO Auto-generated catch block
* e.printStackTrace(); }
*/
}
});
t1.start();
try {
t1.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Getting from Post Data Method "+sb.toString());
return sb.toString();
}
I'm trying to use httpost to get data from our WCF webservice
If the webservice function is without params , something like List getAllMessages()
I'm getting the List in json, no problem here
The tricky part is when the function needs to get argument
let's say Message getMessage(string id)
when trying to call this kind of functions I get error code 500
The working code is:
public String GetAllTitles()
{
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(
"http://www.xxx.com/Service/VsService.svc/GetAllTitles");
httppost.setHeader("Content-Type", "application/json; charset=utf-8");
try {
// Add your data
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = httpclient.execute(httppost);
return readHttpResponse(response);
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
this code works great for functios without arguments..
I took this code and changed it to:
public String SearchTitle(final String id)
{
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(
"http://www.xxx.com/Service/VsService.svc/SearchTitle");
httppost.setHeader("Content-Type", "application/json; charset=utf-8");
httppost.setHeader("Accept", "application/json; charset=utf-8");
NameValuePair data = new BasicNameValuePair("id",id);
try {
// Add your data
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
nameValuePairs.add(data);
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = httpclient.execute(httppost);
return readHttpResponse(response);
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
The function header in thr webservice is:
[OperationContract]
public TitleResult SearchTitle(string id)
{
Stopwatch sw = LogHelper.StopwatchInit();
try
{
TitleManager tm = new TitleManager();
Title title = tm.TitleById(id);
sw.StopAndLog("SearchTitle", "id: " + id);
return new TitleResult() { Title = title };
}
catch (Exception ex)
{
sw.StopAndLogException("SearchTitle", ex, "id: " + id);
return new TitleResult() { Message = ex.Message };
}
}
Anyone can see what am I missing?
Thanks, I'm breaking my head over this one.
List isn't json,
try
String data = "{ id : \"" + id + "\" }";
Don't forget to set Content-Length to data.length.