Retrieving JSON from a Web API on Android - java

Here... I have a Web API with a MessageController that will respond to my request from Android and send JSON (Hello World - Just to test it out).
public class MessageController : ApiController
{
public async Task<IHttpActionResult> SendAsync()
{
return Ok(new { text = "hello world" });
}
}
From my Android App I want to request JSON from my API. I have requested from other Web APIs like currency etc. And it worked, but same method don't work on my API.
Here it is:
public void requestMessagesFromApi(View v)
throws ClientProtocolException, IOException {
final String response = getJSON(finalUrl);
TextView msgTV = (TextView) findViewById(R.id.msgTxt);
msgTV.setText(response);
}
public String getJSON(String url) {
HttpURLConnection c = null;
try {
URL u = new URL(url);
c = (HttpURLConnection) u.openConnection();
c.setRequestMethod("GET");
c.setRequestProperty("Content-length", "0");
c.setUseCaches(false);
c.setAllowUserInteraction(false);
int status = c.getResponseCode();
switch (status) {
case 200:
case 201:
BufferedReader br = new BufferedReader(new InputStreamReader(c.getInputStream()));
StringBuilder sb = new StringBuilder();
String line;
while ((line = br.readLine()) != null) {
sb.append(line+"\n");
}
br.close();
return sb.toString();
}
} catch (MalformedURLException ex) {
Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, ex);
} finally {
if (c != null) {
try {
c.disconnect();
} catch (Exception ex) {
Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, ex);
}
}
}
return null;
}
I get ResonseCode -1. Don't know why. In Final URL I am targeting my Web API on Azure:
finalUrl ="http://<hereIsMineWebApiURL>/api/message"
I'm sure that I'm wrong in API.

Related

Trouble with "inputstream" when creating mobile app that downloads weather information (with AsyncTask)

