HtmlUnit - Connection through proxy : URLConnection OK, WebClient KO - htmlunit

I cannot access http pages through a proxy with WebClient.
When I use an URLConnection there is no problem :
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("hostname", 8080));
URLConnection urlConnection = new URL("https://www.google.com/").openConnection(proxy);
BufferedReader bufferedReader = null;
try {
bufferedReader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
String line;
while ((line = bufferedReader.readLine()) != null) {
System.out.println(line);
}
} finally {
if (bufferedReader != null) {
bufferedReader.close();
}
}
But when I try with WebClient, I have an error :
WebClient webClient = new WebClient(BrowserVersion.CHROME, "hostname", 8080);
webClient.getOptions().setThrowExceptionOnFailingStatusCode(false);
webClient.getOptions().setThrowExceptionOnScriptError(false);
HtmlPage htmlPage = webClient.getPage("https://www.google.com/");
System.out.println(htmlPage.asText());
The error is "407 Proxy Authentication Required. The ISA Server requires authorization to fulfill the request. Access to the Web Proxy filter is denied."
I don't understand why with URLConnection there is no authentication problem.
Thank you for your help !

Related

HTTP POST is not working with Webclient but working with RestTemplate

I am getting Error while making POST calls with webclient as below
org.springframework.web.reactive.function.client.WebClientRequestException: An existing connection was forcibly closed by the remote host; nested exception is java.io.IOException: An existing connection was forcibly closed by the remote host
But same request working fine with restetemplate, both code as below
RestTemplate restTemplate = new RestTemplate();
final String baseUrl = "https://somehost/rest/v1/leads.json";
URI uri = null;
try {
uri = new URI(baseUrl);
} catch (URISyntaxException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
HttpHeaders headers = new HttpHeaders();
headers.set("Authorization", "Bearer 39131a98-7a53-497f-8e04-ca08c35a7775:sj");
HttpEntity<Lead> request = new HttpEntity<>(convertToLead(consent), headers);
ResponseEntity<LeadResponse> result = restTemplate.postForEntity(uri, request, LeadResponse.class);
System.out.println(result.getBody().toString());
Failed with Webclient code
ResponseEntity<Response> leadResponse = marketoWebClient.post().uri("/leads.json").bodyValue(lead).exchange()
.flatMap(clientResponse -> clientResponse.toEntity(LeadResponse.class).doOnSuccess(response -> {
if (clientResponse.statusCode().isError()) {
logger.debug("Error Details = {} {}", clientResponse.statusCode(), response);
}
})).block();

Call RestApi endpoint resource from EJB

I have been looking around for sample code how to call a Restful service written in Spring boot (deployed in different server/ip) from an EJB client.
I couldn't find a simple example or reference to guide me on how to implement an EJB client that can call a restful service(deployed in different server/ip). Could you please point me to a document or example that shows or describe how the two can interface/talk to each other.
I need to call the endpoint by passing two header parameters for authentication, if authentication is success then only retrieve the details from Rest and send back the response to EJB client.
I use something like this, try
`public void calExternal() throws ProtocolException,
MalformedURLException,
IOException,
NoSuchAlgorithmException,
InvalidKeyException {
URL myurl = new URL("API END POINT URL");
ObjectMapper mapper = new ObjectMapper();
HttpURLConnection conn = (HttpURLConnection) myurl.openConnection();
conn.setUseCaches(false);
conn.setDoInput(true);
conn.setDoOutput(true);
String payLoad = mapper.writeValueAsString("your payload here");
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/json");
conn.setRequestProperty("AUTHORIZATION-TYPE", "HMAC");
try {
OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
wr.write(payLoad);
wr.flush();
InputStream in = null;
int responseCode = conn.getResponseCode();
if (responseCode == 200) {
in = conn.getInputStream();
} else {
in = conn.getErrorStream();
}
String encoding = conn.getContentEncoding() == null ? "UTF-8" : conn.getContentEncoding();
String response = IOUtils.toString(in, encoding);
} catch (Exception e) {
e.printStackTrace();
}
}

HttpClient have both SSL and Proxy authentication configured?

I have two pieces of code using HttpClient,
First part in case that the end point requires SSL
Second is proxy connection with basic authentication
My question Is how can I make this code conditional so in cases i have SSL + Proxy or SSL only
I have hard time figuring out how to set the default credentials for example after I created the client using the client in the SSL part
.setDefaultCredentialsProvider(credsProvider)
This part is how I create the Client when I need SSL
CloseableHttpClient client = null;
if(conf.isUseSslConfig()) {
SSLContext sslcontext = SSLContexts.custom()
.loadTrustMaterial(new File(conf.getTrustStoreLocation()), conf.getTrustStorePassword().toCharArray(), new TrustSelfSignedStrategy()).build();
// Allow protocols
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext,conf.getTlsVersions(), null,
SSLConnectionSocketFactory.getDefaultHostnameVerifier());
client = HttpClients.custom().setSSLSocketFactory(sslsf).build();
}else {
client= HttpClients.createDefault();
}
And this part is how I create the Client when I need Proxy authentication:
if(conf.isUseProxyConfig()){
CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(
new AuthScope("fakeProxy.xerox.com", 80),
new UsernamePasswordCredentials("xeroxUser","fakePassword123"));
HttpClients.custom()
.setDefaultCredentialsProvider(credsProvider).build();
}
So the bottom line is how to make the two sections work together so in case
Call with SSL + Proxy and authentication
Call with only SSL
Call with only Proxy and authentication
You can write code this way to get multiple conditions resolved :
CloseableHttpClient client = null;
if(conf.isUseSslConfig() && conf.isUseProxyConfig()) {
setSSLSetting(client);
setProxy()
}else if(conf.isUseSslConfig()) {
setSSLSetting(client);
}else {
client= HttpClients.createDefault();
}
private void setProxy(){
CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(new AuthScope("fakeProxy.xerox.com", 80),new UsernamePasswordCredentials("xeroxUser","fakePassword123"));
}
private void setSSLSetting(CloseableHttpClient client){
SSLContext sslcontext = SSLContexts.custom()
.loadTrustMaterial(new File(conf.getTrustStoreLocation()), conf.getTrustStorePassword().toCharArray(), new TrustSelfSignedStrategy()).build();
// Allow protocols
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext,conf.getTlsVersions(), null,
SSLConnectionSocketFactory.getDefaultHostnameVerifier());
client = HttpClients.custom().setSSLSocketFactory(sslsf).build();
}
or you can create methods that return client with different settings and configs like this :
final Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create().register("http", new PlainConnectionSocketFactory()).register("https", sslsf).build();
final PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(registry);
private CloseableHttpClient createHttpClient(String headerName, String value) throws NoSuchAlgorithmException, KeyManagementException,KeyStoreException {
SSLContextBuilder builder = new SSLContextBuilder();
builder.loadTrustMaterial(null, new TrustSelfSignedStrategy());
Header header = new BasicHeader(headerName,value);
List<Header> headers = new ArrayList<>();
headers.add(header);
RequestConfig reqConfig = RequestConfig.custom().setConnectionRequestTimeout(long milli seconds).build();
CloseableHttpClient httpclient = HttpClients.custom().
setDefaultHeaders(headers).
setDefaultRequestConfig(reqConfig).
setConnectionManager(cm).
build();
return httpclient;
}

How do I Get current topmost stories using spring boot from http://developer.nytimes.com

How do I Get current topmost stories using spring boot from http://developer.nytimes.com
Want to know how a url can be used to get current story
In order to make a HTTP request from Java, you should use HttpURLConnection. The api of the NYT for top stories is very simple, you should send a GET request to the following URL String url = https://api.nytimes.com/svc/topstories/v2/home.json?api-key=" + apiKey, where apiKey has to be requested from NYT.
The following method does the request and returns the response as a String:
public String getTopStories(String apiKey) throws Exception {
URL url = new URL("https://api.nytimes.com/svc/topstories/v2/home.json?api-key=" + apiKey);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
int statusCode = connection.getResponseCode();
if (statusCode != HttpStatus.OK.value()) {
throw new Exception("NYT responded with:" + statusCode);
}
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
StringBuilder stringBuilder = new StringBuilder();
String line;
while ((line = bufferedReader.readLine()) != null) {
stringBuilder.append(line+"\n");
}
bufferedReader.close();
return stringBuilder.toString();
}

Upload file from applet to Spring MVC

In my application I am running an applet to scan a picture from client. I need to upload the scanned file to the server then to database. I can upload the file by submitting a form in JSP, but I need the applet to post the file to URL.
Any hep would be appreciated.
Here is the code:
public static void main(String[] args) throws Exception {
URL url = new URL("http://localhost:8080/spring/upload");
URLConnection connection = url.openConnection();
connection.setDoOutput(true);
connection.setRequestProperty("Content-Type", "text/html;charset=UTF-8");
connection.setRequestProperty("enctype", "multipart/form-data");
DataOutputStream printout = new DataOutputStream(
connection.getOutputStream());
printout.write(FileUtils.readFileToByteArray(new File("c:\\img_khar.jpg")));
printout.flush();
printout.close();
BufferedReader in = new BufferedReader(new InputStreamReader(
connection.getInputStream()));
String decodedString;
while ((decodedString = in.readLine()) != null) {
System.out.println(decodedString);
}
in.close();
}
I prefer to use http client from apache for cases like this. They provide a MultipartEntity class that can be added to your HttpPost.
http://hc.apache.org/httpcomponents-client-ga/httpmime/apidocs/org/apache/http/entity/mime/MultipartEntity.html

Resources