Java rest calls with get parameters - java

How do you add parameters or extra line code to rest calls in java.
GET /ObjectName HTTP/1.1
Host: BucketName.s3.amazonaws.com
Date: date Authorization: authorization string (see Authenticating Requests (AWS Signature Version
4)) Range:bytes=byte_range
Putting /Objectname after GET on the set method causes an error.
The code i am using is;
public void getObject() throws Exception {
String fmt = "EEE, dd MMM yyyy HH:mm:ss ";
SimpleDateFormat df = new SimpleDateFormat(fmt, Locale.US);
df.setTimeZone(TimeZone.getTimeZone("GMT"));
String ob2 = "/bucket/test.txt";
String bucket = "/bucket";
String method = "GET";
String contentMD5 = "";
String contentType = "";
String date = df.format(new Date()) + "GMT";
// Generate signature
StringBuffer buf = new StringBuffer();
buf.append(method).append("\n");`enter code here`
buf.append(contentMD5).append("\n");
buf.append(contentType).append("\n");
buf.append(date).append("\n");
buf.append(ob2);
String signature = sign(buf.toString());
HttpURLConnection httpConn = null;
URL url = new URL("https”,”s3demo.s3demosite.com",443,bucket);
httpConn = (HttpURLConnection) url.openConnection();
httpConn.setDoInput(true);
httpConn.setDoOutput(true);
httpConn.setUseCaches(false);
httpConn.setDefaultUseCaches(false);
httpConn.setAllowUserInteraction(true);
httpConn.setRequestMethod(method);
httpConn.setRequestProperty("Date", date);
httpConn.setRequestProperty("Content-Length", "0");
String AWSAuth = "AWS " + keyId + ":" + signature;
httpConn.setRequestProperty("Authorization", AWSAuth);
// Send the HTTP PUT request.
int statusCode = httpConn.getResponseCode();
InputStream err = httpConn.getErrorStream();
InputStream is = null;
is = httpConn.getInputStream();
int ch;
StringBuffer sb = new StringBuffer();
while ((ch = err.read()) != -1) {
sb.append((char) ch);
}
if ((statusCode/100) != 2)
{
// Deal with S3 error stream.
InputStream in = httpConn.getErrorStream();
System.out.println("Error: "+errorStr);
}
else {
System.out.println("download worked”);
}
}

In REST Services you can pass a parameter in two ways.
as path variables
As a query argument. Example: GET /students/tom or GET /students?name=tom

Related

Handle HttpURLConnection redirect (NASA open API)

I'm writing a Java application that communicates with the NASA open apis. I've a class named NASAClient which exposes the required interface to achieve this task, but I'm facing with the following problem when dealing with the Earth Imagery API.
public EarthImageryResponseObject earthImagery(double lon, double lat, String year, String mon, String day, boolean cloud_score) {
String cs;
if(cloud_score) cs = "True";
else cs = "False";
String url = "https://api.nasa.gov/planetary/earth/imagery?lon="
+ lon
+ "&lat="
+ lat
+ "&date="
+ year+"-"+mon+"-"+day
+ "&cloud_score="
+ cs
+ "&api_key=" + api_key;
try {
String json = (read(getConnection(url)));
return gson.fromJson(json, EarthImageryResponseObject.class);
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
private String read(HttpURLConnection conn) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader((conn.getInputStream())));
return readFromBufferedReader(br);
}
private String readFromBufferedReader(BufferedReader br) throws IOException {
StringBuilder sb = new StringBuilder();
String line = br.readLine();
while (line != null) {
sb.append(line);
line = br.readLine();
}
return sb.toString();
}
private HttpURLConnection getConnection(String url) throws IOException {
HttpURLConnection connection;
connection = createConnection(url);
this.availability = connection.getHeaderField("X-RateLimit-Remaining");
connection.setConnectTimeout(2000);
this.last_resp = connection.getResponseCode();
return connection;
}
private HttpURLConnection createConnection(String url) throws IOException {
URL UniformResourceLocation = new URL(url);
return (HttpURLConnection) UniformResourceLocation.openConnection();
}
When I call earthImagery with some standard parameters, I get the following url:
https://api.nasa.gov/planetary/earth/imagery?lon=100.75&lat=1.5&date=2017-01-01&cloud_score=False&api_key=[MY_KEY]
If I navigate to this url using curl or the browser, I get the expected Json serialized object, but when invoked within my application, I get a redirection link (with 301 response code) to an heroku app:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"><title>Redirecting...</title><h1>Redirecting...</h1><p>You should be redirected automatically to target URL: http://earth-imagery-api.herokuapp.com/earth/imagery/?lon=100.75&lat=1.5&date=2017-01-01&cloud_score=False. If not click the link.
If I try to open a connection to such link, as explained here ,or open it in a browser it returns an error message (parameters are wrong). Really don't know what I am doing wrong. This strategy is the same for the other API I'm using in the application, and they work. Here it follows the stacktrace
Exception in thread "Thread-1" com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 1 path $
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:226)
at com.google.gson.Gson.fromJson(Gson.java:927)
at com.google.gson.Gson.fromJson(Gson.java:892)
at com.google.gson.Gson.fromJson(Gson.java:841)
at com.google.gson.Gson.fromJson(Gson.java:813)
at com.alexfoglia.nasaapi.NASAClient.earthImagery(NASAClient.java:151)
at com.alexfoglia.nasaapi.gui.EarthPanel.lambda$2(EarthPanel.java:127)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 1 path $
at com.google.gson.stream.JsonReader.beginObject(JsonReader.java:385)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:215)
... 7 more
And that's because i'm expecting a Json object, but I get a String (html redirect page).
If you want your code to automatically follow redirects then set this flag
connection.setFollowRedirects (true);
https://developer.android.com/reference/java/net/HttpURLConnection.html#setFollowRedirects(boolean)
I solved using both HttpURLConnection and SSLSocket. The first connection obtain the redirect link, that is reached not by another httpurlconnection, instead, a SSLSocket is used to get to this link.
public EarthImageryResponseObject earthImagery(double lon, double lat, String year, String mon, String day, boolean cloud_score) {
String cs;
if(cloud_score) cs = "True";
else cs = "False";
String url = "https://api.nasa.gov/planetary/earth/imagery?lon="
+ lon
+ "&lat="
+ lat
+ "&date="
+ year+"-"+mon+"-"+day
+ "&cloud_score="
+ cs
+ "&api_key=" + api_key;
try {
HttpURLConnection conn = getConnection(url);
String new_url = conn.getHeaderField("Location");
SSLSocketFactory factory =
(SSLSocketFactory)SSLSocketFactory.getDefault();
SSLSocket socket =
(SSLSocket)factory.createSocket("api.nasa.gov", 443);
socket.startHandshake();
socket.getOutputStream().write(("GET "+new_url+"\n").getBytes());
BufferedReader in = new BufferedReader(
new InputStreamReader(
socket.getInputStream()));
StringBuilder sb = new StringBuilder();
String inputLine;
while ((inputLine = in.readLine()) != null)
sb.append(inputLine);
in.close();
socket.close();
String json = sb.toString();
System.out.println(json);
return gson.fromJson(json, EarthImageryResponseObject.class);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}

Azure Storage Service REST APIs: Create Container

Getting the below error while making a call to Create Container.
Response Code : 411 Response Message : Length Required
String stringToSign = "PUT\n\n\n\n0\n\n\n\n\n\n\n\nx-ms-date:" + date + "\nx-ms-version:" + "2014-02-14\n" + "/" + storageAccount + "/"+ "container-create-test"+"\nrestype:container"+"\ntimeout:60";
Java code snippet.
HttpURLConnection connection = (HttpURLConnection)new URL(url).openConnection();
connection.setRequestMethod(vMethod);
connection.addRequestProperty("Authorization", authHeader);
connection.addRequestProperty("x-ms-date", date);
connection.addRequestProperty("x-ms-version", "2014-02-14");
connection.addRequestProperty("Content-Length", "0");
Nothing wrong with the format of StringToSign.
411 Response Message : Length Required
This error means you don't add Content-Length:0 header in your http request.
Update
As you work with HttpURLConnection in Java, Content-Length header can't be set manually by default, see this thread.
In case of other trouble, here's the complete sample for you to refer.
public static void putContainer() throws Exception {
// Account info
String accountName = "accountName";
String accountKey = "accountKey";
// Request Uri and Method
String containerName = "containerName";
String requestUri = "https://"+accountName+".blob.core.windows.net/"+containerName+"?restype=container&timeout=60";
HttpURLConnection connection = (HttpURLConnection) (new URL(requestUri)).openConnection();
connection.setRequestMethod("PUT");
// Request Headers
// 1. x-ms-version, recommend to use the latest version if possible
String serviceVersion = "2018-03-28";
// 2. x-ms-date
SimpleDateFormat fmt = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss");
fmt.setTimeZone(TimeZone.getTimeZone("GMT"));
String date = fmt.format(Calendar.getInstance().getTime()) + " GMT";
// 3. Authorization
String authKeyFormat = "SharedKey";
String caHeader = "x-ms-date:"+date+"\nx-ms-version:"+serviceVersion+"\n";
String caResource = "/"+accountName+"/"+containerName+"\nrestype:container\ntimeout:60";
String signStr = "PUT\n\n\n\n\n\n\n\n\n\n\n\n"+caHeader+caResource;
String authorization = getAuthorization(accountName, authKeyFormat, signStr, accountKey);
// Send request
connection.setRequestProperty("x-ms-version", serviceVersion);
connection.setRequestProperty("x-ms-date",date);
connection.setRequestProperty("Authorization", authorization);
// Send 0 byte, code sets Content-Length:0 automatically
connection.setDoOutput(true);
connection.setFixedLengthStreamingMode(0);
System.out.println("Response message : " + connection.getResponseMessage());
System.out.println("Response code : " + connection.getResponseCode());
}
private static String getAuthorization(String accountName, String authKeyFormat, String signStr, String accountKey) throws NoSuchAlgorithmException, UnsupportedEncodingException, InvalidKeyException {
SecretKeySpec secretKey = new SecretKeySpec(Base64.getDecoder().decode(accountKey), "HmacSHA256");
Mac sha256HMAC = Mac.getInstance("HmacSHA256");
sha256HMAC.init(secretKey);
String signature = Base64.getEncoder().encodeToString(sha256HMAC.doFinal(signStr.getBytes("UTF-8")));
return authKeyFormat+" "+accountName+":"+signature;
}

Decode google translate API response in JAVA

I need to write a small tool in JAVA which will translate text from English to French using the Google translate API. Everything works but I have an apostrophe decoding problem.
Original text:
Inherit Tax Rate
Text translated with Google translate API:
Taux d' imposition hérité
How it should be:
Taux d'imposition hérité
This is my translate method(sorry for the long method):
private String translate(String text, String from, String to) {
StringBuilder result = new StringBuilder();
try {
String encodedText = URLEncoder.encode(text, "UTF-8");
String urlStr = "https://www.googleapis.com/language/translate/v2?key=" + sKey + "&q=" + encodedText + "&target=" + to + "&source=" + from;
URL url = new URL(urlStr);
HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
InputStream googleStream;
if (conn.getResponseCode() == 200) {
googleStream = conn.getInputStream(); //success
} else
googleStream = conn.getErrorStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(googleStream));
String line;
while ((line = reader.readLine()) != null) {
result.append(line);
}
JsonParser parser = new JsonParser();
JsonElement element = parser.parse(result.toString());
if (element.isJsonObject()) {
JsonObject obj = element.getAsJsonObject();
if (obj.get("error") == null) {
String translatedText = obj.get("data").getAsJsonObject().
get("translations").getAsJsonArray().
get(0).getAsJsonObject().
get("translatedText").getAsString();
return translatedText;
}
}
if (conn.getResponseCode() != 200) {
System.err.println(result);
}
} catch (IOException | JsonSyntaxException ex) {
System.err.println(ex.getMessage());
}
return null;
}
I'm using an XML writer to write the text and first I though that this has a problem, but I observed that the text is returned like this in the stream so I introduced the encoding parameter when I initialise the InputStreamReader:
BufferedReader reader = new BufferedReader(new InputStreamReader(googleStream, "UTF-8"));
But I receive the string with the same problem. Any ideas about what I can do?
I think this problem is solved by using the format parameter (docs). It defaults to html, but you can change it to text to receive unencoded data. Your request should look like this:
String urlStr = "https://www.googleapis.com/language/translate/v2?key=" + sKey + "&q=" + encodedText + "&target=" + to + "&source=" + from + "&format=text";