I'm trying to make a mobile app that downloads info from the openweathermap.org apis. For example, if you feed that app this link: http://api.openweathermap.org/data/2.5/weather?q=Boston,us&appid=fed33a8f8fd54814d7cbe8515a5c25d7 you will get the information about the weather in Boston, MA. My code seems to work up to the point where I have to convert the input stream to a string variable. When I do that, I get garbage. Is there a particular way to do this seemingly simple task in a proper way? Here is my code so far...
private class DownloadWebpageTask extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... urls) {
// params comes from the execute() call: params[0] is the url.
try {
return downloadUrl(urls[0]);
} catch (IOException e) {
return null;
}
}
// onPostExecute displays the results of the AsyncTask.
#Override
protected void onPostExecute(String result) {
TextView test = (TextView) findViewById(R.id.test);
if(result!=null) test.setText(result);
else{
Log.i(DEBUG_TAG, "returned result is null");}
}
}
private String downloadUrl(String myurl) throws IOException {
InputStream is = null;
try {
URL url = new URL(myurl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(10000 /* milliseconds */);
conn.setConnectTimeout(15000 /* milliseconds */);
conn.setRequestMethod("GET");
conn.setDoInput(true);
// Starts the query
conn.connect();
int response = conn.getResponseCode();
Log.i(DEBUG_TAG, "The response is: " + response);
is = conn.getInputStream();
String text = getStringFromInputStream(is);
//JSONObject json = new JSONObject(text);
//try (Scanner scanner = new Scanner(is, StandardCharsets.UTF_8.name())) {
//text = scanner.useDelimiter("\\A").next();
//}
//Bitmap bitmap = BitmapFactory.decodeStream(is);
return text;
}catch(Exception e) {
Log.i(DEBUG_TAG, e.toString());
}finally {
if (is != null) {
is.close();
}
}
return null;
}
private static String getStringFromInputStream(InputStream is) {
BufferedReader br = null;
StringBuilder sb = new StringBuilder();
String line;
try {
br = new BufferedReader(new InputStreamReader(is));
while ((line = br.readLine()) != null) {
sb.append(line);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return sb.toString();
}
Check this library . Is An asynchronous callback-based Http client for Android built on top of Apache’s HttpClient libraries.

Android Studio deprecated on HttpParams, HttpConnectionParams, ConnManagerParams, setTimeout

Hello I'm new in Android programming. I want to make app that can connect Android to the web server. Here's the code that I use:
public void cari (View v){
ArrayList<NameValuePair> arData = new ArrayList<NameValuePair>();
arData.add(new BasicNameValuePair("nama", edNama.getText().toString()));
String respon = null;
try {
respon = KoneksiHTTP.eksekusiHttpPost("http://example.com/myphp.php", arData);
String r = respon.toString();
r = r.trim();
AlertDialog close = new AlertDialog.Builder(this)
.setTitle("ESTIMASI MANFAAT")
.setMessage(r.toString())
.setNegativeButton("Kembali", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dlg, int sumthin) {
// TODO Auto-generated method stub
}
})
.show();
} catch (Exception e) {
e.printStackTrace();
}
finally {
edNama.setText(null);
}
}
and this another class
public class KoneksiHTTP {
public static final int HTTP_TIMEOUT = 3000;
private static HttpClient client;
private static HttpClient getHttpClient() {
if (client == null) {
client = new DefaultHttpClient();
final HttpParams parameterHttp = client.getParams();
HttpConnectionParams.setConnectionTimeout(parameterHttp, HTTP_TIMEOUT);
ConnManagerParams.setTimeout(parameterHttp, HTTP_TIMEOUT);
}
return client;
}
public static String eksekusiHttpPost(String url, ArrayList<NameValuePair> postParameter) throws Exception {
BufferedReader in = null;
try {
HttpClient klien = getHttpClient();
HttpPost req = new HttpPost(url);
UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(
postParameter);
req.setEntity(formEntity);
HttpResponse resp = klien.execute(req);
in = new BufferedReader(new InputStreamReader(resp.getEntity()
.getContent()));
StringBuffer stringBuff = new StringBuffer("");
String line = "";
String NL = System.getProperty("line.separator");
while ((line = in.readLine()) != null) {
stringBuff.append(line + NL);
}
in.close();
String hasil = stringBuff.toString();
return hasil;
} finally {
if (in != null) {
in.close();
}
}
}
}
But I got deprecated on
HttpParams, HttpConnectionParams, ConnManagerParams, setTimeout.
I've been adding
useLibrary 'org.apache.http.legacy'
but it has no effect. What should I used instead ?
here's my build gradle
apply plugin: 'com.android.application'
android {
compileSdkVersion 23
buildToolsVersion "23.0.1"
useLibrary 'org.apache.http.legacy'
defaultConfig {
applicationId "com.example.plz.taspenmobile"
minSdkVersion 14
targetSdkVersion 23
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.1.1'
compile 'com.android.support:design:23.1.1'
compile 'com.android.support:support-v4:23.1.1'
compile 'com.google.android.gms:play-services:8.4.0'
compile 'com.google.android.gms:play-services-maps:8.4.0'
compile 'com.google.android.gms:play-services-location:8.4.0'
compile 'org.jbundle.util.osgi.wrapped:org.jbundle.util.osgi.wrapped.org.apache.http.client:4.1.2'
compile 'org.apache.httpcomponents:httpclient:4.5'
}
code for showing respon:
try {
CallWebService respon = new CallWebService("POST", "http://example.com/myphp.php", apiParams) {
#Override
public void OnStartingService() {
super.OnStartingService();
}
//#Override
public void OnGettingResult(JSONObject jsonObject) throws JSONException, MethodNotDefinedException {
super.OnGettingResult(toString());
}
};
String r = respon.toString();
r = r.trim();
AlertDialog close = new AlertDialog.Builder(estimasi.this)
.setTitle("Estimasi Manfaat")
.setMessage(r.toString())
.setNegativeButton("Kembali", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dlg, int sumthin) {
// TODO Auto-generated method stub
}
})
.show();
} catch (Exception e) {
e.printStackTrace();
}
finally {
edNama.setText(null);
}
hello i think you should switch over to httpURlConnection. just visit this
link here i have added global class for calling webservice and getting response in json.
replace this code in your CallWebService file you will get response in string.
public class CallWebService {
private static final String GET="GET";
private static final String POST="POST";
private HashMap<String,String> apiParameters;
private static String WebService;
public CallWebService(String MethodType, String WebService, HashMap<String, String> apiParameters) throws MethodNotDefinedException {
if(MethodType!=null) {
if (MethodType.equalsIgnoreCase(GET)) {
if(WebService!=null){
this.WebService=WebService;
new ExecuteAsyncTask(GET).execute();
}else{
throw new NullPointerException("Please define webservice url.");
}
} else if(MethodType.equalsIgnoreCase(POST)){
if(WebService!=null){
if(apiParameters!=null)this.apiParameters=apiParameters;
this.WebService=WebService;
new ExecuteAsyncTask(POST).execute(apiParameters);
}else{
throw new NullPointerException("Please define webservice url.");
}
}else{
throw new MethodNotDefinedException("Define method for webservice.");
}
}else{
throw new MethodNotDefinedException("Define method for webservice.");
}
}
private class ExecuteAsyncTask extends AsyncTask<HashMap<String,String>,Void,String>{
String MethodType;
public ExecuteAsyncTask(String MethodType){
this.MethodType=MethodType;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
OnStartingService();
}
#Override
protected void onPostExecute(String string) {
super.onPostExecute(string);
try {
OnGettingResult(string);
} catch (JSONException e) {
e.printStackTrace();
} catch (MethodNotDefinedException e) {
e.printStackTrace();
}
}
#Override
protected String doInBackground(HashMap<String, String>... params) {
if(MethodType.equalsIgnoreCase(GET))
return getJSON(WebService,15000);
else try {
return getJSONPOST(WebService,params[0]);
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
}
public void OnStartingService(){
}
public void OnGettingResult(String jsonObject) throws JSONException, MethodNotDefinedException {
}
private String getJSON(String url, int timeout) {
HttpURLConnection c = null;
try {
URL u = new URL(url);
c = (HttpURLConnection) u.openConnection();
c.setRequestMethod("GET");
c.setRequestProperty("Content-length", "0");
c.setUseCaches(false);
c.setAllowUserInteraction(false);
c.setConnectTimeout(timeout);
c.setReadTimeout(timeout);
c.connect();
int status = c.getResponseCode();
switch (status) {
case 200:
case 201:
BufferedReader br = new BufferedReader(new InputStreamReader(c.getInputStream()));
StringBuilder sb = new StringBuilder();
String line;
while ((line = br.readLine()) != null) {
sb.append(line+"\n");
}
br.close();
System.out.println(sb.toString());
return sb.toString();
}
} catch (MalformedURLException ex) {
} catch (IOException ex) {
} finally {
if (c != null) {
try {
c.disconnect();
} catch (Exception ex) {
}
}
}
return null;
}
private String getJSONPOST(String url1, HashMap<String,String> apiParams) throws IOException, JSONException {
URL url = new URL(url1);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setDoInput(true);
conn.setDoOutput(true);
String getParams=getQuery(apiParams);
OutputStream os = conn.getOutputStream();
BufferedWriter writer = new BufferedWriter(
new OutputStreamWriter(os, "UTF-8"));
writer.write(getParams);
writer.flush();
writer.close();
os.close();
conn.connect();
int status = conn.getResponseCode();
switch (status) {
case 200:
case 201:
BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
StringBuilder sb = new StringBuilder();
String line;
while ((line = br.readLine()) != null) {
sb.append(line+"\n");
}
br.close();
System.out.println(sb.toString());
return sb.toString();
}
if (conn != null) {
try {
conn.disconnect();
} catch (Exception ex) {
}
}
return null;
}
private String getQuery(HashMap<String,String> params) throws UnsupportedEncodingException
{
StringBuilder result = new StringBuilder();
boolean first = true;
for(Map.Entry<String, String> entry : params.entrySet()) {
if (first)
first = false;
else
result.append("&");
result.append(URLEncoder.encode(entry.getKey(), "UTF-8"));
result.append("=");
result.append(URLEncoder.encode(entry.getValue(), "UTF-8"));
}
return result.toString();
}
}
You have to use HttpURLConnection.
Use below 2 methods for reference.
1. For GET method.
public static String getHttpResponse(String url) {
StringBuffer responseString = null;
String inputLine;
HttpURLConnection connection = null;
try {
URL dataUrl = new URL(url);
connection = (HttpURLConnection) dataUrl.openConnection();
// optional default is GET
connection.setRequestMethod("GET");
int responseCode = connection.getResponseCode();
if (responseCode == 200) {
BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
responseString = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
responseString.append(inputLine);
}
in.close();
}
} catch (Exception e) {
Log.w("Some error occured", e);
return null;
} finally {
try {
connection.disconnect();
} catch (Exception e) {
e.printStackTrace(); //If you want further info on failure...
return null;
}
}
return responseString.toString();
}
2. For POST method.
public static String postHttpResponse(String dataUrl, HashMap<String, String> postData) {
StringBuffer responseString = null;
HttpURLConnection connection = null;
String inputLine;
try {
URL postUrl = new URL(dataUrl);
String email_id = postData.get("email_id");
String device_id = postData.get("device_id");
String status = postData.get("status");
connection = (HttpURLConnection) postUrl.openConnection();
String urlParameters = "device_id=" + device_id + "&email_id=" + email_id + "&status=" + status;
connection.setRequestMethod("POST");
connection.setDoOutput(true);
DataOutputStream wr = new DataOutputStream(connection.getOutputStream());
wr.writeBytes(urlParameters);
wr.flush();
wr.close();
int responseCode = connection.getResponseCode();
if (responseCode == 200) {
BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
responseString = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
responseString.append(inputLine);
}
in.close();
}
} catch (Exception e) {
e.printStackTrace();
return null;
} finally {
try {
connection.disconnect();
} catch (Exception e) {
e.printStackTrace(); //If you want further info on failure...
return null;
}
}
return responseString.toString();
}
Additional advice from me is using Android Volley. You can see information and usage here : Training With Volley
Place this #SuppressWarnings annotation on your class definition that uses HttpClient:
#SuppressWarnings("deprecation")
public class YourClassThatUsesHttpClient {
...
}
But your app could still break in a future version of Android, so migrate your code anyway.
String r = apiParams.toString();
r = r.trim();
AlertDialog close = new AlertDialog.Builder(estimasi.this)
.setTitle("Estimasi Manfaat")
.setMessage(r.toString())
.setNegativeButton("Kembali", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dlg, int sumthin) {
// TODO Auto-generated method stub
}
})
.show();

