Always get video format not supported when posting a video - java

I am trying to use the graph API to upload a video to a users wall. The result is always an error response of "{"error":{"message":"(#352) Video file format is not supported","type":"OAuthException"}}". I have tried several different video types that are all supported based on this list, http://developers.facebook.com/docs/reference/api/video/. Based on my understanding of the documentation i have found, all that needs to be done is send a multipart form data request to "https://graph-video.facebook.com/me/videos" via a POST. BTW, I have been able to post a photo using similar techniques. The code i am using is below. It is based off of the PHP example at, http://developers.facebook.com/blog/post/493/. I have been able to upload the different videos using the facebook upload mechanism, so i know the videos are ok for Facebook. The access token is valid because i have used it to post a photo via the Graph API.
Any suggestions to what i am missing are welcome!
Here is the Java Code that i am using:
File video = new File(pathtovideofile);
DataInputStream dis = new DataInputStream(new FileInputStream(video));
byte[] bytes = new byte[(int)video.length()];
dis.read(bytes, 0, (int)video.length());
// set up the http client, the http method, and the multipart entity
DefaultHttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("https://graph-video.facebook.com/me/videos");
MultipartEntity mpEntity = new MultipartEntity( );
ContentBody cbVideo = new ByteArrayBody(bytes, "video/mp4", "Video Label");
ContentBody cbMessage = new StringBody( "New Video" );
ContentBody cbTitle = new StringBody( "Video Title" );
ContentBody cbAccessToken = new StringBody( accessTokenStr1 );
mpEntity.addPart( "access_token", cbAccessToken );
mpEntity.addPart( "file", cbVideo );
mpEntity.addPart( "description", cbMessage );
mpEntity.addPart( "title", cbTitle );
// put the multipart entity into the request
httppost.setEntity(mpEntity);
// send the request
HttpResponse response = httpclient.execute(httppost);
// get the response entity
HttpEntity resEntity = response.getEntity();
// read the stream and print out the results
InputStream instream = resEntity.getContent();
BufferedReader reader = new BufferedReader(new InputStreamReader(instream));
String line;
StringBuilder responsestr = new StringBuilder();
while (( line = reader.readLine()) != null) {
responsestr.append(line);
}
System.out.println(responsestr.toString());

In php this worked for me. First upload the file to server and then try API call using Graph API.
$fbvideo_upload=move_uploaded_file($_FILES['attach_video']['tmp_name'],$fbvideo_path);
chmod($fbvideo_path,0777);
if($fbvideo_upload)
{
$args = array('message' => $status, "access_token" =>$accesstoken,"file"
=> '#'.$fbvideo_path, "title"=>$video_title, "description"=>$video_desc);
$post_url = "https://graph-video.facebook.com/me/videos?access_token=".$accesstoken;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $post_url);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $args);
$data = curl_exec($ch);
$data=json_decode($data,true);
if(file_exists($fbvideo_path))
{
#unlink($fbvideo_path);
}
}

Related

How to send binary file using HttpClient approach

I am trying to send a two binary file to one of the REST API. But I get 400 bad request response from the end point.
Need to send below key and values to endpoint.
userForm - user.xml
structureForm - structure.xdp
Below is the java code, [UPDATED CODE]
HttpPost request = new HttpPost(url);
File userForm = new File("D:\\Downloads\\user.xml");
LOG.info("length ---->" + userForm.length()); // See valid file size
HttpEntity userFormEntity = MultipartEntityBuilder.create()
.addPart("userForm", new FileBody(userForm))
.build();
File structureFile = new File("D:\\Downloads\\structure.xdp");
LOG.info("length structureFile ---->" + structureFile.length()); // See valid file size
HttpEntity structureEntity = MultipartEntityBuilder.create()
.addPart("structureForm", new FileBody(structureFile))
.build();
if (userFormEntity != null && structureEntity != null) {
request.setEntity(userFormEntity);
request.setEntity(structureEntity);
}
final CloseableHttpClient httpClient = HttpClientBuilder.create().build();
CloseableHttpResponse response = httpClient.execute(request);
Seemed like the key 'userForm' and 'structureForm' are not going properly to end point. Is it correct way to send the key?
It is working when I try to submit through postman as below

Converting HTTP POST from curl (PHP) to HttpURLConnection (Java)

