I need to send a get request to an API and get the results. I am using Java, Jersey library in my project and I decided to use Jersey client in order to get the data. However, the API returns an error message which indicates that I should enable cookies to reach out this API. I can get correct response when try with applications like postman, or just with using a normal browser like chrome. But I could not find out how can I enable cookies in Java Jersey client object.
I searched to learn how to enable cookies in a Java Jersey client but I could not find any resource about it. So I could not try any solution.
My code is very simple:
Client client = Client.create(); // Create jerseu client
WebResource webResource = client.resource(BASEURI + EXCHANGEINFO); // create web resource with a specific URI
System.out.println(webResource
.accept("application/json")
.get(ClientResponse.class)
.getEntity(String.class)); // Write results to console
At the result of this request, I got the error that I mentioned above. How can I enable cookies while sending a request with Java Jersey client?
As per the discussion, I have gone through the api you have provided. Actually, the api provides a misleading message while making rest call. If you look into the details of the error message which is received from the api call, it says.
The owner of this website (api.pro.coinbase.com) has banned your
access based on your browser's signature (4e0a3c06895d89af-ua21).
So what is the answer ? The api actually wants that the call should be made from browser and each browser sends a header called "User-Agent". See what is user agent. However, I have solved your problem, you can check the complete code below.
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.WebResource;
public class TestGetCallByJersey {
public static void main(String[] args) {
String resourceUri = "https://api.pro.coinbase.com/products";
try {
Client client = Client.create();
WebResource webResource = client.resource(resourceUri);
ClientResponse response =
webResource
.accept("application/json")
.header("User-Agent", "Mozilla/5.0")
.get(ClientResponse.class);
System.out.println("response status = " + response.getStatus());
String result = response.getEntity(String.class);
System.out.println("Output from api call .... \n" + result);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Currently, I have tested in Java 8 and I used the following jar file.
jersey-client version 1.8
If you are using, Maven, you can include the following dependency in pom.xml.
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-client</artifactId>
<version>1.8</version>
</dependency>
Related
I'm new to the java rest CXF client. I will make various requests to a remote server, but first I need to create a Ticket Granting Ticket (TGT). I looked through various sources but I could not find a solution. The server requests that I will create a TGT are as follows:
Content-Type: text as parameter, application / x-www-form-urlencoded as value
username
password
I create TGT when I make this request with the example URL like below using Postman. (URL is example). But in the code below, I'm sending the request, but the response is null. Could you help me with the solution?
The example URL that I make a request with POST method using Postman: https://test.service.com/v1/tickets?format=text&username=user&password=pass
List<Object> providers = new ArrayList<Object>();
providers.add(new JacksonJsonProvider());
WebClient client = WebClient.create("https://test.service.com/v1/tickets?format=text&username=user&password=pass", providers);
Response response = client.getResponse();
You need to do a POST, yet you did not specify what your payload looks like?
Your RequestDTO and ResponseDTO have to have getters/setters.
An example of using JAX-RS 2.0 Client.
Client client = ClientBuilder.newBuilder().register(new JacksonJsonProvider()).build();
WebTarget target = client.target("https://test.service.com/v1/tickets");
target.queryParam("format", "text");
target.queryParam("username", "username");
target.queryParam("password", "password");
Response response = target.request().accept(MediaType.APPLICATION_FORM_URLENCODED).post(Entity.entity(yourPostDTO,
MediaType.APPLICATION_JSON));
YourResponseDTO responseDTO = response.readEntity(YourResponseDTO.class);
int status = response.getStatus();
Also something else that can help is if you copy the POST request from POSTMAN as cURL request. It might help to see the differences between your request and POSTMAN. Perhaps extra/different headers are added by postman?
Documentation: https://cxf.apache.org/docs/jax-rs-client-api.html#JAX-RSClientAPI-JAX-RS2.0andCXFspecificAPI
Similar Stackoverflow: Is there a way to configure the ClientBuilder POST request that would enable it to receive both a return code AND a JSON object?
When using the java.net.http.HttpClient classes in Java 11 and later, how does one tell the client to follow through an HTTP 303 to get to the redirected page?
Here is an example. Wikipedia provides a REST URL for getting the summary of a random page of their content. That URL redirects to the URL of the randomly-chosen page. When running this code, I see the 303 when calling HttpResponse#toString. But I do not know how to tell the client class to follow along to the new URL.
HttpClient client = HttpClient.newHttpClient();
HttpRequest request =
HttpRequest
.newBuilder()
.uri( URI.create( "https://en.wikipedia.org/api/rest_v1/page/random/summary" ) )
.build();
try
{
HttpResponse < String > response = client.send( request , HttpResponse.BodyHandlers.ofString() );
System.out.println( "response = " + response ); // ⬅️ We can see the `303` status code.
String body = response.body();
System.out.println( "body = " + body );
}
catch ( IOException e )
{
e.printStackTrace();
}
catch ( InterruptedException e )
{
e.printStackTrace();
}
When run:
response = (GET https://en.wikipedia.org/api/rest_v1/page/random/summary) 303
body =
Problem
You're using HttpClient#newHttpClient(). The documentation of that method states:
Returns a new HttpClient with default settings.
Equivalent to newBuilder().build().
The default settings include: the "GET" request method, a preference of HTTP/2, a redirection policy of NEVER [emphasis added], the default proxy selector, and the default SSL context.
As emphasized, you are creating an HttpClient with a redirection policy of NEVER.
Solution
There are at least two solutions to your problem.
Automatically Follow Redirects
If you want to automatically follow redirects then you need to use HttpClient#newBuilder() (instead of #newHttpClient()) which allows you to configure the to-be-built client. Specifically, you need to call HttpClient.Builder#followRedirects(HttpClient.Redirect) with an appropriate redirect policy before building the client. For example:
HttpClient client =
HttpClient.newBuilder()
.followRedirects(HttpClient.Redirect.NORMAL) // follow redirects
.build();
The different redirect policies are specified by the HttpClient.Redirect enum:
Defines the automatic redirection policy.
The automatic redirection policy is checked whenever a 3XX response code is received. If redirection does not happen automatically, then the response, containing the 3XX response code, is returned, where it can be handled manually.
There are three constants: ALWAYS, NEVER, and NORMAL. The meaning of the first two is obvious from their names. The last one, NORMAL, behaves just like ALWAYS except it won't redirect from https URLs to http URLs.
Manually Follow Redirects
As noted in the documentation of HttpClient.Redirect you could instead manually follow a redirect. I'm not well versed in HTTP and how to properly handle all responses so I won't give an example here. But I believe, at a minimum, this requires you:
Check the status code of the response.
If the code indicates a redirect, grab the new URI from the response headers.
If the new URI is relative then resolve it against the request URI.
Send a new request.
Repeat 1-4 as needed.
Obviously configuring the HttpClient to automatically follow redirects is much easier (and less error-prone), but this approach would give you more control.
Please find below code where i was calling another api from my REST APi in java.
To note I am using java version 17. This will solve error code 303.
#GetMapping(value = "url/api/url")
private String methodName() throws IOException, InterruptedException {
var url = "api/url/"; // remote api url which you want to call
System.out.println(url);
var request = HttpRequest.newBuilder().GET().uri(URI.create(url)).setHeader("access-token-key", "accessTokenValue").build();
System.out.println(request);
var client = HttpClient.newBuilder().followRedirects(HttpClient.Redirect.NORMAL).build();
System.out.println(client);
var response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response);
System.out.println(response.body());
return response.body();
}
I'm trying to make a request to the Genius API, but I'm running into some issues using OkHTTP. This is my small script I'm using to make the call:
public class OkHttpScript {
OkHttpClient client = new OkHttpClient();
String run(String url) throws IOException {
Request request = new Request.Builder()
.header("Authorization", "Bearer uDtfeAgTKL3_YnOxco4NV6B-WVZAIGyuzgH6Yp07FiV9K9ZRFOAa3r3YoxHVG1Gg")
.url(url)
.build();
try (Response response = client.newCall(request).execute()) {
return response.body().string();
}
}
public static void main(String[] args) throws IOException {
OkHttpScript okHttpScript = new OkHttpScript();
String response = okHttpScript.run("http://api.genius.com/songs/378195/");
System.out.println(response);
}
}
When I run this script, I get a 403 error:
{"meta":{"status":401,"message":"This call requires an access_token. Please see: https://genius.com/developers"}}
For reference, here is a picture of me making the same exact request with Postman, and it works:
Any ideas on what the problem could be?
Edit:
Not sure if this is normal, but when I print out my request object that gets built, I see no indication that there are headers in the request:
Request{method=GET, url=http://api.genius.com/songs/378195/, tag=null}
Is what I get. Could this be part of the problem?
Edit2:
Nevermind, doing a
System.out.println(newRequest.headers());
gives me what I originally put in:
Authorization: Bearer 4mfDBVzCnp2S1Fc0l0K0cfqOrQYjRrb-OHi8W1f-PPU7LNLI6-cXY2E727-1gHYR
So I figured out what my problem was. I'm not sure of the details behind it, but I should have been using my URL has https://api.genius.com/songs/378195/ instead of http://api.genius.com/songs/378195/
Postman seems fine with the http, but OkHttp needed https.
Not sure how your server side is written, I had the same problem today when requesting someone else's service. My solution was to change the User-Agent, even if PostmanRuntime/7.26.10
You should add an interceptor for okhttp something like this should work
How to handle auth0 403 error without adding specific code everywhere (Retrofit/okhttp/RxAndroid)
*Used Alex Hermstad Answer
--> Use https instead of http in android ,
Postman seems fine with the http, but OkHttp needed https.
I was stuck for a day for this error 403 forbidden in android , but giving 200 success in Postman .
I have two web applications in two different server.I want send some data in header or request to other web application.How can I do that, please help me.
You can pass data by many means:
by making http request from your app:
URLConnection conn = new URL("your other web app servlet url").openConnection();
// pass data using conn. Then on other side you can have a servlet that will receive these calls.
By using JMS for asynchronous communication.
By using webservice (SOAP or REST)
By using RMI
By sharing database between the apps. So one writes to a table and the other reads from that table
By sharing file system file(s)...one writes to a file the other reads from a file.
You can use socket connection.
HttpClient can help
http://hc.apache.org/index.html
Apache HttpComponents
The Apache HttpComponents™ project is responsible for creating and
maintaining a toolset of low level Java components focused on HTTP and
associated protocols.
One web application is functioning as the client of the other. You can use the org.apache.http library to create your HTTP client code in Java. How you will do this depends on a couple of things:
Are you using http or https?
Does the application you are sending data to have a REST API?
Do you have a SOAP based web service?
If you have a SOAP based web service, then creating a Java client for it is very easy. If not, you could do something like this and test the code in a regular Java client before trying to run it in the web application.
import org.apache.http.client.utils.*;
import org.apache.http.*;
import org.apache.http.impl.client.*;
HttpClient httpclient = new DefaultHttpClient();
try {
URIBuilder builder = new URIBuilder();
builder.setHost("yoursite.com").setPath(/appath/rsc/);
builder.addParameter("user", username);
builder.addParameter("param1", "SomeData-sentAsParameter");
URI uri = builder.build();
HttpGet httpget = new HttpGet(uri);
HttpResponse response = httpclient.execute(httpget);
System.out.println(response.getStatusLine().toString());
if (response.getStatusLine().getStatusCode() == 200) {
String responseText = EntityUtils.toString(response.getEntity());
httpclient.getConnectionManager().shutdown();
} else {
log(Level.SEVERE, "Server returned HTTP code "
+ response.getStatusLine().getStatusCode());
}
} catch (java.net.URISyntaxException bad) {
System.out.println("URI construction error: " + bad.toString());
}
Getting an error while trying to consume a Restful web service using
POST method(with form param).
I want to consume a REST application using POST method.
Please find below the resource class I want to access.
#Path("/user")
public class User {
#POST
#Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public Response get(#FormParam("username") String userName,
#FormParam("userid") String userId ){
}
I tried using Jesry Client for accessing.Please find below the code i tried.
I tried adding values to FormParam as shown below.
Trail 1
WebResource webResource = client.resource("baseURL/user");
String input = "userid:1001,username:demo1";
ClientResponse response = webResource.type("application/x-www-form-urlencoded").post(ClientResponse.class, input);
I am getting a an error response back "The server encountered an internal error () that prevented it from fulfilling this request".
I think I am not adding the values to FormParam properly.
Trial 2
I also tried adding the form params using the below code
MultivaluedMap formData = new MultivaluedMapImpl();
formData.add("userid", "1001");
formData.add("username", "demo1");
ClientResponse response = webResource.type("application/x-www-form-urlencoded").post(ClientResponse.class, formData);
This also resulted in the same error.
Trial 3
Form f = new Form();
f.add("userid", "1001D");
f.add("username", "1001D");
ClientResponse response = webResource.type(MediaType.APPLICATION_FORM_URLENCODED_TYPE).post(ClientResponse.class, f);
This also resulted in the same error.
Any help is appreciated.
Since your error indicates "Server encountered an internal error" you need to look at the server (logs) to see what went wrong. Certainly your 3rd client looks fine to reach the service you defined (assuming you are using something real instead of the string "baseURL").
You can easily test your server is working separately from your client by creating a HTML page to reach the service. Create a HTML form using enctype="application/x-www-form-urlencoded" and posting to your service endpoint (what you are calling "baseURL/user") with form parameters userid and username. When you view the HTML form in a browser and hit the submit button, it will call your server - if you get the same error you can be sure it is nothing to do with your client code.
Hope http://yogeshmprajapati.blogspot.in/2011/12/login-to-fb-from-java.html will help you.