0

I want to send a json object from my android device to the server (in post).

In my json object, I need to add an image in Base64. I cannot use to String to convert my image to Base64 because a String is too short to contain a Base64 encoded file. I must use a BytesArray.

How to send something like that to a JSON webservice ?

{
"emergency":"gsjqsbl",
"cod_valid":"O",
"image":{
  "content":"/9j/4AAQSkZJRg ## MY VERY VERY VERY VERY VERY VERY VERY LONG IMAGE IN BASE64 ## BWNn+SV5H8KQADnn9ysrKA1EVX+lNDkSJ8ai8UADCLoAR3TWVlHT95AVvcfwCvD4Hq1joP5NX3Ciat7zyP4VlZW9bnl1sf//Z",
  "content_type":"image/jpg"
},
"indoor":"yes",
"access_conditional":"text",
"geo_shape":{
  "type":"Point",
  "coordinates":[
     2.0202024,
     45.799005
  ]
},
"lastupdate":"",
"ref_fr_sdis91":"",
"name":"TEST IN UPPERCASE WITH SPECIAL CHARACTERS ;/*-é@$~æ€",
"geo_point_2d":"45.799005,2.0202024",
"source":"soures",
"objectid":"",
"aed_location":"Spopopo"
}

I really cannot use String.

Thanks

EDIT : What i've done yet :

 //output stream
  ByteArrayOutputStream outputStream = new ByteArrayOutputStream();

  //write text
  OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream);
  BufferedWriter bufferedWriter = new BufferedWriter(outputStreamWriter);
  bufferedWriter.write("json start { blabla: value");

  //Write image
  AssetManager assetManager = context.getAssets();

  InputStream istr;
  Bitmap bitmap = null;
  try {
    istr = assetManager.open("pictures/defib12.jpg");
    bitmap = BitmapFactory.decodeStream(istr);
  } catch (IOException e) {
    e.printStackTrace();
  }
  ByteArrayOutputStream baos = new ByteArrayOutputStream();
  bitmap.compress(Bitmap.CompressFormat.JPEG, 90, baos);
  outputStream.write(Base64.encode(baos.toByteArray(), Base64.DEFAULT));

  //write text
  OutputStreamWriter outputStreamWriter2 = new OutputStreamWriter(outputStream);
  bufferedWriter = new BufferedWriter(outputStreamWriter2);
  bufferedWriter.write("json end }");

  HttpResponse response = restClient.executePostRequest(pushUrl, outputStream);

And :

public HttpResponse executePostRequest(String url, ByteArrayOutputStream outputStream) throws IOException {
LogWrapper.debug(DmaRestClient.class, "New HttpPost request: " + url);

DefaultHttpClient client = new DefaultHttpClient();
HttpPost request = new HttpPost(url);

request.setEntity(new ByteArrayEntity(outputStream.toByteArray()));
request.setHeader("Content-Type", "application/json");

return client.execute(request);
}
psv
  • 3,147
  • 5
  • 32
  • 67
  • How is a String "too short" to contain the base64? – Pedro Oliveira Oct 09 '14 at 10:03
  • 1
    I have an error like that : https://community.oracle.com/thread/1524893?start=0&tstart=0 – psv Oct 09 '14 at 10:07
  • @psv did you manage to solve your problem? what solution have you finally used? – eugen Oct 10 '14 at 23:27
  • I used a StringBuilder to build my string. Even if I must do a stringBuilder.toString() to parse the string, I don't have any error right now. I didn't understand what happened with my String object before using StringBuilder. – psv Oct 11 '14 at 09:47

1 Answers1

0

You should use a lib to do that. Check Genson, it provides two mechanisms to ser/de binary content: using the classic base64 encoded strings (but in your case it looks like it won't work) or ser/de as an array of ints. Note that you will have to use the same mechanism on the server side - but it could be another library that support this kind of format.

With Genson you would create classes to represent your json and image.content value would be the byte array. To enable this option in Genson:

Genson genson = new GensonBuilder().useByteAsInt(true).create();
genson.serialize(yourObject, theOutputStream);

If you want to do it by hand without using any lib you still can (but it is a bad practice...) use the same trick => Ser/de the byte array as an int array.

eugen
  • 5,856
  • 2
  • 29
  • 26
  • Ok, thank you. I don't have access to the server side. Everything I know is that it is able to deserialize data according to a predefined JSON. I'll test Genson. – psv Oct 09 '14 at 11:36
  • The server side will have the same constraints as you have (concerning the max string size), so the server code will have to be updated to support the format you use. Concerning the use of array of ints, you will still have a limit (outside the memory limit) that is the max size of an integer, see http://stackoverflow.com/questions/816142/strings-maximum-length-in-java-calling-length-method and http://stackoverflow.com/questions/12120002/is-there-any-limit-for-string-size-in-a-java-program. – eugen Oct 09 '14 at 13:59
  • When I use postman to test the server, it accepts when I send a very long json (and a very long String in Base64 in the image field). For me the server side doesn't have any problem with the Image string length – psv Oct 09 '14 at 14:15