Header and footer Dynamically Changing but we are passing the Static URL access from GWT

We are maintaining the Static URL in the xml file the same is getting reading in the java filter file.
URL hit may vary from Locale but currently I want for India location.
I am keep on reloading the same Page but header and Footer URL is getting changed as some other countries URL. Not able to understand how its getting changed.
Below is the code for the filtering from xml file,
try{
Map<String, String> configData = null;
configData = EcomConfigService.getConfigurationDataForLocale(
httpReq, locale);
// Here Locale will be loaded Example: INDIA as the country
String proxy = "";
String port = "";
String gwtShfFlag = "";
int shfTimeOutValue;
if (configData != null) {
proxy = configData.get("proxy");
port = configData.get("port");
gwtShfFlag = configData.get("gwtShfFlag");
//Setted the gwtShfFlag as "TRUE"
shfTimeOutValue = Integer.parseInt(configData.get("shf_timeout"));
logger.info("gwtShfFlag:: " + gwtShfFlag);
logger.info("SHF Timeout Value in Milliseconds:: " + shfTimeOutValue);
if(gwtShfFlag != null && gwtShfFlag.equalsIgnoreCase("true")){
HEADER_URL=configData.get("gwt_shared_header");//Loading the Header URL
FOOTER_URL=configData.get("gwt_shared_footer"); //Loading the Footer URL
HEADER_RESPONSIVE_URL=configData.get("gwt_shared_responsive_header"); //Static Header URL from GWT for INDIA
FOOTER_RESPONSIVE_URL=configData.get("gwt_shared_responsive_footer"); //Static Footer URL from GWT for INDIA
Proxy proxyTemp = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(
proxy, Integer.parseInt(port)));
// Open connection and get response for Header.
URL urlH = new URL(HEADER_URL);
URLConnection conH = urlH.openConnection(proxyTemp);
conH.setConnectTimeout(shfTimeOutValue);
conH.setReadTimeout(shfTimeOutValue);
InputStream isH = conH.getInputStream();
BufferedReader brH = new BufferedReader(new InputStreamReader(isH));
StringBuilder sbH = new StringBuilder();
while ((inputLineH = brH.readLine()) != null) {
sbH.append(inputLineH);
}
// Open connection and get response for Footer.
URL urlF = new URL(FOOTER_URL);
URLConnection conF = urlF.openConnection(proxyTemp);
conF.setConnectTimeout(shfTimeOutValue);
conF.setReadTimeout(shfTimeOutValue);
InputStream isF = conF.getInputStream();
BufferedReader brF = new BufferedReader(new InputStreamReader(isF));
StringBuilder sbF = new StringBuilder();
while ((inputLineF = brF.readLine()) != null) {
sbF.append(inputLineF);
}
URL urlRH = new URL(HEADER_RESPONSIVE_URL);
URLConnection conRH = urlRH.openConnection(proxyTemp);
conRH.setConnectTimeout(shfTimeOutValue);
conRH.setReadTimeout(shfTimeOutValue);
InputStream isRH = conRH.getInputStream();
BufferedReader brRH = new BufferedReader(new InputStreamReader(isRH));
StringBuilder sbRH = new StringBuilder();
while ((inputLineRH = brRH.readLine()) != null) {
sbRH.append(inputLineRH);
}
URL urlRF = new URL(FOOTER_RESPONSIVE_URL);
URLConnection conRF = urlRF.openConnection(proxyTemp);
conRF.setConnectTimeout(shfTimeOutValue);
conRF.setReadTimeout(shfTimeOutValue);
InputStream isRF = conRF.getInputStream();
BufferedReader brRF = new BufferedReader(new InputStreamReader(isRF));
StringBuilder sbRF = new StringBuilder();
while ((inputLineRF = brRF.readLine()) != null) {
sbRF.append(inputLineRF);
}
// Set header and footer response in request scope.
httpReq.setAttribute("inputLineH", sbH.toString());
httpReq.setAttribute("inputLineF", sbF.toString());
httpReq.setAttribute("inputLineRH", sbRH.toString());
httpReq.setAttribute("inputLineRF", sbRF.toString());
Locales locales = localeList;
if (locales != null) {
for (Locale local : locales.getLocale()) {
String localeId = local.getLocaleId();
if ((localeId == locale) || (localeId.equals(locale))) {
if(local.getEnabled()){
logger.info("locale_id:: " + localeId);
logger.info("locale Enabled():: " + local.getEnabled());
List<Section> sections = local.getSections().getSection();
logger.info("sections:: " + sections.size());
httpReq.setAttribute("shfSections", sections);
}
}
}
}
isH.close();
brH.close();
isF.close();
brF.close();
isRH.close();
brRH.close();
brRF.close();
isRF.close();
}
}
} catch (Exception exception) {
logger.error("An Exception occured while calling the SHF urls"
+ exception.getMessage());
}
chain.doFilter(request, response);
}

