I am very new to Jersey and I did a search but unable to figure out whether Is there a way in jersey client to use connection pooling instead of creating a connection each and every time we are sending a new request.
The whole idea is to reuse set of connection from the pool, which will save lots or resource.
FYI I'm not looking for Connection: keep-alive.
This is what I'm doing now
public void postData()
{
Client client = new Client();
WebResource webResource = client.resource("http://SomeService.com/..");
ClientResponse response = webResource.accept("text/plain").get(ClientResponse.class);
System.out.println(response.getStatus());
System.out.println(response.getEntity(String.class));
}
Any help is highly appreciable,Expecting code snippet. Thanks in advance.
You can configure Jersey client to use Apache HttpClient with connection pooling. Details of how to do so can be found on this blog post. Note that the post itself covers Jersey 2.x, but there is a gist for Jersey 1.x mentioned in the comments.
Related
I can't get OkHttp to connect to https://www.google.com using SPDY. I used the simplest code sample to send a GET request to the site, and added a bunch of logs in the OkHttp source code to realize that the code kept creating HttpConnection, not a single SPDYConnection. Also, the ConnectionPool was empty the whole time. I am sure I was missing something because I couldn't get any of the biggest benefits: connection pooling and SPDY to work in OkHttp.
My client code:
for (int i = 0; i < 100; i++) {
Request request = new Request.Builder().url("https://www.google.com").build();
Response response = client.newCall(request).execute();
}
Why:
No SPDY connection was created?
ConnectionPool was always empty, no connection was recycled?
What is the 'correct' way to connect to SPDY website?
Adding
-Xbootclasspath/p:/home/lee/.m2/repository/org/mortbay/jetty/npn/npn-boot/1.1.7.v20140316/npn-boot-1.1.7.v20140316.jar
to JVM args fixed it for me. Now I can see SPDY connection is up.
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());
}
I am using com.sun.httpserver.HttpServer and javax.xml.ws.Endpoint to publish a JAX-WS web service, which was generated by running wsimport on an existing WSDL and implementing the genereated service interface. All this was part of JDK 1.6 (JAX-WS RI 2.1.6). My web service, running as a Java program without an additional Web container is supposed to simulate an existing SOAP service that was implemented using Apache Axis, running on Tomcat. Existing clients are likewise implemented using Apache Axis.
The problem I am having is that Soap operation calls from the clients to my JAX-WS service hang for a while, and then end with socket time-out on the client's side. This occurs even though the JAX-WS service is returning the SOAP response right away.
Inspecting the packets with tcpdump and wireshark, I noticed that with the existing Axis web service, after the SOAP response is sent from the server to the client, the server sends a "FIN ACK" packet, to which the clients responds with "FIN ACK". This concludes all packets pertinent to the SOAP operation. On the other hand, when running with the JAX-WS service, the server does not send a "FIN ACK" after the SOAP response is sent to the client. And the client seems to continue reading the socket input stream for it.
This leads me to believe that the JAX-WS web service stack is somehow keeping the socket open, even after the response to a SOAP call has been sent. And it appears that the client is expecting the socket to close at the end of a SOAP operation. Unfortunately, I cannot modify the client to behave differently.
Is there a way to configure the Endpoint or the HttpServer instances that I am using to publish the JAX-WS service to always close a socket after each SOAP operation?
I tried setting the system property http.keepAlive to false, but this did not seem to make any difference.
Thanks in advance for your help.
I found a way around this problem, but it's not very elegant. Essentially I get the HttpHandler object from the HttpContext after it's been created by the Endpoint.publish operation. And I call its handle() method from another HttpHandler class I wrote, which follows it up by sending a HttpHeader with "Connection" set to "close". Something like this:
...
HttpServer server = HttpServer.create(myInetSocketAddress, 5);
HttpContext context = server.createContext(mySoapPath);
Endpoint endpoint = Endpoint.create(mySoapImpl);
endpoint.publish(context);
MyHandler handler = new MyHandler(context.getHandler());
server.removeContext(mySoapPath);
server.createContext(mySoapPath, handler);
server.start();
...
private class MyHandler implements HttpHandler {
private HttpHandler h;
public MyHandler(HttpHandler in) {
h = in;
}
public void handle(HttpExchange t) throws IOException {
h.handle(t);
t.getResponseHeaders().set("Connection", "close");
t.sendResponseHeaders(200, 0);
t.close();
}
}
It works for my current needs, but it just seems like there's got to be a better way. Please do post if you have another solution. Thanks!
When I had this problem in Java 8 all requests from JAX-WS RI 2.2.9 had header: Connection: keep-alive
To force closing TCP connection after each request I had to change this header to Connection: close
I had done it by:
SoapService service = new SoapService(url);
SoapPort port = service.getSomePort();
Map<String, List<String>> requestHeaders = new HashMap<>();
requestHeaders.put("Connection", Collections.singletonList("close"));
BindingProvider bindingProvider = (BindingProvider)port;
bindingProvider.getRequestContext().put(MessageContext.HTTP_REQUEST_HEADERS, requestHeaders);
where:
public static final String HTTP_REQUEST_HEADERS = "javax.xml.ws.http.request.headers";
It's not clicking how one is supposed to connect to a hosted Cloudant database using Ektorp. I'm using Ektorp 1.1 in Eclipse via the new m2eclipse Maven integration (which is pretty sweet). I'm struggling to find good CouchDB/Cloudant/Ektorp documentation other than javadocs.
I'm trying to get the sample Ektorp API example from their main page to work:
HttpClient httpClient = new StdHttpClient.Builder()
.host("localhost")
.port(5984)
.build();
CouchDbInstance dbInstance = new StdCouchDbInstance(httpClient);
CouchDbConnector db = new StdCouchDbConnector("mydatabase", dbInstance);
db.createDatabaseIfNotExists();
It doesn't matter what I use to build the httpClient with, I always get the UnknownHostException error below. I've tried these URLs for the host: https/http://cloudant.com/db/_session and https/http://[username].cloudant.com
What about the port number? Should the username and password be included in the StdHttpClient.Builder()?
Here's the full error - it's failing on the createDatabaseIfNotExists() call but I'm not confident the CouchDbConnector variable is correct.
Exception in thread "main" org.ektorp.DbAccessException: java.net.UnknownHostException: https://cloudant.com/db/_session
at org.ektorp.util.Exceptions.propagate(Exceptions.java:19)
at org.ektorp.http.StdHttpClient.executeRequest(StdHttpClient.java:104)
at org.ektorp.http.StdHttpClient.get(StdHttpClient.java:42)
at org.ektorp.http.RestTemplate.get(RestTemplate.java:21)
at org.ektorp.impl.StdCouchDbInstance.getAllDatabases(StdCouchDbInstance.java:61)
at org.ektorp.impl.StdCouchDbConnector.createDatabaseIfNotExists(StdCouchDbConnector.java:256)
at com.codegouge.examples.App.main(App.java:30)
Caused by: java.net.UnknownHostException: https://cloudant.com/db/_session
at java.net.Inet6AddressImpl.lookupAllHostAddr(Native Method)
at java.net.InetAddress$1.lookupAllHostAddr(InetAddress.java:850)
at java.net.InetAddress.getAddressFromNameService(InetAddress.java:1201)
at java.net.InetAddress.getAllByName0(InetAddress.java:1154)
at java.net.InetAddress.getAllByName(InetAddress.java:1084)
at java.net.InetAddress.getAllByName(InetAddress.java:1020)
at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:126)
at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:149)
at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:108)
at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:415)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:641)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:576)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:554)
at org.ektorp.http.StdHttpClient.executeRequest(StdHttpClient.java:96)
So I was doing a couple things wrong. Using SSL requires additional parameters. Also, Ektorp 1.1.1 includes SSL-related bug fixes to 1.1.0. So this is my final HttpClient constructor:
HttpClient httpClient = new StdHttpClient.Builder()
.host("[username].cloudant.com")
.port(443)
.username("[username]")
.password("[password]")
.enableSSL(true)
.relaxedSSLSettings(true)
.build();
Also, be sure to update ektorp's dependency in pom.xml to look for version "1.1.1". I have a blog post covering this exercise here if interested.
You also can use the URL to connect with Ektorp:
JSONObject serviceAttr = val.getJSONObject(0);
JSONObject credentials = serviceAttr.getJSONObject("credentials");
httpClient = new StdHttpClient.Builder()
.url(credentials.getString("url"))
.build();
That's is easy way to connect. I found a tutorial to connect using Ektorp 1.4.2:
http://www.ibm.com/developerworks/java/library/j-hangman-app/index.html
I'm not very familiar with Ektorp, but you'll definitely need to get your username/password in there. I'd suggest creating the HttpClient with the following code:
HttpClient httpClient = new StdHttpClient.Builder()
.host("[username].cloudant.com")
.port(443)
.username("[username]")
.password("[password]")
.build();
I've changed the port to 443 (the default for HTTPS, which Cloudant listens on) and I've added a username and password. I don't see any way to let Ektorp know that you want to use HTTPS, but with luck that'll be handled internally.
I need to establish and send/read over/from an https connection (to a website of course) but through an http proxy or SOCKS proxy. A few other requirements
supports blocking (I can't use non-blocking/nio)
isn't set as an environment or some other global scope property (there are multiple threads accessing)
I was looking into HttpCore components but I did not see any support for blocking https.
Look at the java.net.Proxy class. That does what you need. You create one, and then pass it to the URLConnection to create the connection.
To support per-thread proxy, your best bet is Apache HttpClient 4 (Http Components Client). Get the source code,
http://hc.apache.org/downloads.cgi
It comes with examples for both HTTP proxy and SOCKS proxy,
ClientExecuteProxy.java
ClientExecuteSOCKS.java
Did you look at Apache HTTP Client? Haven't used it in ages but I did use it to pick a proxy server dynamically. Example from site here:
HttpClient httpclient = new HttpClient();
httpclient.getHostConfiguration().setProxy("myproxyhost", 8080);
httpclient.getState().setProxyCredentials("my-proxy-realm", " myproxyhost",
new UsernamePasswordCredentials("my-proxy-username", "my-proxy-password"));
GetMethod httpget = new GetMethod("https://www.verisign.com/");
try {
httpclient.executeMethod(httpget);
System.out.println(httpget.getStatusLine());
} finally {
httpget.releaseConnection();
}
System.setProperty("http.proxyHost", "proxy.com");
System.setPropery("http.proxyPort", "8080");
URL url = new URL("http://java.sun.com/");
InputStream in = url.openStream();
http://java.sun.com/javase/6/docs/technotes/guides/net/proxies.html