Call asmx HTTP POST from android - java

I'm trying to post HTTP from android. If I'll request using that C# code in LINQPAD it works
void Main()
{
string r = String.Format(#"<s:Body><TrackMobileApp xmlns=""soap action url"" xmlns:i=""http://www.w3.org/2001/XMLSchema-instance""><device>test</device><imei>test</imei><ipAddress>127.0.0.1</ipAddress><timeStamp>2016-02-17T17:32:00.5147663+04:00</timeStamp></TrackMobileApp></s:Body>", DateTime.Now.ToString("o"));
HttpWebRequest wr = (HttpWebRequest)HttpWebRequest.Create("URL.asmx");
wr.ProtocolVersion = HttpVersion.Version11;
wr.Headers.Add("SOAPAction", "soap action");
wr.Method = "POST";
wr.ContentType = "text/xml;charset=utf-8";
using (StreamWriter sw = new StreamWriter(wr.GetRequestStream()))
{
sw.Write(r);
}
HttpWebResponse rs = (HttpWebResponse)wr.GetResponse();
if (rs.StatusCode == HttpStatusCode.OK)
{
XmlDocument xd = new XmlDocument();
using (StreamReader sr = new StreamReader(rs.GetResponseStream()))
{
xd.LoadXml(sr.ReadToEnd());
xd.InnerXml.Dump();
}
}
}
But from android it gives me http 415. What's wrong?
I have this in onCreate
new DownloadTask().execute("URL.asmx");
and my methods are:
private class DownloadTask extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
//do your request in here so that you don't interrupt the UI thread
try {
return downloadContent(params[0]);
} catch (IOException e) {
return "Unable to retrieve data. URL may be invalid.";
}
}
#Override
protected void onPostExecute(String result) {
//Here you are done with the task
}
}
private String downloadContent(String myurl) throws IOException {
InputStream is = null;
int length = 500;
try {
URL url = new URL(myurl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(10000 /* milliseconds */);
conn.setConnectTimeout(15000 /* milliseconds */);
conn.setRequestProperty("SOAPAction", "soap action");
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/xml");
conn.setDoInput(true);
conn.connect();
int response = conn.getResponseCode();
Log.d(TAG, "The response is: " + response);
is = conn.getInputStream();
// Convert the InputStream into a string
String contentAsString = convertInputStreamToString(is, length);
return contentAsString;
} finally {
if (is != null) {
is.close();
}
}
}
public String convertInputStreamToString(InputStream stream, int length) throws IOException, UnsupportedEncodingException {
Reader reader = null;
reader = new InputStreamReader(stream, "UTF-8");
char[] buffer = new char[length];
reader.read(buffer);
return new String(buffer);
}

Related

Android POST request with JSON Constraint

Error which i am facing
The Error Tells me on class execution to create and inner class or create a new class
But i am executing it inside a button which is in onCreate method so please if anybody can guide me how to proceed ....
The Main Class
private class SendDeviceDetails extends AsyncTask {
#Override
protected String doInBackground(String... params) {
String data = "";
HttpURLConnection httpURLConnection = null;
try {
httpURLConnection = (HttpURLConnection) new URL(params[0]).openConnection();
httpURLConnection.setRequestMethod("POST");
httpURLConnection.setDoOutput(true);
DataOutputStream wr = new DataOutputStream(httpURLConnection.getOutputStream());
wr.writeBytes("PostData=" + params[1]);
wr.flush();
wr.close();
InputStream in = httpURLConnection.getInputStream();
InputStreamReader inputStreamReader = new InputStreamReader(in);
int inputStreamData = inputStreamReader.read();
while (inputStreamData != -1) {
char current = (char) inputStreamData;
inputStreamData = inputStreamReader.read();
data += current;
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (httpURLConnection != null) {
httpURLConnection.disconnect();
}
}
return data;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
Log.e("TAG", result); // this is expecting a response code to be sent from your server upon receiving the POST data
}
}
You missed () after newSendDeviceDetails. It should be like the line below:
new newSendDeviceDetails().execute(...);

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 returning a JSONObject from a static method + network on main thread

I have this method which is giving a network on main thread. I want to make this api call on a separate thread using asynctask.
However, the business logic prohibits me to use non static methods. The code is:
public static JSONObject acceptOrder(String orderId, Integer loadsToAccept) throws IOException{
BufferedReader reader = null;
JSONObject resultOrder = null;
AsyncTask asyncTask = new AsyncTask() {
#Override
protected Object doInBackground(Object[] objects) {
return null;
}
};
HttpURLConnection conn = (HttpURLConnection) new URL(GlobalConfig.getInstance().GetGoVulcanConfig().getUrl() + "/api/Order/ProcessAcceptedOrder?acceptedLoads=" + loadsToAccept + "&haulerId=" + GlobalConfig.getInstance().GetGoVulcanConfig().getHaulerId() + "&orderId=" + orderId).openConnection();
conn.setDoOutput(true);
//conn.setFixedLengthStreamingMode(jsonString.length());
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/json");
conn.setRequestProperty("Accept","application/json");
InputStream inputStream = conn.getInputStream();
StringBuffer buffer = new StringBuffer();
if (inputStream == null) {
// Nothing to do.
return null;
}
reader = new BufferedReader(new InputStreamReader(inputStream));
String inputLine;
while ((inputLine = reader.readLine()) != null)
buffer.append(inputLine);
if (buffer.length() == 0) {
// Stream was empty. No point in parsing.
return null;
}
try {
resultOrder = new JSONObject(buffer.toString());
}catch (JSONException ex){
Log.d(ex.getMessage(), "acceptOrder: ");
}
conn.disconnect();
reader.close();
return resultOrder;
}
How can I do this?
This is the form that i do to request POST or GET, I hope can help you
1) I have my class with all the request
public class RequestManager {
public static class requestPostExample extends AsyncTask<String, Void, String>{
Context context;
int exampleId;
String exampleData;
//interface to get the response in the activity
Public AsynkTaskRespone response = null;
public requestPostExample(Context context, int exampleID, String exampleData){
this.context = context;
this.exampleId = exampleID;
this.exampleData = exampleData;
}
#Override
protected String doInBackground(String... params) {
try {
String urlString = "yourUrl";
URL url = new URL(urlString);
//the variables and data you want to send by POST
String postData = "exampleID="+exampleID+"&exampleData="+exampleData;
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoOutput(true);
connection.setRequestMethod("POST");
OutputStream os = connection.getOutputStream();
os.write(postData.getBytes());
StringBuilder responseSB = new StringBuilder();
int result = connection.getResponseCode();
BufferedReader br;
// 401 - 422 - 403 - 500
if (result == 401 || result == 422 || result == 403 || result == 404 || result == 500){
br = new BufferedReader(new InputStreamReader(connection.getErrorStream()));
}else {
br = new BufferedReader(new InputStreamReader(connection.getInputStream()));
}
while ( (JSON_STRING = br.readLine()) != null)
responseSB.append(JSON_STRING+ "\n");
// Close streams
br.close();
return responseSB.toString().trim();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
#Override
protected void onPostExecute(String result) {
Log.d("Result:", result);
//send the result to interface;
response.resultPostExample(result);
}
}
2) Here is the Interface
public interface AsynkTaskRespone {
void resultPostExample(String result);
}
3) Now in the activity
public class MainActivity extends AppCompatActivity implements AsynkTaskResponse {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Start Request
RequestManager.requestPostExample requestPostExample = new RequestManager.requestPostExample(this, exampleID, exampleData);
requestPostExample.response = this;
requestPostExample.execute();
}
#Override
public void resultPostExample(String result){
//here you get the result of the asynktask
}
}

Data usage when connecting to the server

I'm trying to connect and retrieve the data from xml file from server.
The data usage in get the xml data is quite large for a single data in the xml file. It exceeded up to 700 bytes where if i'm open directly from the browser in android phone, it is only 18 bytes.
Why there is so much different on number of bytes when getting data through app?
Below is my asynctask code on getting xml data from server.
Thank You
public class GetXMLTask extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... urls) {
if (!isCancelled()) {
try {
String output = null;
//String[] newurl = { GlobalVariables.Global_URL + "/appstatus.xml" };
for (String url : urls) {
output = getOutputFromUrl(url);
}
return output;
} catch (Exception e) {
return null;
}
}
else
{
return null;
}
}
#Override
protected void onCancelled() {
}
private String getOutputFromUrl(String url) {
StringBuffer output = new StringBuffer("");
try {
InputStream stream = getHttpConnection(url);
BufferedReader buffer = new BufferedReader(new InputStreamReader(
stream));
String s = "";
while ((s = buffer.readLine()) != null)
output.append(s);
} catch (IOException e1) {
e1.printStackTrace();
}
return output.toString();
}
// Makes HttpURLConnection and returns InputStream
private InputStream getHttpConnection(String urlString) throws IOException {
InputStream stream = null;
URL url = new URL(urlString);
URLConnection connection = url.openConnection();
try {
HttpURLConnection httpConnection = (HttpURLConnection) connection;
httpConnection.setRequestMethod("GET");
httpConnection.connect();
if (httpConnection.getResponseCode() == HttpURLConnection.HTTP_OK) {
stream = httpConnection.getInputStream();
}
} catch (Exception ex) {
ex.printStackTrace();
}
return stream;
}
#Override
protected void onPostExecute(String output) {
String XML = output;
// GlobalVariables.Global_data = output;
// String XML = prepareXML();
try {
SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser sp = spf.newSAXParser();
XMLReader xr = sp.getXMLReader();
/** Create handler to handle XML Tags ( extends DefaultHandler ) */
MyXMLHandler myXMLHandler = new MyXMLHandler();
xr.setContentHandler(myXMLHandler);
ByteArrayInputStream is = new ByteArrayInputStream(XML.getBytes());
xr.parse(new InputSource(is));
} catch (Exception e) {
}
}
}
How are you measuring the data usage? I think you are confused. You might be looking at the file size of 18 bytes when taking via browser, but calculating the request + response (including file) while though mobile device.
If you concerned about the packet size of HTTP, upgrade to WebSockets
Intro to WebSockets and Why
WebSockets in Android

