REST API | Jersey jar | 405 error - java

I am trying to do automate REST API through Java. For this, I am using Jersy jar.
I googled enough and was able to write a code that doesn't throw any exception. However, I am always getting 405 - Method not allowed error response when I try to reach my project's endpoint and post the request. Same endpoint returns success response on Soap UI. And there are no headers required. Media type is JSON.
Basically, I just want to do the SOAP UI operation, but through Eclipse.
PS: I'm novice, any help is appreciated.
package sample;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.Form;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status.Family;
import org.glassfish.jersey.client.JerseyInvocation.Builder;
public class Sample
{
public static void main(String a[])
{
Client client = ClientBuilder.newClient();
WebTarget resource = client.target("https://endpoint-url/Resource");
Form form = new Form();
form.param("name", "bond");
form.param("ID", "007");
Builder request = (Builder) resource.request();
request.accept(MediaType.APPLICATION_JSON);
Response response = request.get();
if (response.getStatusInfo().getFamily() == Family.SUCCESSFUL)
{
System.out.println("Success! " + response.getStatus());
System.out.println(response.readEntity(String.class));
}
else
{
System.out.println("ERROR! " + response.getStatus());
// System.out.println(response);
System.out.println(response.readEntity(String.class));
}
}
}

The issue at accept,get resource instead of Post resource
you aren't passing form parameter to resource method. That is reason getting issues.Check below
public class Sample {
public static void main(String a[])
{
Client client = ClientBuilder.newClient();
WebTarget resource = client.target("https://endpoint-url/Resource");
Form form = new Form();
form.param("name", "bond");
form.param("ID", "007");
Builder request = (Builder) resource.request();
request.accept(MediaType.APPLICATION_JSON);
Response response = request.post(Entity.entity(form,MediaType.APPLICATION_FORM_URLENCODED));
if (response.getStatusInfo().getFamily() == Family.SUCCESSFUL)
{
System.out.println("Success! " + response.getStatus());
System.out.println(response.readEntity(String.class));
}
else
{
System.out.println("ERROR! " + response.getStatus()); // System.out.println(response);
System.out.println(response.readEntity(String.class));
}
}
}

