| <!-- |
| /*************************************************************************************************************************** |
| * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations under the License. |
| ***************************************************************************************************************************/ |
| --> |
| |
| Interceptors |
| |
| <p> |
| The {@link oajrc.RestClientBuilder#interceptors(RestCallInterceptor...)} and |
| {@link oajrc.RestCall#interceptor(RestCallInterceptor)} methods can be used to |
| intercept responses during specific connection lifecycle events. |
| </p> |
| <p> |
| The {@link oajrc.RestCallLogger} class is an example of an interceptor that uses |
| the various lifecycle methods to log HTTP requests. |
| </p> |
| <p class='bpcode w800'> |
| <jd>/** |
| * Specialized interceptor for logging calls to a log file. |
| */</jd> |
| <jk>public class</jk> RestCallLogger <jk>extends</jk> RestCallInterceptor { |
| |
| <jk>private</jk> Level <jf>level</jf>; |
| <jk>private</jk> Logger <jf>log</jf>; |
| |
| <jd>/** |
| * Constructor. |
| * |
| * <ja>@param</ja> level The log level to log messages at. |
| * <ja>@param</ja> log The logger to log to. |
| */</jd> |
| <jk>protected</jk> RestCallLogger(Level level, Logger log) { |
| <jk>this</jk>.<jf>level</jf> = level; |
| <jk>this</jk>.<jf>log</jf> = log; |
| } |
| |
| <ja>@Override</ja> <jc>/* RestCallInterceptor */</jc> |
| <jk>public void</jk> onInit(RestCall restCall) { |
| <jk>if</jk> (<jf>log</jf>.isLoggable(<jf>level</jf>)) |
| restCall.captureResponse(); |
| } |
| |
| <ja>@Override</ja> <jc>/* RestCallInterceptor */</jc> |
| <jk>public void</jk> onConnect(RestCall restCall, <jk>int</jk> statusCode, HttpRequest req, HttpResponse res) { |
| <jc>// Do nothing.</jc> |
| } |
| |
| <ja>@Override</ja> <jc>/* RestCallInterceptor */</jc> |
| <jk>public void</jk> onRetry(RestCall restCall, <jk>int</jk> statusCode, HttpRequest req, HttpResponse res) { |
| <jk>if</jk> (<jf>log</jf>.isLoggable(<jf>level</jf>)) |
| <jf>log</jf>.log(level, MessageFormat.<jsm>format</jsm>(<js>"Call to {0} returned {1}. Will retry."</js>, req.getRequestLine().getUri(), statusCode)); |
| } |
| |
| <ja>@Override</ja> <jc>/* RestCallInterceptor */</jc> |
| <jk>public void</jk> onClose(RestCall restCall) <jk>throws</jk> RestCallException { |
| <jk>try</jk> { |
| <jk>if</jk> (<jf>log</jf>.isLoggable(<jf>level</jf>)) { |
| String output = restCall.getCapturedResponse(); |
| StringBuilder sb = <jk>new</jk> StringBuilder(); |
| HttpUriRequest req = restCall.getRequest(); |
| HttpResponse res = restCall.getResponse(); |
| <jk>if</jk> (req != <jk>null</jk>) { |
| sb.append(<js>"\n=== HTTP Call (outgoing) ========================================================="</js>); |
| |
| sb.append(<js>"\n=== REQUEST ===\n"</js>).append(req); |
| sb.append(<js>"\n---request headers---"</js>); |
| <jk>for</jk> (Header h : req.getAllHeaders()) |
| sb.append(<js>"\n"</js>).append(h); |
| <jk>if</jk> (req <jk>instanceof</jk> HttpEntityEnclosingRequestBase) { |
| sb.append(<js>"\n---request entity---"</js>); |
| HttpEntityEnclosingRequestBase req2 = (HttpEntityEnclosingRequestBase)req; |
| HttpEntity e = req2.getEntity(); |
| <jk>if</jk> (e == <jk>null</jk>) |
| sb.append(<js>"\nEntity is null"</js>); |
| <jk>else</jk> { |
| <jk>if</jk> (e.getContentType() != <jk>null</jk>) |
| sb.append(<js>"\n"</js>).append(e.getContentType()); |
| <jk>if</jk> (e.getContentEncoding() != <jk>null</jk>) |
| sb.append(<js>"\n"</js>).append(e.getContentEncoding()); |
| <jk>if</jk> (e.isRepeatable()) { |
| <jk>try</jk> { |
| sb.append(<js>"\n---request content---\n"</js>).append(EntityUtils.<jsm>toString</jsm>(e)); |
| } <jk>catch</jk> (Exception ex) { |
| <jk>throw new</jk> RuntimeException(ex); |
| } |
| } |
| } |
| } |
| } |
| <jk>if</jk> (res != <jk>null</jk>) { |
| sb.append(<js>"\n=== RESPONSE ===\n"</js>).append(res.getStatusLine()); |
| sb.append(<js>"\n---response headers---"</js>); |
| <jk>for</jk> (Header h : res.getAllHeaders()) |
| sb.append(<js>"\n"</js>).append(h); |
| sb.append(<js>"\n---response content---\n"</js>).append(output); |
| sb.append(<js>"\n=== END ========================================================================"</js>); |
| } |
| <jf>log</jf>.log(<jf>level</jf>, sb.toString()); |
| } |
| } <jk>catch</jk> (IOException e) { |
| <jf>log</jf>.log(Level.<jsf>SEVERE</jsf>, e.getLocalizedMessage(), e); |
| } |
| } |
| } |
| </p> |