@@ -214,7 +214,8 @@ public Builder mutate() {
214214
215215 @ SuppressWarnings ({"rawtypes" , "unchecked" })
216216 private <T > @ Nullable T readWithMessageConverters (
217- ClientHttpResponse clientResponse , Runnable callback , Type bodyType , Class <T > bodyClass ) {
217+ ClientHttpResponse clientResponse , Runnable callback , Type bodyType , Class <T > bodyClass ,
218+ @ Nullable Map <String , Object > hints ) {
218219
219220 MediaType contentType = getContentType (clientResponse );
220221
@@ -241,7 +242,7 @@ else if (messageConverter instanceof SmartHttpMessageConverter smartMessageConve
241242 if (logger .isDebugEnabled ()) {
242243 logger .debug ("Reading to [" + resolvableType + "]" );
243244 }
244- return (T ) smartMessageConverter .read (resolvableType , responseWrapper , null );
245+ return (T ) smartMessageConverter .read (resolvableType , responseWrapper , hints );
245246 }
246247 }
247248 else if (messageConverter .canRead (bodyClass , contentType )) {
@@ -308,6 +309,8 @@ private class DefaultRequestBodyUriSpec implements RequestBodyUriSpec {
308309
309310 private @ Nullable Consumer <ClientHttpRequest > httpRequestConsumer ;
310311
312+ private @ Nullable Map <String , Object > hints ;
313+
311314 public DefaultRequestBodyUriSpec (HttpMethod httpMethod ) {
312315 this .httpMethod = httpMethod ;
313316 }
@@ -478,6 +481,21 @@ public RequestBodySpec body(StreamingHttpOutputMessage.Body body) {
478481 return this ;
479482 }
480483
484+ @ Override
485+ public DefaultRequestBodyUriSpec hint (String key , Object value ) {
486+ getHints ().put (key , value );
487+ return this ;
488+ }
489+
490+ private Map <String , Object > getHints () {
491+ Map <String , Object > hints = this .hints ;
492+ if (hints == null ) {
493+ hints = new ConcurrentHashMap <>(1 );
494+ this .hints = hints ;
495+ }
496+ return hints ;
497+ }
498+
481499 @ SuppressWarnings ({"rawtypes" , "unchecked" })
482500 private void writeWithMessageConverters (Object body , Type bodyType , ClientHttpRequest clientRequest )
483501 throws IOException {
@@ -497,7 +515,7 @@ else if (messageConverter instanceof SmartHttpMessageConverter smartMessageConve
497515 ResolvableType resolvableType = ResolvableType .forType (bodyType );
498516 if (smartMessageConverter .canWrite (resolvableType , bodyClass , contentType )) {
499517 logBody (body , contentType , smartMessageConverter );
500- smartMessageConverter .write (body , resolvableType , contentType , clientRequest , null );
518+ smartMessageConverter .write (body , resolvableType , contentType , clientRequest , this . hints );
501519 return ;
502520 }
503521 }
@@ -581,7 +599,7 @@ public <T> T exchangeForRequiredValue(RequiredValueExchangeFunction<T> exchangeF
581599 }
582600 clientResponse = clientRequest .execute ();
583601 observationContext .setResponse (clientResponse );
584- ConvertibleClientHttpResponse convertibleWrapper = new DefaultConvertibleClientHttpResponse (clientResponse );
602+ ConvertibleClientHttpResponse convertibleWrapper = new DefaultConvertibleClientHttpResponse (clientResponse , this . hints );
585603 return exchangeFunction .exchange (clientRequest , convertibleWrapper );
586604 }
587605 catch (IOException ex ) {
@@ -745,6 +763,8 @@ private class DefaultResponseSpec implements ResponseSpec {
745763
746764 private final int defaultStatusHandlerCount ;
747765
766+ private @ Nullable Map <String , Object > hints ;
767+
748768 DefaultResponseSpec (RequestHeadersSpec <?> requestHeadersSpec ) {
749769 this .requestHeadersSpec = requestHeadersSpec ;
750770 this .statusHandlers .addAll (DefaultRestClient .this .defaultStatusHandlers );
@@ -777,14 +797,14 @@ private ResponseSpec onStatusInternal(StatusHandler statusHandler) {
777797
778798 @ Override
779799 public <T > @ Nullable T body (Class <T > bodyType ) {
780- return executeAndExtract ((request , response ) -> readBody (request , response , bodyType , bodyType ));
800+ return executeAndExtract ((request , response ) -> readBody (request , response , bodyType , bodyType , this . hints ));
781801 }
782802
783803 @ Override
784804 public <T > @ Nullable T body (ParameterizedTypeReference <T > bodyType ) {
785805 Type type = bodyType .getType ();
786806 Class <T > bodyClass = bodyClass (type );
787- return executeAndExtract ((request , response ) -> readBody (request , response , type , bodyClass ));
807+ return executeAndExtract ((request , response ) -> readBody (request , response , type , bodyClass , this . hints ));
788808 }
789809
790810 @ Override
@@ -801,7 +821,7 @@ public <T> ResponseEntity<T> toEntity(ParameterizedTypeReference<T> bodyType) {
801821
802822 private <T > ResponseEntity <T > toEntityInternal (Type bodyType , Class <T > bodyClass ) {
803823 ResponseEntity <T > entity = executeAndExtract ((request , response ) -> {
804- T body = readBody (request , response , bodyType , bodyClass );
824+ T body = readBody (request , response , bodyType , bodyClass , this . hints );
805825 try {
806826 return ResponseEntity .status (response .getStatusCode ())
807827 .headers (response .getHeaders ())
@@ -838,13 +858,28 @@ public ResponseEntity<Void> toBodilessEntity() {
838858 return entity ;
839859 }
840860
861+ @ Override
862+ public ResponseSpec hint (String key , Object value ) {
863+ getHints ().put (key , value );
864+ return this ;
865+ }
866+
867+ private Map <String , Object > getHints () {
868+ Map <String , Object > hints = this .hints ;
869+ if (hints == null ) {
870+ hints = new ConcurrentHashMap <>(1 );
871+ this .hints = hints ;
872+ }
873+ return hints ;
874+ }
875+
841876 public <T > @ Nullable T executeAndExtract (RequestHeadersSpec .ExchangeFunction <T > exchangeFunction ) {
842877 return this .requestHeadersSpec .exchange (exchangeFunction );
843878 }
844879
845- private <T > @ Nullable T readBody (HttpRequest request , ClientHttpResponse response , Type bodyType , Class <T > bodyClass ) {
880+ private <T > @ Nullable T readBody (HttpRequest request , ClientHttpResponse response , Type bodyType , Class <T > bodyClass , @ Nullable Map < String , Object > hints ) {
846881 return DefaultRestClient .this .readWithMessageConverters (
847- response , () -> applyStatusHandlers (request , response ), bodyType , bodyClass );
882+ response , () -> applyStatusHandlers (request , response ), bodyType , bodyClass , hints );
848883
849884 }
850885
@@ -871,20 +906,23 @@ private class DefaultConvertibleClientHttpResponse implements RequestHeadersSpec
871906
872907 private final ClientHttpResponse delegate ;
873908
874- public DefaultConvertibleClientHttpResponse (ClientHttpResponse delegate ) {
909+ private final @ Nullable Map <String , Object > hints ;
910+
911+ public DefaultConvertibleClientHttpResponse (ClientHttpResponse delegate , @ Nullable Map <String , Object > hints ) {
875912 this .delegate = delegate ;
913+ this .hints = hints ;
876914 }
877915
878916 @ Override
879917 public <T > @ Nullable T bodyTo (Class <T > bodyType ) {
880- return readWithMessageConverters (this .delegate , () -> {} , bodyType , bodyType );
918+ return readWithMessageConverters (this .delegate , () -> {} , bodyType , bodyType , this . hints );
881919 }
882920
883921 @ Override
884922 public <T > @ Nullable T bodyTo (ParameterizedTypeReference <T > bodyType ) {
885923 Type type = bodyType .getType ();
886924 Class <T > bodyClass = bodyClass (type );
887- return readWithMessageConverters (this .delegate , () -> {}, type , bodyClass );
925+ return readWithMessageConverters (this .delegate , () -> {}, type , bodyClass , this . hints );
888926 }
889927
890928 @ Override
0 commit comments