I want to send JSON data to a REST service which includes authentication, but when I try to run this code, it throws a RuntimeException and HTTP code 302. But the link is working fine through a REST client. I think my code is unable to provide the authentication details to the link.
I have tried so many combinations, but it's still not working. Can anyone suggest where I am going wrong?
JSONObject obj=new JSONObject(req); //JSON Object
ClientConfig clientConfig = new DefaultClientConfig();
clientConfig.getFeatures().put(JSONConfiguration.FEATURE_POJO_MAPPING,
Boolean.TRUE);
Client client = Client.create(clientConfig);
//Authentication filter
client.addFilter(new HTTPBasicAuthFilter("username", "password"));
WebResource webResource = client.resource(
"http://licruleswb-dev.cloudapps.cisco.com/LicenseRules/rest/invokeRule");
ClientResponse response = webResource.accept("application/json").type(
MediaType.APPLICATION_JSON_TYPE).post(ClientResponse.class, obj.toString());
if (response.getStatus() != 200) {
throw new RuntimeException("Failed : HTTP error code : " + response.getStatus());
}
This is the error:
ERROR:Exception in thread "main" java.lang.RuntimeException: Failed :
HTTP error code : 302
at Test2.main(Test2.java:64)
Test2 is my class.
What framework are you using? Jersey? You can try setting the basic auth with:
Authenticator.setDefault(new Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("username", "password".toCharArray());
}
});
It seems that you use Jersey REST client. You need to be aware that this approach is deprecated in version 2.5 and removed in version 2.6. In higher versions of Jersey, you need to use this:
// Send with all calls
HttpAuthenticationFeature feature = HttpAuthenticationFeature.basic(
"username", "password");
or
// Send with a single call
Response response = client.target("http://...").request()
.property(HTTP_AUTHENTICATION_BASIC_USERNAME, "username")
.property(HTTP_AUTHENTICATION_BASIC_PASSWORD, "password").get();
See this link for more details: https://jersey.java.net/documentation/latest/client.html#d0e5181.
You could enable traces in your application or use an external HTTP proxy (like tcpmon) to see the actual sent request (if there is a header Authorization with content).
Hope it helps you,
Thierry
Related
I am calling a post request using Jersey rest client which contains no request body but contains authorization header. I am always getting 400 error. I tried from postman i got 200 response. Here is my code
ClientResponse response = null;
Client cliente=Client.create();
cliente.addFilter(new LoggingFilter(System.out));
WebResource webResource=cliente.resource("https://URL/token");
Builder builder = webResource.accept("application/json");
builder.type(MediaType.APPLICATION_JSON);
builder.header("Authorization", "Basic YbjjkwliOTQtNjRiYy00NWE5LWFhMzQtMTFhNDkyZZjNTVlOjZjYjk2OTMwNGE5YTQ3OTlhODVjZTM5MDFiMDEyMTI2";
builder.post(ClientResponse.class,Entity.json(""));
Don't use the way you are trying right now. Use HttpAuthenticationFeature from Jersey like this
HttpAuthenticationFeature feature = HttpAuthenticationFeature.basic("username", "password");
final Client client = ClientBuilder.newClient();
client.register(feature);
If you are getting 200 success respone in postman and failure response in your application then you need to check your api with another api tester online tool. I had the same issue i put / at the last of end point.
I'm using jersey-client 1.19.4 to test my web application.
If I test with postman, I can find the cookie "JSESSIONID" after 'send' action. And I can find 'jsessionid=...' in ClientResponse.toString(), But ClientResponse.getCookies() returns nothing.
WebResource webResource = client.resource(someUrl);
FormDataMultiPart formData = new FormDataMultiPart();
formData.bodyPart(new FormDataBodyPart("userId", userId));
formData.bodyPart(new FormDataBodyPart("uPasswd", uPasswd));
ClientResponse response = webResource.accept("*/*").type(MediaType.MULTIPART_FORM_DATA_TYPE).post(ClientResponse.class, formData);
System.out.println("response: " + response.toString()); // 'jsessionid' found here
List<NewCookie> cookies = response.getCookies();
System.out.println("# of cookies: " + cookies.size()); // prints "# of cookies: 0"
How can I get "JSESSIONID" from ClientResponse?
JSESSIONID can be set in few different ways. As per
JSR-000315 Java Servlet 3.0 Final Release, chapter 7.1 Session Tracking Mechanisms, following can be used:
Cookies
SSL Sessions
URL Rewriting
In your case it appears that URL Rewriting is being used. The two most common reasons being:
The server is configured not to issue cookies
Your client doesn't support cookies
Since you get the cookie while using Postman it most likely means that your Jersey Client doesn't handle cookies. One way to integrate it with Apache HttpClient using jersey-apache-client as per this answer.
From the mailing list:
http://jersey.576304.n2.nabble.com/Session-Handling-not-working-with-Jersey-Client-td4519663.html
The Jersey client by default uses HttpURLConnection that does not
support cookie management (and thus sessions).
You need to switch to using the Apache HTTP client support.
Then set the following property to true: PROPERTY_HANDLE_COOKIES
DefaultApacheHttpClientConfig config = new
DefaultApacheHttpClientConfig(); config
.setProperty("com.sun.jersey.impl.client.httpclient.handleCookies",
true);
ApacheHttpClient c = ApacheHttpClient.create(config);
Plus you can also use authorization with the Apache HTTP client
integration.
DefaultApacheHttpClientConfig config = new DefaultApacheHttpClientConfig();
config.getState().setCredentials(null, null, -1, "foo", "bar");
ApacheHttpClient c = ApacheHttpClient.create(config);
WebResource r = c.resource("http://host/base");
String s = r.get(String.class);
s = r.post(String.class, s);
I am trying to send a POST request via a WebResource instance using a Jersey Client. But no matter how i specify the request headers or types, it will give me a 415 Unsupported Media Type error. Below is my code
String SERVICE_URL = "http://hostIpAddress:8080/JiraUpdate/rest/createin/jira/createticket?"; // hostIpaddress is our server ip
ClientConfig config = new DefaultClientConfig();
Client client = Client.create(config);
System.out.println("SERVICE_URL=" + SERVICE_URL);
WebResource webResource = client.resource(UriBuilder.fromUri(SERVICE_URL).build());
String input = "{\"fields\":{\"project\":{\"key\":\"Invoicing\"},\"summary\":\"REST Test\",\"description\": \"Creating of an issue using project keys and issue type names using the REST API\",\"issuetype\":{\"name\":\"Bug\"}}}";
ClientResponse response = webResource.header("Content-Type", "application/json;charset=UTF-8")
.type(MediaType.TEXT_PLAIN_TYPE).post(ClientResponse.class, input);
I have tried to set the type to MediaType.APPLICATION_FORM_URLENCODED_TYPE as well as MediaType.APPLICATION_JSON but it doesnt change the response. I am running this code as a standalone executable JAR in a linux environment. Any help is appreciated.
Based on Vijay-Bhushan example in the linked SO article mentioned in my second comment your code should be (and he noted UTF-8 wasnt needed):
String SERVICE_URL = "http://hostIpAddress:8080/JiraUpdate/rest/createin/jira/createticket?"; // hostIpaddress is our server ip
ClientConfig config = new DefaultClientConfig();
Client client = Client.create(config);
System.out.println("SERVICE_URL=" + SERVICE_URL);
WebResource webResource = client.resource(UriBuilder.fromUri(SERVICE_URL).build());
String input = "{\"fields\":{\"project\":{\"key\":\"Invoicing\"},\"summary\":\"REST Test\",\"description\": \"Creating of an issue using project keys and issue type names using the REST API\",\"issuetype\":{\"name\":\"Bug\"}}}";
ClientResponse response = webResource.header("Content-Type","application/json;charset=UTF-8").post(ClientResponse.class,input);
The Jersey Client API documentation has some great examples.
Context
I have a desktop JAVA application I use to upload files (blobs) to a google app blobstore.
Everything works fine with a direct connection to the Internet but it doesn't when connecting through an HTTP proxy (Squid) with authentication.
I am using httpClient 4.2.3 and I don't get any error or response. It just gets stuck when calling httpClient.execute(post).
Code
I added these lines to handle the proxy authentication and it works well when using URL to get a page:
System.setProperty("http.proxyUser", username);
System.setProperty("http.proxyPassword", password);
I tried those as well:
Authenticator.setDefault(
new Authenticator() {
#Override
public PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(
username, password.toCharArray());
}
}
);
And from now on this is the same code that works when not using a proxy.
First of all I download a page where I get the url to use to post a file to the blobstore:
URL url = new URL("http://www.example.com/get-upload-url.jsp");
String urlWhereToPost=IOUtils.toString(url.openStream());
DefaultHttpClient client = new DefaultHttpClient ();
Here we prepare the multipart post:
HttpPost post
= new HttpPost( urlWhereToPost.trim() );
MultipartEntity entity
= new MultipartEntity( HttpMultipartMode.BROWSER_COMPATIBLE);
entity.addPart( "key"
, new FileBody(new File(jpgFilePath)
, "image/jpeg" )
);
post.setEntity((HttpEntity)entity);
And it is when calling execute that nothing happens (and it never get's to the next instruction):
HttpResponse execute = client.execute( post );
Tests
I have been trying several things but nothing worked:
In the beginning I thought the problem was using POST because GET works fine using URL()
but I tried using HttpClient to execute a GET and it gets stuck as well.
I used Wireshark to check the packets send to the proxy and I saw that when using URL() Wireshark recognizes the calls to the proxy as requests to execute a GET from the proxy. But when using httpClient it looks like the request is not well built because Wireshark shows a packet but doesn't recognize the inner request.
Then I tried building the POST using HttpURLConnection and it gets through the proxy and I get the answer from the server but it looks like I am not building it well because appengine doesn't find the file I send (but this would be another question...).
Conclusion
Anyone with the same problem? Any idea?
Your proxy settings are for the Java system classes. Apache HttpClient is supposed to be configured in a different way.
This link may help: Proxy authentication
I'm trying to configure Glassfish using the REST interface. I am using Jersey in my Java code. All works well, except authenticating. Bellow is a peace of code i use to do a GET. Whenever i have a used defined in Glassfish, this peace of code returns 401. I have checked the credentials using Glassfish Administration Console and CURL and they are valid. I suppose it is a problem in the way i am using Jersey. I have googled this, but i can not find relevant information. Does anyone have any suggestions? Thanks
Client client;
public JerseyRESTClient() {
client = Client.create();
client.addFilter(new HTTPBasicAuthFilter("user1", "a"));
}
public String GET(String url, String format) throws IOException {
WebResource webResource = client.resource(url);
ClientResponse c = webResource.accept(format).get(ClientResponse.class);
return new Integer(c.getStatus()).toString() + System.getProperty("line.separator") + c.getEntity(String.class);
}