Android Sending Image to server - android

HttpClient httpclient1 = new DefaultHttpClient();
HttpParams p=new BasicHttpParams();
p.setParameter("vname",name);
p.setParameter("address", addr);
p.setParameter("age", age);
p.setParameter("contact", cnct);
p.setParameter("gender", gen);
p.setParameter("whomto", wtm);
p.setParameter("myFile", f);
HttpPost res1=new HttpPost(result);
res1.setHeader("Content-Type", "text/plain");
res1.setHeader("Content-Type","image/jpeg");
HttpResponse response1 = httpclient1.execute(res1);
HttpEntity entity1 = response1.getEntity();
i1 = entity1.getContent();
BufferedReader reader1 = new BufferedReader(new InputStreamReader(i1,"iso-8859-1"),8);
StringBuilder sb1 = new StringBuilder();
String line1 = null;
if((line1 = reader1.readLine()) != null) {
sb1.append(line1);
back=sb1.toString();
}
else{
Log.e("GET data","null");
}
i1.close();
Log.e("GET",""+back);
//Server Code
private BlobstoreService blobstoreService = BlobstoreServiceFactory.getBlobstoreService();
public void doPost(HttpServletRequest req, HttpServletResponse res)throws ServletException, IOException {
res.setContentType("text/html");
Map<String, BlobKey> blobs = blobstoreService.getUploadedBlobs(req);
BlobKey blobKey = blobs.get("myFile");
final BlobInfo blobInfo = new BlobInfoFactory().loadBlobInfo(new BlobKey(blobKey.getKeyString()));
System.out.println(blobInfo.getContentType());
if(!blobInfo.getContentType().equalsIgnoreCase("image/jpeg")){
blobstoreService.delete(blobInfo.getBlobKey());
res.getWriter().println("Please Provide JPG image only");
}
I am sending one image file with some other data to server.I am not getting any error or exception But when I am printing the "back",in log it is showing "The request's content type is not accepted on this URL". "f" is my image file..What is the problem?

Have a look at my answer to a similar question as yours: link
It will save you the hassle of writing server side code and letting you android app send data eg. images to it.

You are setting the Content-Type header to two different values, neither of which is "multipart/form-data" which I believe is what you need when sending an file.
Here is an answer that should help:
https://stackoverflow.com/a/3003402/412558

Related

Android Http Response is incomplete. Returns an unterminated json object

I am using HttpClient 4.3.6 to perform http GET and POST requests. Right now I am using multipartentity to send a few string parameters and an image in the form of a file. I am able to successfully post the data but my problem comes in when I get the HTTP response. The response contains json data.
What happens is the HTTP response is incomplete and when i try to create a json object with the data i get jsonexception error saying:
Unterminated object at character 407.
I noticed that the response does not contain closed braces. Is this a problem on android or should I check the server? Because I am able to see the data properly on postman and on ios. I have never faced this issue before and don't know how to solve this.
This is my code to post and get the response:
#Override
protected String doInBackground(String... params) {
try {
String url = params[0];
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(url);
MultipartEntity entity = new MultipartEntity();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
byte[] imageBytes = baos.toByteArray();
ByteArrayBody bab = new ByteArrayBody(imageBytes, "image.jpg");
entity.addPart("image_data", bab);
entity.addPart("action", new StringBody("1", "text/plain", Charset.forName("UTF-8")));
entity.addPart("name", new StringBody("asdfg", "text/plain", Charset.forName("UTF-8")));
entity.addPart("user_id", new StringBody("157", "text/plain", Charset.forName("UTF-8")));
entity.addPart("birthday", new StringBody("18-04-1995", "text/plain", Charset.forName("UTF-8")));
entity.addPart("gender", new StringBody("male", "text/plain", Charset.forName("UTF-8")));
entity.addPart("is_jlpt_student", new StringBody(String.valueOf(0), "text/plain", Charset.forName("UTF-8")));
entity.addPart("relationship", new StringBody("Father", "text/plain", Charset.forName("UTF-8")));
entity.addPart("relationship_id", new StringBody(String.valueOf(10002), "text/plain", Charset.forName("UTF-8")));
entity.addPart("is_creator", new StringBody(String.valueOf(1), "text/plain", Charset.forName("UTF-8")));
entity.addPart("email", new StringBody(email, "text/plain", Charset.forName("UTF-8")));
httppost.setEntity(entity);
HttpResponse resp = httpclient.execute(httppost);
String response = EntityUtils.toString(resp.getEntity());
Log.i("HttpResponse", response);
return response;
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute (String result) {
super.onPostExecute(result);
JSONObject jsonObject = null;
try {
jsonObject = new JSONObject(result);
JSONObject json_data = jsonObject.getJSONObject("data");
String json_userid = json_data.getString("user_id");
String json_username = json_data.getString("name");
String json_email = json_data.getString("email");
String json_country = json_data.getString("country_code");
String json_imagefilename = json_data.getString("image_filename");
String json_imgurl = json_data.getString("image_url");
Toast.makeText(ParentGuardianProfile.this, "ImageFile " + json_imagefilename, Toast.LENGTH_SHORT).show();
User new_user = userdao.createUser(json_userid, json_username, json_email,json_imagefilename,json_country,selectedImageUri.toString(), 1);
Log.i("SQLITE", "added user : " + new_user.getmUserName() + new_user.getmId());
} catch (JSONException e) {
e.printStackTrace();
}
}
And my json response is :
{"status":1,"message":"success","data":{"child_id":"381","name":"asdfg","image_filename":"C201603021734476.jpg","image_url":"https:\/\/innokid.blob.core.windows.net\/media\/child\/381.jpg","birthday":"18-04-1995","gender":"male","is_jltp_student":"0","relationship":"Father","relationship_id":"10002","is_creator":1,"rank":1,"qrcode_url":"http:\/\/innokid.azurewebsites.net\/uploads\/qrcode\/child_381.png"
I tried using String buffer as suggested in this post String is being truncated when its too long . But i still get the same result.
Code looks ok at first glance.
How do you got know that the json data is cut? Logcat can truncate text. Debugger should be more reliable in this case.
Try to generate this same request with some tools like curl / SoapUI and validate JSON you got with some formatter / validator (you'll easily find a few of such tools).
It's beyond the range of question, but using raw Android built-in communication libraries seems to be a little bit masochistic. Have you ever consider to use Retrofit?
I think this code is problematic String response = EntityUtils.toString(resp.getEntity());
may be you should use some other function to convert response toString...
Apparently the json is missing two curly brackets '}}' at the end, which can happen due to some bug in the toString code.
I pulled up an old project that was using the org.apache.http stuff and below is how I was parsing the response. As you can see it is rather cumbersome. There are many tested and maintained libraries out there that are better suited to this kind of heavy-lifting.
// Get hold of the response entity (-> the data):
HttpEntity entity = response.getEntity();
if (entity != null) {
// Read the content stream
InputStream instream = entity.getContent();
Header contentEncoding = response.getFirstHeader("Content-Encoding");
if (contentEncoding != null && contentEncoding.getValue().equalsIgnoreCase("gzip")) {
instream = new GZIPInputStream(instream);
}
// Convert content stream to a String
resultString = convertStreamToString(instream);
instream.close();
// Do stuff with resultString here
// Consume Content
entity.consumeContent();
}
And the convertStreamToString() method:
private static String convertStreamToString(InputStream is) {
/*
* To convert the InputStream to String we use the
* BufferedReader.readLine() method. We iterate until the BufferedReader
* return null which means there's no more data to read. Each line will
* appended to a StringBuilder and returned as String.
*
* (c) public domain:
* http://senior.ceng.metu.edu.tr/2009/praeda/2009/01/
* 11/a-simple-restful-client-at-android/
*/
BufferedReader reader = new BufferedReader(new InputStreamReader(is), 8192);
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();
}
}
return sb.toString();
}
I finally solved this issue by replacing httpclient library with Android Asynchronous Http Client. Now it works fine. Thanks a lot for your help!
However, I still dont understand why the response was truncated when i used httpclient.

Send Image and String by using MultipartEntity

I am working on an app that allows the user upload an image by using HttpPost method. I use MultipartEntity and therefore I added the libraries apache-mime4j-0.6.1.jar, httpclient-4.3.1.jar, httpcore-4.3.1.jar and httpmime-4.2.1.jar into my app. My upload code is like below:
public String uploadFile() throws Exception
{
String result = "";
try
{
HttpResponse response = null;
HttpClient httpClient = new DefaultHttpClient();
HttpPost request = new HttpPost(_url);
request.setHeader("Accept", "application/json");
File file=new File(filePath);
String fileName=file.getName();
MultipartEntity imageEntity=new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE,null,Charset.forName("UTF-8"));
imageEntity.addPart("imageName", new StringBody(fileName));
imageEntity.addPart("image", new FileBody(file, "application/octet-stream"));
request.setEntity(imageEntity);
response = httpClient.execute(request);
InputStream dataStream = response.getEntity().getContent();
BufferedReader dataReader = new BufferedReader(new InputStreamReader(dataStream));
String line = "";
while ((line = dataReader.readLine()) != null)
result+=line;
}
catch (Exception e)
{
}
return result;
}
I get response from my server but in my web service code Request.Files has no file. If I change the line:
MultipartEntity imageEntity=new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE,null,Charset.forName("UTF-8"));
to
MultipartEntity imageEntity=new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);
app is in process for a long time (about 3-4 minutes) and throws error. This is caused if I add an image. If I send only StringBody without FileBody, I get response from server and Request.Files in my webservice code return file count correctly. How can I fix this problem and upload image correctly? Any suggestion?

parse Multipart response in Android

I'm sending images and json text from the android client to a tomcat server and the other way around by using Multipart HttpPost's. Sending a Multipart Entity to the server is no big deal, because you can process the parts easily using request.getPart(<name>). But at the client side you can only access the response as a Stream. So I end up appending both, the JSON string and the image to the same ServletOutputStream and have to parse them by hand on the client side. I found apache-mime4j in the web but its hardly documented and I cant find a single example how to use it.
On the server side I build the response like this:
ServletResponse httpResponse = ctx.getResponse();
ResponseFacade rf = (ResponseFacade) httpResponse;
rf.addHeader("Access-Control-Allow-Origin", "*");
rf.addHeader("Access-Control-Allow-Methods", "POST");
rf.addHeader("content-type", "multipart/form-data");
httpResponse.setCharacterEncoding("UTF-8");
MultipartResponse multi = new MultipartResponse((HttpServletResponse) httpResponse);
ServletOutputStream out = httpResponse.getOutputStream();
multi.startResponse("text/plain");
out.println(CMD + "#" + content);
multi.endResponse();
multi.startResponse("image/jpeg");
out.write(data);
multi.endResponse();
multi.finish();
ctx.complete();
And on the client side on Android I want to access the text and the image data:
InputStream is = response.getEntity().getContent();
MimeStreamParser parser = new MimeStreamParser();
MultipartContentHandler con = new MultipartContentHandler();
parser.setContentHandler(con);
try {
parser.parse(is);
String json = con.getJSON(); //get extracted json string
byte[] imgBytes = con.getBytes(); //get extracted bytes
} catch (MimeException e) {
e.printStackTrace();
} finally {
is.close();
}
class MultipartContentHandler implements ContentHandler{
public void body(BodyDescriptor bd, InputStream in) throws MimeException, IOException {
//if MIME-Type is "text/plain"
// process json-part
//else
// process image-part
}
In the method body(BodyDescriptor bd, InputStream in) my whole response is treated as text\plain mime type. So I finally have to parse every byte manually again and the whole apache-mime4j is useless. Can you tell me what I am doing wrong? Thanks!
Ok i finally solved it myself. No here's what i did:
First I need to create a multipart/mixed Response at the server side. It can be done using apache-mime-4j API:
ServletResponse httpResponse = ctx.getResponse();
ResponseFacade rf = (ResponseFacade) httpResponse;
httpResponse.setCharacterEncoding("UTF-8");
httpResponse.setContentType("multipart/mixed");
MultipartEntity entity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE, "SEPERATOR_STRING",Charset.forName("UTF-8"));
entity.addPart("json", new StringBody(CMD + "#" + content, "text/plain", Charset.forName("UTF-8")));
entity.addPart("image", new ByteArrayBody(data, "image/jpeg", "file"));
httpResponse.setContentLength((int) entity.getContentLength());
entity.writeTo(httpResponse.getOutputStream());
ctx.complete();
Now at the client side to access the MIME-Parts of the HttpResponse I use the javax.mail API.
ByteArrayDataSource ds = new ByteArrayDataSource(response.getEntity().getContent(), "multipart/mixed");
MimeMultipart multipart = new MimeMultipart(ds);
BodyPart jsonPart = multipart.getBodyPart(0);
BodyPart imagePart = multipart.getBodyPart(1);
But you can't use the native API, instead take this one http://code.google.com/p/javamail-android/
Now you can proceed handling your individual parts.
It is also possible with apache-mime-4j:
HttpURLConnection conn = ...;
final InputStream is = conn.getInputStream();
try {
final StringBuilder sb = new StringBuilder();
sb.append("MIME-Version: ").append(conn.getHeaderField("MIME-Version")).append("\r\n");
sb.append("Content-Type: ").append(conn.getHeaderField("Content-Type")).append("\r\n");
sb.append("\r\n");
parser.parse(new SequenceInputStream(new ByteArrayInputStream(sb.toString().getBytes("US-ASCII")), is));
} catch (final MimeException e) {
e.printStackTrace();
} finally {
is.close();
}

Sending an Image to a server to create Blob key in android

I want to send an image captured by camera to a server, which creates blob key. I am not getting how to send that image to the server. In which format is the image is sent?
I am trying to send parameters through HttpParams.
This is my code but the data is not going to server. What is the problem?
String name=tname.getText().toString();
String addr=taddr.getText().toString();
String age=tage.getText().toString();
String cnct=tcnct.getText().toString();
String gen=tgen.getText().toString();
String wtm=twtm.getText().toString();
ba1=Base64.encodeToString(imageform, 0);
Date d=new Date();
String date=d.toString();
InputStream i1;
String back="";
HttpParams p=new BasicHttpParams();
p.setParameter("vname",name);
p.setParameter("address", addr);
p.setParameter("age", age);
p.setParameter("contact", cnct);
p.setParameter("gender", gen);
p.setParameter("whomto", wtm);
p.setParameter("myFile", ba1);
try {
HttpClient httpclient = new DefaultHttpClient(p);
HttpPost res=new HttpPost(result);
HttpResponse response = httpclient.execute(res);
HttpEntity entity = response.getEntity();
i1 = entity.getContent();
BufferedReader reader = new BufferedReader(new InputStreamReader(i1,"iso-8859-1"),8);
StringBuilder sb = new StringBuilder();
if ( reader.readLine() == null) {
Log.e("inside if","No data");
} else {
String line = reader.readLine();
i1.close();
back=sb.toString();
}
I am not getting any errors or exceptions.
You should make an MultipartPost and add the file to your MultipartEntity as follows :
multipartEntity.addPart("data", new FileBody(capturedImagePath));
You should have a look a this answer Multipart post with Android for a more detailed answer.
Encode the image, using Base64, to a String and send it using MultipartEntity.
In php retrieve the string an unpack it with base64_decode to the image.
Check this question:
https://stackoverflow.com/questions/10145417/android-send-image-through-http-post

Android and Google-app-engine createuploadURL - how to pass additional parameters (i.e. email address)

I'm able to use createuploadurl to successfully store a bitmap image. My problem is that I want to pass in an email address parameter also to send the image to after.
Here is the code I tried to use:
//Code for uploading image within android
//Now upload the image
ByteArrayOutputStream bao = new ByteArrayOutputStream();
mBitmap.compress(Bitmap.CompressFormat.JPEG, 90, bao);
HttpPost httppost = new HttpPost(url);
HttpParams postParams = new BasicHttpParams();
postParams.setParameter( "email", "someone#gmail.com" );
httppost.setParams(postParams);
MultipartEntity entity = new MultipartEntity( HttpMultipartMode.BROWSER_COMPATIBLE );
byte [] ba = bao.toByteArray();
entity.addPart("imageField", new ByteArrayBody(ba, "myimage.jpg"));
httppost.setEntity(entity);
// Execute HTTP Post Request
response = httpclient.execute(httppost);
In the servlet code I then try to get the email param:
public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
//this comes up as null
if (req.getParameter("email") != null) {
this.email = req.getParameter(email);
}
Map<String, BlobKey> blobs = blobstoreService.getUploadedBlobs(req);
BlobKey blobKey = blobs.get("imageField");
resp.setContentType("text/plain");
}
Thanks in advance for the help.
You can replace the "imageField" key in the android to the email address.
In the server side, get all the keys from the get upload methods.
Map<String, BlobKey> blobs = blobstoreService.getUploadedBlobs(req);
Iterator<String> iter = blobs.keySet().iterator();
while (iter.hasNext()) {
String key = iter.next(); // your email
}

Categories

Resources