I tried to convert the below PHP code (taken from https://www.cryptocoincharts.info/tools/api) to java
// define pairs
$post = array("pairs" => "ltc_usd,ppc_btc");
// fetch data
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, "http://api.cryptocoincharts.info/tradingPairs");
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $post);
$rawData = curl_exec($curl);
curl_close($curl);
// decode to array
$data = json_decode($rawData);
// show data
echo "<pre>";
foreach ($data as $row)
{
echo "Price of ".$row->id.": ".$row->price."\n";
echo "Trade this pair on ".$row->best_market."\n";
}
echo "</pre>";
Java Code
URL url = new URL("http://api.cryptocoincharts.info/tradingPairs");
HttpURLConnection con = (HttpURLConnection) url.openConnection();
// CURLOPT_POST
con.setRequestMethod("POST");
// CURLOPT_FOLLOWLOCATION
con.setInstanceFollowRedirects(true);
String postData = "ltc_usd,ppc_btc";
con.setRequestProperty("Content-length", String.valueOf(postData.length()));
con.setDoOutput(true);
con.setDoInput(true);
DataOutputStream output = new DataOutputStream(con.getOutputStream());
output.writeBytes(postData);
output.close();
// "Post data send ... waiting for reply");
int code = con.getResponseCode(); // 200 = HTTP_OK
System.out.println("Response (Code):" + code);
System.out.println("Response (Message):" + con.getResponseMessage());
// read the response
DataInputStream input = new DataInputStream(con.getInputStream());
int c;
StringBuilder resultBuf = new StringBuilder();
while ( (c = input.read()) != -1) {
resultBuf.append((char) c);
}
input.close();
System.out.println("resultBuf.toString() " + resultBuf.toString());
As per the API, after converting this to java I should get only the details of LTC and PPC details. Instead I am getting a strange Json with all trading pairs.
2 $post = array("pairs" => "ltc_usd,ppc_btc"); Posted the PHP code as I am not known the exact equivalent in Java
Could you please point out if my conversion from PHP to Java is correct ?
As far as I see, the main difference between the two implementation is related to the $post variable.
In the PHP implementation $post is a key/value array but in Java I only see the value part.
I suggest to change the postData variable content into pairs=ltc_usd,ppc_btc
You didn't mentioned key part, only value is mentioned. And when we fetch data from PHP API, we have an associative array. If u want to display the output, u need to know the key and value of the particular associative array.
And the InputStream and OutputStream should be inside try-resources
you can try curl-to-java lib to convert curl php code to java code
https://github.com/jeffreyning/curl-to-java
demo like this
public Object curl(String url, Object postData, String method) {
CurlLib curl = CurlFactory.getInstance("default");
ch = curl.curl_init();
curl.curl_setopt(ch, CurlOption.CURLOPT_CONNECTTIMEOUT, 1000);
curl.curl_setopt(ch, CurlOption.CURLOPT_TIMEOUT, 5000);
curl.curl_setopt(ch, CurlOption.CURLOPT_SSL_VERIFYPEER, false);
curl.curl_setopt(ch, CurlOption.CURLOPT_SSL_VERIFYHOST, false);
String postDataStr = "key1=v1";
curl.curl_setopt(ch, CurlOption.CURLOPT_CUSTOMREQUEST, "POST");
curl.curl_setopt(ch, CurlOption.CURLOPT_POSTFIELDS, postDataStr);
curl.curl_setopt(ch, CurlOption.CURLOPT_URL, "https://xxxx.com/yyy");
Object html = curl.curl_exec(ch);
Object httpCode = curl.curl_getinfo(ch, CurlInfo.CURLINFO_HTTP_CODE);
if (httpCode != null && 200 == Integer.valueOf(httpCode.toString())) {
return null;
}
return html;
}

POST multipart/mixed in .NET

Just what the title says, if it helps in any way I have this java code (multipart consists of json object and file):
// Construct a MultiPart
MultiPart multiPart = new MultiPart();
multiPart.bodyPart(new BodyPart(inParams, MediaType.APPLICATION_JSON_TYPE));
multiPart.bodyPart(new BodyPart(fileToUpload, MediaType.APPLICATION_OCTET_STREAM_TYPE));
// POST the request
final ClientResponse clientResp = resource.type("multipart/mixed").post(ClientResponse.class, multiPart);
(using com.sun.jersey.multipart ) and I want to create the same in .NET (C#)
So far I managed to POST the json object like this:
Uri myUri = new Uri("http://srezWebServices/rest/ws0/test");
var httpWebRequest = (HttpWebRequest)WebRequest.Create(myUri);
httpWebRequest.Proxy = null;
httpWebRequest.Accept = "application/json";
httpWebRequest.ContentType = "application/json";
httpWebRequest.Method = "POST";
Console.Write("START!");
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream())){
string json = new JavaScriptSerializer().Serialize(new
{
wsId = "0",
accessId = "101",
accessCode = "x#ds!2"
});
streamWriter.Write(json);
streamWriter.Flush();
streamWriter.Close();
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
}
But I want to send the file together. The content type has to be "multipart/mixed" because that's what the web service gets. I tried to find some package that supports multiparts but I found nothing except maybe this http://www.example-code.com/csharp/mime_multipartMixed.asp (which is not free so I can't use it).
I finally managed to do it like this:
HttpContent stringStreamContent = new StringContent(json);
stringStreamContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");
HttpContent fileStreamContent = new StreamContent(fileStream);
fileStreamContent.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
// Construct a MultiPart
// 1st : JSON Object with IN parameters
// 2nd : Octet Stream with file to upload
var content = new MultipartContent("mixed");
content.Add(stringStreamContent);
content.Add(fileStreamContent);
// POST the request as "multipart/mixed"
var result = client.PostAsync(myUrl, content).Result;

