Introduced
The Jetty HTTP client module provides an easy-to-use API, a tool class, and a high-performance, asynchronous implementation to run HTTP and HTTPS requests.
The Jetty HTTP client module requires Java version number 1.7 or higher, and Java 1.8 Applications can use lambda expressions in some HTTP client APIs.
The Jetty HTTP client is implemented and provides an asynchronous API. There is no blockage due to I/O time, so it is more efficient to utilize the thread, and it is not often suitable for load testing and parallel computing.
However, sometimes all you need to do is run a GET request for a resource, and the HTTP client also provides an asynchronous API. The thread that initiates the request is blocked until the request is processed.
In the external view. Jetty HTTP Client provides:
1) redirect support; Redirect codes such as 302 or 303 are actively trailing by themselves.
2) cookies are supported; cookies sent by the server are sent back to the server on the matching request.
3) authentication support; HTTP "Basic" and "Digest" Fever are supported. The others can be added;
4) Pre-Transfer Protocol support.
Initialization
The name of the base class is org.eclipse.jetty.client.HttpClient, as in Jetty 7 and Jetty 8 (although it is not backwards compatible with the same name in Jetty 7 and Jetty 8).
You can treat a httpclient instance as a browser instance. Like a browser, it can initiate requests to different domains, it manages redirects, cookies and certifications, and you can configure it with proxies. And he gives you a response to the request you initiated.
In order to use HttpClient, you must initialize it, configure it, and then start it:
Instantiate httpclienthttpclient httpClient = new HttpClient (); Configure HttpClient, for example:httpClient.setFollowRedirects (false); Start Httpclienthttpclient.start ();
You can create instances of multiple httpclient. The reason may be that you want to specify different configuration parameters (for example,. One instance is configured as a forward proxy and one is not), or because you want to have two instances performing like two different browsers, there are different cookies, different certifications, and so on.
When you create a httpclient instance with the parameter constructor, you can only perform simple HTTP requests, and you will not be able to fulfill HTTPS requests.
In order to fulfill the HTTPS request. You should first create a sslcontextfactory and configure it. and pass it to the HttpClient constructor. When created with a sslcontextfactory. HttpClient will be able to fulfill HTTP and HTTPS requests to whatever domain.
Instantiate and configure the sslcontextfactorysslcontextfactory sslcontextfactory = new Sslcontextfactory (); Instantiate HttpClient with the sslcontextfactoryhttpclient HttpClient = new HttpClient (sslcontextfactory); Configure HttpClient, for example:httpClient.setFollowRedirects (false); Start Httpclienthttpclient.start ();
API Introduction Blocking API
The easier way to perform an HTTP request is to:
Contentresponse response = Httpclient.get (<a target=_blank href= "Http://domain.com/path?query" >http:// domain.com/path?query</a>);
Method Httpclient.get (...) Fulfills an HTTP GET request to a given URI. Returns a contentresponse after success.
The Contentresponse object includes HTTP response information: status code, headers, and possible content. Content length is limited to 2M by default, and the following "Response content processing" describes how to handle larger content.
Suppose you want to customize a request, such as by initiating a head request instead of a get, and emulating a browser user agent. You can use such a way:
Contentresponse response = httpclient.newrequest ("Http://domain.com/path?query") . Method (Httpmethod.head) . Agent ("mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:17.0) gecko/20100101 firefox/17.0 ") . Send ();
Here's how to use shorthand:
Request Request = Httpclient.newrequest ("Http://domain.com/path?query"); Request.method (Httpmethod.head); Request.agent ("mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:17.0) gecko/20100101 firefox/17.0 "); Contentresponse response = Request.send ();
You first use Httpclient.newrequest (...) A Request object was created. Then you customize it.
When the request object is customized. You call Request.send (). Returns Contentresponse when the request processing has been played.
A simple post request also has a shorthand method:
Contentresponse response = Httpclient.post ("HTTP://DOMAIN.COM/ENTITY/1") . param ("P", "value") . Send ();
The value of the post is encoded by its own active URL.
The Jetty HTTP client actively follows the redirect itself, so it proactively handles such typical web schema Post/redirect/get, and the response object includes the contents of the response of the GET request. Trailing redirection is a feature that you can activate/stop for each request or global.
File uploads also require one line, using the Java.nio.file class of JDK 7:
Contentresponse response = httpclient.newrequest ("Http://domain.com/upload") . File (Paths.get ("File_to_ Upload.txt ")," Text/plain ") . Send ();
You can also add a time-out:
Contentresponse response = httpclient.newrequest ("Http://domain.com/path?query") . Timeout (5, timeunit.seconds) . Send ();
In the above example, after more than 5 seconds, the request is terminated and a Java.util.concurrent.TimeoutException exception is thrown.
Asynchronous API
So far we have shown how to use the blocking API of the jetty HTTP client, that is, the thread that initiates the request is blocked until the request is processed.
In this section we will look at the asynchronous, non-clogging API of the Jetty HTTP client, which is ideal for big data downloads, parallel request/response processing, and for all occasions where performance and efficient threading and resource utilization are a key factor.
The asynchronous API relies on calls to the callback listener at all stages of the request and response processing. These listener are implemented by application. Able to fulfill whatever application logic. These listener are now called in the thread that handles the request or response. Therefore, assuming that the application code in these listener takes a long time, the processing of the request or response will be blocked.
Assuming you need to run a time-consuming operation within a listener, you must use your own thread, and remember to deep copy whatever data the listener provides, because when listener returns, the data may be recycled/erased/destroyed.
Requests and responses run in two different threads, so they can run in parallel. A typical example of this parallel processing is a echo server. A large upload and a large echo download are performed at the same time.
Attention. Remember that the response can be processed and completed before the request. A typical example is a large upload (such as an error) triggered by the server to a high-speed response: When the requested content is still on the upload. The response has arrived and has been completed.
The application thread calls Request.send (Completelistener) to perform the processing of the request. Until either the request is fully processed or the blockage is returned in I/O (and therefore never blocked). Assuming that it will clog up the I/O, the thread requests the I/O system to issue an event when I/O finishes and then returns.
When such an event is triggered. A thread from the httpclient threads pool will resume processing of the response.
The response is processed by the thread. These threads either trigger the I/O system thread that the bytecode has been prepared for, or it is a thread from the httpclient thread pool (this is controlled by the Httpclient.isdispatchio () property). The response is processed until the response is processed or blocked in I/O. Assuming it is plugged in I/O, the thread requests the I/O system to emit a time after I/O is ready and then return.
When such an event is triggered. A thread from the httpclient threads pool will resume processing of the response.
When both the request and the response are processed. The last thread to be processed (typically the thread that handles the response, but also the thread that handles the request-assuming that the request takes a lot of other time than the processing of the response) will take down a request for processing.
An asynchronous get request that discards the response content can be implemented like this:
Httpclient.newrequest ("Http://domain.com/path") . Send (New Response.completelistener () { @Override Public void OnComplete (result result) { //Your logic here } });
Method Request.send (Response.completelistener) returns void and does not clog; when a request/ After the response is processed, Response.completelistener is notified that the result parameter can be obtained to the response object.
You can use the lambda expression of JDK 8 to write the same code:
Httpclient.newrequest ("Http://domain.com/path") . Send (Result), {/* Your logic here */});
You can also specify a total time-out for it:
Request Request = Httpclient.newrequest ("Http://domain.com/path") . Timeout (3, timeunit.seconds) . Send (new Response.completelistener () { @Override public void OnComplete (result result) { //Your logic Here } });
The example above specifies a timeout of 3 seconds for request/response processing.
The HTTP Client API extensively uses listener to provide hooks for all possible request and response times in a lambda expression in JDK 8. They become easier to use:
Httpclient.newrequest ("Http://domain.com/path") //ADD Request hooks . onrequestqueued ((Request), {...}) . Onrequestbegin (Request), {...} ...//More request hooks available //ADD response hooks . Onresponsebegin ((response), {...}) . Onresponseheaders ((response), {...}) . Onresponsecontent ((response, buffer), {...}) ...//More response hooks available . Send (Result), {...});
This makes the jetty HTTP client ideal for HTTP load testing, for example. You can know exactly how long each step of the request/response process takes (and therefore know where the request/response time is actually consumed).
Understanding Request events See Request.listener for response events see Response.listener.
Content Processing Request Content processing
The Jetty HTTP Client provides a number of ready-made tool classes to handle request content.
You can provide the requested content in these formats: String, byte[], Bytebuffer, Java.nio.file.Path, InputStream, and provide the implementation of your org.eclipse.jetty.client.api.ContentProvider.
Here is a sample. Use Java.nio.file.Paths to provide the requested content:
Contentresponse response = httpclient.newrequest ("Http://domain.com/upload") . File (Paths.get ("File_to_ Upload.txt ")," Text/plain ") . Send ();
This is equivalent to using the Pathcontentprovider tool class:
Contentresponse response = httpclient.newrequest ("Http://domain.com/upload") . Content (New Pathcontentprovider ( Paths.get ("File_to_upload.txt")), "Text/plain") . Send ();
Same. You can use FileInputStream through the Inputstreamcontentprovider tool class:
Contentresponse response = httpclient.newrequest ("Http://domain.com/upload") . Content (New Inputstreamcontentprovider (New FileInputStream ("File_to_upload.txt")), "Text/plain") . Send ();
Because the InputStream is blocked, the sending of the request will be blocked and the ability to consider using the asynchronous API.
Suppose you have read the content into memory. You can use the Bytescontentprovider tool class to pass it as byte[]:
byte[] bytes = ...; Contentresponse response = httpclient.newrequest ("Http://domain.com/upload") . Content (New Bytescontentprovider (bytes), "Text/plain") . Send ();
Assuming that the requested content is not immediately available, you can use Deferredcontentprovider:
Deferredcontentprovider content = new Deferredcontentprovider (); Httpclient.newrequest ("Http://domain.com/upload") . Content (content) . Send (New Response.completelistener () { @Override public void OnComplete ( Result result) { //Your logic here } });//Content not available yet here ...//an event happens, now Content is availablebyte[] bytes = ...; Content.offer (Bytebuffer.wrap (bytes)); ...//all content have arrivedcontent.close ();
Another way to provide the requested content is to use Outputstreamcontentprovider, which agrees to apply the write request content to the OutputStream provided by Outputstreamcontentprovider when the requested content is available:
Outputstreamcontentprovider content = new Outputstreamcontentprovider (); Use Try-with-resources to close the OutputStream if all content is writtentry (outputstream output = CONTENT.GETOUTPU TStream ()) { client.newrequest ("localhost", 8080) . Content (content) . Send (new Response.completelistener () { @Override public void OnComplete (result result) { //Your logic Here } }); ... Write content writecontent (output);} End of Try-with-resource, Output.close () called automatically to signal end of content
Response content Processing
Jetty HTTP Client agrees that the application handles the response content in a variety of ways.
The first way is to cache the response content in memory; using the plug-in API, the maximum cache for content in a contentresponse is 2MiB.
Suppose you want to control the length of the response content (such as limiting to a default value less than 2MiB), then you can use a org.eclipse.jetty.client.util.FutureResponseListener:
Request Request = Httpclient.newrequest ("Http://domain.com/path"); Limit response content buffer to Kibfutureresponselistener listener = new Futureresponselistener (Request, 512 * 102 4); Request.send (listener); Contentresponse response = Listener.get (5, timeunit.seconds);
Assume that the response content length escapes. The response wants to be terminated, and an exception is thrown by the method get ().
Suppose you are using an asynchronous API. You can use the Bufferingresponselistener tool class:
Httpclient.newrequest ("Http://domain.com/path") //Buffer response content up to 8 MiB . Send (new Bufferingresponselistener (8 * 1024x768 * 1024x768) { @Override public void OnComplete (result result) { if (!result.isfailed ()) { byte[] responsecontent = GetContent (); Your logic here}} );
Another method is most efficient (because it avoids content copying) and agrees that you specify a response.contentlistener, or a subclass. To process what arrives:
Contentresponse response = HttpClient . Newrequest ("Http://domain.com/path") . Send (new Response.Listener.Empty () { @Override public void Oncontent (Response Response, Bytebuffer buffer) { //Your logic here } });
The third method agrees that you wait for the response and then outputs the content using the Inputstreamresponselistener tool class:
Inputstreamresponselistener listener = new Inputstreamresponselistener (); Httpclient.newrequest ("http://domain.com/ Path ") . Send (listener);//Wait for the response headers to arriveresponse response = Listener.get (5, Timeunit.seconds ); Look at the Responseif (response.getstatus () = =) { //use try-with-resources to close input stream. Try (InputStream responsecontent = Listener.getinputstream ()) { //Your logic here }}
Other features Cookies support
Jetty HTTP Client native support cookie.
The HttpClient instance receives a cookie from the HTTP response. Then store them in Java.net.CookieStore, this class belongs to the JDK. When a new request is created, the cookie cache is consulted, assuming there is a matching cookie (that is, Coolie does not escape.) and the matching domain and request path), these cookies will be added to the request.
Applications can be programmed to enter cookie caches. To find the cookie set:
Cookiestore Cookiestore = Httpclient.getcookiestore (); list
Applications can also programmatically set cookies, assuming they are returned from an HTTP response:
Cookiestore Cookiestore = Httpclient.getcookiestore (); HttpCookie cookie = new HttpCookie ("foo", "Bar"), Cookie.setdomain ("domain.com"); Cookie.setpath ("/"); Cookie.setmaxage (TimeUnit.DAYS.toSeconds (1)), Cookiestore.add (Uri.create ("http://domain.com"), cookie);
You can remove any cookies you don't want to use:
Cookiestore Cookiestore = Httpclient.getcookiestore (); Uri uri = uri.create ("http://domain.com"); list
Assuming you want to completely disable cookie processing, you can install a Httpcookiestore.empty instance:
Httpclient.setcookiestore (New Httpcookiestore.empty ());
You can activate cookie filtering by installing a cookie cache that fulfills the filtering logic:
Httpclient.setcookiestore (New Googleonlycookiestore ()); public class Googleonlycookiestore extends httpcookiestore{ @Override public void Add (Uri uri, HttpCookie Cookie) { if (Uri.gethost () endsWith ("google.com")) Super.add (URI, cookie);} }
The example above will only keep cookies from the google.com domain or subdomain.
Certification supportThe Jetty HTTP client supports the "Basic" and "Digest" authentication mechanisms, as defined in RFC 2617.
You can configure the authentication certificate in the HTTP client instance as follows:
Uri uri = new Uri ("Http://domain.com/secure"); String realm = "Myrealm"; String user = "username"; String pass = "password"; ADD authentication Credentialsauthenticationstore auth = Httpclient.getauthenticationstore (); Auth.addauthentication (New Basicauthentication (URI, realm, user, pass)); Contentresponse response = HttpClient . Newrequest (URI) . Send () . Get (5, timeunit.seconds);
Successful authentication is cached, but you can clear them and force another authentication:
Httpclient.getauthenticationstore (). Clearauthenticationresults ();
Agent SupportThe HTTP client for jetty can be configured to use proxies.
The two types of proxies are native supported: HTTP proxies (provided via class Org.eclipse.jetty.client.HttpProxy) and Socks 4 proxies (provided through class Org.eclipse.jetty.client.Socks4Proxy). Other implementations can be written by subclass Proxyconfiguration.proxy.
A typical configuration such as the following:
Proxyconfiguration proxyconfig = Httpclient.getproxyconfiguration (); Httpproxy proxy = new Httpproxy ("ProxyHost", proxyport);//Do not proxy requests for Localhost:8080proxy.getexcludedaddre SSEs (). Add ("localhost:8080"); Httpclient.setproxyconfiguration (Proxyconfig); Contentresponse response = Httpclient.get (URI);
You specify the agent's host and port. Also set the address that you do not want to be proxied, and then set the proxy configuration on the HttpClient instance.
Jetty Development Guide: HTTP Client