How to keep chaining Completable Futures? - java

Have the following code:
public class NewMain {
public static void main(String[] args)
{
try
{
NewMain nm =new NewMain();
nm.run(args);
}
catch (Exception ex)
{
System.err.println( ex.getMessage() );
}
}
public void run (String[] args) throws Exception
{
System.out.println("testing async");
ExecutorService ex = Executors.newFixedThreadPool(10);
CompletableFuture<String> promise = CompletableFuture.supplyAsync(sendPost, ex);
promise.thenAccept(MuestraResultado);
System.out.println("done testing async");
}
Consumer<String> MuestraResultado = (String str) ->
{
System.err.println( str.toUpperCase() );
};
Supplier<String> sendPost = ()-> {
try
{
URL url = new URL("https://myspace.co/app/a_method");
HttpURLConnection http = (HttpURLConnection) url.openConnection();
http.setRequestMethod("POST");
http.setDoOutput(true);
http.setRequestProperty("Accept", "application/json");
http.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
String data = "token=2dasdfe&id=1";
byte[] out = data.getBytes(StandardCharsets.UTF_8);
OutputStream stream = http.getOutputStream();
stream.write(out);
System.out.println(http.getResponseCode() + " " + http.getResponseMessage());
http.disconnect();
}
catch( IOException ex)
{
System.out.println(ex.getMessage());
}
return "Done Post";
};
}
This code works perfect for me as it works asynchronously, console throws the following:
testing async
done testing async
200 200
DONE POST
However, I would like to keep chaining various async functions that depends from values obtained from the previous functions. Something like in javascript:
function().then(function(res)
{
function_two(res).then(function(res_two))
{
function_three(res_two).then(function(res_three))
{
etc...
});
});
});
But I dont seem to understand the underlying objects that works beneath CompletableFutures, since thenApply and ThenCompose doesnt espect suppliers...
EDIT
Just did the following...
public void run (String[] args) throws Exception
{
System.out.println("testing async");
ExecutorService ex = Executors.newFixedThreadPool(10);
CompletableFuture<String> promise = CompletableFuture.supplyAsync(sendPost, ex);
promise.thenApply((val)->
{
return secondfunc(val);
}).thenApply( (val) ->
{
return thirdfunc(val);
}).thenAccept(val->System.out.println(val));
System.out.println("done testing async");
}
Consumer<String> MuestraResultado = (String str) ->
{
System.err.println( str.toUpperCase() );
};
Supplier<String> sendPost = ()-> {
try
{
URL url = new URL("https://myspace.co/app/a_method");
HttpURLConnection http = (HttpURLConnection) url.openConnection();
http.setRequestMethod("POST");
http.setDoOutput(true);
http.setRequestProperty("Accept", "application/json");
http.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
String data = "token=2dasdfe&id_logins=1";
byte[] out = data.getBytes(StandardCharsets.UTF_8);
OutputStream stream = http.getOutputStream();
stream.write(out);
System.out.println(http.getResponseCode() + " " + http.getResponseMessage());
http.disconnect();
}
catch( IOException ex)
{
System.out.println(ex.getMessage());
}
return "Done Post";
};
String secondfunc(String secondStr)
{
try
{
URL url = new URL("https://myspace.co/app/a_method");
HttpURLConnection http = (HttpURLConnection) url.openConnection();
http.setRequestMethod("POST");
http.setDoOutput(true);
http.setRequestProperty("Accept", "application/json");
http.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
String data = "token=2dasdfe&id_logins=1";
byte[] out = data.getBytes(StandardCharsets.UTF_8);
OutputStream stream = http.getOutputStream();
stream.write(out);
System.out.println(http.getResponseCode() + " " + http.getResponseMessage());
http.disconnect();
}
catch( IOException ex)
{
System.out.println(ex.getMessage());
}
return secondStr.concat( "Done Post two" );
}
String thirdfunc(String thirdStr)
{
try
{
URL url = new URL("https://myspace.co/app/a_method");
HttpURLConnection http = (HttpURLConnection) url.openConnection();
http.setRequestMethod("POST");
http.setDoOutput(true);
http.setRequestProperty("Accept", "application/json");
http.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
String data = "token=2dasdfe&id_logins=1";
byte[] out = data.getBytes(StandardCharsets.UTF_8);
OutputStream stream = http.getOutputStream();
stream.write(out);
System.out.println(http.getResponseCode() + " " + http.getResponseMessage());
http.disconnect();
}
catch( IOException ex)
{
System.out.println(ex.getMessage());
}
return thirdStr.concat( "Done Post three" );
}
And it worked... though I dont know if it is the best approach or practice...
Results:
testing async
done testing async
200 200
200 200
200 200
Done PostDone Post twoDone Post three