Android multipart upload + blueimp UploadHandler: filetype not allowed

I'm trying to get my Android multipart image upload to work with the default blueimp PHP UploadHandler, which I'm using for the web version of my app.
It didn't work out of the box, so I experimented with the header of the requests.
I played around with it for quite a while, but since nothing worked I ended up firing up Wireshark and comparing the packets of the blueimp demo and the ones that are sent by the Android app.After some further tweaking, they look exactly the same (well the important parts):
Blueimp demo: http://i.imgur.com/T9styyR.png
Android MultipartEntity: http://i.imgur.com/OuDuyJ0.png
This is what my customized generate_response function returns:
Array
(
[0] => stdClass Object
(
[name] => 1387215600-9207
[size] => 97894
[type] => multipart/form-data; boundary=-----Don'tmindmeI'mjustaboundary
[error] => Filetype not allowed
)
)
It seems to load the whole packet instead of just it's multipart part.
Is there any way to fix that?
Here's how I create the request (not quite but these are the relevant lines):
public static String BOUNDARY = "-----Don'tmindmeI'mjustaboundary";
MultipartEntity entity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE, BOUNDARY, null);
File file = new File(params[2]); //params[2] contains the absolute path + filename
String filename = file.getName();
entity.addPart(filename, new FileBody(file, getMimeType(params[2]))); //getMimeType returns the MIME Type of the image e.g. image/png
HttpPost request = new HttpPost(params[0]); //params[0] contains the URL
request.setHeader("Content-Type", "multipart/form-data; boundary="+BOUNDARY);
request.setEntity(entity);
HttpResponse response = client.execute(request, context);
I've been working on this for hours and it's really driving me nuts.
What am I doing wrong?
Edit:
Nevermind I got it to work
I forgot to set the name of the form to files[], which is what the UploadHandler is looking for ...
So now it looks like this:
...
public static String BOUNDARY = "-----Don'tmindmeI'mjustaboundary";
...
MultipartEntity entity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE, BOUNDARY, null);
File file = new File(params[2]);
String filename = file.getName();
FileBody body = new FileBody(file, getMimeType(params[2]));
FormBodyPart part = new FormBodyPart("files[]", body);
part.addField("Content-Type", getMimeType(params[2]));
part.addField("Content-Disposition", "form-data; filename=\""+filename+"\"");
entity.addPart(part);
HttpPost request = new HttpPost(params[0]);
request.setHeader("Content-Type", "multipart/form-data; boundary="+BOUNDARY);
request.addHeader("Accept", "application/json, text/javascript, */*; q=0.01");
request.addHeader("Accept-Language", "en-US,en;q=0.8,de;q=0.6,es;q=0.4");
request.setEntity(entity);
HttpResponse response = client.execute(request, context);
...

Simulate clicking a submit button in Java

I am writing the program in Java, and i want to fill out the specified fields of form, simulate submit clicking, so get the result page. I am testing my idea on the url http://stu21.kntu.ac.ir/Login.aspx that have two fields txtusername and txtpassword. I am trying the code as follow but it does not return the result page for me. How can i do it ? What do i wrong in this code ?
DefaultHttpClient conn = new DefaultHttpClient();
conn = new DefaultHttpClient();
ArrayList<NameValuePair> pairs = new ArrayList<NameValuePair>();
pairs.add(new BasicNameValuePair("txtusername", "8810103"));
pairs.add(new BasicNameValuePair("txtpassword", "8810103"));
HttpPost httpPost = new HttpPost("http://stu21.kntu.ac.ir/Login.aspx");
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(pairs,
"UTF-8");
httpPost.setHeader(
"UserAgent",
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/535.19 (KHTML, like Gecko) Ubuntu/12.04 Chromium/18.0.1025.151 Chrome/18.0.1025.151 Safari/535.19");
httpPost.setEntity(entity);
HttpResponse response = conn.execute(httpPost);
InputStream is = response.getEntity().getContent();
RandomAccessFile raf = new RandomAccessFile(
"/home/hossein/Desktop/random.aspx", "rw");
raf.seek(0);
int bytes = 0;
byte[] buffer = new byte[1024];
while ((bytes = is.read(buffer)) != -1)
raf.write(buffer, 0, bytes);
raf.close();
is.close();
Sorry if my question duplicates with another threads, i can not find my solution on other threads.
Thanks In Advance :)
I think you need HTTPUnit. There is a good tutorial at javaworld.
Just look at the following example there :
public void testGoodLogin() throws Exception {
WebConversation conversation = new WebConversation();
WebRequest request = new GetMethodWebRequest( "http://www.meterware.com/servlet/TopSecret" );
WebResponse response = conversation.getResponse( request );
WebForm loginForm = response.getForms()[0];
request = loginForm.getRequest();
request.setParameter( "name", "master" );
// "clicking the button" programatically
response = conversation.getResponse( request );
assertTrue( "Login not accepted",
response.getText().indexOf( "You made it!" ) != -1 );
assertEquals( "Page title", "Top Secret", response.getTitle() );
}
I am sure that you can do your testing just like this.

Categories

Resources