@@ -206,8 +206,8 @@ public Builder mutate() {
206206
207207 @ Nullable
208208 @ SuppressWarnings ({"rawtypes" , "unchecked" })
209- private <T > T readWithMessageConverters (ClientHttpResponse clientResponse , Runnable callback , Type bodyType ,
210- Class <T > bodyClass , @ Nullable Observation observation ) {
209+ private <T > T readWithMessageConverters (
210+ ClientHttpResponse clientResponse , Runnable callback , Type bodyType , Class <T > bodyClass ) {
211211
212212 MediaType contentType = getContentType (clientResponse );
213213
@@ -257,21 +257,8 @@ else if (messageConverter.canRead(bodyClass, contentType)) {
257257 else {
258258 cause = exc ;
259259 }
260- RestClientException restClientException = new RestClientException ("Error while extracting response for type [" +
260+ throw new RestClientException ("Error while extracting response for type [" +
261261 ResolvableType .forType (bodyType ) + "] and content type [" + contentType + "]" , cause );
262- if (observation != null ) {
263- observation .error (restClientException );
264- }
265- throw restClientException ;
266- }
267- catch (RestClientException restClientException ) {
268- if (observation != null ) {
269- observation .error (restClientException );
270- }
271- throw restClientException ;
272- }
273- finally {
274- clientResponse .close ();
275262 }
276263 }
277264
@@ -536,14 +523,16 @@ private void logBody(Object body, @Nullable MediaType mediaType, HttpMessageConv
536523
537524 @ Override
538525 public ResponseSpec retrieve () {
539- return exchangeInternal ( DefaultResponseSpec :: new , false );
526+ return new DefaultResponseSpec ( this );
540527 }
541528
542529 @ Override
530+ @ Nullable
543531 public <T > T exchange (ExchangeFunction <T > exchangeFunction , boolean close ) {
544532 return exchangeInternal (exchangeFunction , close );
545533 }
546534
535+ @ Nullable
547536 private <T > T exchangeInternal (ExchangeFunction <T > exchangeFunction , boolean close ) {
548537 Assert .notNull (exchangeFunction , "ExchangeFunction must not be null" );
549538
@@ -578,39 +567,31 @@ private <T> T exchangeInternal(ExchangeFunction<T> exchangeFunction, boolean clo
578567 }
579568 clientResponse = clientRequest .execute ();
580569 observationContext .setResponse (clientResponse );
581- ConvertibleClientHttpResponse convertibleWrapper = new DefaultConvertibleClientHttpResponse (clientResponse , observation , observationScope );
570+ ConvertibleClientHttpResponse convertibleWrapper = new DefaultConvertibleClientHttpResponse (clientResponse );
582571 return exchangeFunction .exchange (clientRequest , convertibleWrapper );
583572 }
584573 catch (IOException ex ) {
585574 ResourceAccessException resourceAccessException = createResourceAccessException (uri , this .httpMethod , ex );
586- if (observationScope != null ) {
587- observationScope .close ();
588- }
589575 if (observation != null ) {
590576 observation .error (resourceAccessException );
591- observation .stop ();
592577 }
593578 throw resourceAccessException ;
594579 }
595580 catch (Throwable error ) {
596- if (observationScope != null ) {
597- observationScope .close ();
598- }
599581 if (observation != null ) {
600582 observation .error (error );
601- observation .stop ();
602583 }
603584 throw error ;
604585 }
605586 finally {
587+ if (observationScope != null ) {
588+ observationScope .close ();
589+ }
590+ if (observation != null ) {
591+ observation .stop ();
592+ }
606593 if (close && clientResponse != null ) {
607594 clientResponse .close ();
608- if (observationScope != null ) {
609- observationScope .close ();
610- }
611- if (observation != null ) {
612- observation .stop ();
613- }
614595 }
615596 }
616597 }
@@ -719,17 +700,14 @@ private interface InternalBody {
719700
720701 private class DefaultResponseSpec implements ResponseSpec {
721702
722- private final HttpRequest clientRequest ;
723-
724- private final ClientHttpResponse clientResponse ;
703+ private final RequestHeadersSpec <?> requestHeadersSpec ;
725704
726705 private final List <StatusHandler > statusHandlers = new ArrayList <>(1 );
727706
728707 private final int defaultStatusHandlerCount ;
729708
730- DefaultResponseSpec (HttpRequest clientRequest , ClientHttpResponse clientResponse ) {
731- this .clientRequest = clientRequest ;
732- this .clientResponse = clientResponse ;
709+ DefaultResponseSpec (RequestHeadersSpec <?> requestHeadersSpec ) {
710+ this .requestHeadersSpec = requestHeadersSpec ;
733711 this .statusHandlers .addAll (DefaultRestClient .this .defaultStatusHandlers );
734712 this .statusHandlers .add (StatusHandler .defaultHandler (DefaultRestClient .this .messageConverters ));
735713 this .defaultStatusHandlerCount = this .statusHandlers .size ();
@@ -761,15 +739,15 @@ private ResponseSpec onStatusInternal(StatusHandler statusHandler) {
761739 @ Override
762740 @ Nullable
763741 public <T > T body (Class <T > bodyType ) {
764- return readBody (bodyType , bodyType );
742+ return executeAndExtract (( request , response ) -> readBody (request , response , bodyType , bodyType ) );
765743 }
766744
767745 @ Override
768746 @ Nullable
769747 public <T > T body (ParameterizedTypeReference <T > bodyType ) {
770748 Type type = bodyType .getType ();
771749 Class <T > bodyClass = bodyClass (type );
772- return readBody (type , bodyClass );
750+ return executeAndExtract (( request , response ) -> readBody (request , response , type , bodyClass ) );
773751 }
774752
775753 @ Override
@@ -785,50 +763,64 @@ public <T> ResponseEntity<T> toEntity(ParameterizedTypeReference<T> bodyType) {
785763 }
786764
787765 private <T > ResponseEntity <T > toEntityInternal (Type bodyType , Class <T > bodyClass ) {
788- T body = readBody (bodyType , bodyClass );
789- try {
790- return ResponseEntity .status (this .clientResponse .getStatusCode ())
791- .headers (this .clientResponse .getHeaders ())
792- .body (body );
793- }
794- catch (IOException ex ) {
795- throw new ResourceAccessException ("Could not retrieve response status code: " + ex .getMessage (), ex );
796- }
766+ ResponseEntity <T > entity = executeAndExtract ((request , response ) -> {
767+ T body = readBody (request , response , bodyType , bodyClass );
768+ try {
769+ return ResponseEntity .status (response .getStatusCode ())
770+ .headers (response .getHeaders ())
771+ .body (body );
772+ }
773+ catch (IOException ex ) {
774+ throw new ResourceAccessException (
775+ "Could not retrieve response status code: " + ex .getMessage (), ex );
776+ }
777+ });
778+ Assert .state (entity != null , "No ResponseEntity" );
779+ return entity ;
797780 }
798781
799782 @ Override
800783 public ResponseEntity <Void > toBodilessEntity () {
801- try (this .clientResponse ) {
802- applyStatusHandlers ();
803- return ResponseEntity .status (this .clientResponse .getStatusCode ())
804- .headers (this .clientResponse .getHeaders ())
805- .build ();
806- }
807- catch (UncheckedIOException ex ) {
808- throw new ResourceAccessException ("Could not retrieve response status code: " + ex .getMessage (), ex .getCause ());
809- }
810- catch (IOException ex ) {
811- throw new ResourceAccessException ("Could not retrieve response status code: " + ex .getMessage (), ex );
812- }
784+ ResponseEntity <Void > entity = executeAndExtract ((request , response ) -> {
785+ try (response ) {
786+ applyStatusHandlers (request , response );
787+ return ResponseEntity .status (response .getStatusCode ())
788+ .headers (response .getHeaders ())
789+ .build ();
790+ }
791+ catch (UncheckedIOException ex ) {
792+ throw new ResourceAccessException (
793+ "Could not retrieve response status code: " + ex .getMessage (), ex .getCause ());
794+ }
795+ catch (IOException ex ) {
796+ throw new ResourceAccessException (
797+ "Could not retrieve response status code: " + ex .getMessage (), ex );
798+ }
799+ });
800+ Assert .state (entity != null , "No ResponseEntity" );
801+ return entity ;
813802 }
814803
804+ @ Nullable
805+ public <T > T executeAndExtract (RequestHeadersSpec .ExchangeFunction <T > exchangeFunction ) {
806+ return this .requestHeadersSpec .exchange (exchangeFunction );
807+ }
815808
816809 @ Nullable
817- private <T > T readBody (Type bodyType , Class <T > bodyClass ) {
818- return DefaultRestClient .this .readWithMessageConverters (this . clientResponse , this :: applyStatusHandlers ,
819- bodyType , bodyClass , getCurrentObservation () );
810+ private <T > T readBody (HttpRequest request , ClientHttpResponse response , Type bodyType , Class <T > bodyClass ) {
811+ return DefaultRestClient .this .readWithMessageConverters (
812+ response , () -> applyStatusHandlers ( request , response ), bodyType , bodyClass );
820813
821814 }
822815
823- private void applyStatusHandlers () {
816+ private void applyStatusHandlers (HttpRequest request , ClientHttpResponse response ) {
824817 try {
825- ClientHttpResponse response = this .clientResponse ;
826818 if (response instanceof DefaultConvertibleClientHttpResponse convertibleResponse ) {
827819 response = convertibleResponse .delegate ;
828820 }
829821 for (StatusHandler handler : this .statusHandlers ) {
830822 if (handler .test (response )) {
831- handler .handle (this . clientRequest , response );
823+ handler .handle (request , response );
832824 return ;
833825 }
834826 }
@@ -838,44 +830,29 @@ private void applyStatusHandlers() {
838830 }
839831 }
840832
841- @ Nullable
842- private Observation getCurrentObservation () {
843- if (this .clientResponse instanceof DefaultConvertibleClientHttpResponse convertibleResponse ) {
844- return convertibleResponse .observation ;
845- }
846- return null ;
847- }
848-
849833 }
850834
851835
852836 private class DefaultConvertibleClientHttpResponse implements RequestHeadersSpec .ConvertibleClientHttpResponse {
853837
854838 private final ClientHttpResponse delegate ;
855839
856- private final Observation observation ;
857-
858- private final Observation .Scope observationScope ;
859-
860- public DefaultConvertibleClientHttpResponse (ClientHttpResponse delegate , Observation observation , Observation .Scope observationScope ) {
840+ public DefaultConvertibleClientHttpResponse (ClientHttpResponse delegate ) {
861841 this .delegate = delegate ;
862- this .observation = observation ;
863- this .observationScope = observationScope ;
864842 }
865843
866-
867844 @ Nullable
868845 @ Override
869846 public <T > T bodyTo (Class <T > bodyType ) {
870- return readWithMessageConverters (this .delegate , () -> {} , bodyType , bodyType , this . observation );
847+ return readWithMessageConverters (this .delegate , () -> {} , bodyType , bodyType );
871848 }
872849
873850 @ Nullable
874851 @ Override
875852 public <T > T bodyTo (ParameterizedTypeReference <T > bodyType ) {
876853 Type type = bodyType .getType ();
877854 Class <T > bodyClass = bodyClass (type );
878- return readWithMessageConverters (this .delegate , () -> {}, type , bodyClass , this . observation );
855+ return readWithMessageConverters (this .delegate , () -> {}, type , bodyClass );
879856 }
880857
881858 @ Override
@@ -901,8 +878,6 @@ public String getStatusText() throws IOException {
901878 @ Override
902879 public void close () {
903880 this .delegate .close ();
904- this .observationScope .close ();
905- this .observation .stop ();
906881 }
907882
908883 }
0 commit comments