I have got an issue with a simple program to get the data from an url using 'apache http client (4.5.2 version)'.
Please find the code and the error below:
public static void main(String[] args) throws Exception {
String username = "user";
String password = "pwd";
String urlString = "xyz.com?a=b&c=d";
org.apache.http.client.HttpClient client = HttpClientBuilder.create().build();
HttpGet request = new HttpGet(urlString);
org.apache.http.auth.UsernamePasswordCredentials creds = new org.apache.http.auth.UsernamePasswordCredentials(
username, password);
request.addHeader(new BasicScheme().authenticate(creds, request));
HttpResponse response = client.execute(request);
System.out.println("Response Code : " + response.getStatusLine().getStatusCode());
BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
StringBuffer result = new StringBuffer();
String line = "";
while ((line = rd.readLine()) != null) {
System.out.println(line);
result.append(line);
}
}
Error:
<Error><Code>InvalidArgument</Code><Message>Only one auth mechanism allowed; only the X-Amz-Algorithm query parameter, Signature query string parameter or the Authorization header should be specified</Message>
Could you please help ?
I did not experience the error above, but I was able to run this code sample with no error after adding "http://" to the beginning of the given
String urlString = "xyz.com?a=b&c=d";
Related
I am currently learning to consume an API in Java, I am using the Exchange Rates API, however, it failed to understand what is happening, I send all the requested parameters and I also send my API key as header.
private static void sendHttpGETRequest(String fromCode, String toCode, double amount) throws IOException, JSONException{
String GET_URL = "https://api.apilayer.com/exchangerates_data/convert?to="+toCode+"&from="+fromCode+"&amount="+amount;
URL url = new URL(GET_URL);
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.setReadTimeout(200 * 1000);
httpURLConnection.setConnectTimeout(200 * 1000);
httpURLConnection.setRequestMethod("GET");
httpURLConnection.setRequestProperty("apikey", "MyApiKeY");
int responseCode = httpURLConnection.getResponseCode();
System.out.println("Response code: " + responseCode);
if(responseCode == httpURLConnection.HTTP_OK){//SUCESS
BufferedReader in = new BufferedReader(new InputStreamReader(httpURLConnection.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while((inputLine = in.readLine()) != null){
response.append(inputLine);
}in.close();
JSONObject obj = new JSONObject(response.toString());
Double exchangeRate = obj.getJSONObject("rates").getDouble(fromCode);
System.out.println(obj.getJSONObject("rates"));
System.out.println(exchangeRate); //keep for debugging
System.out.println();
}
else {
System.out.println("GET request failed");
}
}
I have used setConnectTimeout and setReadTimeout to set the network timeout thinking that was the problem but still getting the same error.
I ran into a similar issue while using Spring Web's RestTemplate to try and make the API call.
APILayer is using OKHttpClient (from the okhttp3 library) for their demo samples.
This fixed it for me.
Here is what this could look like for you:
import java.io.*;
import okhttp3.*;
public class main {
public static void main(String []args) throws IOException{
OkHttpClient client = new OkHttpClient().newBuilder().build();
Request request = new Request.Builder()
.url("https://api.apilayer.com/exchangerates_data/convert?to=to&from=from&amount=amount")
.addHeader("apikey", "MyApiKeY")
.method("GET", })
.build();
Response response = client.newCall(request).execute();
System.out.println(response.body().string());
}
}
Here is my code
private static final String MEDIA_TYPE = "application/json";
private static final String FORMAT = "UTF-8";
private static String baseServiceUrl;
private static String apiServiceUrl;
#RequestMapping("/")
public ResponseEntity<?> getMessage() throws Exception {
logger.info("Started");
try {
messageProcessor.getMessage("test service");
// Read from request
StringBuilder buffer = new StringBuilder();
BufferedReader reader = request.getReader();
String line;
while ((line = reader.readLine()) != null) {
buffer.append(line);
}
String data = buffer.toString();
StringRequestEntity requestEntity = null;
HttpClient httpclient = new HttpClient();
int statusCode;
logger.info("RequestBody"+data);
baseServiceUrl="http://localhost:8080/services";
apiServiceUrl="/services/rest/json";
StringBuffer eventResponse = new StringBuffer();
requestEntity = new StringRequestEntity(data, MEDIA_TYPE, FORMAT);
PostMethod postMethod = new PostMethod(baseServiceUrl+apiServiceUrl);
postMethod.setRequestEntity(requestEntity);
statusCode = httpclient.executeMethod(postMethod);
logger.info("Status code"+statusCode);
}
catch (Exception ex) {
logger.error("Exception occurs ", ex);
return new ResponseEntity("Internal server error !!", HttpStatus.INTERNAL_SERVER_ERROR);
}
return new ResponseEntity("Successfully called the service!!", HttpStatus.OK);
}
I want to get the requestbody of one API and send to another API .And a json is my request body.But in this code,I got the status code as 400.Can anyone help me to solve the problem
I think you have appended the /services in the url twice. It should be like:
baseServiceUrl="http://localhost:8080/services";
apiServiceUrl="/rest/json";
In your code you are reading the request body as a string , could you share the request body that is logged.The HTTP response code 400 corresponds to BAD request . So probably, either the endpoint that you are trying to hit is different or the request body has an issue. Try removing the /services from your apiServiceUrl to correct the url path.Also, since you are most probably having a json as request body try the following approach :
String json = "{"id":1,"name":"xxxx"}";
StringEntity entity = new StringEntity(json);
postMethod.setEntity(entity);
postMethod.setHeader("Accept", "application/json");
postMethod.setHeader("Content-type", "application/json");
make sure that the string that you read from the request using BufferedReader reader = request.getReader(); is in appropriate json format.
Below is what i tried to send a HTTP POST request which send the json file as payload. The Error I always get is
java.io.FileNotFoundException: test.json (The system cannot find the file specified)
Although the test.json file is in the same folder.
private void sendPost() throws Exception {`
String url = "url";
HttpClient httpClient = HttpClientBuilder.create().build();
HttpPost post = new HttpPost(url);
List<NameValuePair> urlParameters = new ArrayList<NameValuePair>();
String postData = AutomaticOnboarding.readFile("test.json");
urlParameters.add(new BasicNameValuePair("data", postData));
StringEntity se = new StringEntity(postData);
post.setHeader(HttpHeaders.CONTENT_TYPE, "application/json");
post.setEntity(se);
HttpResponse response = httpClient.execute(post);
System.out.println("\nSending 'POST' request to URL : " + url);
System.out.println("Post parameters : " + post.getEntity());
int responseCode = response.getStatusLine().getStatusCode();
System.out.println("Response Code : " +responseCode);
if(responseCode == 200){
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());
}
}
Here follows the readFile method:
public static String readFile(String filename) {
String result = "";
try {
BufferedReader br = new BufferedReader(new FileReader(filename));
StringBuilder sb = new StringBuilder();
String line = br.readLine();
while (line != null) {
sb.append(line);
line = br.readLine();
}
result = sb.toString();
} catch(Exception e) {
e.printStackTrace();
}
return result;
}
Use the class loader to get resources inside the jar
getClass().getClassLoader().getResourceAsStream(filename)
I am attempting to use Apache HttpClient API to access Atlassian Confluence wiki pages.
Here is my code:
public class ConcfluenceTest{
public static void main(String[] args) {
String pageID = "107544635";
String hostName = "valid_hostname";
String hostScheme = "https";
String username = "verified_username";
String password = "verified_password";
int port = 443;
//set up the username/password authentication
BasicCredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(
new AuthScope(hostName, port, AuthScope.ANY_REALM, hostScheme),
new UsernamePasswordCredentials(username, password));
HttpClient client = HttpClientBuilder.create()
.setDefaultCredentialsProvider(credsProvider)
.build();
try {
HttpGet getRequest = new HttpGet("valid_url");
System.out.println(getRequest.toString());
HttpResponse response = client.execute(getRequest);
//Parse the response
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());
} catch (UnsupportedEncodingException e) {
System.out.println(e.getStackTrace());
} catch (IOException e) {
System.out.println(e.getStackTrace());
}
}
}
When I attempt to execute this code, the printed response is the HTML of the Log In screen, which means that the authentication failed. This code does, however, return the correct response when I provide it with the URL to a page that is not restricted to registered users (i.e credentials aren't required). I also tried all permutations of port/scheme.
Can someone tell me what I am missing?
Afaik, if http-basic-auth is supported, something like
user:password#server:port/path
should work, too. You could see if that works with a browser.
If Confluence dosen't support basic auth, use firebug to find out the action of the login-form (eg. the path, something like /dologin.action), the method (POST) and the Names of the user/password fields.
With that information you can create a request like this:
HttpPost httpPost = new HttpPost(fullFormActionUrlWithServerAndPort);
List <NameValuePair> nvp = new ArrayList <NameValuePair>();
nvp.add(new BasicNameValuePair("name-of-the-user-field", "your-user-name"));
nvp.add(new BasicNameValuePair("name-of-the-pass-field", "your-password"));
httpPost.setEntity(new UrlEncodedFormEntity(nvp));
I'm trying to remotely deploy application to Tomcat. To do that, I need to do the following GET request:
http://localhost:8080/manager/text/deploy?path=/client-001&war=file:C:/.DS/tmp/client-001.war
I do it from my Java code:
String url = "http://localhost:8080/manager/text/deploy?path=/client-001&war=file:C:/.DS/tmp/client-001.war";
HttpClient client = HttpClientBuilder.create().build();
HttpGet request;
try {
request = new HttpGet(url);
request.addHeader(BasicScheme.authenticate(
new UsernamePasswordCredentials("test", "test"),
"UTF-8", false));
HttpResponse response = client.execute(request);
BufferedReader rd = new BufferedReader(
new InputStreamReader(response.getEntity().getContent()));
StringBuffer result = new StringBuffer();
String line = "";
while ((line = rd.readLine()) != null) {
result.append(line);
}
System.err.println(result.toString());
} catch (Exception e){
e.printStackTrace();
}
but I get 403, even though I've passed my credentials.
What am I doing wrong?
So I found out what the problem was.
1) I didn't need to pass credentials to the Header, I just needed to change url from localhost:8080 to test:test#localhost:8080
2) My user test had role manager-gui, and for GET to work it needed the role manager-script