There is the following code:
private static String doPostRequest(List<NameValuePair> params, String url) throws ClientProtocolException, IOException {
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(url);
httppost.setEntity(new UrlEncodedFormEntity(params, "UTF-8"));
HttpResponse response = httpclient.execute(httppost);
return getContentFromInputStream(response.getEntity().getContent());
}
private static String getContentFromInputStream(InputStream is) throws IOException {
String line;
StringBuilder sb=new StringBuilder();
BufferedReader reader=new BufferedReader(new InputStreamReader(is));
while((line=reader.readLine())!=null) {
sb.append(line);
}
reader.close();
return sb.toString();
}
So, how can I add some image (for example, File f) to my POST request? Thanks in advance.
This was part of Servlet 3's "multi part file upload".
You would build up a blob of the image then post it to a Servlet 3 endpoint.
Take a look at the examples here and here
If you plan on using Spring, that has some really nice easy annotations to define your controllers which will work with file upload you can see here
You can use MultipartRequestEntity .
File f = new File(filePath);
PostMethod postMessage = new PostMethod(urlString);
Part[] parts = {
new StringPart("param", "value"),
new FilePart(f.getName(), f)
};
postMessage.setRequestEntity(new MultipartRequestEntity(parts, postMessage.getParams()));
HttpClient client = new HttpClient();
int status = client.executeMethod(postMessage);
Related
I want to automate REST API using selenium(java), is it possible ? if it have header and body part in json form
In Java you can use ApacheHttpClient for example lerned from https://www.mkyong.com/java/apache-httpclient-examples/
For instance a method in ApacheHttpClientPost could be like that:
public static String post(String tokenMobile, String method, String version, String body) throws Exception{
try {
HttpClient httpClient = HttpClientBuilder.create().build();
URIBuilder builder = new URIBuilder();
builder.setScheme("https").setHost(host).setPath(method)
.setParameter("", ""); //Params
URI uri = builder.build();
HttpGet httpget = new HttpGet(uri);
HttpPost postRequest = new HttpPost(httpget.getURI()); //Header
postRequest.addHeader("Content-Type", "application/json");
postRequest.addHeader("version", version);
postRequest.addHeader("Authorization", "Bearer "+tokenMobile);
StringEntity input = new StringEntity(body); //Body in json
input.setContentType("application/json");
postRequest.setEntity(input);
HttpResponse response = httpClient.execute(postRequest);
BufferedReader br = new BufferedReader(
new InputStreamReader((response.getEntity().getContent())));
String output;
while ((output = br.readLine()) != null) {
StringBuilder stringBuilder = new StringBuilder();
outputs = stringBuilder.append(output).toString();
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return outputs;
}
Selenium is a tool which is designed for automation of UI or e2e test cases. You can integrate the Selenium test case with API test cases but that is always a bad idea.
Try something like Rest-Assured, Postman, HTTPClient if you want to automate the API test cases.
I followed the example here (Incoming webhook with Python), which sends a simple message to a Hangouts chat room and works as expected
from httplib2 import Http
from json import dumps
def main():
url = 'https://chat.googleapis.com/v1/spaces/AAAAUfABqBU/messages?key=<WEBHOCK-KEY>'
bot_message = {
'text' : 'Hello from Python script!'}
message_headers = { 'Content-Type': 'application/json; charset=UTF-8'}
http_obj = Http()
response = http_obj.request(
uri=url,
method='POST',
headers=message_headers,
body=dumps(bot_message),
)
print(response)
if __name__ == '__main__':
main()
Now I want achive the same simple thing using Java and tried it with this code
private void sendPost() throws IOException {
String url = "https://chat.googleapis.com/v1/spaces/AAAAUfABqBU/messages?key=<WEBHOCK-KEY>";
final HttpClient client = new DefaultHttpClient();
final HttpPost request = new HttpPost(url);
final HttpResponse response = client.execute(request);
request.addHeader("Content-Type", "application/json; charset=UTF-8");
final StringEntity params = new StringEntity("{\"text\":\"Hello from Java!\"}", ContentType.APPLICATION_FORM_URLENCODED);
request.setEntity(params);
final BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
StringBuffer result = new StringBuffer();
String line;
while ((line = rd.readLine()) != null) {
result.append(line);
}
System.out.println(result.toString());
}
But this leads to an error message saying
{
"error": {
"code": 400,
"message": "Message cannot be empty. Discarding empty create message request in spaces/AAAAUfABqBU.",
"status": "INVALID_ARGUMENT"
}
}
I assume there is something wrong with the way I add the json object. Does anybody see the mistake?
Kind of dump, but moving the line final HttpResponse response = client.execute(request); after setting the request body solves the issue.
private void sendPost() throws IOException {
String url = "https://chat.googleapis.com/v1/spaces/AAAAUfABqBU/messages?key=<WEBHOCK-KEY>";
final HttpClient client = new DefaultHttpClient();
final HttpPost request = new HttpPost(url);
// FROM HERE
request.addHeader("Content-Type", "application/json; charset=UTF-8");
final StringEntity params = new StringEntity("{\"text\":\"Hello from Java!\"}", ContentType.APPLICATION_FORM_URLENCODED);
request.setEntity(params);
// TO HERE
final HttpResponse response = client.execute(request);
final BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
StringBuffer result = new StringBuffer();
String line;
while ((line = rd.readLine()) != null) {
result.append(line);
}
System.out.println(result.toString());
}
Order sometimes does matter :)
I try to connect to the poloniex.com API https://poloniex.com/support/api/ which says:
(All calls to the trading API are sent via HTTP POST to https://poloniex.com/tradingApi and must contain the following headers:
Key - Your API key.
Sign - The query's POST data signed by your key's "secret" according to the HMAC-SHA512 method.
Additionally, all queries must include a "nonce" POST parameter. The nonce parameter is an integer which must always be greater than the previous nonce used.)
But I always get
{"error":"Invalid
API key\/secret pair."}
My hmac512Digest works fine, I've checked it.
There must be something wrong in my code.
Can someone please Help?
public class Pol2 {
public static String POLONIEX_SECRET_KEY = "12345";
public static String POLONIEX_API_KEY = "ABX";
public static void main(String[] args) {
try {
accessPoloniex();
} catch (IOException e) {
e.printStackTrace();
}
}
public static final void accessPoloniex() throws IOException {
final String nonce = String.valueOf(System.currentTimeMillis());
String connectionString = "https://poloniex.com/tradingApi";
String queryArgs = "command=returnBalances";
String hmac512 = hmac512Digest(queryArgs, POLONIEX_SECRET_KEY);
// Produce the output
ByteArrayOutputStream out = new ByteArrayOutputStream();
Writer writer = new OutputStreamWriter(out, "UTF-8");
writer.append(queryArgs);
writer.flush();
CloseableHttpClient httpClient = HttpClients.createDefault();
HttpPost post = new HttpPost(connectionString);
post.addHeader("Key", POLONIEX_API_KEY); //or setHeader?
post.addHeader("Sign", hmac512); //or setHeader?
post.setEntity(new ByteArrayEntity(out.toByteArray()));
List<NameValuePair> params = new ArrayList<>();
params.add(new BasicNameValuePair("command", "returnBalances"));
params.add(new BasicNameValuePair("nonce", nonce));
CloseableHttpResponse response = null;
Scanner in = null;
try {
post.setEntity(new UrlEncodedFormEntity(params));
response = httpClient.execute(post);
HttpEntity entity = response.getEntity();
in = new Scanner(entity.getContent());
while (in.hasNext()) {
System.out.println(in.next());
}
EntityUtils.consume(entity);
} finally {
in.close();
response.close();
}
}
}
I struggled with this myself and finally got it to work. Here's a very basic, working example:
public class PoloTest {
public static void main(String[] args) throws NoSuchAlgorithmException, InvalidKeyException, ClientProtocolException, IOException {
String key = "YOUR API KEY HERE";
String secret = "YOUR API SECRET HERE";
String url = "https://poloniex.com/tradingApi";
String nonce = String.valueOf(System.currentTimeMillis());
String queryArgs = "command=returnBalances&nonce=" + nonce;
Mac shaMac = Mac.getInstance("HmacSHA512");
SecretKeySpec keySpec = new SecretKeySpec(secret.getBytes(), "HmacSHA512");
shaMac.init(keySpec);
final byte[] macData = shaMac.doFinal(queryArgs.getBytes());
String sign = Hex.encodeHexString(macData);
CloseableHttpClient httpClient = HttpClients.createDefault();
HttpPost post = new HttpPost(url);
post.addHeader("Key", key);
post.addHeader("Sign", sign);
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("command", "returnBalances"));
params.add(new BasicNameValuePair("nonce", nonce));
post.setEntity(new UrlEncodedFormEntity(params));
CloseableHttpResponse response = httpClient.execute(post);
HttpEntity responseEntity = response.getEntity();
System.out.println(response.getStatusLine());
System.out.println(EntityUtils.toString(responseEntity));
}
}
I've looked into the Python example that they've linked to on their page. The nonce parameter must be MAC'ed along with the command and the final MAC is appended in Hex-encoded format:
String queryArgs = "command=returnBalances&nonce=" + nonce;
String hmac512 = hmac512Digest(queryArgs, POLONIEX_SECRET_KEY);
Also, the following
ByteArrayOutputStream out = new ByteArrayOutputStream();
Writer writer = new OutputStreamWriter(out, "UTF-8");
writer.append(queryArgs);
writer.flush();
//...
post.setEntity(new ByteArrayEntity(out.toByteArray()));
can be reduced to
post.setEntity(new ByteArrayEntity(queryArgs.getBytes("UTF-8")));
The nonce parameter must be MAC'ed along with the command...
If a hash is a one way function, and Polo have no idea what nonce I might choose, (or when, if i'm using UTC), how can Polo ever extract anything meaningful from what I send them.
I am getting the following error:
java.lang.IllegalStateException: Target host must not be null, or set in parameters. scheme=null, host=null, path=CONNECT_URL
Following are my Global variables:
String CONNECT_URL = "http://api.openweathermap.org/data/2.5/weather?q=Mumbai";
int LAST_INDEX;
String NAME;
String TYPE;
String GREETING_YEAR;
String GREETING_GENERAL;
String RADIO_TYPE;
InputStream ins = null;
String result = null;
following is my parse function:
public void parse(){
DefaultHttpClient http = new DefaultHttpClient(new BasicHttpParams());
System.out.println("URL is: "+CONNECT_URL);
HttpPost httppost = new HttpPost("CONNECT_URL");
httppost.setHeader("Content-type", "application/json");
try{
HttpResponse resp = http.execute(httppost);
HttpEntity entity = resp.getEntity();
ins = entity.getContent();
BufferedReader bufread = new BufferedReader(new InputStreamReader(ins, "UTF-8"), 8);
StringBuilder sb = new StringBuilder();
String line = null;
while((line = bufread.readLine()) != null){
sb.append(line +"\n");
}
result = sb.toString();
System.out.println("Result: "+result);
}catch (Exception e){
System.out.println("Error: "+e);
}finally{
try{
if(ins != null){
ins.close();
}
}catch(Exception squish){
System.out.println("Squish: "+squish);
}
}
}
I tried to refator it with other similar questions on SO, but my URL seems to be okay and it returns the JSON once I check the same URL from a browser, any hints?
You´ve got
HttpPost httppost = new HttpPost("CONNECT_URL");
and looking to your code should be like
HttpPost httppost = new HttpPost(CONNECT_URL);
You are passing "CONNECT_URL" in HttpPost object which is wrong. Use
HttpPost httppost = new HttpPost(CONNECT_URL) //instead of HttpPost("CONNECT_URL")
HttpPost httppost = new HttpPost("CONNECT_URL");
should be
HttpPost httppost = new HttpPost(CONNECT_URL);
As a side note, Java convention dictates that variables are camel case (connectUrl) and constants are uppercase (CONNECT_URL).
I think the problem comes from this line:
HttpPost httppost = new HttpPost("CONNECT_URL");
You are passing the string "CONNECT_URL" instead of passing the variable CONNECT_URL :)
I am trying to upload file but i am not doing it through html form. QueryParam and PathParam can't be used. So can anyone tell how to pass stream.
My HttPClient looks like:
try
{
HttpClient httpclient = new DefaultHttpClient();
InputStream stream=new FileInputStream(new File("C:/localstore/ankita/Desert.jpg"));
String url="http://localhost:8080/Cloud/webresources/fileupload";
HttpPost httppost = new HttpPost(url);
HttpResponse response = httpclient.execute(httppost);
}
catch(Exception e){}
and my web service class looks somewhat like:
#Path("/fileupload")
public class UploadFileService {
#POST
#Consumes(MediaType.APPLICATION_OCTET_STREAM)
public Response uploadFile(InputStream in) throws IOException
{
String uploadedFileLocation = "c://filestore/Desert.jpg" ;
// save it
saveToFile(in, uploadedFileLocation);
String output = "File uploaded via Jersey based RESTFul Webservice to: " + uploadedFileLocation;
return Response.status(200).entity(output).build();
}
// save uploaded file to new location
private void saveToFile(InputStream uploadedInputStream,String uploadedFileLocation)
{
try {
OutputStream out = null;
int read = 0;
byte[] bytes = new byte[1024];
out = new FileOutputStream(new File(uploadedFileLocation));
while ((read = uploadedInputStream.read(bytes)) != -1)
{
out.write(bytes, 0, read);
}
out.flush();
out.close();
} catch (IOException e)
{
e.printStackTrace();
}
}
}
Can anyone help??
String url="http://localhost:8080/Cloud/webresources/fileupload";
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(url);
InputStreamEntity reqEntity = new InputStreamEntity(new FileInputStream(new File("C:/localstore/ankita/Desert.jpg")), -1);
reqEntity.setContentType("binary/octet-stream");
reqEntity.setChunked(true); // Send in multiple parts if needed
httppost.setEntity(reqEntity);
HttpResponse response = httpclient.execute(httppost);
How web service will look like?
You can't do it that way. You can't pass a stream in an HTTP request, because streams are not serializable.
The way to do this is to is create an HttpEntity to wrap the stream (e.g. an InputStreamEntity) then attach it to the HttpPOST object using setEntity. Then the POST is sent, the client will read from your stream and send the bytes as the request's "POST data".