Edit (Answer): KEY is case sensitive. I was using Key instead of key
I am creating a simple HTTP request to google places autocomplete api but I am getting an error
https://developers.google.com/places/web-service/autocomplete
Code: 200
Response: OK
HTTP/1.1 200 OK
"error_message" : "This service requires an API key.",
"predictions" : [],
"status" : "REQUEST_DENIED"
My Key is enabled and live is related to "Google Places API Web Service".
Here is my sample code. What I am doing wrong?
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
public class GoogleAPI {
public static void main(String[] args) throws URISyntaxException, ClientProtocolException, IOException {
CloseableHttpClient client = HttpClients.createDefault();
URI uri = new URIBuilder().setScheme("https")
.setHost("maps.googleapis.com")
.setPath("maps/api/place/autocomplete/json")
.setParameter("input", "London")
.setParameter("Key", "*********")
.build();
HttpGet getMethod = new HttpGet(uri);
HttpResponse response = client.execute(getMethod);
System.out.println("Code: " + response.getStatusLine().getStatusCode());
System.out.println(("Response: ")+ response.getStatusLine().getReasonPhrase() );
System.out.println(response.getStatusLine().toString());
HttpEntity entity = response.getEntity();
String responseString = EntityUtils.toString(entity, "UTF-8");
System.out.println(responseString);
}
}
I have hid my key.
Related
When making a post request to my backend, I get the following error. I can't really find a fix online and am very new to Java.
Here is the error:
Caused by: java.lang.ClassNotFoundException: org.apache.http.concurrent.Cancellable
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520)
... 59 more
Code
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.http.HttpHeaders;
import java.util.ArrayList;
import java.util.List;
public class APIBridge {
private final CloseableHttpClient httpClient = HttpClients.createDefault();
public String url = "http://localhost:9004/index.php";
public static void Register(String username, String password) throws UnsupportedEncodingException {
String url = "http://localhost:9004/index.php";
HttpPost post = new HttpPost(url);
// Add request parameter, form parameters
List<NameValuePair> urlParameters = new ArrayList<>();
urlParameters.add(new BasicNameValuePair("username", username));
urlParameters.add(new BasicNameValuePair("password", password));
urlParameters.add(new BasicNameValuePair("Register", "true"));
post.setEntity(new UrlEncodedFormEntity(urlParameters));
try (CloseableHttpClient httpClient = HttpClients.createDefault();
CloseableHttpResponse response = httpClient.execute(post)) {
System.out.println(EntityUtils.toString(response.getEntity()));
} catch (ClientProtocolException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
private void close() throws IOException {
httpClient.close();
}
private void sendGet() throws Exception {
HttpGet request = new HttpGet("https://www.google.com/search?q=mkyong");
// Add request headers
request.addHeader("custom-key", "mkyong");
//request.addHeader(, "Googlebot");
try (CloseableHttpResponse response = httpClient.execute(request)) {
// Get HttpResponse Status
System.out.println(response.getStatusLine().toString());
HttpEntity entity = response.getEntity();
Header headers = entity.getContentType();
System.out.println(headers);
if (entity != null) {
// Return it as a String
String result = EntityUtils.toString(entity);
System.out.println(result);
}
}
}
IMO, it is easier to use the HTTP client in the JDK, so I have provided an answer demonstrating this alternate approach.
The Apache HTTP libraries were never targeted at somebody who is "new to Java". If you use them, make sure you use the correct versions of all the libraries and matching documentation as the library has gone through multiple incompatible API changes over years of library upgrades.
From your question, your module-info.java may be wrong or may need to be deleted. But your issue could also be caused by an environment setup or dependency version issue.
Basically, the class isn’t on the class or module path. Or it is on a path, but it is not accessible. The reason for that is not discernable from your question.
Example JavaFXApp using JDK HTTP Client
Makes a post request, gets the result as text and places the text in a TextArea.
module-info.java
module com.example.httpapp {
requires javafx.controls;
requires java.net.http;
exports com.example.httpapp;
}
src/main/java/com/example/httpapp/HttpApp.java
package com.example.httpapp;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.TextArea;
import javafx.stage.Stage;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class HttpApp extends Application {
#Override
public void start(Stage stage) throws IOException, URISyntaxException, InterruptedException {
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(new URI("http://jsonplaceholder.typicode.com/posts"))
.POST(HttpRequest.BodyPublishers.ofString("Sample Post Request"))
.build();
HttpResponse<String> response = client.send(
request,
HttpResponse.BodyHandlers.ofString()
);
String responseBody = response.body();
TextArea textArea = new TextArea(responseBody);
textArea.setStyle("-fx-font-family: monospace;");
stage.setScene(new Scene(textArea));
stage.show();
}
public static void main(String[] args) {
launch();
}
}
Authentication
Outside of a local test app, you should not send unencrypted authentication data over a network connection as you have in your question code.
If you also need authentication, it is best to communicate over HTTPS. Then you can securely use basic or digest authentication, or HTTPS mutual authentication, or encode the authentication information in the post body.
Examples for basic authentication using the Java HTTP client are at:
Baeldung: Java HttpClient Basic Authentication
I have been able to successfully authentication to a service that requires ntlm authentication when using the WinHttpClients and a GET request. However when I try to do a POST I always get a 401 return code. Has anyone done this sucessfully before?
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.NTCredentials;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.WinHttpClients;
public class WindowsAuthPOst {
public static void main (String []args) throws Exception, IOException
{
org.apache.log4j.BasicConfigurator.configure();
CloseableHttpClient httpclient = WinHttpClients.createDefault();
HttpHost target = new HttpHost("SomeHost.domain", 443, "https");
HttpClientContext context = HttpClientContext.create();
HttpGet httpget = new HttpGet("/some/Service.svc");
CloseableHttpResponse response1 = httpclient.execute(target, httpget, context);
try {
HttpEntity entity1 = response1.getEntity();
} finally {
response1.close();
}
// Execute an expensive method next reusing the same context (and connection)
HttpPost httppost = new HttpPost("/some/Service.svc");
httppost.setHeader("SOAPAction", "Some Soap Action");
httppost.setEntity(new StringEntity("Soap Payload"));
CloseableHttpResponse response2 = httpclient.execute(target, httppost, context);
try {
HttpEntity entity2 = response2.getEntity();
} finally {
response2.close();
}
}
}
You can check if it is available with.
if (!WinHttpClients.isWinAuthAvailable()) {
System.out.println("Integrated Win auth is not supported!!!");
}
If not, it could be that you do not have jna.jar in your classpath. It depends on jna and will silently return false on the above if it not there, see source code.
Try with get (or options) before post. Some webservers requires that because of CORS.
https://stackoverflow.com/a/38410411/2376661
I'm coding a custom yet simple client to test elgg web services with Java. I want to send a post request to the server with a simple parameter but.
Here is my exposed function in elgg:
function hello_world($name) {
return "Hello ".$name;
}
elgg_ws_expose_function(
"test.echo",
"hello_world",
array("name" => array("type" => "string", "required" => true)),
'A testing method which echos back a string',
'POST',
false,
false
);
and here is my java code for sending a post request:
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package readjson;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.StatusLine;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
public class Main {
public static void main(String[] args) {
try {
CloseableHttpClient client = HttpClients.createDefault();
JSONObject object = new JSONObject();
String name = "Mousa";
object.put("name", name);
HttpPost httpPost = new HttpPost("http://localhost/elgg/services/api/rest/json?method=test.echo");
httpPost.setHeader("Accept", "application/json");
httpPost.setHeader("Content-type", "application/json");
StringEntity entity = new StringEntity(object.toJSONString());
System.out.println(object);
httpPost.setEntity(entity);
CloseableHttpResponse response = client.execute(httpPost);
System.out.println(response.getStatusLine().getStatusCode());
HttpEntity httpEntity = response.getEntity();
StringBuilder stringBuilder = new StringBuilder();
InputStream inputStream = httpEntity.getContent();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
String line;
while((line = bufferedReader.readLine()) != null) {
stringBuilder.append(line);
}
inputStream.close();
System.out.println(stringBuilder.toString());
client.close();
}
catch(Exception ex) {
System.out.println(ex.getLocalizedMessage());
}
}
}
But I'm receiving this output and there is a problem with post request. I don't know what is wrong with that code:
{"name":"Mousa"}
200
{"status":-1,"message":"Missing parameter name in method test.echo"}
It says that "name" parameter is missing!!!
Please help
As far as I remember, Elgg's web services can't handle JSON in request body, use serialized query string instead, e.g.:
name=Mousa&interest[]=interest1&interest[]=interest2
Elgg will likely use parse_str(), so this might be helpful: http://php.net/manual/en/function.parse-str.php
I've implemented a REST service on Glassfish server (GF4) and also a small client program to test it. But the server responds with a "Status 415 - Unsupported Media Type" error. Please have a look at my code and give me some hints.
Server code:
import javax.ws.rs.core.Context;
import javax.ws.rs.core.UriInfo;
import javax.ws.rs.PathParam;
import javax.ws.rs.Consumes;
import javax.ws.rs.Path;
import javax.ws.rs.POST;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.mail.MessagingException;
import javax.ws.rs.GET;
#Path("generic")
public class GenericResource {
#Context
private UriInfo context;
public GenericResource() {
System.out.println("Mediatype: "+MediaType.MULTIPART_FORM_DATA);
}
#Path("post")
#POST
#Consumes(MediaType.MULTIPART_FORM_DATA)
public void postXml(javax.mail.internet.MimeMultipart multiPart) {
try {
System.out.println(multiPart.getCount());
} catch (MessagingException ex) {
Logger.getLogger(GenericResource.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
This is my client code:
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.commons.io.FileUtils;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.impl.client.HttpClientBuilder;
public class URLTester {
public static void main(String[] args) throws Exception {
URLTester http = new URLTester();
http.sendPost();
}
// HTTP POST request
private void sendPost() throws Exception {
String filename = "C:\\development\\java\\URLTester\\test.obx";
String xml = readXML(filename);
String url = "http://localhost:8080/RESTgarbio2oex/webresources/generic/post";
HttpClient httpclient = HttpClientBuilder.create().build();
HttpPost post = new HttpPost(url);
// MultiPart POST
FileBody fb = new FileBody(new File(filename));
post.setHeader("Content-type", "multipart/form-data");
MultipartEntityBuilder multipartEntity = MultipartEntityBuilder.create();
multipartEntity.addPart("file", fb);
multipartEntity.addTextBody("data", "Here is the data.");
post.setEntity(multipartEntity.build());
HttpResponse response = httpclient.execute(post);
BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
String inputLine;
while ((inputLine = rd.readLine()) != null) {
System.out.println(inputLine.toString());
}
}
private String readXML(String xmlsource) {
String xml = "";
try {
File in = new File(xmlsource);
xml = FileUtils.readFileToString(in);
} catch (IOException ex) {
Logger.getLogger(URLTester.class.getName()).log(Level.SEVERE, null, ex);
}
return xml;
}
}
As you can see, I'm setting the content type to "multipart/form-data" and use a MultipartEntityBuilder to create the data to send. I also use the Apache HTTPClientBuilder class to post the data to the server.
On server side, the postXml method isn't called at all, even when my debug console says the constructer has been called and puts Mediatype: multipart/form-data as result.
If you need further infos, please let me know. I've googled so many sites, but haven't come across a solution for my problem. Thanks in advance.
I have been trying to connect to CRM using the below Java code, but I am getting an authentication issue.
package com.raj;
import java.io.IOException;
import org.apache.commons.io.IOUtils;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.NTCredentials;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.HttpContext;
public class MSDynaOData {
/**
* #param args
*/
public static void main(String[] args) throws ClientProtocolException, IOException {
DefaultHttpClient httpclient = new DefaultHttpClient();
NTCredentials creds = new NTCredentials("XXXXXXXXXX", "XXXXXXX", "", "");
httpclient.getCredentialsProvider().setCredentials(AuthScope.ANY, creds);
HttpHost target = new HttpHost("XXXXXXXXX", 80, "http");
HttpContext localContext = new BasicHttpContext();
// Execute a cheap method first. This will trigger NTLM authentication
String url = "/XRMServices/2011/Organization.svc/Account";
url += "?$select=Name";
HttpGet httpget = new HttpGet(url);
httpget.addHeader("Accept", "application/json");
HttpResponse response = httpclient.execute(target, httpget, localContext);
HttpEntity entity = response.getEntity();
System.out.println(" Status :: " + response.getStatusLine());
for (Header header : response.getAllHeaders()) {
System.out.println(header.getName() + " : " + header.getValue());
}
System.out.println(IOUtils.toString(entity.getContent()));
}
}
Response contains :
Constants.TokenizedStringMsgs.GENERIC_ERROR = "<H1>Sorry, but we're having trouble signing you in</H1><p>Please try again in a few minutes. If this doesn't work, you might want to contact your admin and report the following error: #~#ErrorCode#~#.</p>";
Constants.TokenizedStringMsgs.UPN_DISAMBIGUATE_MESSAGE = "It looks like #~#MemberName_LS#~# is used with more than one account. Which account do you want to use?";
I am able to login to CRM 2011 online through the credentials used in Java code successfully, but when I used same credentials in the code I am getting the above login issue response.
Please let me know if I am missing anything in the above code.