Cannot download an image with an HttpClientBuilder object - java

I'm trying to download images in Java using HttpClientBuilder. On most of the cases I do not have any problem, but on this particular example, I cannot make it work and I do not know what else to try.
I attach a code example, when I run it I always get a java.net.SocketTimeoutException: Read timed out.
I've tried setting a specific User-Agent, and other settings in the request with no luck.
Any help would be appreciate, thanks.
CloseableHttpClient httpClient2 = HttpClientBuilder.create()
.setDefaultRequestConfig(
RequestConfig.custom()
.setCookieSpec(CookieSpecs.STANDARD)
.setConnectTimeout(TIMEOUT_IN_SECONDS * 1000)
.setConnectionRequestTimeout(TIMEOUT_IN_SECONDS * 1000)
.setSocketTimeout(TIMEOUT_IN_SECONDS * 1000)
.build())
.build();
final HttpGet httpGet = new HttpGet(URI.create("https://www.net-a-porter.com/variants/images/1647597286238991/in/w230_q80.jpg"));
try (CloseableHttpResponse response2 = httpClient2.execute(httpGet)) {
// code never reached
}

Try setting the user agent to something else. For example "Safari/537.36".
CloseableHttpClient httpClient2 = HttpClientBuilder.create()
.setDefaultRequestConfig(
RequestConfig.custom()
.setCookieSpec(CookieSpecs.STANDARD)
.setConnectTimeout(TIMEOUT_IN_SECONDS * 1000)
.setConnectionRequestTimeout(TIMEOUT_IN_SECONDS * 1000)
.setSocketTimeout(TIMEOUT_IN_SECONDS * 1000)
.build())
.setUserAgent("Safari/537.36")
.build();
It seems to be working for me with the "Safari/537.36" user agent.

Related

How to Make a GET Request from a Servlet

I am trying to make a GET request to a certain URL and get some data that I am going to use inside a Java servlet. This is the code I am using:
final HttpClient httpClient = HttpClient.newBuilder()
.version(HttpClient.Version.HTTP_2)
.build();
String httpPath = "http://path/to/the/thirdparty/service";
HttpRequest httpRequest = HttpRequest.newBuilder()
.GET()
.uri(URI.create(httpPath))
.build();
HttpResponse httpResponse = null;
try {
httpResponse = httpClient.send(httpRequest, HttpResponse.BodyHandlers.ofString());
} catch (InterruptedException e) {
response.getWriter().println(e.getMessage());
}
response.setContentType("application/json");
PrintWriter out = response.getWriter();
out.println(httpResponse.body().toString());
This works perfectly and gives the desired output when I run the code from inside a standalone class inside it's main method. However, when I run this from the servelet, I can't produce the output. The response code is 200, however the content is missing with a curl error:
* transfer closed with outstanding read data remaining
* Closing connection 0
curl: (18) transfer closed with outstanding read data remaining
To see whether the length of the data is the problem, I hardcoded the output that is expected from the third party response (and commented out the call from httpClient), that gets sent out in the response correctly when I make a curl request to the servlet. Any help is much appreciated.

How to fixed response time to call REST API in java?

I want to call REST API by java programming. And I also want to give a time limitation during calling that API. If response time take more than 10 second than I want to disconnect API calling and print a message that response time is more than 10 second.
Please help me by given example code of java.
Given bellow the source code of calling API.
JSONParserPost jsonParserpost = new JSONParserPost();
String output = jsonParserpost.makeHttpRequest(URL, "POST", request);
System.out.println("Row output :"+ output.toString());
JSONObject jsonObject = new JSONObject(output);
if(jsonObject != null)
responeXML = (String)jsonObject.get("response");
Here in 2nd line I've called a REST API. Now I want to fixed a time limit on duration of response of REST API.
If you are using httpClient this following link can help you from my understanding of your problem. Apache HttpClient Timeout.
int CONNECTION_TIMEOUT_MS = timeoutSeconds * 1000; // Timeout in millis.
RequestConfig requestConfig = RequestConfig.custom()
.setConnectionRequestTimeout(CONNECTION_TIMEOUT_MS)
.setConnectTimeout(CONNECTION_TIMEOUT_MS)
.setSocketTimeout(CONNECTION_TIMEOUT_MS)
.build();
HttpPost httpPost = new HttpPost(URL);
httpPost.setConfig(requestConfig);
1
URL url = new URL(this.serviceURL);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "text/xml; charset=utf-8");
connection.setRequestProperty("Accept", "application/xml;");
connection.setDoInput(true);
connection.setDoOutput(true);
/*
* connection timeout value to 20 seconds
*/
int apiReadTimeOut = 20; // 20 seconds
connection.setConnectTimeout(apiReadTimeOut * 1000);
connection.setReadTimeout(apiReadTimeOut * 1000);
2
HttpClient httpClient = null;
/*
* connection timeout value to 20 seconds
*/
final HttpParams httpParams = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(httpParams, 20 * 1000);
httpClient = new DefaultHttpClient(httpParams);
You can use spring restTemplate
#Bean
public RestTemplate restTemplate() {
RestTemplate restTemplate = new RestTemplate();
((SimpleClientHttpRequestFactory) restTemplate.getRequestFactory()).setConnectTimeout(milisecond);
((SimpleClientHttpRequestFactory) restTemplate.getRequestFactory()).setReadTimeout(milisecond);
return restTemplate;
}
Please find example
- https://howtodoinjava.com/spring-boot2/resttemplate-timeout-example/

Is a way to set Connection refused time to HTTPGet Apache ?

