I'm having some issues with incomplete post data being received by our server. This only occurs for a few users of our app. Still not sure which versions of Android we are talking about, but will try to recover that information as soon as possible.
For the time being: maybe there is someone who also experienced similar problems? It occurs only for our textarea field where users can type large custom texts. There is no filter whatsoever on this field, and will be sent as StringBody to our server directly. The code below is the relevant parts. My concern is the part where the StringBody is created. Is this sufficient for escaping the text properly to not interfere with the post headers?
MultipartEntity entity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);
for(int j=0; j<fields.length; j++){
String value = mydata.get(fields[j]);
entity.addPart(fields[j], new StringBody(value, "text/plain", Charset.forName("UTF-8")));
}
(..) //some files are added too later on
entity.addPart(image.get("hash"), new FileBody(imageFile));
(..) //and sending the data to the server
HttpPost post = new HttpPost(url);
if(entity != null)
post.setEntity(entity);
final HttpClient http = new DefaultHttpClient();
final HttpParams params = http.getParams();
HttpConnectionParams.setConnectionTimeout(params, 10000);
HttpConnectionParams.setSoTimeout(params, 30000);
ConnManagerParams.setTimeout(params, 30000);
HttpResponse response = http.execute(post);
StatusLine statusLine = response.getStatusLine();
if(statusLine.getStatusCode() != HttpStatus.SC_OK){
response.getEntity().getContent().close();
throw new IOException(statusLine.getReasonPhrase());
}
ByteArrayOutputStream out = new ByteArrayOutputStream();
response.getEntity().writeTo(out);
out.close();
String result = out.toString();
Finally solved this problem. The problem was not in the frontend but in the backend. People were posting unicode emoticons . The backend was built with an MySQL utf8_general_ci collation table/column. This collation does not support the unicode characters and will break the text before the unicode character. So the resulting insert will have all text missing after the unicode character.
Related
I would like to get full content of website including some content loaded wich is depend of parameters in GET query. I have website www.example.com?date=2012-12-12. If I use it in any broswer first I see page with "waiting for serwer", after some miliseconds full content is loading. Now I would like to load content of this website after this some miliseconds in android. I don't know how to wait for full loading this.
private String makeHTTPRequest() throws IOException
{
String url = "http://www.centrum.saletyni.pl/index.php?option=com_content&view=article&id=18&data=2014-11-06";
HttpClient httpclient = new DefaultHttpClient();
HttpResponse response = httpclient.execute(new HttpGet(url));
StatusLine statusLine = response.getStatusLine();
String responseString;
if(statusLine.getStatusCode() == HttpStatus.SC_OK){
ByteArrayOutputStream out = new ByteArrayOutputStream();
response.getEntity().writeTo(out);
out.close();
responseString = out.toString();
//..more logic
} else{
//Closes the connection.
response.getEntity().getContent().close();
throw new IOException(statusLine.getReasonPhrase());
}
return responseString;
}
Sounds like you need a thread to execute after this other method is run, or as specified, after a certain amount of time.
e.g. You could use this for a specified time:
System.Threading.Thread.Sleep(10000);
http://msdn.microsoft.com/en-us/library/system.threading.thread(v=vs.110).aspx
I have a method to send image and text as a HttpPost using MultipartEntity content type. Everything works great with English symbols, but for unicode symbols (for example Cyrliics) it sends only ???. So, I'm wondering, how to set UTF-8 encoding for MultipartEntity correctly, since I've tried several sulutions, suggested on SO, but none of them worked.
Here what I have already:
HttpClient httpclient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url);
MultipartEntityBuilder mpEntity = MultipartEntityBuilder.create();
mpEntity.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
mpEntity.setCharset(Consts.UTF_8);
mpEntity.addPart("image", new FileBody(new File(attachmentUri), ContentType.APPLICATION_OCTET_STREAM));
ContentType contentType = ContentType.create(HTTP.PLAIN_TEXT_TYPE, HTTP.UTF_8);
StringBody stringBody = new StringBody(mMessage, contentType);
mpEntity.addPart("message", stringBody);
final HttpEntity fileBody = mpEntity.build();
httpPost.setEntity(fileBody);
HttpResponse httpResponse = httpclient.execute(httpPost);
UPD
I tried to use InputStream as per #Donaudampfschifffreizeitfahrt suggestion. Now I'm getting ��� characters.
InputStream stream = new ByteArrayInputStream(mMessage.getBytes(Charset.forName("UTF-8")));
mpEntity.addBinaryBody("message", stream);
Also tried:
mpEntity.addBinaryBody("message", mMessage.getBytes(Charset.forName("UTF-8")));
I solved it a different way, using:
builder.addTextBody(key, שלום, ContentType.TEXT_PLAIN.withCharset("UTF-8"));
You can use below line for add part in multipart entity
entity.addPart("Data", new StringBody(data,Charset.forName("UTF-8")));
to send unicode in request.
To the ones who stuck with this issue, this is how I resolved it:
I investigated apache http components libraries source code and found following:
org.apache.http.entity.mime.HttpMultipart::doWriteTo()
case BROWSER_COMPATIBLE:
// Only write Content-Disposition
// Use content charset
final MinimalField cd = part.getHeader().getField(MIME.CONTENT_DISPOSITION);
writeField(cd, this.charset, out);
final String filename = part.getBody().getFilename();
if (filename != null) {
final MinimalField ct = part.getHeader().getField(MIME.CONTENT_TYPE);
writeField(ct, this.charset, out);
}
break;
So, seems like it is some kind of bug / feature in apache lib, which only allowes to add Content-type header to one part of MultipartEntity, if this part has filename not null. So I modified my code as:
Charset utf8 = Charset.forName("utf-8");
ContentType contentType = ContentType.create(ContentType.TEXT_PLAIN.getMimeType(), utf8);
ContentBody body = new ByteArrayBody(mMessage.getBytes(), contentType, "filename");
mpEntity.addPart("message", body);
And Content-type header appeared for string part, and symbols are now encoded and decoded correctly.
I am using the following piece of code to perform an HTTP Request in Android. Everything seems fine, but it appears that the response gets clipped at some point and I can't read the full content of the requested url.
Is there any size limit on the response?
HttpClient httpclient = new DefaultHttpClient();
HttpGet request = new HttpGet(someUrl);
HttpResponse response = httpclient.execute(request);
StatusLine statusLine = response.getStatusLine();
if(statusLine.getStatusCode() == HttpStatus.SC_OK){
ByteArrayOutputStream out = new ByteArrayOutputStream();
response.getEntity().writeTo(out);
out.close();
String responseString = out.toString();
Log.w("Response", responseString); // The response is clipped at some point
}
Thank you.
Ok, silly me. Turns out this is a log problem. I checked out for size and the full content is there. The problem lies with the size limitation for LogCat, as explained in the following answer.
What is the size limit for Logcat and how to change its capacity?
Cheers
I am uploading a large string to web-service. The string contains new line character which is written as "\n".
The data looks some thing like:
05/06/2012 11:35:43 AM- DB exists, transferring data\n05/06/2012
11:48:20 AM- loadUserSpinners, cursor.getCount()=2\n05/06/2012
11:48:20 AM- Battery: 50%\n05/06/2012 11:48:20 AM- ITEM SELECTED: 0
the above data is stored in string JsonArrObj. To upload the data/string, i am using the following code:
HttpParams httpParameters = new BasicHttpParams();
int timeoutConnection = 360000; //6 minutes
HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection);
int timeoutSocket = 420000; //7 minutes
HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);
HttpClient httpClient = new DefaultHttpClient(httpParameters);
JSONArray jsonParams = new JSONArray();
Object[] params={IPAddress,Database,DbName,DbPassword,JsonArrObj};
for (int i = 0; i < params.length; i++) {
jsonParams.put(params[i]);
}
JSONObject jsonRequest = new JSONObject();
jsonRequest.put("id", Id);
jsonRequest.put("method", FunctionName);
jsonRequest.put("params", jsonParams);
JSONEntity entity = new JSONEntity(jsonRequest);
entity.setContentType("application/json; charset=utf-8");
HttpPost request = new HttpPost(URL);
request.setEntity(entity);
HttpResponse response = httpClient.execute(request);
StatusLine statusLine = response.getStatusLine();
int statusCode = statusLine.getStatusCode();
if (statusCode == 200) {
HttpEntity httpEntity = response.getEntity();
InputStream content = httpEntity.getContent();
BufferedReader reader = new BufferedReader(
new InputStreamReader(content,"iso-8859-1"),8);
String line;
while ((line = reader.readLine()) != null) {
builder.append(line);
LogE("result line: "+line);
String str=convertString(line);
parseJson(str);
}
content.close();
}
The string is uploaded successfully. The problem I am facing is: while string is being converted to jsonParams, the "\n" in the string data gets converted to "\\n" as a result, on the server side, it shows a small box in stead of new line.
When I open this string in NOTEPAD application, it displays small boxes. But when I open it in WORDPAD app, text is displayed on a new line. According to me, I might have entered in-correct "content-type" or encoding. Please suggest a solution for the same.
JsonArrObj= URLEncoder.encode(JsonArrObj, "utf-8"); gave error while uploading itself...
The data which is sent in the jsonParams- jsonArrObj finally looks like:
05\/06\/2012 04:05:52 PM- DB exists, transferring
data\\n05\/06\/2012 04:32:56 PM- loadUserSpinners,
cursor.getCount()\\u003d2\\n05\/06\/2012 04:32:56 PM- Battery:
50%\\n05\/06\/2012 04:32:56 PM- ITEM SELECTED: 0
Well, the encoder escapes your newline characters. If you want to transport newline chars properly, you can encode the whole stream with base64. If your target os (for data to send) is Windows then you should use \r\n, if mac then \r if unix\linux then \n. After encoding data try to send the encoded and decode it on the other side. For base64 Mr. Google will convince you.
Hey why don't you use the Unicode values for \n as and any other character that is creating this problem
like this U+002FU+006E
Okay, so I was trying to send Http Post Requests to this one site, and I sniffed the sent request with wireshark thus getting the text data from the post request of this site. I used this in a stock Java application, and it worked perfectly fine. I could use the post method regularly with no problem whatsoever, and it would return the appropriate website. Then I tried doing this with Android. Instead of returning the actual html data after executing the post request, it returns the regular page html data untouched. It DOES send a post request (sniff with wireshark again), it just doesn't seem to get the appropriate response. I took the exact same method used from another one of my projects, which worked perfectly fine in that project, and pasted it into my new project. I added the INTERNET user permission in Android, so there's nothing wrong with that. The only visible difference is that I used NameValuePairs in the other one (the one that worked) and in this one I'm directly putting the string into a StringEntity without encoding (using UTF-8 encoding screws up the String though). I used this exact same line of text in regular Java like I said, and it worked fine with no encoding. So what could be the problem? This is the code:
public static String sendNamePostRequest(String urlString) {
HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost(urlString);
StringBuffer sb = new StringBuffer();
try {
post.setEntity(new StringEntity(
"__EVENTTARGET=&__EVENTARGUMENT=&__VIEWSTATE=%2FwEPDwULLTE3NDM5MzMwMzRkZA%3D%3D&__EVENTVALIDATION=%2FwEWBAL%2B%2B4CfBgK52%2BLYCQK1gpH7BAL0w%2FPHAQ%3D%3D&_nameTextBox=John&_zoekButton=Zoek&numberOfLettersField=3"));
HttpResponse response = client.execute(post);
HttpEntity entity = response.getEntity();
BufferedReader br = new BufferedReader(new InputStreamReader(
entity.getContent()));
String in = "";
while ((in = br.readLine()) != null) {
sb.append(in + "\n");
}
br.close();
} catch (Exception e) {
e.printStackTrace();
}
return sb.toString();
}
Can you see what's wrong here?