Question

As stated in the title

It seems that oauthRequest.addBodyParameter(key, value) doesn't work so well if the input is a file

I tried to do the following to force the file into a string, but to no avail:

File f = new File("xyz.png");
InputStream is = new FileInputStream(f);
int intValue = -1;
String value = "";
do {
   intValue = is.read();
   if (intValue != -1) {
      char c = (char) intValue;
      value += c;
   }
} while (intValue != -1);

By the way, I am attempting to upload an image to Flickr programmatically (not sure whether there is more straightforward way)

Was it helpful?

Solution

Of course addBodyParameter wont work because you don't want to include a body parameter, you want to create a multipart http request.

Scribe does not makes this easy on you, and the reason is that it's not very common for Apis to support file uploads, and other libraries do this nicely. (When scribe is migrated to use apache commons http, things will be easier for everyone)

As @Chris says though (+1) you can and are encouraged to use the addPayload method, but you'll need to create the multipart request yourself. Sorry.

Disclaimer: I'm the library author.

OTHER TIPS

I think the issue you are having here is how you are reading in the image file. Representing an image as a String built from chars that you read in one at a time is causing the problem. While a char is a byte, Strings in Java are in UTF-8. When you output a String, you don't just get the chars you used to build it, you get the UTF-8 representation.

So not having tried this myself, have you tried using the public void addPayload(byte[] payload) method instead of addBodyParameter(key, value)? That seems like the right away to do it.

To add onto what @Pablo said, if you are already using the Apache Commons HTTP client libraries, you can use your MultipartEntity object to handle the multipart request formatting:

MultipartEntity reqEntity = new MultipartEntity();
// add your ContentBody fields as normal...

// Now, pull out the contents of everything you've added and set it as the payload
ByteArrayOutputStream bos = new ByteArrayOutputStream((int)reqEntity.getContentLength());
reqEntity.writeTo(bos);
oAuthReq.addPayload(bos.toByteArray());

// Finally, set the Content-type header (with the boundary marker):
Header contentType = reqEntity.getContentType();
oAuthReq.addHeader(contentType.getName(), contentType.getValue());

// Sign and send like normal:
service.signRequest(new Token(oAuthToken, oAuthSecret), oAuthReq);
Response oauthResp = oAuthReq.send();

Of course, this has the downside of this is that you need to read the entire content body into a byte[] in memory, so if you're sending giant files this might not be optimal. However, for small uploads, this did the trick for me.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top