I want to get a web page but if return Connection refused I want to wait only 1 second
My code :
final DefaultHttpClient client = HTTPSHelper.getClientThatAllowAnyHTTPS(connectionManager);
client.getParams().setParameter(ClientPNames.COOKIE_POLICY,
CookiePolicy.BROWSER_COMPATIBILITY);
client.getParams().setParameter("http.socket.timeout", 1000);
client.getParams().setParameter("http.connection.timeout", 1000);
client.addRequestInterceptor(new RequestAcceptEncoding());
client.addResponseInterceptor(new ResponseContentEncoding());
final HttpGet get = new HttpGet(url.getUrl());
final HttpResponse resp = this.httpClient.execute(get, localContext);
When returns connection refused I have to wait a lot ...Is there a way to specify time to wait on connection refused ? Thanks
You can set the timeout for the connection this way:
final HttpParams p = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(p, 1000);
client = new DefaultHttpClient(httpParams) ;

Java httpClient 4.3.6 basic Authentication with complete URI and scheme

What I want:
Send a GET request with a preemtive bassic authentication.
The request looks about like this:
<startURL>/app/process?job=doSomething&param=value1,value2
whereas startURL is always a https link depends on the enviroment.
Looks something like this:
https://testABC.com
https://prodABC.com
startURL is also placed in a properties file as is for the diffrent enviroments.
What I looked into:
http://www.baeldung.com/httpclient-4-basic-authentication
http://www.java-tips.org/other-api-tips/httpclient/how-to-use-basic-authentication.html
http://hc.apache.org/httpcomponents-client-ga/httpclient/examples/org/apache/http/examples/client/ClientPreemptiveBasicAuthentication.java
http://hc.apache.org/httpcomponents-client-ga/tutorial/html/authentication.html
It all contains a
HttpHost targetHost = new HttpHost("hostname", portnumber, "scheme");
Which is what I am having trouble with. This method is also the only one that lets you specify the scheme as "https".
One issue is, hat I don't know the portnumber. I think (?) I probably could just specify -1 for the default port, to make it work, but even aside that I also don't have the hostname, only the above mentioned startURL. I don't really want to parse this extra each time, while I also don't really want to add another property, just for the hostname.
I digged around and found this snippet, which looks like just what I want:
HttpClient httpClient = new DefaultHttpClient();
HttpGet httpGet = new HttpGet("http://foo.com/bar");
httpGet.addHeader(BasicScheme.authenticate(
new UsernamePasswordCredentials("user", "password"),
"UTF-8", false));
HttpResponse httpResponse = httpClient.execute(httpGet);
HttpEntity responseEntity = httpResponse.getEntity();
from HTTP requests with basic authentication
It gives the complete request URL and simply adds the basic header and does not need any port specified. Only that this is now deprecated since Version 4.2:
Deprecated. (4.2) Use ContextAwareAuthScheme.authenticate( Credentials, HttpRequest, org.apache.http.protocol.HttpContext)
I couldn't find a single example for this method to return the basic auth header. It also wants a context as a parameter, which above snipped doesn't have. I really have no real clue how this is supposed to be used.
So, what i want to know concretely:
I just want to set up a request with the complete link, that contains all that there is, like:
https://testABC.com/app/process?job=doSomething&param=value1,value2
and just give this as a parameter for a request that does preemptive basic authentication.
Is there any way to do this without digging up the deprecated methods and how does it look like?
I ran into the same problem as yours.
What worked for me is the following:
UsernamePasswordCredentials creds = new UsernamePasswordCredentials("user", "12345");
HttpGet get = new HttpGet("https://foo.bar.com/rest");
HttpHost targetHost = new HttpHost("foo.bar.com", 443, "https");
CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(
new AuthScope(targetHost.getHostName(), targetHost.getPort()),
creds);
credsProvider.setCredentials(AuthScope.ANY,creds);
// Create AuthCache instance
AuthCache authCache = new BasicAuthCache();
// Generate BASIC scheme object and add it to the local auth cache
BasicScheme basicAuth = new BasicScheme();
authCache.put(targetHost, basicAuth);
// Add AuthCache to the execution context
HttpClientContext context = HttpClientContext.create();
context.setCredentialsProvider(credsProvider);
context.setAuthCache(authCache);
HttpResponse response = client.execute(targetHost, get, context);
And I found this solution on: HttpClientBuilder basic auth
In the end I wound up writing the header manually on my own and sending things with that:
String header = "Basic ";
String headerValue = "username" + ":" + "password";
String encodedHeaderValue = Base64.encodeBase64String(headerValue.getBytes());
String headerBasic = header + encodedHeaderValue;
Header authHeader = new BasicHeader("Authorization", headerBasic);
ArrayList<Header> headers = new ArrayList<Header>();
headers.add(authHeader);
ArrayList<Header> headers = getHttpHeaders();
HttpClient client = HttpClients.custom().setDefaultHeaders(headers).build();
HttpUriRequest request = RequestBuilder.get().setUri(uri).build();
HttpResponse response = client.execute(request);
int responseCode = response.getStatusLine().getStatusCode();

Apache HttpClient: set timeout for NoRouteToHostException

I am using Apache HttpClient 4.2.5 and need to set connection timeout for 30 seconds. I do the following:
int timeout = 30 * 1000;
HttpParams params = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(params, timeout);
HttpConnectionParams.setSoTimeout(params, timeout);
HttpClient client = new DefaultHttpClient(params);
HttpGet request = new HttpGet(url.toURI());
client.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT, timeout);
client.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, timeout);
HttpResponse response = client.execute(request);
But after 12 seconds NoRouteToHostException is thrown form client.execute(request). As I understand, CONNECTION_TIMEOUT and SO_TIMEOUT is useless here. Have you any idea, how to set timeout for NoRouteToHostException? I should hope that server became available within this time. Thanks for any comment and advice!

Categories

Resources