Can not read request body from servlet

This is my controller code:
#RequestMapping(value = "/test", method = RequestMethod.POST)
public #ResponseBody String testPost(#RequestParam(value = "testParam") int testParam, HttpServletRequest request) {
try {
System.out.println("body is "+BufferUtil.getHttpRequestBody(request));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
BufferUtil.getHttpRequestBody(request) is
public static String getHttpRequestBody(HttpServletRequest request)
throws IOException {
Scanner s = null;
try {
s = new Scanner(request.getInputStream(), "UTF-8")
.useDelimiter("\\A");
} catch (IOException e) {
e.printStackTrace();
}
return s.hasNext() ? s.next() : "";
}
This is the code to use to test controller:
HTTPUtil.sendRequest("http://localhost:8081/es09android/test?testParam=1", "POST", "hello world");
sendRequest() implementation:
public static HttpResponse sendRequest(String url, String method,
String data) {
DataOutputStream wr = null;
BufferedReader in = null;
HttpResponse httpResponse = new HttpResponse();
try {
URL obj = new URL(url);
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod(method);
con.setRequestProperty("User-Agent", USER_AGENT);
con.setRequestProperty("Accept-Language", "en-US,en;q=0.5");
con.setDoOutput(true);
if (data != null) {
wr = new DataOutputStream(con.getOutputStream());
wr.write(data.getBytes(UTF8_CHARSET));
}
int responseCode = con.getResponseCode();
httpResponse.setResponseCode(responseCode);
if (httpResponse.isOk()) {
in = new BufferedReader(new InputStreamReader(
con.getInputStream(), "UTF8"));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
httpResponse.setData(response.toString());
}
return httpResponse;
} catch (IOException e) {
e.printStackTrace();
return null;
} finally {
if (wr != null) {
try {
wr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (in != null) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
If I run it and then send request, controller will not print body. But if remove #RequestParam(value = "testParam") from the controller, everything will be ok. What is wrong?
Edited after more information provided in comments below
I assume what's hapening is that s.hasNext() is returning false, because you're at the end of the request's InputStream. This is as designed, you can only read the InputStream once.
This question has a good example of a way you can cache the request to read it more than once.
This question describes a way you can use Spring to log the entire request, which seems to be what your aim is in your question.

Sending SMS through low end API

I have a message constructor method of the form:
public static String constructMsg(CustomerInfo customer) {
... snipped
String msg = String.format("Snipped code encapsulated by customer object");
return msg;
}
The API link is:
http://xxx.xxx.xx.xx:8080/bulksms?username=xxxxxxx &password=xxxx &type=0 &dlr=1&destination=10digitno & source=xxxxxx& message=xxxxx
In my main method I have(s):
List<CustomerInfo> customer = dao.getSmsDetails(userDate);
theLogger.info("Total No : " + customer.size() );
if (!customer.isEmpty()) {
for (CustomerInfo cust : customer) {
String message = constructMsg(cust);
// Add link and '?' and query string
// use URLConnection's connect method
}
}
So I am using connect method of URLConnection. The API does not have any documentation. Is there any way for checking response?
My other question is, I have been advised to use ThreadPoolExecutor. How would I use use it here?
This method use HTTPURLConnection to perform a GET request returning the response as a String. There're many way to do it, this is not particularly brilliant but it's really readable.
public String getResponse(String url, int timeout) {
HttpURLConnection c;
try {
URL u = new URL(url);
c = (HttpURLConnection) u.openConnection();
c.setRequestMethod("GET");
c.setRequestProperty("Content-length", "0");
c.setUseCaches(false);
c.setAllowUserInteraction(false);
c.setConnectTimeout(timeout);
c.setReadTimeout(timeout);
c.connect();
int status = c.getResponseCode();
switch (status) {
case 200:
case 201:
BufferedReader br = new BufferedReader(new InputStreamReader(c.getInputStream()));
StringBuilder sb = new StringBuilder();
String line;
while ((line = br.readLine()) != null) {
sb.append(line+"\n");
}
br.close();
return sb.toString();
default:
return "HTTP CODE: "+status;
}
} catch (MalformedURLException ex) {
Logger.getLogger(DebugServer.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(DebugServer.class.getName()).log(Level.SEVERE, null, ex);
} finally{
if(c!=null) c.disconnect();
}
return null;
}
Call this method like this:
getResponse("http://xxx.xxx.xx.xx:8080/bulksms?username=xxxxxxx&password=xxxx&type=0 &dlr=1&destination=10digitno&source=xxxxxx&message=xxxxx",2000);
I assume the whitespaces in your URL are not supposed to be there.

Getting text from internet

If you go to http://www.elven.ee/ip/ - you can see it gives ip. If you refresh, it gives different port.
How can I get that IP into android? I don't know how to make it also update after like every 5 seconds, but right now I want to know how can i get it into my phone. I want to display it as TextView :).
#mopsled solution did not work for me, so here is mine:
public class TestActivity extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
TextView tv = (TextView) findViewById(R.id.textView1);
String ip = "";
final DefaultHttpClient httpClient = new DefaultHttpClient();
final HttpGet httpGet = new HttpGet("http://www.elven.ee/ip/");
try {
final HttpResponse response = httpClient.execute(httpGet);
if (response.getStatusLine().getStatusCode() == 200) {
ip = getString(response);
}
} catch (final ClientProtocolException e) {
e.printStackTrace();
} catch (final IOException e) {
e.printStackTrace();
}
tv.setText(ip);
}
private static String getString(HttpResponse response) {
final HttpEntity retEntity = response.getEntity();
if (retEntity != null) {
InputStream instream = null;
try {
instream = retEntity.getContent();
} catch (final IllegalStateException ise) {
ise.printStackTrace();
} catch (final IOException ioe) {
ioe.printStackTrace();
}
final String result = convertStreamToString(instream);
return result;
} else {
return "";
}
}
private static String convertStreamToString(final InputStream is) {
final BufferedReader reader = new BufferedReader(new InputStreamReader(is));
final StringBuilder sb = new StringBuilder();
String line = null;
try {
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
} catch (final IOException ioe) {
ioe.printStackTrace();
} finally {
try {
is.close();
} catch (final IOException ioe) {
ioe.printStackTrace();
}
}
return sb.toString().trim();
}
}
EDIT: Fixed code
Try a HTTPURLConnection (a simplified version of an example found here):
StringBuilder content = new StringBuilder();
try {
URL url = new URL("http://www.elven.ee/ip/");
URLConnection urlConnection = url.openConnection();
BufferedReader bufferedReader =
new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
String line;
while ((line = bufferedReader.readLine()) != null) {
content.append(line + "\n");
}
bufferedReader.close();
} catch(Exception e) {
e.printStackTrace();
}
String myIp = content.toString();

Categories