Avansert HttpClient-konfigurasjon
1. Oversikt
I denne artikkelen vil vi se på den avanserte bruken av Apache HttpClient bibliotek.
Vi ser på eksemplene på å legge til egendefinerte overskrifter i HTTP-forespørsler, og vi ser hvordan du konfigurerer klienten til å autorisere og sende forespørsler via en proxy-server.
Vi bruker Wiremock til å stubbe HTTP-serveren. Hvis du vil lese mer om Wiremock, kan du sjekke ut denne artikkelen.
2. HTTP-forespørsel med en egendefinert Bruker agent Overskrift
La oss si at vi vil legge til en egendefinert Bruker agent topptekst til en HTTP GET-forespørsel. De Bruker agent header inneholder en karakteristisk streng som lar nettverksprotokollfagfagene identifisere applikasjonstype, operativsystem og programvareleverandør eller programvareversjon av den forespurte programvarebrukeragenten.
Før vi begynner å skrive vår HTTP-klient, må vi starte den innebygde mock-serveren vår:
@Rule offentlige WireMockRule serviceMock = nye WireMockRule (8089);
Når vi oppretter en HttpGet eksempel kan vi ganske enkelt bruke en setHeader () metode for å sende et navn på overskriften vår sammen med verdien. Denne overskriften blir lagt til i en HTTP-forespørsel:
String userAgent = "BaeldungAgent / 1.0"; HttpClient httpClient = HttpClients.createDefault (); HttpGet httpGet = new HttpGet ("// localhost: 8089 / detail"); httpGet.setHeader (HttpHeaders.USER_AGENT, userAgent); HttpResponse respons = httpClient.execute (httpGet); assertEquals (respons.getStatusLine (). getStatusCode (), 200);
Vi legger til en Bruker agent topptekst og sende forespørselen via en henrette() metode.
Når GET-forespørsel blir sendt for en URL /detalj med topptekst Bruker agent som har en verdi lik "BaeldungAgent / 1.0" da serviceMock vil returnere 200 HTTP-responskode:
serviceMock.stubFor (get (urlEqualTo ("/ detail")) .withHeader ("User-Agent", equalTo (userAgent)) .willReturn (aResponse (). withStatus (200)));
3. Sende data i POST-anmodningsorganet
Vanligvis, når vi kjører HTTP POST-metoden, vil vi sende en enhet som et forespørselsorgan. Når du oppretter en forekomst av en HttpPost objekt, kan vi legge til kroppen i forespørselen ved hjelp av en setEntity () metode:
Streng xmlBody = "1"; HttpClient httpClient = HttpClients.createDefault (); HttpPost httpPost = ny HttpPost ("// localhost: 8089 / person"); httpPost.setHeader ("Content-Type", "application / xml"); StringEntity xmlEntity = ny StringEntity (xmlBody); httpPost.setEntity (xmlEntity); HttpResponse respons = httpClient.execute (httpPost); assertEquals (respons.getStatusLine (). getStatusCode (), 200);
Vi lager en StringEntity eksempel med en kropp som er i XML format. Det er viktig å stille inn Innholdstype overskrift til “applikasjon / xml”For å overføre informasjon til serveren om typen innhold vi sender. Når serviceMock mottar POST-forespørselen med XML-kropp, svarer den med statuskode 200 OK:
serviceMock.stubFor (post (urlEqualTo ("/ person")) .withHeader ("Content-Type", equalTo ("application / xml")) .withRequestBody (equalTo (xmlBody)) .willReturn (aResponse (). withStatus (200 )));
4. Sende forespørsler via en proxy-server
Ofte kan nettjenesten vår være bak en proxy-server som utfører ekstra logikk, cacher statiske ressurser osv. Når vi oppretter HTTP-klienten og sender en forespørsel til en faktisk tjeneste, vil vi ikke håndtere det på hver eneste HTTP-forespørsel.
For å teste dette scenariet, må vi starte en annen innebygd webserver:
@Rule offentlige WireMockRule proxyMock = nye WireMockRule (8090);
Med to innebygde servere er den første faktiske tjenesten i 8089-porten, og en proxy-server lytter på 8090-porten.
Vi konfigurerer vår HttpClient å sende alle forespørsler via proxy ved å opprette en DefaultProxyRoutePlanner som tar HttpHost eksempel proxy som argument:
HttpHost proxy = ny HttpHost ("localhost", 8090); DefaultProxyRoutePlanner routePlanner = ny DefaultProxyRoutePlanner (proxy); HttpClient httpclient = HttpClients.custom () .setRoutePlanner (routePlanner) .build ();
Proxy-serveren vår omdirigerer alle forespørsler til den faktiske tjenesten som lytter i 8090-porten. På slutten av testen bekrefter vi at forespørselen ble sendt til vår faktiske tjeneste via en fullmektig:
proxyMock.stubFor (get (urlMatching (". *")) .willReturn (aResponse (). proxiedFrom ("// localhost: 8089 /"))); serviceMock.stubFor (get (urlEqualTo ("/ private")) .willReturn (aResponse (). withStatus (200))); assertEquals (respons.getStatusLine (). getStatusCode (), 200); proxyMock.verify (getRequestedFor (urlEqualTo ("/ private")); serviceMock.verify (getRequestedFor (urlEqualTo ("/ private")));
5. Konfigurere HTTP-klienten til å autorisere via proxy
Utvide det forrige eksemplet, er det noen tilfeller når proxy-serveren brukes til å utføre autorisasjon. I en slik konfigurasjon kan en proxy autorisere alle forespørsler og sende dem til serveren som er skjult bak en proxy.
Vi kan konfigurere HttpClient til å sende hver forespørsel via proxy, sammen med Autorisasjon topptekst som skal brukes til å utføre en autorisasjonsprosess.
Anta at vi har en proxy-server som bare autoriserer én bruker - “brukernavn_admin“, med passord “hemmelig passord“.
Vi må lage BasicCredentialsProvider forekomst med legitimasjon fra brukeren som vil bli autorisert via proxy. Å lage HttpClient automatisk legge til Autorisasjon topptekst med riktig verdi, må vi lage en HttpClientContext med legitimasjon gitt og a BasicAuthCache som lagrer legitimasjon:
HttpHost proxy = ny HttpHost ("localhost", 8090); DefaultProxyRoutePlanner routePlanner = ny DefaultProxyRoutePlanner (proxy); // Client credentials CredentialsProvider credentialsProvider = new BasicCredentialsProvider (); credentialsProvider.setCredentials (nytt AuthScope (proxy), nytt UsernamePasswordCredentials ("brukernavn_admin", "hemmelig_passord")); // Opprett AuthCache-forekomst AuthCache authCache = ny BasicAuthCache (); BasicScheme basicAuth = ny BasicScheme (); authCache.put (proxy, basicAuth); HttpClientContext context = HttpClientContext.create (); context.setCredentialsProvider (credentialsProvider); context.setAuthCache (authCache); HttpClient httpclient = HttpClients.custom () .setRoutePlanner (routePlanner) .setDefaultCredentialsProvider (credentialsProvider) .build ();
Når vi setter opp vår HttpClient, komme med forespørsler til vår tjeneste vil resultere i å sende en forespørsel via fullmakt med en Autorisasjon topptekst for å utføre autorisasjonsprosessen. Det vil bli angitt i hver forespørsel automatisk.
La oss utføre en faktisk forespørsel til tjenesten:
HttpGet httpGet = new HttpGet ("// localhost: 8089 / private"); HttpResponse respons = httpclient.execute (httpGet, context);
Bekrefte en henrette() metoden på httpKlient med vår konfigurasjon bekrefter at en forespørsel gikk gjennom en proxy med en Autorisasjon Overskrift:
proxyMock.stubFor (get (urlMatching ("/ private")) .willReturn (aResponse (). proxiedFrom ("// localhost: 8089 /"))); serviceMock.stubFor (get (urlEqualTo ("/ private")) .willReturn (aResponse (). withStatus (200))); assertEquals (respons.getStatusLine (). getStatusCode (), 200); proxyMock.verify (getRequestedFor (urlEqualTo ("/ private")) .withHeader ("Authorization", inneholder ("Basic"))); serviceMock.verify (getRequestedFor (urlEqualTo ("/ private")));
6. Konklusjon
Denne artikkelen viser hvordan du konfigurerer Apache HttpClient for å utføre avanserte HTTP-samtaler. Vi så hvordan du sender forespørsler via en proxy-server og hvordan du autoriserer via proxy.
Implementeringen av alle disse eksemplene og kodebitene finnes i GitHub-prosjektet - dette er et Maven-prosjekt, så det skal være enkelt å importere og kjøre som det er.