Amazon S3 bucket sub objects REST and Java without SDK

I want to get a list of objects and folders that are in a Bucket in Amazon S3 but I can't, I should not use Amazon S3 SDK.
It's important not to use SDK and only with Rest and Java should I sent a Request and then receive a Response.
I have a method like this :
public String BucketSubList(String strPath) throws Exception {
String answer = null;
// S3 timestamp pattern.
String fmt = "EEE, dd MMM yyyy HH:mm:ss ";
SimpleDateFormat df = new SimpleDateFormat(fmt, Locale.US);
df.setTimeZone(TimeZone.getTimeZone("GMT"));
// Data needed for signature
String method = "GET";
String contentMD5 = "";
String contentType = "";
String date = df.format(new Date()) + "GMT";
String bucket = "/" + strPath + "/";
// Generate signature
StringBuffer buf = new StringBuffer();
buf.append(method).append("\n");
buf.append(contentMD5).append("\n");
buf.append(contentType).append("\n");
buf.append(date).append("\n");
buf.append(bucket);
// try {
String signature = sign(buf.toString());
// Connection to s3.amazonaws.com
URL url = new URL("http", "s3.amazonaws.com", 80, bucket);
HttpURLConnection httpConn = null;
httpConn = (HttpURLConnection) url.openConnection();
httpConn.setDoInput(true);
httpConn.setDoOutput(true);
httpConn.setUseCaches(false);
httpConn.setDefaultUseCaches(false);
httpConn.setAllowUserInteraction(true);
httpConn.setRequestMethod(method);
httpConn.setRequestProperty("Date", date);
// httpConn.setRequestProperty("Content-Type", "text/plain");
String AWSAuth = "AWS " + keyId + ":" + signature;
httpConn.setRequestProperty("Authorization", AWSAuth);
// Send the HTTP PUT request.
int statusCode = httpConn.getResponseCode();
System.out.println(statusCode);
if ((statusCode / 100) != 2) {
// Deal with S3 error stream.
InputStream in = httpConn.getErrorStream();
String errorStr = getS3ErrorCode(in);
System.out.println("Error: " + errorStr);
} else {
answer = "";
// System.out.println("Bucket listed successfully");
InputStream inst = httpConn.getInputStream();
BufferedReader in = new BufferedReader(new InputStreamReader(inst));
String decodedString;
while ((decodedString = in.readLine()) != null) {
answer += decodedString;
System.out.println(answer);
}
in.close();
}
return answer;
}
Without knowing what your problem is, i just can give you the link to the AWS S3 Rest API.
This method does what you want.
I hope this might help you.
Otherwise please give us some more information about your problem.

Categories