HTTPClient といえば、
https://hc.apache.org/ の HttpClient
この中の ResponseHandler は、残念なのか仕方ないのか、@FunctionalInterface を持っているわけではない。
あの面倒くさいHTTPで受け取る処理をもう少しスマートに書きたくて、とりあえず以下の static メソッドを書いてみる。
static void executeHttp(HttpClient client, HttpUriRequest request, Consumer<HttpResponse> handler) throws ClientProtocolException, IOException{ client.execute(request, response ->{ handler.accept(response); return null; }); }
そして、HttpGet してみる。
try(CloseableHttpClient httpclient = HttpClients.createDefault()){ HttpGet httpget = new HttpGet("http://google.com"); System.out.println("Executing request " + httpget.getRequestLine()); executeHttp(httpclient, httpget, response->{ int status = response.getStatusLine().getStatusCode(); if (status >= 200 && status < 300){ Optional.ofNullable(response.getEntity()).<Runnable>map(entity->()->{ try{ System.out.println("EntityUtils.toString(entity) = " + EntityUtils.toString(entity) ); }catch(ParseException | IOException e){ e.printStackTrace(); } }).orElse(()->{ System.out.println("NULL receive!!"); }).run(); }else{ System.out.println("Error! HTTP status = " + status ); } }); }catch(Exception e){ e.printStackTrace(); }finally{ }
なんだか、あまりスマートじゃない。
思い切って、HTTP 200 以外は全てエラーということで、、、
でも、HttpEntity を正常処理でわたさないとならないか悩んで、、
static void executeHttp(HttpClient client, HttpUriRequest request, Consumer<HttpEntity> receive, Consumer<HttpResponse> error) { try{ client.execute(request, new ResponseHandler<String>(){ @Override public String handleResponse(HttpResponse response) throws ClientProtocolException, IOException{ int status = response.getStatusLine().getStatusCode(); if (status==200){ Optional.ofNullable(response.getEntity()).<Runnable>map(entity->()->{ receive.accept(entity); }).orElse(()->{ error.accept(response); }).run(); }else{ error.accept(response); } return null; } }); }catch(IOException e){ error.accept(null); } }
try(CloseableHttpClient httpclient = HttpClients.createDefault()){ HttpGet httpget = new HttpGet("http://google.com"); System.out.println("Executing request " + httpget.getRequestLine()); executeHttp(httpclient, httpget , entity->{ try{ System.out.println("EntityUtils.toString(entity) = " + EntityUtils.toString(entity) ); }catch(IOException e1){ e1.printStackTrace(); } } , res->{ // エラー処理 }); }catch(Exception e){ e.printStackTrace(); }finally{ }
それでもやはりスマートとは言えない。EntityUtils.toString か toByteArray かは、Consumer 実行の中で記述するから
こうなってしまうのか。。。