I try to get some Data from a WebService using KSoap2.
The WebService responses a very large XML-File so while I'm doing the HttpTransportSE.call() I get an ouOfMemory Exception.
Is it possible to get a snipped response from a Soap Webservice?
Or is there a way to write it directly in a file on the device?
This is my Class to get the Data:
public static SoapObject GetItemData()
{
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME_ITEM_DATA);
request.addProperty("Company", company);
request.addProperty("SerialNumber", serialId);
itemEnvelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
itemEnvelope.dotNet = true;
itemEnvelope.setOutputSoapObject(request);
AndroidHttpTransportSE androidHttpTransport = new AndroidHttpTransportSE(URL);
androidHttpTransport.debug = true;
Log.d("==ITEM_URL==", URL);
try
{
androidHttpTransport.call(SOAP_ACTION_ITEM_DATA, itemEnvelope);
Log.d("==ItemVerbindung==", "Verbindung aufgebaut");
}
catch (Exception e)
{
e.printStackTrace();
Log.d("==ItemVerbindung==", "HTTPCALL nicht ausgeführt");
}
try
{
itemResult = (SoapObject)itemEnvelope.getResponse();
Log.d("==ItemResponse==", "PropertyCount: "+itemResult.getPropertyCount());
}
catch(ClassCastException e)
{
itemResult = (SoapObject)itemEnvelope.bodyIn;
}
catch (SoapFault e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
if(itemResult != null)
{
return itemResult;
}
return null;
}
I have also coppied the HttpTransportSE.java and manipulated it to write directly in a file. But there I get an unvalid Token error.
I remember to have seen this problem before:
Two Recommendations:
1) Save your SOAP XML stream directly to disk as you download it. Don't store it in memory.
2) Parse it using a SAX-style parser, where you don't load the whole DOM in memory, but rather parse it in chunks.
EDIT: Check this -> Very large SOAP response - Android- out of memory error
I found a solution without using the KSoap2 Library.
Here is the code:
try {
java.net.URL url = new java.net.URL(URL);
HttpURLConnection rc = (HttpURLConnection) url.openConnection();
rc.setRequestMethod("POST");
rc.setDoOutput(true);
rc.setDoInput(true);
rc.setRequestProperty("Content-Type", "text/xml; charset=utf-8");
rc.addRequestProperty("User-Agent", HTTP.USER_AGENT);
rc.setRequestProperty("SOAPAction", SOAP_ACTION_ITEM_DATA);
OutputStream out = rc.getOutputStream();
Writer wout;
wout = new OutputStreamWriter(out);
wout.write("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
wout.write("<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">");
wout.write("<soap:Body>");
wout.write("<GetItemData2 xmlns=\"http://localhost/HSWebBL\">");
wout.write("<Company>" + company + "</Company>");
wout.write("<SerialNumber>" + serialId + "</SerialNumber>");
wout.write("</GetItemData2>");
wout.write("</soap:Body>");
wout.write("</soap:Envelope>");
wout.flush();
wout.close();
rc.connect();
Log.d("==CLIENT==", "responsecode: " + rc.getResponseCode() + " " + rc.getResponseMessage());
InputStream in = new BufferedInputStream(rc.getInputStream(), BUFFER_SIZE);
} catch (ProtocolException e) {
e.printStackTrace();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
I use a SAXParser to parse the InputStream.
In that way I don't get an outOfMemoryException and no parsing error anymore.
Related
I was testing a method by which I could upload an Image available on my Android device into a BLOB field of a mySQL table. Couple of posts I ran into spoke about broader points but I was not able to tie them all up together.
Here is a part of my code. This is written in a new Thread of a service.
try {
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
builder.addTextBody(StaticVariables.filename, fileNames[i]);
//builder.addBinaryBody(StaticVariables.image, new File (getExternalCacheDir().getParent() + File.separator + StaticVariables.bills + File.separator + fileNames[i]));
builder.addTextBody(StaticVariables.image, getStringImage(Uri.fromFile(new File(getExternalCacheDir().getParent() + File.separator + StaticVariables.bills + File.separator + fileNames[i]))));
httppost.setEntity(builder.build());
HttpResponse response = httpClient.execute(httppost);
entity = response.getEntity();
String line = StaticVariables.emptyString;
InputStream instream = entity.getContent();
BufferedReader obr = new BufferedReader(new InputStreamReader(instream));
while ((line = obr.readLine()) != null) {
confirmed.add(line);
}
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
THE main issue I am facing now is that on execution, an exception is being raised where it states "413: Request Entity is too large". This occurs if I pass the file in the Binary format (the commented line of code) or the Text format.
The solution to write the images on to a folder of the server has already been done by me but I am curious to know if there is some way I could get them directly on to the DB.
Other information I should share is that I am running a very basic godaddy server and hence might not have any access to change any parameters on the server.
Let me know if you would require any other information.
Appreciate any input.
I need to upload a file to server. If i use the "curl -i -F filedata=#"PATH TO FILE" http://█.199.166.14/audiostream " it return a 200 OK code (Or may be this command incorrect) .
But when I use java function
public String send()
{
try {
url = "http://█.199.166.14/audiostream";
File file = new File(Environment.getExternalStorageDirectory().getAbsolutePath(), "test.pcm");
try {
Log.d("transmission", "started");
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(url);
ResponseHandler Rh = new BasicResponseHandler();
InputStreamEntity reqEntity = new InputStreamEntity(new FileInputStream(file), -1);
reqEntity.setContentType("binary/octet-stream");
reqEntity.setChunked(true); // Send in multiple parts if needed
httppost.setEntity(reqEntity);
HttpResponse response = httpclient.execute(httppost);
response.getEntity().getContentLength();
StringBuilder sb = new StringBuilder();
try {
BufferedReader reader =
new BufferedReader(new InputStreamReader(response.getEntity().getContent()), 65728);
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line);
}
}
catch (IOException e) { e.printStackTrace(); }
catch (Exception e) { e.printStackTrace(); }
Log.d("Response", sb.toString());
Log.d("Response", "StatusLine : " + response.getStatusLine() + " Entity: " + response.getEntity()+ " Locate: " + response.getLocale() + " " + Rh);
return sb.toString();
} catch (Exception e) {
// show error
Log.d ("Error", e.toString());
return e.toString();
}
}
catch (Exception e)
{
Log.d ("Error", e.toString());
return e.toString();
}
}
It's return 400 Bad request.
I'm also not sure that server proceed correctly my attempts to upload this file, but I can't check it.
From the error received its likely a bad formatted HTTP query. If audiostream is a php, write the full link.
Also it seems that there might be a wrong/bad encoded char at "http://█.199.166.14/audiostream, the link should be http://(IP or DNS)/(rest of URL)(the URI)
You should erase the link, then manually writte it again.
If those didnt fix the issue, its also possible that the Server (or its path equipment) might be blocking you. Check from the Access Log and the security rules of its accesses, that you are not blocked (some routers may block users from performing repeated querys as a sort of anti "Denial of Service" measure)
Im trying to learn more about webbbservices and python at the same time.
So if you got ideas or solution, explain to me like Im 5. :)
So I want to send a string to the server and just store it in a database (guestbook).
I've managed to do this with a webpage but now I want to access and store a string by phone, this is the python code:
import os
import urllib
import json
from google.appengine.ext import ndb
import jinja2
import webapp2
JINJA_ENVIRONMENT = jinja2.Environment(
loader=jinja2.FileSystemLoader(os.path.dirname(__file__)),
extensions=['jinja2.ext.autoescape'],
autoescape=True)
DEFAULT_GUESTBOOK_NAME = 'default_guestbook'
GUESTBOOKS_NAME = 'guestbook'
def guestbook_key(guestbook_name=DEFAULT_GUESTBOOK_NAME):
return ndb.Key('Guestbook', guestbook_name)
class Guestbook(ndb.Model):
identity = ndb.StringProperty(indexed=True
class Chat(webapp2.RequestHandler):
def get(self):
guestbook = Guestbook(parent=guestbook_key(GUESTBOOKS_NAME))
guestbook.identity=self.request.get("content")
guestbook.put()
self.response.headers['Content-Type'] = "text/plain"
self.response.out.write("ok")
application = webapp2.WSGIApplication([
(r'/chat', Chat),
], debug=True)
and this is the android code:
private void sendData(){
try {
JSONObject jsonobj = new JSONObject();
jsonobj.put("content", "asdf1234");
DefaultHttpClient httpclient = new DefaultHttpClient();
HttpPost httppostreq = new HttpPost("http://<myappid>.appspot.com/chat/");
StringEntity se = new StringEntity(jsonobj.toString());
se.setContentType("application/json;charset=UTF-8");
se.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE,"application/json;charset=UTF-8"));
httppostreq.setEntity(se);
HttpResponse httpresponse = httpclient.execute(httppostreq);
Log.d("Debug", "Response: " + EntityUtils.toString(httpresponse.getEntity()));
} catch (JSONException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e){
Log.d("Debug", "Exception: " + e.getMessage());
}
}
In your routing table : (r'/chat/(\d+)', Chat), this line maps the url to the handler.
which is handled by mapping the (\d+) to product_id in the get function of the handler.
valid urls
/chat/1
/chat/302490205
invalid urls
/chat
/chat/jedi
edit
since your posting your need a post method in your handler
def post(self):
#do stuff
I want to know if a specific file exists a on server or not. For example, suppose I have an .xml file on my server and I want to know if the file is there or not through java from my android application.
What server is it? If its HTTP server, you can request that file and check from response if it exist. If its custom server you have to implement that feature yourself.
You could use something like this:
URL url = null;
URLConnection connection = null;
InputStreamReader stream = null;
// Parse the URL
try {
url = new URL(urlString);
} catch (MalformedURLException e1) {
System.out.println("Malformed URL");
return null;
}
// Open a connection to the URL
try {
connection = url.openConnection();
} catch (IOException e) {
System.out.println("Could not create connection");
return null;
}
// Get the remote file
try {
stream = new InputStreamReader(connection.getInputStream());
} catch (IOException e) {
System.out.printf("File \"%s\" does not exist!",urlString);
return null;
}
i want to send my data in form of json to server using post method in android.
here is my format |data1|data2|data3|<>|data11|data22|data33
hope some example since i difficult to catch the procedure of post method.
Anyidea?
Edit:
my json format |data1|data2|data3|<>|data11|data22|data33|
where each data is a plain text (text get from database)
how can create it??
This blog post seems to talk about just that.
Post JSON Using Android And HttpClient
Edit: I saw your reply. Here's how. Hope this does the trick :)
public static void main(String[] args) {
File file = new File("<path to json file>");
FileInputStream fis;
String json = "";
try {
fis = new FileInputStream(file);
BufferedInputStream bis = new BufferedInputStream(fis);
DataInputStream dis = new DataInputStream(bis);
// dis.available() returns 0 if the file does not have more lines.
while (dis.available() != 0) {
json += dis.readLine();
}
// dispose all the resources after using them.
fis.close();
bis.close();
dis.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Essentially after this you would create the string entity to send
StringEntity st = new StringEntity(json.toString());
Then just follow the steps in that link
Haha, edit for your 2nd question: Just create a string with the text from the database. Thats all there is to it. Then create a StringEntity like the one above.