Finally, I found the code here that worked wonders for me :)
Below is the working code:
package sample;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
public class JavaNetURLRESTFulClient
{
private static final String targetURL = "https://endpoint-url/Resource";
public static void main(String[] args)
{
try {
URL targetUrl = new URL(targetURL);
HttpURLConnection httpConnection = (HttpURLConnection) targetUrl.openConnection();
httpConnection.setDoOutput(true);
httpConnection.setRequestMethod("POST");
httpConnection.setRequestProperty("Content-Type", "application/json");
String input = "{\"name\":\"bond\",\"Id\":007}";
OutputStream outputStream = httpConnection.getOutputStream();
outputStream.write(input.getBytes());
outputStream.flush();
if (httpConnection.getResponseCode() != 200) {
throw new RuntimeException("Failed : HTTP error code : "
+ httpConnection.getResponseCode());
}
BufferedReader responseBuffer = new BufferedReader(new InputStreamReader(
(httpConnection.getInputStream())));
String output;
System.out.println("Output from Server:\n");
while ((output = responseBuffer.readLine()) != null) {
System.out.println(output);
}
httpConnection.disconnect();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}

Related

Java HTTP GET for bearer token?

I'd like to get a bearer token with Java. My API reference says to do a GET with curl:
curl -G "https://api.company.com/api/auth" --data-urlencode "username=<username>" --
data-urlencode "secret=<secret>"
Then, extract the “Value” property or the bearer token from the returned JSON object.
What is the equivalent way to do this with java 8?
Please use something like this:
import javax.net.ssl.HttpsURLConnection;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
public class Main {
public static void main(String[] args) {
URL url;
try {
url = new URL("https://api.company.com/api/auth?username=<username>&secret=<secret>");
HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
con.setRequestMethod("GET");
con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
int status = con.getResponseCode();
BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuilder content = new StringBuilder();
while ((inputLine = in.readLine()) != null) {
content.append(inputLine);
}
in.close();
con.disconnect();
System.out.println("Response status: " + status);
System.out.println(content.toString());
} catch (IOException e) {
e.printStackTrace();
}
}
}
Or
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import java.io.IOException;
public class Main {
public static void main(String[] args) {
String params = "username=<username>&secret=<secret>";
CloseableHttpClient httpClient = HttpClientBuilder.create().build();
HttpGet request = new HttpGet("https://api.company.com/api/auth?" + params);
request.setHeader("Content-Type", "application/x-www-form-urlencoded");
CloseableHttpResponse response = null;
try {
response = httpClient.execute(request);
} catch (IOException e) {
e.printStackTrace();
}
System.out.println(response.getStatusLine().getStatusCode());
try {
System.out.println(response.getEntity().getContent());
} catch (IOException e) {
e.printStackTrace();
}
}
}

How to perform post request in header and body in JSON

I'm using JSON and want to send post request to server via username, password in body and x-auth-app-id, x-auth-app-hash in header..
I have test on Postmen and it return 200 (status ok), But when I build my sources it happen error.
This is my class header:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.ConnectException;
import java.net.HttpURLConnection;
import java.net.URL;
import net.sf.json.JSONObject;
public class HttpRequestUtil {
public static JSONObject httpRequest(String requestUrl, String requestMethod, String outputStr) {
JSONObject jsonObject = null;
StringBuffer buffer = new StringBuffer();
InputStream inputStream=null;
try {
URL url = new URL(requestUrl);
HttpURLConnection httpUrlConn = (HttpURLConnection) url.openConnection();
httpUrlConn.setDoOutput(true);
httpUrlConn.setDoInput(true);
httpUrlConn.setUseCaches(false);
httpUrlConn.setRequestProperty("x-auth-app-id", "6166611659356156223");
httpUrlConn.setRequestProperty("x-auth-app-hash", "a44f4ea21475fa6761392ba4bc659990bee771c413b2c207490a79f9ec78c2a61234");
httpUrlConn.setRequestProperty("Content-Type", "application/json");
httpUrlConn.setRequestMethod(requestMethod);
if ("POST".equalsIgnoreCase(requestMethod))
httpUrlConn.connect();
if (null != outputStr) {
OutputStream outputStream = httpUrlConn.getOutputStream();
outputStream.write(outputStr.getBytes("UTF-8"));
outputStream.close();
}
inputStream = httpUrlConn.getInputStream();
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
String str = null;
while ((str = bufferedReader.readLine()) != null) {
buffer.append(str);
}
bufferedReader.close();
inputStreamReader.close();
inputStream.close();
inputStream = null;
httpUrlConn.disconnect();
jsonObject = JSONObject.fromObject(buffer.toString());
}
catch (ConnectException ce) {
ce.printStackTrace();
System.out.println("Our server connection timed out");
}
catch (Exception e) {
e.printStackTrace();
System.out.println("https request error:{}");
}
finally {
try {
if(inputStream!=null) {
inputStream.close();
}
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return jsonObject;
}
}
And class Body:
import java.util.UUID;
import java.util.Map;
import java.util.HashMap;
import java.util.Formatter;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.io.UnsupportedEncodingException;
import net.sf.json.JSONException;
import net.sf.json.JSONObject;
public class CallCenterController {
public static void main(String[] args) throws JSONException {
String sipUser = "vchi_dd";
String sipPassword = "m9Bp7s+CtQj85HygnIFjPn7O4Vithrunaa";
Map<String, Object> sipAccount = new HashMap<String, Object>();
sipAccount.put("sipUser", sipUser);
sipAccount.put("sipPassword", sipPassword);
sipAccount = postData(sipUser, sipPassword);
System.out.println("result: " + sipAccount);
};
public static JSONObject postData(String sipUser, String sipPassword) {
String url="https://myservice.com/oapi/v1/call/click-to-call/02437590555&sipUser="+sipUser+"&sipPassword="+sipPassword;
return HttpRequestUtil.httpRequest(url, "POST", "");
}
}
When I build it happen an exception following as:
java.io.IOException: Server returned HTTP response code: 400 for URL: https://myservice.com/oapi/v1/call/click-to-call/02437590555&sipUser=vchi_dd&sipPassword=m9Bp7s+CtQj85HygnIFjPn7O4Vithrunaa
https request error:{}
result: null
at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1876)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1474)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:254)
at com.mypackage.HttpRequestUtil.httpRequest(HttpRequestUtil.java:63)
at com.mypackage.CallCenterController.postData(CallCenterController.java:45)
at com.mypackage.CallCenterController.main(CallCenterController.java:34)
How to send correct data to my url and fix the problem?
I would use Java HTTP Client API if your java version is high enough.
Here's a link to it https://www.baeldung.com/java-9-http-client
I have used it and it feels more maintainable and clear.
Also, it seems that you're sending the request with empty body even though you say in your question that you are sending username and password in body.
And why are you adding username and password to a map if you are not using the map?
sipAccount.put("sipUser", sipUser);
sipAccount.put("sipPassword", sipPassword);

FileNotFoundException for URL that works in browser

I am trying to use an API from https://us.mc-api.net/ for a project and I have made this as a test.
public static void main(String[] args){
try {
URL url = new URL("http://us.mc-api.net/v3/uuid/193nonaxishsl/csv/");
BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
String line;
while ((line = in.readLine()) != null) {
System.out.println(line);
}
in.close();
}
catch (MalformedURLException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
System.out.println("I/O Error");
}
}
}
And this is giving me an IOException error but when ever I open the same page in my web browser I get
false,Unknown-Username
which is what I want to get from the code. I am new and don't really know why it is happening or why.
EDIT: StackTrace
java.io.FileNotFoundException: http://us.mc-api.net/v3/uuid/193nonaxishsl/csv/
at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source)
at java.net.URL.openStream(Unknown Source)
at com.theman1928.Test.Main.main(Main.java:13)
The URL is returning status code 404 and therefore the input stream (mild guess here) is not being created and therefore is null. Sort the status code and you should be OK.
Ran it with this CSV and it is fine: other csv
If the error code is important to you then you can use HttpURLConnection:
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
System.out.println("code:"+conn.getResponseCode());
In that way you can process the response code before proceeding with a quick if-then-else check.
I tried it with the Apache HTTP libraries. The API endpoint seems to return a status code of 404, hence your error. Code I used is below.
public static void main(String[] args) throws URISyntaxException, ClientProtocolException, IOException {
HttpClient httpclient = HttpClients.createDefault();
URIBuilder builder = new URIBuilder("http://us.mc-api.net/v3/uuid/193nonaxishsl/csv/");
URI uri = builder.build();
HttpGet request = new HttpGet(uri);
HttpResponse response = httpclient.execute(request);
System.out.println(response.getStatusLine().getStatusCode()); // 404
}
Switching out the http://us.mc-api.net/v3/uuid/193nonaxishsl/csv/ with www.example.com or whatever returns a status code of 200, which further proves an error with the API endpoint. You can take a look at [Apache HTTP Components] library here.
This has to do with how the wire protocols are working in comparison with the java.net classes and an actual browser. A browser is going to be much more sophisticated than the simple java.net API you are using.
If you want to get the equivalent response value in Java, then you need to use a richer HTTP API.
This code will give you the same response as the browser; however, you need to download the Apache HttpComponents jars
The code:
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import javax.net.ssl.HttpsURLConnection;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.impl.client.HttpClients;
public class TestDriver
{
public static void main(String[] args)
{
try
{
String url = "http://us.mc-api.net/v3/uuid/193nonaxishsl/csv";
HttpGet httpGet = new HttpGet(url);
getResponseFromHTTPReq(httpGet, url);
}
catch (Throwable e)
{
e.printStackTrace();
}
}
private static String getResponseFromHTTPReq(HttpUriRequest httpReq, String url)
{
HttpClient httpclient = HttpClients.createDefault();
// Execute and get the response.
HttpResponse response = null;
HttpEntity entity = null;
try
{
response = httpclient.execute(httpReq);
entity = response.getEntity();
}
catch (IOException ioe)
{
throw new RuntimeException(ioe);
}
if (entity == null)
{
String errMsg = "No response entity back from " + url;
throw new RuntimeException(errMsg);
}
String returnRes = null;
InputStream is = null;
BufferedReader buf = null;
try
{
is = entity.getContent();
buf = new BufferedReader(new InputStreamReader(is, "UTF-8"));
System.out.println("Response Code : " + response.getStatusLine().getStatusCode());
StringBuilder sb = new StringBuilder();
String s = null;
while (true)
{
s = buf.readLine();
if (s == null || s.length() == 0)
{
break;
}
sb.append(s);
}
returnRes = sb.toString();
System.out.println("Response: [" + returnRes + "]");
}
catch (UnsupportedOperationException | IOException e)
{
throw new RuntimeException(e);
}
finally
{
if (buf != null)
{
try
{
buf.close();
}
catch (IOException e)
{
}
}
if (is != null)
{
try
{
is.close();
}
catch (IOException e)
{
}
}
}
return returnRes;
}
}
Outputs:
Response Code : 404
Response: [false,Unknown-Username]