Related

How to send post request in java with a JSON body

I am confused as to how to send a post request in Java with JSON parameters. I have seen many examples that use HttpPost library which I can not access. Below is my code:
public class endpointtest {
public String endpoint(String urlStr, String username) {
final StringBuilder response = new StringBuilder();
try {
//creating the connection
URL url = new URL(urlStr);
HttpClient client = HttpClient.newHttpClient();
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoOutput(true);
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "application/json");
connection.connect();
//builds the post body, adds parameters
final DataOutputStream out = new DataOutputStream(connection.getOutputStream());
//out.writeBytes(toJSON(globalId));
out.flush();
out.close();
//Reading the response
BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String inputline;
while ((inputline = in.readLine()) != null) {
response.append(inputline);
}
in.close();
connection.getResponseCode();
connection.disconnect();
} catch (final Exception ex) {
ex.printStackTrace();
System.out.println(" error ");
}
return response.toString();
}
}
class main {
public static void main(String[] args){
endpointtest ep = new endpointtest();
ep.endpoint("localhost:8080/endpoint","""
{
"name": "mike",
"Id": "123"
}
""");
}
}
I am trying to pass the json in the main method (I know I am not doing it right), and was wondering as to how I would do this correctly.
This is the simplest way to do it.
public class Main {
public static void main(String[] args) throws IOException {
String apiUrl = "http://myserver/rest/V1.0/manage/export"; // Your api/http link
String userName = "admin"; // Your username
String password = "adminpro"; // Your password
sendRequest(basicUrl, userName, password);
}
public static void sendRequest(String apiurl,String userName,String password){
try{
URL url = new URL(apiurl);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setDoOutput(true);
connection.setRequestProperty("Content-Type","application/json");
connection.setRequestProperty("Accept", "application/json");
connection.setRequestProperty("Authorization", "Basic " + Base64.getEncoder().encodeToString((userName + ":" + password).getBytes()));
String payload = "{\"sampleKey\":\"sampleValue\"}";// This should be your json body i.e. {"Name" : "Mohsin"}
byte[] out = payload.getBytes(StandardCharsets.UTF_8);
OutputStream stream = connection.getOutputStream();
stream.write(out);
System.out.println(connection.getResponseCode() + " " + connection.getResponseMessage()); // THis is optional
connection.disconnect();
}catch (Exception e){
System.out.println(e);
System.out.println("Failed successfully");
}
}
}
This Question is asked before here:
HTTP POST using JSON in Java
See it and comment this if you face any problem.

Upload an attachment to azure devops [REST API]

