I'm trying to access one of IBM Watson RESTful interfaces (speech to text) from a Java client using Apache HttpPost, but failing to upload a binary .wav input file properly.
The following 'curl' command works just fine, producing correct results:
curl -u "user:password" -H "content-type: audio/wav" --data-binary #"newfile.wav" "https://stream.watsonplatform.net/speech-to-text/api/v1/recognize" -X POST
The Java client below intends to replicate above curl functionality:
public void speech2text(String user, String password, String file_name) {
try {
String ulr_string = "https://stream.watsonplatform.net/speech-to-text/api/v1/recognize";
HttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(ulr_string);
httpPost.addHeader(BasicScheme.authenticate(
new UsernamePasswordCredentials(user, password), "UTF-8", false));
httpPost.addHeader("content-type", "audio/wav");
httpPost.addHeader("content-type", "multipart/form-data");
// httpPost.addHeader("transfer-encoding", "chunked");
File input_file = new File(file_name);
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
builder.addBinaryBody("upfile", input_file, ContentType.DEFAULT_BINARY, "c:\\Temp\\newfile.wav");
HttpEntity entity = builder.build();
httpPost.setEntity(entity);
System.out.println("executing request " + httpPost.getRequestLine());
Header headers[] = httpPost.getAllHeaders();
HttpResponse response = httpClient.execute(httpPost);
HttpEntity resEntity = response.getEntity();
System.out.println(response.getStatusLine());
if (resEntity != null) {
System.out.println(EntityUtils.toString(resEntity));
}
if (resEntity != null) {
EntityUtils.consume(resEntity);
}
httpClient.getConnectionManager().shutdown();
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
But the request fails, returning:
HTTP/1.1 400 Bad Request
{
"code_description": "Bad Request",
"code": 400,
"error": "unable to transcode data stream audio/wav -> audio/x-float-array "
}
Watson's API requires chunked transfer encoding for large files, but the sample I'm working with is pretty small.
Related
I have started to test http client apache API. I need it because I would like to send requests and to receive responses to virustotal API. Virus total API requires to parameters in the post request:
the api key value (a unique value for each user)
the file itself as I understood from their website.
For example:
>>> url = "https://www.virustotal.com/vtapi/v2/url/scan"
>>> parameters = {"url": "http://www.virustotal.com",
... "apikey": "-- YOUR API KEY --"}
>>> data = urllib.urlencode(parameters)
>>> req = urllib2.Request(url, data)
At the moment, I am trying to do the same thing in Java instead of Python. Here is a part of my source code commented to guide throughout the steps:
CloseableHttpClient httpClient = HttpClientBuilder.create().build();
//create post request
HttpPost request = new HttpPost("https://www.virustotal.com/vtapi/v2/file/scan");
//http json header
request.addHeader("content-type", "application/json");
String str = gson.toJson(param);
String fileName = UUID.randomUUID().toString() + ".txt";
try {
//API key
StringEntity entity = new StringEntity(str);
Writer writer = new BufferedWriter(new FileWriter(fileName));
writer.write(VirusDefinitionTest.malware());
request.setEntity(entity);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
FileBody fileBody = new FileBody(new File(fileName));
builder.addTextBody("my_file", fileName);
HttpEntity entity = builder.build();
request.setEntity(entity);
HttpResponse response;
try {
response = httpClient.execute(request);
...
Unfortunately, I receive HTTP/1.1 403 Forbidden. Obviously, the error is somewhere in the entities but I cannot find how to do it. Any help would be deeply welcomed.
This worked for me with Apache 4.5.2 HttpClient:
CloseableHttpClient httpclient = HttpClients.createDefault();
try {
HttpPost httppost = new HttpPost("https://www.virustotal.com/vtapi/v2/file/scan");
FileBody bin = new FileBody(new File("... the file here ..."));
// the API key here
StringBody comment = new StringBody("5ec8de.....", ContentType.TEXT_PLAIN);
HttpEntity reqEntity = MultipartEntityBuilder.create()
.addPart("apikey", comment)
.addPart("file", bin)
.build();
httppost.setEntity(reqEntity);
System.out.println("executing request " + httppost.getRequestLine());
CloseableHttpResponse response = httpclient.execute(httppost);
try {
System.out.println("----------------------------------------");
System.out.println(response.getStatusLine());
HttpEntity resEntity = response.getEntity();
if (resEntity != null) {
System.out.println("ToString:" + EntityUtils.toString(resEntity));
}
EntityUtils.consume(resEntity);
} finally {
response.close();
}
} finally {
httpclient.close();
}
The important part was the reqEntity which had to have two specifically named fields, "apikey", and "file". Running this with a valid API key gives me the expected response from the API.
The problem seems to be that first you add explicit "content-type" header which is "application/json" and at the end you send the Muiltipart entity. You need to add all the parameters and the file to the Muiltipart entity. Now the parameters are not send, because they are overwritten by Muiltipart entity:
CloseableHttpClient httpClient = HttpClientBuilder.create().build();
//create post request
HttpPost request = new HttpPost("https://www.virustotal.com/vtapi/v2/file/scan");
//http json header
request.addHeader("content-type", "application/json");
String str = gson.toJson(param);
String fileName = UUID.randomUUID().toString() + ".txt";
try {
//API key
StringEntity entity = new StringEntity(str);
Writer writer = new BufferedWriter(new FileWriter(fileName));
writer.write(VirusDefinitionTest.malware());
// --> You set parameters here !!!
request.setEntity(entity);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
FileBody fileBody = new FileBody(new File(fileName));
builder.addTextBody("my_file", fileName);
HttpEntity entity = builder.build();
// --> You overwrite the parameters here !!!
request.setEntity(entity);
HttpResponse response;
try {
response = httpClient.execute(request);
I am new in android and java I want to get access data from this API.
All we need to do convert this into java code
curl --include --header "X-Access-Token: YOUR_API_TOKEN_HERE" "http://api.travelpayouts.com/v2/prices/latest?currency=rub&period_type=year&page=1&limit=30&show_to_affiliates=true&sorting=price&trip_class=0"
Your given API has a header and basic GET format. This can be converted in Java easily.
See the code example,
public String httpGet(String s, String api_token) {
String url = s;
StringBuilder body = new StringBuilder();
httpclient = new DefaultHttpClient(); // create new httpClient
HttpGet httpGet = new HttpGet(url); // create new httpGet object
httpGet.setHeader("X-Access-Token", api_token);
try {
response = httpclient.execute(httpGet); // execute httpGet
StatusLine statusLine = response.getStatusLine();
int statusCode = statusLine.getStatusCode();
if (statusCode == HttpStatus.SC_OK) {
// System.out.println(statusLine);
body.append(statusLine + "\n");
HttpEntity e = response.getEntity();
String entity = EntityUtils.toString(e);
body.append(entity);
} else {
body.append(statusLine + "\n");
// System.out.println(statusLine);
}
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
httpGet.releaseConnection(); // stop connection
}
return body.toString(); // return the String
}
Now call the function and pass the url along with your header API token,
httpGet("http://api.travelpayouts.com/v2/prices/latest?currency=rub&period_type=year&page=1&limit=30&show_to_affiliates=true&sorting=price&trip_class=0", YOUR_API_TOKEN)
I have following situation:
Sending http post (post data contains json string) request to my remote server.
Getting http post response from my server in json: {"result":true}
Disconnecting all internet connections in my tablet.
Repeating post request described in step 1.
Getting the same cached "response" - {"result":true} which I didn't expected to get... I don't want that my http client would cache any data. I expect to get null or something like this.
How to prevent http client caching data?
My service handler looks like this:
public String makeServiceCall(String url, int method,
List<NameValuePair> params, String requestAction) {
try {
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpEntity httpEntity = null;
HttpResponse httpResponse = null;
// Checking http request method type
if (method == POST) {
HttpPost httpPost = new HttpPost(url);
// adding post params
if (params != null) {
httpPost.setEntity(new UrlEncodedFormEntity(params));
}
httpResponse = httpClient.execute(httpPost);
}
else if (method == GET) {
// appending params to url
if (params != null) {
String paramString = URLEncodedUtils
.format(params, "utf-8");
url += "?" + paramString;
}
HttpGet httpGet = new HttpGet(url);
httpResponse = httpClient.execute(httpGet);
}
httpEntity = httpResponse.getEntity();
response = EntityUtils.toString(httpEntity);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
// Toast.makeText(Globals.getContext(), "check your connection", Toast.LENGTH_SHORT).show();
}
return response;
}
I just noticed that response is a member variable. Why do you need a member variable to return this result. You're probably returning the same result on the 2nd try. Re-throw the exception that you catch instead and let the caller handle it.
I have this command.
# curl --header "Authorization: key=$api_key" --header Content-Type:"application/json" https://android.googleapis.com/gcm/send -d "{\"registration_ids\":[\"ABC\"]}"
it is sending push notification in my device. Now I am trying java to sending it but my code is not working.
String body = "{\"registration_ids\":[\"ABC\"]}";
HttpPost httppost = new HttpPost("https://android.googleapis.com/gcm/send");
StringEntity stringentity = new StringEntity(body, "UTF-8");
httppost.addHeader("Content-Type","application/json");
httppost.addHeader("Authorization: key", "AIza*********YUI");
httppost.setEntity(stringentity);
HttpClient httpclient = new DefaultHttpClient();
HttpResponse response;
try {
response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
String strresponse = null;
if (entity != null) {
strresponse = EntityUtils.toString(entity);
System.out.println("strresponse = "+strresponse);
}
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
I am confuse what i am missing. This doc http://developer.android.com/google/gcm/http.html#request told that i needs to send header with body.
Based on your curl example, this should be your Authorization header:
httppost.addHeader("Authorization", "key=AIza*********YUI");
This should resolve your issue. I just confirmed this header with the referenced documentation.
I need a simple code example of sending http post request with post parameters that I get from form inputs.
I have found Apache HTTPClient, it has very reach API and lots of sophisticated examples, but I couldn't find a simple example of sending http post request with input parameters and getting text response.
Update: I'm interested in Apache HTTPClient v.4.x, as 3.x is deprecated.
Here's the sample code for Http POST, using Apache HTTPClient API.
import java.io.InputStream;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.PostMethod;
public class PostExample {
public static void main(String[] args){
String url = "http://www.google.com";
InputStream in = null;
try {
HttpClient client = new HttpClient();
PostMethod method = new PostMethod(url);
//Add any parameter if u want to send it with Post req.
method.addParameter("p", "apple");
int statusCode = client.executeMethod(method);
if (statusCode != -1) {
in = method.getResponseBodyAsStream();
}
System.out.println(in);
} catch (Exception e) {
e.printStackTrace();
}
}
}
I pulled this code from an Android project by Andrew Gertig that I have used in my application. It allows you to do an HTTPost. If I had time, I would create an POJO example, but hopefully, you can dissect the code and find what you need.
Arshak
https://github.com/AndrewGertig/RubyDroid/blob/master/src/com/gertig/rubydroid/AddEventView.java
private void postEvents()
{
DefaultHttpClient client = new DefaultHttpClient();
/** FOR LOCAL DEV HttpPost post = new HttpPost("http://192.168.0.186:3000/events"); //works with and without "/create" on the end */
HttpPost post = new HttpPost("http://cold-leaf-59.heroku.com/myevents");
JSONObject holder = new JSONObject();
JSONObject eventObj = new JSONObject();
Double budgetVal = 99.9;
budgetVal = Double.parseDouble(eventBudgetView.getText().toString());
try {
eventObj.put("budget", budgetVal);
eventObj.put("name", eventNameView.getText().toString());
holder.put("myevent", eventObj);
Log.e("Event JSON", "Event JSON = "+ holder.toString());
StringEntity se = new StringEntity(holder.toString());
post.setEntity(se);
post.setHeader("Content-Type","application/json");
} catch (UnsupportedEncodingException e) {
Log.e("Error",""+e);
e.printStackTrace();
} catch (JSONException js) {
js.printStackTrace();
}
HttpResponse response = null;
try {
response = client.execute(post);
} catch (ClientProtocolException e) {
e.printStackTrace();
Log.e("ClientProtocol",""+e);
} catch (IOException e) {
e.printStackTrace();
Log.e("IO",""+e);
}
HttpEntity entity = response.getEntity();
if (entity != null) {
try {
entity.consumeContent();
} catch (IOException e) {
Log.e("IO E",""+e);
e.printStackTrace();
}
}
Toast.makeText(this, "Your post was successfully uploaded", Toast.LENGTH_LONG).show();
}
HTTP POST request example using Apache HttpClient v.4.x
HttpClient httpClient = HttpClients.createDefault();
HttpPost httpPost = new HttpPost(url);
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.addTextBody("param1", param1Value, ContentType.TEXT_PLAIN);
builder.addTextBody("param2", param2Value, ContentType.TEXT_PLAIN);
HttpEntity multipart = builder.build();
httpPost.setEntity(multipart);
HttpResponse response = httpClient.execute(httpMethod);
http://httpunit.sourceforge.net/doc/cookbook.html
use PostMethodWebRequest and setParameter method
shows a very simple exapmle where you do post from Html page, servlet processes it and sends a text response..
http://java.sun.com/developer/onlineTraining/Programming/BasicJava1/servlet.html