Error in mapper.writeValue() method

I am developing a Java application to be the server in a Google Cloud Messaging Android app.
I have been following a tutorial and I managed to do rest of the tutorial with out a trouble.
My Java application has three classes which are Content.java, POST2GCM.java, App.java. These classes do what the name describes.
Content.java class is below.
package com.hmkcode.vo;
import java.io.Serializable;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
public class Content implements Serializable {
private List<String> registration_ids;
private Map<String,String> data;
public void addRegId(String regId){
if(registration_ids == null)
registration_ids = new LinkedList<String>();
registration_ids.add(regId);
}
public void createData(String title, String message){
if(data == null)
data = new HashMap<String,String>();
data.put("title", title);
data.put("message", message);
}
}
App.java class is below
package com.hmkcode.vo;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.hmkcode.vo.Content;
public class App
{
public static void main( String[] args )
{
System.out.println( "Sending POST to GCM" );
String apiKey = "AIzaSyB8azikXJKi_NjpWcVNJVO0d........";
Content content = createContent();
POST2GCM.post(apiKey, content);
}
public static Content createContent(){
Content c = new Content();
c.addRegId("APA91bFqnQzp0z5IpXWdth1lagGQZw1PTbdBAD13c-UQ0T76BBYVsFrY96MA4SFduBW9RzDguLaad-7l4QWluQcP6zSoX1HSUaAzQYSmI93....");
c.createData("Test Title", "Test Message");
return c;
}
}
POST2GCM.java class is below
package com.hmkcode.vo;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import com.fasterxml.jackson.databind.*;
public class POST2GCM {
public static void post(String apiKey, Content content){
try{
// 1. URL
URL url = new URL("https://android.googleapis.com/gcm/send");
// 2. Open connection
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
// 3. Specify POST method
conn.setRequestMethod("POST");
// 4. Set the headers
conn.setRequestProperty("Content-Type", "application/json");
conn.setRequestProperty("Authorization", "key="+apiKey);
conn.setDoOutput(true);
// 5. Add JSON data into POST request body
//`5.1 Use Jackson object mapper to convert Content object into JSON
ObjectMapper mapper = new ObjectMapper();
// 5.2 Get connection output stream
DataOutputStream wr = new DataOutputStream(conn.getOutputStream());
// 5.3 Copy Content "JSON" into
mapper.writeValue(wr,content);
// 5.4 Send the request
wr.flush();
// 5.5 close
wr.close();
// 6. Get the response
int responseCode = conn.getResponseCode();
System.out.println("\nSending 'POST' request to URL : " + url);
System.out.println("Response Code : " + responseCode);
BufferedReader in = new BufferedReader(
new InputStreamReader(conn.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
// 7. Print result
System.out.println(response.toString());
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
The problem arises in the POST2GCM.java class, in the line
mapper.writeValue(wr,content);
Where the suggestions are to add try catch block,Add exception to method signature, Add catch clauses(s).
I did all the suggestions which did not solve the problem.
What would be the problem here?
You need to add the jackson-core-2.4.3.jar library file to your project.
Add it to your java build path too.
Of course ... 2.4.3 is the version I used, but it should work with previous versions.

Http Basic Authentication in Java using HttpClient?

I am trying to mimic the functionality of this curl command in Java:
curl --basic --user username:password -d "" http://ipaddress/test/login
I wrote the following using Commons HttpClient 3.0 but somehow ended up getting an 500 Internal Server Error from the server. Can someone tell me if I'm doing anything wrong?
public class HttpBasicAuth {
private static final String ENCODING = "UTF-8";
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
try {
HttpClient client = new HttpClient();
client.getState().setCredentials(
new AuthScope("ipaddress", 443, "realm"),
new UsernamePasswordCredentials("test1", "test1")
);
PostMethod post = new PostMethod(
"http://address/test/login");
post.setDoAuthentication( true );
try {
int status = client.executeMethod( post );
System.out.println(status + "\n" + post.getResponseBodyAsString());
} finally {
// release any connection resources used by the method
post.releaseConnection();
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
And I later tried a Commons HttpClient 4.0.1 but still the same error:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
public class HttpBasicAuth {
private static final String ENCODING = "UTF-8";
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
try {
DefaultHttpClient httpclient = new DefaultHttpClient();
httpclient.getCredentialsProvider().setCredentials(
new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT),
new UsernamePasswordCredentials("test1", "test1"));
HttpPost httppost = new HttpPost("http://host:post/test/login");
System.out.println("executing request " + httppost.getRequestLine());
HttpResponse response;
response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
System.out.println("----------------------------------------");
System.out.println(response.getStatusLine());
if (entity != null) {
System.out.println("Response content length: " + entity.getContentLength());
}
if (entity != null) {
entity.consumeContent();
}
httpclient.getConnectionManager().shutdown();
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Have you tried this (using HttpClient version 4):
String encoding = Base64.getEncoder().encodeToString((user + ":" + pwd).getBytes());
HttpPost httpPost = new HttpPost("http://host:post/test/login");
httpPost.setHeader(HttpHeaders.AUTHORIZATION, "Basic " + encoding);
System.out.println("executing request " + httpPost.getRequestLine());
HttpResponse response = httpClient.execute(httpPost);
HttpEntity entity = response.getEntity();
Ok so this one works. Just in case anybody wants it, here's the version that works for me :)
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Base64;
public class HttpBasicAuth {
public static void main(String[] args) {
try {
URL url = new URL ("http://ip:port/login");
String encoding = Base64.getEncoder().encodeToString(("test1:test1").getBytes(‌"UTF‌​-8"​));
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setDoOutput(true);
connection.setRequestProperty ("Authorization", "Basic " + encoding);
InputStream content = (InputStream)connection.getInputStream();
BufferedReader in =
new BufferedReader (new InputStreamReader (content));
String line;
while ((line = in.readLine()) != null) {
System.out.println(line);
}
} catch(Exception e) {
e.printStackTrace();
}
}
}
This is the code from the accepted answer above, with some changes made regarding the Base64 encoding. The code below compiles.
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import org.apache.commons.codec.binary.Base64;
public class HttpBasicAuth {
public static void main(String[] args) {
try {
URL url = new URL ("http://ip:port/login");
Base64 b = new Base64();
String encoding = b.encodeAsString(new String("test1:test1").getBytes());
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setDoOutput(true);
connection.setRequestProperty ("Authorization", "Basic " + encoding);
InputStream content = (InputStream)connection.getInputStream();
BufferedReader in =
new BufferedReader (new InputStreamReader (content));
String line;
while ((line = in.readLine()) != null) {
System.out.println(line);
}
}
catch(Exception e) {
e.printStackTrace();
}
}
}
A small update - hopefully useful for somebody - it works for me in my project:
I use the nice Public Domain class Base64.java from Robert Harder (Thanks Robert - Code availble here: Base64 - download and put it in your package).
and make a download of a file (image, doc, etc.) with authentication and write to local disk
Example:
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
public class HttpBasicAuth {
public static void downloadFileWithAuth(String urlStr, String user, String pass, String outFilePath) {
try {
// URL url = new URL ("http://ip:port/download_url");
URL url = new URL(urlStr);
String authStr = user + ":" + pass;
String authEncoded = Base64.encodeBytes(authStr.getBytes());
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setDoOutput(true);
connection.setRequestProperty("Authorization", "Basic " + authEncoded);
File file = new File(outFilePath);
InputStream in = (InputStream) connection.getInputStream();
OutputStream out = new BufferedOutputStream(new FileOutputStream(file));
for (int b; (b = in.read()) != -1;) {
out.write(b);
}
out.close();
in.close();
}
catch (Exception e) {
e.printStackTrace();
}
}
}
Here are a few points:
You could consider upgrading to HttpClient 4 (generally speaking, if you can, I don't think version 3 is still actively supported).
A 500 status code is a server error, so it might be useful to see what the server says (any clue in the response body you're printing?). Although it might be caused by your client, the server shouldn't fail this way (a 4xx error code would be more appropriate if the request is incorrect).
I think setDoAuthentication(true) is the default (not sure). What could be useful to try is pre-emptive authentication works better:
client.getParams().setAuthenticationPreemptive(true);
Otherwise, the main difference between curl -d "" and what you're doing in Java is that, in addition to Content-Length: 0, curl also sends Content-Type: application/x-www-form-urlencoded. Note that in terms of design, you should probably send an entity with your POST request anyway.
while using Header array
String auth = Base64.getEncoder().encodeToString(("test1:test1").getBytes());
Header[] headers = {
new BasicHeader(HTTP.CONTENT_TYPE, ContentType.APPLICATION_JSON.toString()),
new BasicHeader("Authorization", "Basic " +auth)
};
Thanks for all answers above, but for me, I can not find Base64Encoder class, so I sort out my way anyway.
public static void main(String[] args) {
try {
DefaultHttpClient Client = new DefaultHttpClient();
HttpGet httpGet = new HttpGet("https://httpbin.org/basic-auth/user/passwd");
String encoding = DatatypeConverter.printBase64Binary("user:passwd".getBytes("UTF-8"));
httpGet.setHeader("Authorization", "Basic " + encoding);
HttpResponse response = Client.execute(httpGet);
System.out.println("response = " + response);
BufferedReader breader = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
StringBuilder responseString = new StringBuilder();
String line = "";
while ((line = breader.readLine()) != null) {
responseString.append(line);
}
breader.close();
String repsonseStr = responseString.toString();
System.out.println("repsonseStr = " + repsonseStr);
} catch (IOException e) {
e.printStackTrace();
}
}
One more thing, I also tried
Base64.encodeBase64String("user:passwd".getBytes());
It does NOT work due to it return a string almost same with
DatatypeConverter.printBase64Binary()
but end with "\r\n", then server will return "bad request".
Also following code is working as well, actually I sort out this first, but for some reason, it does NOT work in some cloud environment (sae.sina.com.cn if you want to know, it is a chinese cloud service). so have to use the http header instead of HttpClient credentials.
public static void main(String[] args) {
try {
DefaultHttpClient Client = new DefaultHttpClient();
Client.getCredentialsProvider().setCredentials(
AuthScope.ANY,
new UsernamePasswordCredentials("user", "passwd")
);
HttpGet httpGet = new HttpGet("https://httpbin.org/basic-auth/user/passwd");
HttpResponse response = Client.execute(httpGet);
System.out.println("response = " + response);
BufferedReader breader = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
StringBuilder responseString = new StringBuilder();
String line = "";
while ((line = breader.readLine()) != null) {
responseString.append(line);
}
breader.close();
String responseStr = responseString.toString();
System.out.println("responseStr = " + responseStr);
} catch (IOException e) {
e.printStackTrace();
}
}
An easy way to login with a HTTP POST without doing any Base64 specific calls is to use the HTTPClient BasicCredentialsProvider
import java.io.IOException;
import static java.lang.System.out;
import org.apache.http.HttpResponse;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.HttpClientBuilder;
//code
CredentialsProvider provider = new BasicCredentialsProvider();
UsernamePasswordCredentials credentials = new UsernamePasswordCredentials(user, password);
provider.setCredentials(AuthScope.ANY, credentials);
HttpClient client = HttpClientBuilder.create().setDefaultCredentialsProvider(provider).build();
HttpResponse response = client.execute(new HttpPost("http://address/test/login"));//Replace HttpPost with HttpGet if you need to perform a GET to login
int statusCode = response.getStatusLine().getStatusCode();
out.println("Response Code :"+ statusCode);
for HttpClient always use HttpRequestInterceptor
for example
httclient.addRequestInterceptor(new HttpRequestInterceptor() {
public void process(HttpRequest arg0, HttpContext context) throws HttpException, IOException {
AuthState state = (AuthState) context.getAttribute(ClientContext.TARGET_AUTH_STATE);
if (state.getAuthScheme() == null) {
BasicScheme scheme = new BasicScheme();
CredentialsProvider credentialsProvider = (CredentialsProvider) context.getAttribute(ClientContext.CREDS_PROVIDER);
Credentials credentials = credentialsProvider.getCredentials(AuthScope.ANY);
if (credentials == null) {
System.out.println("Credential >>" + credentials);
throw new HttpException();
}
state.setAuthScope(AuthScope.ANY);
state.setAuthScheme(scheme);
state.setCredentials(credentials);
}
}
}, 0);
HttpBasicAuth works for me with smaller changes
I use maven dependency
<dependency>
<groupId>net.iharder</groupId>
<artifactId>base64</artifactId>
<version>2.3.8</version>
</dependency>
Smaller change
String encoding = Base64.encodeBytes ((user + ":" + passwd).getBytes());

Categories