I want to make some searches in spotify database only for learning purpose of rest app.
I'm stuck on the first point of
https://developer.spotify.com/documentation/general/guides/authorization-guide/
Authorization Code Flow
to login in spotify with java app:
package spotify;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
/*
1) https://developer.spotify.com/dashboard/applications
*/
public class SpotifyMain {
static final String CLIENTID = "blablablablablablablabla";
static final String CLIENTSECRET = "blablablablablablablabla";
static final String REDIRECTURL = "https://github.com/blablablablablablablabla"; //whiltelisted set inside spotify
public static void main(String[] args) {
try {
String url_auth =
"https://accounts.spotify.com/authorize?"
+ "client_id="+CLIENTID+"&"
+ "response_type=code&"
+ "redirect_uri="+REDIRECTURL+"&"
+ "scope=user-read-private%20user-read-email&"
+ "state=34fFs29kd09";
System.out.println(url_auth);
URL url = new URL(url_auth);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setRequestProperty("Accept", "application/json");
if (conn.getResponseCode() != 200) {
throw new RuntimeException("Failed : HTTP error code : " + conn.getResponseCode());
}
BufferedReader br = new BufferedReader(new InputStreamReader((conn.getInputStream())));
String output;
System.out.println("Output from Server .... \n");
while ((output = br.readLine()) != null) {
System.out.println(output);
}
conn.disconnect();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
I get error 406.
The url I think is correct because if I put that url inside a browser it displays correctly that the app want to access some resources.
If I put that url inside postman the error changes in 400 bad request...
Am I missing something?
thanks
Try removing this line:
conn.setRequestProperty("Accept", "application/json");
HTTP 406 Error is "Not Acceptable" meaning the server has generated a reply that it can't return as the requested Accept content type.
You are trying to open a webpage (HTML) via code and you set
conn.setRequestProperty("Accept", "application/json");
This will not work for auth. You should open the link in the browser, let the user sign in and take the code from the redirect url.
Related
I'm making the HTTP GET request from a basic java program to a URL which happens to be "http://localhost:9992/users/john.doe#example.com":
public class Tester {
public static void main(String[] args) {
HttpRequester.doesUserExist("john.doe#example.com");
}
}
The implementation of the HTTPRequester is this:
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
public class HttpRequester {
private static HttpURLConnection connection = null;
public static boolean doesUserExist(final String email) {
final String targetUrl = Constants.URL_USER_SRVC + email;
System.out.println(targetUrl);
try {
URL url = new URL(targetUrl);
connection = (HttpURLConnection) url.openConnection();
System.out.println(connection.getRequestMethod());
connection.setRequestMethod("GET");
connection.setRequestProperty("Content-Type", "application/json");
connection.setUseCaches(false);
connection.setDoOutput(true);
DataOutputStream outputStream = new DataOutputStream(
connection.getOutputStream());
outputStream.writeBytes(email);
outputStream.close();
InputStream inputStream = connection.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
StringBuffer response = new StringBuffer();
String line;
while((line = reader.readLine()) != null) {
response.append(line);
response.append('\r');
}
reader.close();
System.out.println(response.toString());
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
}
The webservice embedded in a Grizzly server and here are the APIs:
#Path("/users")
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
public class UserResource {
#GET
public List<User> getUsers() {
return UserService.getUsers();
}
#GET
#Path("/{userEmail}")
public User getUser(#PathParam("userEmail") String userEmail) {
return UserService.getUser(userEmail);
}
}
Please take note that the webservice and java program are two separate projects. When I execute the main method I get this error output in the console:
java.io.IOException: Server returned HTTP response code: 405 for URL: http://localhost:9992/users/john.doe#example.com
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1627)
at com.axa.visualizr.auth.utils.HttpRequester.doesUserExist(HttpRequester.java:30)
at com.axa.visualizr.auth.core.Tester.main(Tester.java:8)
What I think is odd is that the error outputs this at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1627) even though I imported java.net.HttpURLConnection;. I have tried opening the declaration on that line but Eclipse states that it is not an valid line number in that class.
I don't know why it's saying that the method is not allowed when I have setRequestMethod("GET"). Maybe it might be because the java program is not running on any kind of server? The Tester.java is only for testing purposes eventually I will move HTTPRequester to another webservice and make the call from webservice A to webservice B.
Since you are passing something in the requestbody, java is interpreting it as a POST request. Please remove below lines from your code and try:
DataOutputStream outputStream = new DataOutputStream(
connection.getOutputStream());
outputStream.writeBytes(email);
outputStream.close();
Try below code:
final String targetUrl = Constants.URL_USER_SRVC + URLEncoder.encode(email, "UTF-8");
instead of: final String targetUrl = Constants.URL_USER_SRVC + email;
I started bitnami's iso on vmware machine.
Standard administration login and pass for bitnami is :
login: user,
pass: bitnami.
In Authentication tab is selected Authentication required, Enable REST web service and enable JSONP support.
Any body knows, why I get below statement?
For any help i will be very grateful.
I got a statement :
Exception in thread "main" java.lang.RuntimeException: Failed : HTTP
error code : 401 at NetClientGet.main(NetClientGet.java:36)
Java Result: 1
My code:
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
public class NetClientGet {
public static void main(String[] args) {
try {
URL url = new URL("http://192.168.0.78/issues.json?key=pjxjDvD9ez0Qm97iApka");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setRequestProperty("Accept", "application/json");
conn.setDoOutput(true);
if (conn.getResponseCode() != 200) {
throw new RuntimeException("Failed : HTTP error code : " + conn.getResponseCode());
}
BufferedReader br = new BufferedReader(new InputStreamReader((conn.getInputStream())));
String output;
System.out.println("Output from Server .... \n");
while ((output = br.readLine()) != null) {
System.out.println(output);
}
conn.disconnect();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
An HTTP status code 401 means you have an authentication problem. That has nothing to do with your code.
However throwing a RuntimeException for a bad status code is rough.
if (conn.getResponseCode() != 200) {
throw new RuntimeException("Failed : HTTP error code : " + conn.getResponseCode());
}
Maybe you can handle different scenarios gracefully. Example :
if (conn.getResponseCode() >= 300) {
// Something unexpected happened
System.out.println("Unexpected response from server");
return // Stop here
}
EDIT
Sorry, I did not read your code carefully. Given the status code you get, it seems you need to send an HTTP auth to your server. It would look like that :
String username = "user"
String password = "bitnami"
String userPassword = username + ":" + password;
String encoding = new sun.misc.BASE64Encoder().encode(userPassword.getBytes());
URL url = new URL("http://192.168.0.78/issues.json?key=pjxjDvD9ez0Qm97iApka");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestProperty("Authorization", "Basic " + encoding);
conn.setRequestMethod("GET");
conn.setRequestProperty("Accept", "application/json");
Note : No promise that it will compile/work :)
Code taken from this SO thread : "How to handle HTTP authentication using HttpURLConnection?"
So in a nutshell, I'm just trying to get a small working skeleton program that I can use to sort of learn about Http communication and "feel" my way around to figure out what I will eventually need for a bigger program I am working on. This particular code here is actually just a chopped up version of an example from the Apache libraries. I could compile the examples listed on the Apache website, but they didn't run properly, giving a "java.net.ConnectException". I figured it had to do with Windows c-blocking a program like this from making a connection, and that I would need to run it as an administrator. I then tried taking the code and throwing it into an executable jar file, but I get a Cannot-find-or-load-main-class error. Am I an idiot or is the Apache library a little outdated/not fit for Win 8/something else?
Code below:
package NewProject;
import java.net.Socket;
import org.apache.http.ConnectionReuseStrategy;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.impl.DefaultBHttpClientConnection;
import org.apache.http.impl.DefaultConnectionReuseStrategy;
import org.apache.http.message.BasicHttpRequest;
import org.apache.http.protocol.HttpCoreContext;
import org.apache.http.protocol.HttpProcessor;
import org.apache.http.protocol.HttpProcessorBuilder;
import org.apache.http.protocol.HttpRequestExecutor;
import org.apache.http.protocol.RequestConnControl;
import org.apache.http.protocol.RequestContent;
import org.apache.http.protocol.RequestExpectContinue;
import org.apache.http.protocol.RequestTargetHost;
import org.apache.http.protocol.RequestUserAgent;
import org.apache.http.util.EntityUtils;
class NewProject
{
public static void main(String[] args) throws Exception
{
HttpProcessor httpproc = HttpProcessorBuilder.create()
.add(new RequestContent())
.add(new RequestTargetHost())
.add(new RequestConnControl())
.add(new RequestUserAgent("Test/1.1"))
.add(new RequestExpectContinue(true)).build();
HttpRequestExecutor httpexecutor = new HttpRequestExecutor();
HttpCoreContext coreContext = HttpCoreContext.create();
HttpHost host = new HttpHost("localhost", 8080);
coreContext.setTargetHost(host);
Out os = new Out("TestOut.txt");
DefaultBHttpClientConnection conn = new DefaultBHttpClientConnection(8 * 1024);
ConnectionReuseStrategy connStrategy = DefaultConnectionReuseStrategy.INSTANCE;
try
{
String[] targets =
{
"http://www.google.com/"
};
for (int i = 0; i < targets.length; i++)
{
if (!conn.isOpen())
{
Socket socket = new Socket(host.getHostName(), host.getPort());
conn.bind(socket);
}
BasicHttpRequest request = new BasicHttpRequest("GET", targets[i]);
os.println(">> Request URI: " + request.getRequestLine().getUri());
httpexecutor.preProcess(request, httpproc, coreContext);
HttpResponse response = httpexecutor.execute(request, conn, coreContext);
httpexecutor.postProcess(response, httpproc, coreContext);
os.println("<< Response: " + response.getStatusLine());
os.println(EntityUtils.toString(response.getEntity()));
os.println("==============");
if (!connStrategy.keepAlive(response, coreContext))
{
conn.close();
}
else
{
os.println("Connection kept alive...");
}
}
}
catch (IndexOutOfBoundsException iob)
{
os.println("What happened here?");
}
finally
{
conn.close();
}
return;
}
}
... they didn't run properly, giving a "java.net.ConnectException"
That could be caused by lots of things. There are clues in the exception message ... which you chose not to share with us.
... "Cannot find or load Main-Class"
Again multiple possible causes, and there are clues in the exception message ... which you chose not to share with us.
But the fact that you have created a JAR file plus the "Main-Class" hint in the error message fragment you provided suggest that you made a mistake in the creation of the JAR file; i.e. you used the wrong name for the "Main-Class" attribute.
Given that source code, the "Main-Class" attribute should be "NewProject.NewProject". I suspect you set it to something else.
A second possibility is that you haven't handled the dependency on the Apache library correctly. The Apache classes need to be on the classpath specified by the JAR file. (You can't use a -cp argument or $CLASSPATH when you launch with java -jar.)
Am I an idiot or is the Apache library a little outdated/not fit for Win 8/something else?
There is nothing wrong with the Apache library.
The code you posted seems a little low level (e.g. interacting directly with Socket connections). The code posted below should give you what it sounds like you are looking for. The classes used also give you a lot of inroads into setting and getting http parameters (e.g. headers, time-outs, etc).
package org.yaorma.example.http.client;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
public class HttpClientExample {
public static void main(String[] args) throws Exception {
String response;
response = get("http://www.google.com");
System.out.println("RESPONSE FROM GET -----------------------------------------");
System.out.println(response);
response = post("http://httpbin.org/post", "This is the message I posted to httpbin.org/post");
System.out.println("RESPONSE FROM POST -----------------------------------------");
System.out.println(response);
}
/**
* Method to post a request to a given URL.
*/
public static String post(String urlString, String message) {
try {
// get a connection
URL url = new URL(urlString);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
// set the parameters
conn.setRequestMethod("POST");
conn.setDoOutput(true);
// send the message
OutputStream os = conn.getOutputStream();
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os, "UTF-8"));
writer.write(message);
writer.flush();
writer.close();
os.close();
// get the response
conn.connect();
InputStream content = (InputStream) conn.getInputStream();
// read the response
BufferedReader in = new BufferedReader(new InputStreamReader(content));
String rtn = "";
String line;
while ((line = in.readLine()) != null) {
rtn += line + "\n";
}
return rtn;
} catch (Exception exp) {
throw new RuntimeException(exp);
}
}
/**
* Method to do a get from a given URL.
*/
public static String get(String urlString) {
try {
// get a connection
URL url = new URL(urlString);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
// set the parameters
conn.setRequestMethod("GET");
conn.setDoOutput(true);
// get the response
conn.connect();
InputStream content = (InputStream) conn.getInputStream();
// read the response
BufferedReader in = new BufferedReader(new InputStreamReader(content));
String rtn = "";
String line;
while ((line = in.readLine()) != null) {
rtn += line + "\n";
}
return rtn;
} catch (Exception exp) {
throw new RuntimeException(exp);
}
}
}
i want to get also the email from https://www.googleapis.com/plus/v1/people/me call. I receive a lots of informations, but not the email. Can anyone help?
HttpGet request = new HttpGet("https://www.googleapis.com/plus/v1/people/me?scope=https://www.googleapis.com/auth/userinfo.email");
request.setHeader("Authorization", "Bearer <access_token>");
HttpResponse response = client.execute(request);
EDIT: Updated as part of the improved Google+ Sign-In options in December 2013 - you now can get the email address with the Google+ profile response.
You will get the email from this endpoint as long as you have the email or https://www.googleapis.com/auth/plus.profile.emails.read scopes. See https://developers.google.com/+/web/people/#retrieve_an_authenticated_users_email_address for details.
var request = gapi.client.plus.people.get( {'userId' : 'me'} );
request.execute(function(person) {
if(person['emails']) {
console.log(person['emails'][0].value);
}
});
I found the answer.
My aim was also this.
And We can do it successfully :)
U need:
https://www.googleapis.com/auth/userinfo.email consent
accessToken
and after above two just make HTTP GET request to https://www.googleapis.com/oauth2/v2/userinfo
BUT with added header "Authorization: Bearer <accessToken>"
U can do it by many ways.
My way is customised REST call
package com.google.plus.samples.photohunt.custom;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
public class NetClientGet {
// http://localhost:8080/RESTfulExample/json/product/get
public static void makeRequest(String access_token) {
try {
URL url = new URL("https://www.googleapis.com/oauth2/v2/userinfo");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestProperty("Authorization", "Bearer "+access_token);
conn.setRequestMethod("GET");
conn.setRequestProperty("Accept", "application/json");
if (conn.getResponseCode() != 200) {
throw new RuntimeException("Failed : HTTP error code : "
+ conn.getResponseCode());
}
BufferedReader br = new BufferedReader(new InputStreamReader(
(conn.getInputStream())));
String output;
System.out.println("REST call made. Output from Server .... \n");
while ((output = br.readLine()) != null) {
System.out.println(output);
}
conn.disconnect();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
I have something I am trying to achieve.
I have a web application running on my localhost on port 8080.
I have a HTTP Server running on localhost:9005.
I have a JSP form that passes info to a servlet java class, that in turn performs the HTTP post to the URL on the HTTP Server localhost:9010 with the data string.
What I need to do is perform the POST and GET as part of the same connection. I have them working as two separate calls, but not on the same connection. It needs to be the same connection, as I post data, the HTTP Server takes this data, processes it and outputs unique data to this URL. Therefore the GET needs to be part of the same connection as he POST.
Can anyone please help?
This is my Process Request java code:
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import javax.servlet.*;
import javax.servlet.http.*;
import java.util.List;
import java.util.Map.Entry;
public class ProcessRequest {
public void sendRequestToGateway() throws Throwable{
String message = URLEncoder.encode("OP1387927", "UTF-8");
try {
URL url = new URL("http://localhost:9005/json");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoOutput(true);
connection.setRequestMethod("POST");
OutputStreamWriter writer = new OutputStreamWriter(connection.getOutputStream());
writer.write("operator=" + message);
writer.close();
System.out.println("connection.getResponseCode() : " + connection.getResponseCode());
System.out.println("connection.getResponseMessage()" + connection.getResponseMessage());
if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
receiveMessageFromGateway();
} else {
// Server returned HTTP error code.
}
//receiveMessageFromGateway();
} catch (MalformedURLException e) {
// ...
} catch (IOException e) {
// ...
}
}
public void receiveMessageFromGateway() throws Throwable {
HttpURLConnection client = null;
OutputStreamWriter wr = null;
BufferedReader rd = null;
StringBuilder sb = null;
String line = null;
try {
URL url = new URL("http://localhost:9005/json");
client = (HttpURLConnection) url.openConnection();
client.setRequestMethod("GET");
client.setDoOutput(true);
client.setReadTimeout(10000);
client.connect();
System.out.println(" *** headers ***");
for (Entry<String, List<String>> headernew : client.getHeaderFields().entrySet()) {
System.out.println(headernew.getKey() + "=" + headernew.getValue());
}
System.out.println(" \n\n*** Body ***");
rd = new BufferedReader(new InputStreamReader(client.getInputStream()));
sb = new StringBuilder();
while ((line = rd.readLine()) != null) {
sb.append(line + '\n');
}
System.out.println("body=" + sb.toString());
} finally {
client.disconnect();
rd = null;
sb = null;
wr = null;
}
}
}
Why don't you just return the result from the original POST?
In general you can't control connection reuse with HttpUrlConnection. You might be able to cast your connection to the specific implementation class and interfere with it but that's a horribly unstable way of doing it.
Apache HttpClient is probably a better option, given the requirements.
You can use Apache HTTP Client for this. Its very simple.
If you are using maven, just add the following lines into your POM file:
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.3.3</version>
</dependency>
In this example, I'm submitting a POST request and after that a GET request.
Take a look:
public static String get(String p_url) throws IOException
{
CloseableHttpClient httpclient = HttpClients.createDefault();
// First request: POST
HttpPost httpPost = new HttpPost("http://the-api-url.com/Login/Auth&token=12345"));
CloseableHttpResponse response_post = httpclient.execute(httpPost);
System.out.println(response_post.getStatusLine());
HttpEntity entity_post = response_post.getEntity();
System.out.println(EntityUtils.toString(entity_post));
// Second request: GET
HttpGet httpGet = new HttpGet(p_url);
CloseableHttpResponse response_get = httpclient.execute(httpGet);
System.out.println(response_get.getStatusLine());
HttpEntity entity_get = response_get.getEntity();
System.out.println(EntityUtils.toString(entity_get));
response_post.close();
response_get.close();
return EntityUtils.toString(entity_get);
}