ApacheのHttpClinetはデフォルトでAcceptヘッダを付与しません。
例えば、簡単なサンプルを次に示します。
SSLContext
やConnectionManager
,RequestConfig
を設定していませんが、そこは本質的ではないので省略しています。
HttpClientBuilder clientBuilder = HttpClientBuilder.create(); try (CloseableHttpClient client = clientBuilder.build()) { HttpGet getMethod = new HttpGet(); getMethod.setURI(URI.create("https://httpstat.us/200")); try (CloseableHttpResponse resp = client.execute(getMethod)) { String body = EntityUtils.toString(resp.getEntity(), StandardCharsets.UTF_8); logger.info("header:{}", resp.getStatusLine()); logger.info("body:{}", body); } }
|
HttpClientのDebugLogをみたいので、LogレベルをDEBUGに設定していまいます。あとコピペしやすいようにPatternをちょっとだけ修正。
Logger rootLogger = (Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME); rootLogger.setLevel(Level.DEBUG);
PatternLayoutEncoder ple = new PatternLayoutEncoder(); ple.setContext(rootLogger.getLoggerContext()); ple.setPattern("%-50class{1} %msg%n"); ple.start();
ConsoleAppender consoleAppender = (ConsoleAppender) rootLogger.getAppender("console"); consoleAppender.setEncoder(ple);
|
実行結果です。必要なところだけを抜き出しています。
RunningLogo.a.h.i.e.MainClientExec Executing request GET /200 HTTP/1.1 o.a.h.i.e.MainClientExec Target auth state: UNCHALLENGED o.a.h.i.e.MainClientExec Proxy auth state: UNCHALLENGED
o.a.h.i.c.LoggingManagedHttpClientConnection http-outgoing-0 >> GET /200 HTTP/1.1 o.a.h.i.c.LoggingManagedHttpClientConnection http-outgoing-0 >> Host: httpstat.us o.a.h.i.c.LoggingManagedHttpClientConnection http-outgoing-0 >> Connection: Keep-Alive o.a.h.i.c.LoggingManagedHttpClientConnection http-outgoing-0 >> User-Agent: Apache-HttpClient/4.5.4 (Java/11.0.2) o.a.h.i.c.LoggingManagedHttpClientConnection http-outgoing-0 >> Accept-Encoding: gzip,deflate o.a.h.i.c.Wire http-outgoing-0 >> "GET /200 HTTP/1.1[\r][\n]" o.a.h.i.c.Wire http-outgoing-0 >> "Host: httpstat.us[\r][\n]" o.a.h.i.c.Wire http-outgoing-0 >> "Connection: Keep-Alive[\r][\n]" o.a.h.i.c.Wire http-outgoing-0 >> "User-Agent: Apache-HttpClient/4.5.4 (Java/11.0.2)[\r][\n]" o.a.h.i.c.Wire http-outgoing-0 >> "Accept-Encoding: gzip,deflate[\r][\n]" o.a.h.i.c.Wire http-outgoing-0 >> "[\r][\n]"
o.a.h.i.c.Wire http-outgoing-0 << "HTTP/1.1 200 OK[\r][\n]" o.a.h.i.c.Wire http-outgoing-0 << "Cache-Control: private[\r][\n]" o.a.h.i.c.Wire http-outgoing-0 << "Server: Microsoft-IIS/10.0[\r][\n]" o.a.h.i.c.Wire http-outgoing-0 << "X-AspNetMvc-Version: 5.1[\r][\n]" o.a.h.i.c.Wire http-outgoing-0 << "Access-Control-Allow-Origin: *[\r][\n]" o.a.h.i.c.Wire http-outgoing-0 << "X-AspNet-Version: 4.0.30319[\r][\n]" o.a.h.i.c.Wire http-outgoing-0 << "X-Powered-By: ASP.NET[\r][\n]" o.a.h.i.c.Wire http-outgoing-0 << "Set-Cookie: ARRAffinity=beec3692495883b8df6195e900c12f49514e054d865a22ad2951c84f51dbaf93;Path=/;HttpOnly;Domain=httpstat.us[\r][\n]" o.a.h.i.c.Wire http-outgoing-0 << "Date: Sun, 17 Mar 2019 08:21:05 GMT[\r][\n]" o.a.h.i.c.Wire http-outgoing-0 << "Content-Length: 0[\r][\n]" o.a.h.i.c.Wire http-outgoing-0 << "[\r][\n]"
o.a.h.i.c.LoggingManagedHttpClientConnection http-outgoing-0 << HTTP/1.1 200 OK o.a.h.i.c.LoggingManagedHttpClientConnection http-outgoing-0 << Cache-Control: private o.a.h.i.c.LoggingManagedHttpClientConnection http-outgoing-0 << Server: Microsoft-IIS/10.0 o.a.h.i.c.LoggingManagedHttpClientConnection http-outgoing-0 << X-AspNetMvc-Version: 5.1 o.a.h.i.c.LoggingManagedHttpClientConnection http-outgoing-0 << Access-Control-Allow-Origin: * o.a.h.i.c.LoggingManagedHttpClientConnection http-outgoing-0 << X-AspNet-Version: 4.0.30319 o.a.h.i.c.LoggingManagedHttpClientConnection http-outgoing-0 << X-Powered-By: ASP.NET o.a.h.i.c.LoggingManagedHttpClientConnection http-outgoing-0 << Set-Cookie: ARRAffinity=beec3692495883b8df6195e900c12f49514e054d865a22ad2951c84f51dbaf93;Path=/;HttpOnly;Domain=httpstat.us o.a.h.i.c.LoggingManagedHttpClientConnection http-outgoing-0 << Date: Sun, 17 Mar 2019 08:21:05 GMT o.a.h.i.c.LoggingManagedHttpClientConnection http-outgoing-0 << Content-Length: 0 o.a.h.i.e.MainClientExec Connection can be kept alive indefinitely
o.a.HttpClientSample header:HTTP/1.1 200 OK o.a.HttpClientSample body:
|
これを見るとAccept
ヘッダを送信していません。
何が問題か?
ブラウザやcurl
はデフォルトでAcceptを送信しており、そこには*/*
が含まれています。
参照: https://developer.mozilla.org/ja/docs/Web/HTTP/Content_negotiation/List_of_default_Accept_values
サンプルに利用したhttpstatでAcceptヘッダがある場合と無い場合とで確認してみましょう。
include_accept_header$ curl http://httpstat.us/200 -v * Trying 23.99.0.12... * TCP_NODELAY set * Connected to httpstat.us (23.99.0.12) port 80 ( > GET /200 HTTP/1.1 > Host: httpstat.us > User-Agent: curl/7.58.0 > Accept: */* > < HTTP/1.1 200 OK < Cache-Control: private < Content-Length: 6 < Content-Type: text/plain; charset=utf-8 < Server: Microsoft-IIS/10.0 < X-AspNetMvc-Version: 5.1 < Access-Control-Allow-Origin: * < X-AspNet-Version: 4.0.30319 < X-Powered-By: ASP.NET < Set-Cookie: ARRAffinity=beec3692495883b8df6195e900c12f49514e054d865a22ad2951c84f51dbaf93;Path=/;HttpOnly;Domain=httpstat.us < Date: Sun, 17 Mar 2019 08:33:52 GMT < * Connection 200 OK
|
exclude_accept_header$ curl -H "Accept:" http://httpstat.us/200 -v * Trying 23.99.0.12... * TCP_NODELAY set * Connected to httpstat.us (23.99.0.12) port 80 ( > GET /200 HTTP/1.1 > Host: httpstat.us > User-Agent: curl/7.58.0 > < HTTP/1.1 200 OK < Cache-Control: private < Server: Microsoft-IIS/10.0 < X-AspNetMvc-Version: 5.1 < Access-Control-Allow-Origin: * < X-AspNet-Version: 4.0.30319 < X-Powered-By: ASP.NET < Set-Cookie: ARRAffinity=beec3692495883b8df6195e900c12f49514e054d865a22ad2951c84f51dbaf93;Path=/;HttpOnly;Domain=httpstat.us < Date: Sun, 17 Mar 2019 08:36:54 GMT < Content-Length: 0 < * Connection
|
Accpetヘッダを送信しないと、Content-Length
ヘッダが0になってBODYが空のレスポンスが返ってきました。
このサイトに限らず、例えばAcceptヘッダでapplication/json
だとJSON形式で返すようなサイトでは、Frameworkによってはこういう挙動になるかもしれません。
どう書けばいいのか
いくつかやり方がありますがDefaultHeaderを設定するのが楽だと思います。
List<BasicHeader> defaultHeaders = Arrays.asList(new BasicHeader("Accept", "*/*")); HttpClientBuilder clientBuilder = HttpClientBuilder.create() .setDefaultHeaders(defaultHeaders);
|
もしくはGetMethodに設定します。
getMethod.setHeader("Accept", "*/*");
|