I'm having a hard time adding a attachments in my azure devops repo via api...
public static void putAttachments(Integer id) {
try {
URL url = new URL(
"https://dev.azure.com/marcoparra0034/AgileFr/_apis/wit/attachments?api-version=5.1&fileName=imageAs.png");
HttpURLConnection con = ResApiMain.apiConnectionAttachments(PAT, url);
File file = new File("C:\\Users\\marco.parra\\Pictures\\Screenshots\\new.png");
String base64Image = encodeFileToBase64Binary(file);
// String jsonInputString = "[{\"op\":\"add\",\"path\":\"/fields/System.Title\",\"value\":\"" + "tpain"
// + "\"}]";
base64Image = "[" + base64Image + "]";
System.out.println("Base xs" + base64Image);
try (OutputStream os = con.getOutputStream()) {
byte[] input = Base64.decodeBase64(base64Image.getBytes("utf-8"));
System.out.println(new String(input));
os.write(input, 0, input.length);
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
try (BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream(), "utf-8"))) {
StringBuilder response = new StringBuilder();
String responseLine = null;
while ((responseLine = br.readLine()) != null) {
response.append(responseLine.trim());
}
System.out.println(response.toString());
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
con.disconnect();
} catch (Exception ex) {
}
This is the connection method
public static HttpURLConnection apiConnectionAttachments(String PAT, URL url) {
HttpURLConnection con = null;
try {
String AuthStr = ":" + PAT;
Base64 base64 = new Base64();
String encodedPAT = new String(base64.encode(AuthStr.getBytes()));
con = (HttpURLConnection) url.openConnection();
con.setRequestProperty("Authorization", "Basic " + encodedPAT);
con.setDoOutput(true);
System.out.println("URL - " + url.toString());
System.out.println("PAT - " + encodedPAT);
// Image Requierements
// con.setRequestProperty("Content-Type", "image/jpeg");
con.setDoInput(true);
con.setUseCaches(false);
con.setRequestProperty("X-HTTP-Method-Override", "PATCH");
con.setRequestMethod("POST");
con.setRequestProperty("Content-Type", "application/octet-stream");
// con.setRequestProperty("Accept", "application/json");
} catch (Exception e) {
System.out.println(e.getMessage());
}
return con;
}
When i run this it show the next error code
Server returned HTTP response code: 405 for URL: https://dev.azure.com/marcoparra0034/AgileFr/_apis/wit/attachments?api-version=5.1&fileName=imageAs.png
Update i see how to work with python and c# but i canĀ“t follow this logic to create an attachment
https://github.com/Microsoft/azure-devops-python-api/blob/1bacd2a3f0128a6d184cf75e2c6f8859d46f270a/vsts/vsts/work_item_tracking/v4_1/work_item_tracking_client.py#L56
Expectations Example
{
"id": "a5cedde4-2dd5-4fcf-befe-fd0977dd3433",
"url": "https://dev.azure.com/fabrikam/_apis/wit/attachments/a5cedde4-2dd5-4fcf-befe-fd0977dd3433?fileName=imageAsFileAttachment.png"
}
https://learn.microsoft.com/en-us/rest/api/azure/devops/wit/attachments/create?view=azure-devops-rest-5.1
Any help would be appreciated....
I solve this issue commenting line con.setRequestProperty("X-HTTP-Method-Override", "PATCH");

Search Tweets with pure Java 400 get Bad Request

I tried use search tweets use twitter search api.
But when i get bearer token then send request to
/1.1/search/tweets.json?count=2
Its response is 400 (Bad Request)
I don't know how is wrong... Anyone can help me ??
Here is my Code all from http://www.coderslexicon.com/demo-of-twitter-application-only-oauth-authentication-using-java/
I also watch Application-only authentication but still don't know why.
Hope someone can tell me ....
private final static String getTokenURL = "https://api.twitter.com/oauth2/token";
private static String bearerToken;
static final String ACCESS_TOKEN = "1111111112-H************************************s";
static final String ACCESS_SECRET = "S************************************n";
static final String CONSUMER_KEY = "q************************************g";
static final String CONSUMER_SECRET = "Q************************************a";
public static void main(String[] args) {
new Thread(new Runnable() {
#Override
public void run() {
try {
bearerToken = requestBearerToken(getTokenURL);
searchTweets("https://api.twitter.com/1.1/search/tweets.json?count=2");
} catch (IOException e) {
System.out.println("IOException e");
e.printStackTrace();
}
}
}).start();
}
private static String encodeKeys(String consumerKey, String consumerSecret) {
try {
String encodedConsumerKey = URLEncoder.encode(consumerKey, "UTF-8");
String encodedConsumerSecret = URLEncoder.encode(consumerSecret,
"UTF-8");
String fullKey = encodedConsumerKey + ":" + encodedConsumerSecret;
byte[] encodedBytes = Base64.encodeBase64(fullKey.getBytes());
return new String(encodedBytes);
} catch (UnsupportedEncodingException e) {
return new String();
}
}
private static String requestBearerToken(String endPointUrl)
throws IOException {
HttpsURLConnection connection = null;
String encodedCredentials = encodeKeys(CONSUMER_KEY, CONSUMER_SECRET);
try {
URL url = new URL(endPointUrl);
connection = (HttpsURLConnection) url.openConnection();
System.out.println(connection);
connection.setDoOutput(true);
connection.setDoInput(true);
connection.setRequestMethod("POST");
connection.setRequestProperty("Host", "api.twitter.com");
connection.setRequestProperty("User-Agent", "MwTestTwitterAPI");
connection.setRequestProperty("Authorization", "Basic "
+ encodedCredentials);
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
connection.setRequestProperty("Content-Length", "29");
connection.setUseCaches(false);
writeRequest(connection, "grant_type=client_credentials");
System.out.println(connection.getResponseCode());
System.out.println(connection.getResponseMessage());
String result = readResponse(connection);
JSONObject jsonResult=new JSONObject(result);
if (jsonResult.get("token_type") != null && jsonResult.get("token_type").equals("bearer") ) {
return jsonResult.getString("access_token");
}
return new String();
} catch (MalformedURLException | JSONException e) {
throw new IOException("Invalid endpoint URL specified.", e);
} finally {
if (connection != null) {
connection.disconnect();
}
}
}
private static String searchTweets(String endPointUrl) throws IOException {
HttpsURLConnection connection = null;
try {
URL url = new URL(endPointUrl);
connection = (HttpsURLConnection) url.openConnection();
connection.setDoOutput(true);
connection.setDoInput(true);
connection.setRequestMethod("GET");
connection.setRequestProperty("Host", "api.twitter.com");
connection.setRequestProperty("User-Agent", "MwTestTwitterAPI");
connection.setRequestProperty("Authorization", "Bearer " + bearerToken);
connection.setUseCaches(false);
String result = readResponse(connection);
System.out.println("fetchTimelineTweet---result:"+result);
if (result != null || result.equals("")) {
return result;
}
return new String();
}
catch (MalformedURLException e) {
throw new IOException("Invalid endpoint URL specified.", e);
}
finally {
if (connection != null) {
connection.disconnect();
}
}
}
// Writes a request to a connection
private static boolean writeRequest(HttpURLConnection connection,
String textBody) {
try {
BufferedWriter wr = new BufferedWriter(new OutputStreamWriter(
connection.getOutputStream()));
wr.write(textBody);
wr.flush();
wr.close();
return true;
} catch (IOException e) {
return false;
}
}
// Reads a response for a given connection and returns it as a string.
private static String readResponse(HttpURLConnection connection) {
try {
StringBuilder str = new StringBuilder();
BufferedReader br = new BufferedReader(new InputStreamReader(
connection.getInputStream()));
String line = "";
while ((line = br.readLine()) != null) {
str.append(line + System.getProperty("line.separator"));
}
return str.toString();
} catch (IOException e) {
return new String();
}
}
You're missing a query variable q, which is a required parameter.
Try changing your request url to: https://api.twitter.com/1.1/search/tweets.json?count=2&q=test

Socket TimeOutException-Connection timed out

I am trying to connect with Tomcat Server(IP address-192.168.1.120 which is stored in Config.java(static variable APP_SERVER_URL)) but it is giving me socket timeout exception .
How to resolve it.Please help.
But when I
public class ShareExternalServer {
public String shareRegIdWithAppServer(Map<String, String> paramsMap) {
String result = "";
try {
URL serverUrl = null;
try {
serverUrl = new URL(Config.APP_SERVER_URL);
} catch (MalformedURLException e) {
Log.e("AppUtil", "URL Connection Error: "
+ Config.APP_SERVER_URL, e);
result = "Invalid URL: " + Config.APP_SERVER_URL;
}
StringBuilder postBody = new StringBuilder();
Iterator<Entry<String, String>> iterator = paramsMap.entrySet()
.iterator();
while (iterator.hasNext()) {
Entry<String, String> param = iterator.next();
postBody.append(param.getKey()).append('=')
.append(param.getValue());
if (iterator.hasNext()) {
postBody.append('&');
}
}
String body = postBody.toString();
Log.d("&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&",body);
byte[] bytes = body.getBytes();
HttpURLConnection httpCon = null;
try {
httpCon = (HttpURLConnection) serverUrl.openConnection();
httpCon.setDoOutput(true);
httpCon.setUseCaches(false);
httpCon.setFixedLengthStreamingMode(bytes.length);
httpCon.setRequestMethod("POST");
httpCon.setRequestProperty("Content-Type",
"application/x-www-form-urlencoded;charset=UTF-8");
httpCon.setConnectTimeout(20000);
OutputStream out = httpCon.getOutputStream();
out.write(bytes);
out.close();
int status = httpCon.getResponseCode();
Log.d("$$$$$$$$$$$$$$$$$$",String.valueOf(status));
/* if (status == 200) {
result = "RegId shared with Application Server. RegId: "
+ regId;
} else {
result = "Post Failure." + " Status: " + status+regId;
}*/
} finally {
if (httpCon != null) {
((HttpURLConnection) httpCon).disconnect();
}
}
} catch (IOException e) {
result = "Post Failure. Error in sharing with App Server.";
Log.e("AppUtil", "Error in sharing with App Server: " + e);
}
return result;
}
}

java urlconnection get the final redirected URL

I have a url which redirects to another url.I want to be able to get the final redirected URL.My code:
public class testURLConnection
{
public static void main(String[] args) throws MalformedURLException, IOException {
HttpURLConnection con =(HttpURLConnection) new URL( "http://tinyurl.com/KindleWireless" ).openConnection();
System.out.println( "orignal url: " + con.getURL() );
con.connect();
System.out.println( "connected url: " + con.getURL() );
InputStream is = con.getInputStream();
System.out.println( "redirected url: " + con.getURL() );
is.close();
}
}
It always gives original url whereas the redirectURL is:http://www.amazon.com/Kindle-Wireless-Reading-Display-Globally/dp/B003FSUDM4/ref=amb_link_353259562_2?pf_rd_m=ATVPDKIKX0DER&pf_rd_s=center-10&pf_rd_r=11EYKTN682A79T370AM3&pf_rd_t=201&pf_rd_p=1270985982&pf_rd_i=B002Y27P3M.
How can i get this final redirected URL.
Here is what i tried with looping till we get redirects.Still doesent fetch the desired url:
public static String fetchRedirectURL(String url) throws IOException
{
HttpURLConnection con =(HttpURLConnection) new URL( url ).openConnection();
//System.out.println( "orignal url: " + con.getURL() );
con.setInstanceFollowRedirects(false);
con.connect();
InputStream is = con.getInputStream();
if(con.getResponseCode()==301)
return con.getHeaderField("Location");
else return null;
}
public static void main(String[] args) throws MalformedURLException, IOException {
String url="http://tinyurl.com/KindleWireless";
String fetchedUrl=fetchRedirectURL(url);
System.out.println("FetchedURL is:"+fetchedUrl);
while(fetchedUrl!=null)
{ url=fetchedUrl;
System.out.println("The url is:"+url);
fetchedUrl=fetchRedirectURL(url);
}
System.out.println(url);
}
Try this, I using recursively to using for many redirection URL.
public static String getFinalURL(String url) throws IOException {
HttpURLConnection con = (HttpURLConnection) new URL(url).openConnection();
con.setInstanceFollowRedirects(false);
con.connect();
con.getInputStream();
if (con.getResponseCode() == HttpURLConnection.HTTP_MOVED_PERM || con.getResponseCode() == HttpURLConnection.HTTP_MOVED_TEMP) {
String redirectUrl = con.getHeaderField("Location");
return getFinalURL(redirectUrl);
}
return url;
}
and using:
public static void main(String[] args) throws MalformedURLException, IOException {
String fetchedUrl = getFinalURL("<your_url_here>");
System.out.println("FetchedURL is:" + fetchedUrl);
}
public static String getFinalRedirectedUrl(String url) {
HttpURLConnection connection;
String finalUrl = url;
try {
do {
connection = (HttpURLConnection) new URL(finalUrl)
.openConnection();
connection.setInstanceFollowRedirects(false);
connection.setUseCaches(false);
connection.setRequestMethod("GET");
connection.connect();
int responseCode = connection.getResponseCode();
if (responseCode >= 300 && responseCode < 400) {
String redirectedUrl = connection.getHeaderField("Location");
if (null == redirectedUrl)
break;
finalUrl = redirectedUrl;
System.out.println("redirected url: " + finalUrl);
} else
break;
} while (connection.getResponseCode() != HttpURLConnection.HTTP_OK);
connection.disconnect();
} catch (Exception e) {
e.printStackTrace();
}
return finalUrl;
}
My first idea would be setting instanceFollowRedirects to false, or using URLConnection instead.
In both cases, the redirect won't be executed, so you will receive a reply to your original request. Get the HTTP Status value and, if it is 3xx, get the new redirect value.
Of course there may be a chain of redirects, so probably you will want to iterate until you reach the real (status 2xx) page.
#user719950 On my MAC-OSX - this solves the issue of truncated HTTP URL :
To your original code , just add this below line : // You have to find through your browser what is the Request Header IE / Chrome is sending. I still dont have the explanation as why this simple setting is causing correct URL :)
HttpURLConnection con =(HttpURLConnection) new URL
( "http://tinyurl.com/KindleWireless" ).openConnection();
con.setInstanceFollowRedirects(true);
con.setDoOutput(true);
System.out.println( "orignal url: " + con.getURL() );
**con.setRequestProperty("User-Agent",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2)
AppleWebKit/536.26.17 (KHTML, like Gecko) Version/6.0.2
Safari/536.26.17");**
con.connect();
System.out.println( "connected url: " + con.getURL() );
Thread.currentThread().sleep(2000l);
InputStream is = con.getInputStream();
System.out.println( "redirected url: " + con.getURL() );
is.close();
This might help
public static void main(String[] args) throws MalformedURLException,
IOException {
HttpURLConnection con = (HttpURLConnection) new URL(
"http://tinyurl.com/KindleWireless").openConnection(proxy);
System.out.println("orignal url: " + con.getURL());
con.connect();
con.setInstanceFollowRedirects(false);
int responseCode = con.getResponseCode();
if ((responseCode / 100) == 3) {
String newLocationHeader = con.getHeaderField("Location");
responseCode = con.getResponseCode();
System.out.println("Redirected Location " + newLocationHeader);
System.out.println(responseCode);
}
}
#JEETS
Your fetchRedirectURL function may not work because there are a variety of HTTP codes for redirects. Change it to a range check and it will work.
public static String fetchRedirectURL(String url) throws IOException
{
HttpURLConnection con =(HttpURLConnection) new URL( url ).openConnection();
//System.out.println( "orignal url: " + con.getURL() );
con.setInstanceFollowRedirects(false);
con.connect();
InputStream is = con.getInputStream();
if(con.getResponseCode()>=300 && con.getResponseCode() <400)
return con.getHeaderField("Location");
else return null;
}
This one goes recursively in case there are multiple redirects:
protected String getDirectUrl(String link) {
String resultUrl = link;
HttpURLConnection connection = null;
try {
connection = (HttpURLConnection) new URL(link).openConnection();
connection.setInstanceFollowRedirects(false);
connection.connect();
int responseCode = connection.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_MOVED_PERM || responseCode == HttpURLConnection.HTTP_MOVED_TEMP) {
String locationUrl = connection.getHeaderField("Location");
if (locationUrl != null && locationUrl.trim().length() > 0) {
IOUtils.close(connection);
resultUrl = getDirectUrl(locationUrl);
}
}
} catch (Exception e) {
log("error getDirectUrl", e);
} finally {
IOUtils.close(connection);
}
return resultUrl;
}

Categories

Resources