0

for an Android app I'm working on I'd like to be able to send a REST POST using Volley with a body byte stream which includes a number of photos on the device.

I'm using Gson to serialize a list of objects. in my Volley Request getBody() method e.g. something like:

final Set<MySession> sessions;
....
new Gson().toJson(sessions).getBytes();

where MySession looks a bit like:

public class MySession {
....
  private Set<MyDefect> defects;
....
}
public class MyDefect {
...
  private Set<String> photoPaths;
...
}

What I have works fine up to a point: the REST call is made and the sessions/defects are serialized pretty much exactly as I want. The only thing I'd like to change is that when the sessions/defects are serialized by Gson, that instead of serializing the photo paths, that the byte arrays for the corresponding images are serialized???

so, the JSON sent would be something like:

[{
....
  "defects":
    [ {
          .... 
          "photos": [ [byte-array-for-photo-1], [byte-array-for-photo-2].....],
           ....
       }

i.e. the "photoPath" bit has been replaced by "photos".

I know you can use Gson with custom Serializers so that the byte array of each image @ photoPath is read in and added as a property for serialization BUT I'd rather not have to load in large image byte arrays into memory. What I'd like to do is to somehow be able to 'inject' a byte object stream as part of the serialization?

I also know that you can use JsonWriters and Appenders with toJson: what I'm not sure about is whether it's possible to use these in combination with a custom serializer to do what I'm trying to do? (Or whether there's another approach I haven't realised?)

Any suggestions welcome! Kind regards, Mike Beale

Phantômaxx
  • 37,901
  • 21
  • 84
  • 115
  • btw, I'm assuming that a viable approach is something along the lines of encapsulating the photo paths into 'Photo' class objects and registering a customer serializer for the class which returns something like: JsonPrimitive(Base64.encodeToString(src, Base64.NO_WRAP)); where src is the byte[] for the contents of a photo file... But as mentioned originally, I'd rather use something like a ByteArrayOutputStream rather than reading the whole file in, because of the image sizes... – Michael Beale Nov 26 '19 at 15:04
  • I strongly advise against trying to transport binary data in textual format - to properly deserialize this you will need to encode your binary data as a string which increases its size extensively! Instead either do a multipart/form-data POST having the textual information as form-data or POST the metadata first and the images using a different representation afterwards. Also, it might be nitpicky, but REST is a concept, not a technology. You do HTTP POSTs and only if your HTTP-based application adheres to a certain set of rules your API can be called RESTful. – Smutje Nov 26 '19 at 15:05
  • Do you think a `ByteArrayOutputStream` is something like a live stream between client and server? If you want to send giant photos as text they need to be in your memory anyway! A HTTP POST is a single request from Java programming point of view. – Smutje Nov 26 '19 at 15:08
  • Hi Smutje - thanks for the comments.No, didn't think that the BAOS was a 'live stream' but maybe my thought process was a little muddy! – Michael Beale Nov 26 '19 at 15:12
  • Something we did in the past was a POST containing text and author to something like /api/posts returning the ID of the created entry and a list of (binary) POSTs to /api/posts//images where each post contains the images data as binary body. – Smutje Nov 26 '19 at 15:16
  • 2
    I'll take a look at the multi-part/form route: A brief search has come up with https://stackoverflow.com/questions/16797468/how-to-send-a-multipart-form-data-post-in-android-with-volley/16803473#16803473 which I'll digest. Thanks for your input @Smutje. – Michael Beale Nov 26 '19 at 15:26

0 Answers0