New to java, GWT and interacting with APIs. I have what I hope is a simple question.
I have successfully interacted with a REST API using the following curl command:
curl -d "OPERATION_NAME=ADD_REQUEST&TECHNICIAN_KEY=xxxxxxxxxxx&INPUT_DATA=<?xml version=%221.0%22 encoding=%22utf-8%22?><Operation><Details><requester>Me</requester><subject>Test</subject><description>Testing curl input</description></Details></Operation>" http://xx.xx.xx.xx/sdpapi/request/
Now, from a tutorial, I have the following code that I am hoping will post a request to the remote server just like the curl command above.
What I am trying to figure out (with no love from google) is how I pass the OPERATION_NAME, TECHNICIAN_KEY and INPUT_DATA parameters in when I am sending the URL. Any suggestions, tutorials, etc. will be appreciated.
The following is from my server side implementation interface:
#Override
public String postToRemoteServer(String serviceUrl)
throws HelpDeskTestException {
try {
//dividing url into host: http://some.server
//path: a/path/in/it
//and parameters: this=that&those=others
int hostStart= serviceUrl.indexOf("//");
int pathStart= serviceUrl.substring(hostStart + 2).indexOf("/");
int parameterStart= serviceUrl.substring(hostStart + 2 + pathStart).indexOf("?");
final String serverHost= serviceUrl.substring(0, hostStart + pathStart + 2);
final String serverPath= serviceUrl.substring(hostStart + 3,
hostStart + pathStart + 2 + parameterStart);
final String serverParameters= serviceUrl.substring(hostStart + pathStart + 3 + parameterStart);
final URL url = new URL(serverHost);
final URLConnection connection= url.openConnection();
connection.setDoOutput(true);
final OutputStreamWriter out= new OutputStreamWriter(connection.getOutputStream());
final BufferedReader in= new BufferedReader(new InputStreamReader(
connection.getInputStream()));
out.write("POST " + serverPath + "\r\n");
out.write("Host: " + serverHost + "\r\n");
out.write("Accept-Encoding: identity\r\n");
out.write("Connection: close\r\n");
out.write("Content-Type: application/x-www-form-urlencoded\r\n");
out.write("Content-Length: " + serverParameters.length() + "\r\n\r\n" +
serverParameters + "\r\n");
String result = "";
String inputLine;
while ((inputLine=in.readLine()) != null) {
result+= inputLine;
}
in.close();
out.close();
return result;
} catch (final Exception e) {
throw new HelpDeskTestException();
}
Consider using this library: Apache HttpClient. Here is an example of making a POST request with it.
Related
I am creating a Java Rest api to create users on Google Duo admin. I am following the documentation https://duo.com/docs/adminapi and I have added auth and date/time header but still I am getting unauthorised error 401. Can anyone guide me what am I doing wrong I have read the doc and added all the mandatory headers.
public static void POSTRequest() throws IOException {
String userCredentials = "Username:Password";
String basicAuth = "Basic " + new String(Base64.getEncoder().encode(userCredentials.getBytes()));
String dateTime = OffsetDateTime.now().format(DateTimeFormatter.RFC_1123_DATE_TIME);
String POST_PARAMS = "{\n" + "\"userId\": 101,\r\n" +
" \"id\": 101,\r\n" +
" \"title\": \"Test Title\",\r\n" +
" \"body\": \"Test Body\"" + "\n}";
URL obj = new URL("https://api-e9770554.duosecurity.com");
HttpURLConnection postConnection = (HttpURLConnection) obj.openConnection();
postConnection.setRequestMethod("POST");
postConnection.setRequestProperty("Content-Type", "application/json");
postConnection.setRequestProperty("Authorization", basicAuth);
postConnection.setRequestProperty("Date", dateTime);
postConnection.setDoOutput(true);
OutputStream os = postConnection.getOutputStream();
os.write(POST_PARAMS.getBytes());
os.flush();
os.close();
int responseCode = postConnection.getResponseCode();
System.out.println("POST Response Code : " + responseCode);
System.out.println("POST Response Message : " + postConnection.getResponseMessage());
if (responseCode == HttpURLConnection.HTTP_CREATED) { //success
BufferedReader in = new BufferedReader(new InputStreamReader(
postConnection.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
// print result
System.out.println(response.toString());
} else {
System.out.println("POST NOT WORKED");
}
}
Error:
{
"code": 40101,
"message": "Missing request credentials",
"stat": "FAIL"
}
Response code: 401 (Unauthorized); Time: 2022ms; Content length: 73 bytes
I want to use the MailChimp api to add a subscriber. As a start, want to read from one of the REST I'm trying to get a response back from the MailChimp api.
I seem to be doing the authorization correctly as I'm getting status 200, but for some reason, I am not getting the response.
Here is the code so far:
public void doPostAction() throws IOException{
// BASIC Authentication
String name = "user";
String password = apikey;
String authString = name + ":" + password;
byte[] authEncBytes = Base64.encodeBase64(authString.getBytes());
String authStringEnc = new String(authEncBytes);
URL urlConnector = new URL(url);
HttpURLConnection httpConnection = (HttpURLConnection) urlConnector.openConnection();
httpConnection.setRequestMethod("GET");
httpConnection.setDoOutput(true);
httpConnection.setDoInput(true);
httpConnection.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
httpConnection.setRequestProperty("Accept", "application/json");
httpConnection.setRequestProperty("Authorization", "Basic " + authStringEnc);
InputStream is = httpConnection.getInputStream();
// check status
System.out.println("DoPost: status: " + httpConnection.getResponseCode());
StringBuilder sb = new StringBuilder();
BufferedReader br = new BufferedReader(new InputStreamReader(is, "utf-8"));
String line = null;
while ((line = br.readLine()) != null) {
sb.append(line + "\n");
}
System.out.println("DoPost response: \n" + line);
br.close();
}
Looking at the MailChimp playground, it seems like I'm missing out on a lot...
How do I get the response?
****/ EDIT /****
If anyone's looking at the above code, the output should be:
System.out.println("DoPost response: \n" + sb); // not line
OK, the above code works. Basic error.
I was examining the line variable when it was null, not the response...
When I change to:
System.out.println("DoPost response: \n" + line); // not line
System.out.println("DoPost response: \n" + sb); // but sb StringBuilder
...it works.
I've been trying to establish a connection with an API for more than a week now, to no avail. (Magic Card Market's, authentification documentation here and there). I'm supposed to receive a XML file.
I have what MCM call a "widget" access to their API, meaning that I don't have nor need a oauth_token (it's supposed to be an empty string) for the authorization header, and that I'm not supposed to receive nor use an access token/access secret.
The only things I do have are a consumer key (they call it app token sometimes) and a consumer secret.
Here is how I build my Authorization header :
private static String buildOAuthAuthorization(String method, String request)
throws UnsupportedEncodingException, NoSuchAlgorithmException, InvalidKeyException {
String mkmAppToken = APICredentials.appToken;
String mkmAppSecret = APICredentials.appSecret;
String realm = "https://www.mkmapi.eu/ws/v1.1/games";
String oauthVersion = "1.0";
String oauthConsumerKey = mkmAppToken;
String oauthToken = "";
String oauthSignatureMethod = "HMAC-SHA1";
String oauthTimestamp = Long.toString(System.currentTimeMillis() / 1000);
String oauthNonce = Long.toString(System.currentTimeMillis());
String paramString = "oauth_consumer_key=" + oauthConsumerKey
+ "oauth_nonce=" + oauthNonce
+ "oauth_signature_method=" + oauthSignatureMethod
+ "oauth_timestamp=" + oauthTimestamp
+ "oauth_token=" + oauthToken
+ "oauth_version=" + oauthVersion;
String baseString = method + "&" + rawUrlEncode(realm) + "&" + rawUrlEncode(paramString);
String signingKey = rawUrlEncode(mkmAppSecret) + "&";
Mac mac = Mac.getInstance("HMAC-SHA1");
SecretKeySpec secret = new SecretKeySpec(signingKey.getBytes(), mac.getAlgorithm());
mac.init(secret);
byte[] digest = mac.doFinal(baseString.getBytes());
byte[] oauthSignature = Base64.encode(digest, Base64.URL_SAFE);
String authorizationProperty = "OAuth "
+ "realm=\"" + realm + "\", "
+ "oauth_version=\"" + oauthVersion + "\", "
+ "oauth_timestamp=\"" + oauthTimestamp + "\", "
+ "oauth_nonce=\"" + oauthNonce + "\", "
+ "oauth_consumer_key=\"" + oauthConsumerKey + "\", "
+ "oauth_token=\""+ oauthToken + "\", "
+ "oauth_signature_method=\"" + oauthSignatureMethod + "\", "
+ "oauth_signature=\"" + oauthSignature + "\"";
System.out.println(authorizationProperty);
return authorizationProperty;
}
The actual request is in an AsyncTask :
public static class oAuthRequest extends AsyncTask<String, Integer, StringReader> {
private int lastCode;
#Override
protected StringReader doInBackground(String... requestURLs) {
String method = requestURLs[0];
String url = requestURLs[1];
StringReader result = null;
try {
String authProperty = buildOAuthAuthorization(method, url);
HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
connection.addRequestProperty("Authorization:", authProperty);
lastCode = connection.getResponseCode();
System.out.println("RESPONSE CODE 1 " + lastCode);
// Get content
BufferedReader rd = new BufferedReader(new InputStreamReader(lastCode == 200 ? connection.getInputStream() : connection.getErrorStream()));
StringBuilder sb = new StringBuilder();
String line;
while ((line = rd.readLine()) != null) {
sb.append(line);
}
rd.close();
result = new StringReader(sb.toString());
} catch (NoSuchAlgorithmException | InvalidKeyException | IOException e) {
e.printStackTrace();
}
return result;
}
}
It seems like no matter what I change, I'm always getting a 401.
Things I've tried :
oauthSignature as a String using Base64.encodeToString()
Nonce generation using SecureRandom
With and without the empty oauthToken
Another timestamp generation method (can't remember what though)
signing key with and without app token (theorically I need only the consumer secret, but you never know)
Using HttpsURLConnection instead of HttpURLConnection (the URI start in https, so I thought, hey. But no)
At least 2-3 other different implementations (one who was basically a copy/paste of the Java example in the documentation of course -- it still kind of is one now)
(Probably a lot of things I can't even remember)
At this point I'm wondering if maybe the issue comes from my keys, as I've tried to use the Postman app to test requests with the same results.
I am trying to replicate the following unix cURL command in java:
curl -X POST http://api.nigelsmall.com/xml-cypher -d #test/files/abba.xml
edit:
To be more specific I am trying to replicate the following cURL command in java:
curl -X POST http://api.nigelsmall.com/xml-cypher -d "<?xml version='1.0' encoding='UTF-8' ?><group><member></member></group>"
So far I have the following code:
String urlString = "http://api.nigelsmall.com/xml-cypher";
try {
URL url = new URL(urlString);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestProperty("Content-Type", "application/xml");
conn.setDoOutput(true);
conn.setRequestMethod("POST");
String data = "<?xml version='1.0' encoding='UTF-8' ?><group><member></member></group>";
OutputStreamWriter out = new OutputStreamWriter(conn.getOutputStream());
out.write(data);
out.flush();
BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String line;
while ((line = rd.readLine()) != null) {
System.out.println(line);
}
out.close();
rd.close();
}
catch (Exception e) {
System.out.println(e);
e.printStackTrace();
}
But java.io.IOException: Server returned HTTP response code: 400 for URL :http://api.nigelsmall.com/xml-cypher occurs. Can anyone find what the problem is?
The only thing I can think of is that may be I need to put my XML in a file and send it as a request. But I do not know how to do this. Could anyone help me with this? Thanks in advance.
It's not your fault. The documentation of the web-service is missing an important detail:
If posting JSON, you can do it this way. When posting XML, you have to provide the XML like if posted in an HTML form: application/x-www-form-urlencoded.
In the source code of the service you can see:
def _convert(method):
a = request.accept_mimetypes.best_match(["application/json", "text/html"])
if a == "application/json":
xml = request.get_data().decode("utf-8")
else:
xml = request.form["xml"] # <-- xml is a form field!!
# ...
I've tried it with DavidWebb which is only a tiny wrapper around HttpURLConnection and it worked:
public void testNigelsmall() throws Exception {
String payload = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n" +
"<group id=\"abba\">\n" +
" <member id=\"agnetha\">\n" +
" <name>Agnetha Fältskog</name>\n" +
" <birth date=\"1950-04-05\" />\n" +
" </member>\n" +
" <member id=\"frida\">\n" +
" <name>Anni-Frid Lyngstad</name>\n" +
" <birth date=\"1945-11-15\" />\n" +
" </member>\n" +
" <song id=\"waterloo\" release_date=\"1974-03-04\">\n" +
" <name>Waterloo</name>\n" +
" <length min=\"2\" sec=\"42\" />\n" +
" </song>\n" +
"</group>";
Webb webb = Webb.create();
Response<String> response = webb
.post("http://api.nigelsmall.com/xml-cypher")
.param("xml", payload)
.asString();
assertEquals(200, response.getStatusCode());
assertNotNull(response.getBody());
assertTrue(response.getBody().startsWith("CREATE"));
assertTrue(response.getBody().contains("(abba)-[:member]->(frida)"));
}
The output:
CREATE
(abba),
(agnetha {name:"Agnetha F\u00e4ltskog",`birth date`:"1950-04-05"}),
(frida {name:"Anni-Frid Lyngstad",`birth date`:"1945-11-15"}),
(waterloo {`length sec`:42,`length min`:2,name:"Waterloo"}),
(abba)-[:member]->(agnetha),
(abba)-[:member]->(frida),
(abba)-[:song {release_date:"1974-03-04"}]->(waterloo)
I have a question about URI and URL
when i pass a url is work good but result is worst need help!!
as my code look like this.
import java.io.*;
import java.net.*;
import java.net.URL;
public class isms {
public static void main(String[] args) throws Exception {
try {
String user = new String ("boo");
String pass = new String ("boo");
String dstno = new String("60164038811"); //You are going compose a message to this destination number.
String msg = new String("你的哈达哈达!"); //Your message over here
int type = 2; //for unicode change to 2, normal will the 1.
String sendid = new String("isms"); //Malaysia does not support sender id yet.
// Send data
URI myUrl = new URI("http://www.isms.com.my/isms_send.php?un=" + user + "&pwd=" + pass
+ "&dstno=" + dstno + "&msg=" + msg + "&type=" + type + "&sendid=" + sendid);
URL url = new URL(myUrl.toASCIIString());
URLConnection conn = url.openConnection();
conn.setDoOutput(true);
// Get the response
BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String line;
while ((line = rd.readLine()) != null) {
// Print the response output...
System.out.println(line);
}
rd.close();
System.out.println(url);
} catch (Exception e) {
e.printStackTrace();
}
}
}
the output in web is different..
on my java output is
你的哈达哈达!
but on my the site is
ÄãµÄ¹þ´ï¹þ´ï!
Help!!
String user = new String ("boo");
You don't need to (and shouldn't) do new String in Java—String user = "boo"; is fine.
String msg = new String("你的哈达哈达!");
Writing non-ASCII characters in your source means that you have to get the -encoding flag to javac to match the encoding you have saved your text files with. It is possible you have saved the .java file as UTF-8 but not configured your build environment to use UTF-8 at compile time.
If you are not sure that you've got this right, you can use ASCII-safe \u escapes in the meantime:
String msg = "\u4F60\u7684\u54C8\u8FBE\u54C8\u8FBE!"; // 你的哈达哈达!
Finally:
URI myUrl = new URI("http://www.isms.com.my/isms_send.php?un=" + user + "&pwd=" + pass
+ "&dstno=" + dstno + "&msg=" + msg + "&type=" + type + "&sendid=" + sendid);
When you're putting a URI together you should URL-escape each of the parameters you include in the string. Otherwise any & or other invalid character in the value will break the query. This also allows you to choose what charset is used to create the query string.
String enc = "UTF-8";
URI myUrl = new URI("http://www.isms.com.my/isms_send.php?" +
"un=" + URLEncoder.encode(user, enc) +
"&pwd=" + URLEncoder.encode(pass, enc) +
"&dstno=" + URLEncoder.encode(dstno, enc) +
"&msg=" + URLEncoder.encode(msg, enc) +
"&type=" + URLEncoder.encode(Integer.toString(type), enc) +
"&sendid=" + URLEncoder.encode(sendid, enc)
);
What the right value for enc is depends on the service you are connecting to, but UTF-8 is a good guess.