service called two times

I am trying to call my HttpServer with a POST and send a message in the body, on the server side I can see that it is called twice and I cannot figure out why.
Here is a part of the client code
String URL = "http://localhost:8081/" + path +"/service?session=" + sessionId;
connection = openConnection(URL, "POST");
OutputStream output = connection.getOutputStream();
output.write("Some Random body data".getBytes());
output.close();
stream = connection.getInputStream();
stream.close();
connection.disconnect();
On the server side i can see that the service is called two times. I figure it has to do something with my OutputStream and InputStream, but if i dont call the input stream it wont call the service any time.
EDIT!!!
Here is some more code
public class Server {
private static final int BASE_PORT = 8081;
public static void main(String[] args) {
try{
InetSocketAddress address = new InetSocketAddress(BASE_PORT);
HttpServer server = HttpServer.create(address, 0);
server.createContext("/", new PathDelegator());
server.setExecutor(Executors.newCachedThreadPool());
server.start();
System.out.println("Server is listening on : " + BASE_PORT);
}catch(IOException e){
e.printStackTrace();
}
}
}
public class PathDelegator implements HttpHandler{
public void handle(HttpExchange exchange) throws IOException {
String URI = exchange.getRequestURI().toString();
if(URI.indexOf("/session") != -1){
//Call ServiceHandler
System.out.println("Call ServiceHandler");
serviceHandler(exchange, "some session key");
}
}
private void serviceHandler(HttpExchange exchange, String sessionId) throws IOException{
String requestMethod = exchange.getRequestMethod();
OutputStream responseBody = exchange.getResponseBody();
if(requestMethod.equalsIgnoreCase("POST")){
Headers responseHeaders = exchange.getResponseHeaders();
responseHeaders.set("Content-Type", "text/plain");
InputStream stream = exchange.getRequestBody();
int b = 0;
StringBuffer buffer = new StringBuffer();
while((b = stream.read()) != -1){
buffer.append((char)b);
}
System.out.println("body data: " + buffer.toString());
exchange.sendResponseHeaders(200, 0);
}else {
exchange.sendResponseHeaders(400, 0);
}
responseBody.close();
}
}
public class ClientTest {
#Test
public void shouldBeAbleToPostToService(){
try {
String SCORE_URL = "http://localhost:8081/service?session=" + sessionId;
connection = openConnection(URL, "POST");
OutputStream output = connection.getOutputStream();
output.write("Some body data".getBytes());
output.close();
stream = connection.getInputStream();
stream.close();
connection.disconnect();
fail("Not implemented yet!");
} catch (IOException e) {
e.printStackTrace();
}
}
private HttpURLConnection openConnection(String url, String method) throws IOException{
URL connectionURL = new URL(url);
HttpURLConnection connection = (HttpURLConnection)connectionURL.openConnection();
connection.setRequestMethod(method);
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setUseCaches(false);
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
return connection;
}
}
Finallty i see that the System.out.println("body data: " + buffer.toString()); is outputted two times
Well, i finally figured out what was going on...
i had a method
public synchronized boolean addValue(int id, int value){
Integer previous = values.put(id, value);
return previous.intValue() != value;
}
problem was that the first time, the put would return a NULL value and as soon as i took care of this method the error does not occur no more.

Categories