33
33
34
34
import org .springframework .beans .BeanUtils ;
35
35
import org .springframework .http .client .AbstractClientHttpRequestFactoryWrapper ;
36
+ import org .springframework .http .client .ClientHttpRequest ;
36
37
import org .springframework .http .client .ClientHttpRequestFactory ;
37
38
import org .springframework .http .client .ClientHttpRequestInterceptor ;
39
+ import org .springframework .http .client .HttpComponentsClientHttpRequestFactory ;
40
+ import org .springframework .http .client .SimpleClientHttpRequestFactory ;
38
41
import org .springframework .http .converter .HttpMessageConverter ;
39
42
import org .springframework .util .Assert ;
40
43
import org .springframework .util .CollectionUtils ;
60
63
* @author Andy Wilkinson
61
64
* @author Brian Clozel
62
65
* @author Dmytro Nosan
66
+ * @author Kevin Strijbos
63
67
* @since 1.4.0
64
68
*/
65
69
public class RestTemplateBuilder {
@@ -506,6 +510,24 @@ public RestTemplateBuilder setReadTimeout(Duration readTimeout) {
506
510
this .interceptors );
507
511
}
508
512
513
+ /**
514
+ * Sets if the underling {@link ClientHttpRequestFactory} should buffer the
515
+ * {@linkplain ClientHttpRequest#getBody() request body} internally.
516
+ * @param bufferRequestBody value of the bufferRequestBody parameter
517
+ * @return a new builder instance.
518
+ * @since 2.2.0
519
+ * @see SimpleClientHttpRequestFactory#setBufferRequestBody(boolean)
520
+ * @see HttpComponentsClientHttpRequestFactory#setBufferRequestBody(boolean)
521
+ */
522
+ public RestTemplateBuilder setBufferRequestBody (boolean bufferRequestBody ) {
523
+ return new RestTemplateBuilder (this .detectRequestFactory , this .rootUri ,
524
+ this .messageConverters , this .requestFactorySupplier ,
525
+ this .uriTemplateHandler , this .errorHandler , this .basicAuthentication ,
526
+ this .restTemplateCustomizers ,
527
+ this .requestFactoryCustomizer .bufferRequestBody (bufferRequestBody ),
528
+ this .interceptors );
529
+ }
530
+
509
531
/**
510
532
* Build a new {@link RestTemplate} instance and configure it using this builder.
511
533
* @return a configured {@link RestTemplate} instance.
@@ -617,34 +639,46 @@ private static class RequestFactoryCustomizer
617
639
618
640
private final Duration readTimeout ;
619
641
642
+ private final Boolean bufferRequestBody ;
643
+
620
644
RequestFactoryCustomizer () {
621
- this (null , null );
645
+ this (null , null , null );
622
646
}
623
647
624
- private RequestFactoryCustomizer (Duration connectTimeout , Duration readTimeout ) {
648
+ private RequestFactoryCustomizer (Duration connectTimeout , Duration readTimeout ,
649
+ Boolean bufferRequestBody ) {
625
650
this .connectTimeout = connectTimeout ;
626
651
this .readTimeout = readTimeout ;
652
+ this .bufferRequestBody = bufferRequestBody ;
627
653
}
628
654
629
655
public RequestFactoryCustomizer connectTimeout (Duration connectTimeout ) {
630
- return new RequestFactoryCustomizer (connectTimeout , this .readTimeout );
656
+ return new RequestFactoryCustomizer (connectTimeout , this .readTimeout ,
657
+ this .bufferRequestBody );
631
658
}
632
659
633
660
public RequestFactoryCustomizer readTimeout (Duration readTimeout ) {
634
- return new RequestFactoryCustomizer (this .connectTimeout , readTimeout );
661
+ return new RequestFactoryCustomizer (this .connectTimeout , readTimeout ,
662
+ this .bufferRequestBody );
663
+ }
664
+
665
+ public RequestFactoryCustomizer bufferRequestBody (boolean bufferRequestBody ) {
666
+ return new RequestFactoryCustomizer (this .connectTimeout , this .readTimeout ,
667
+ bufferRequestBody );
635
668
}
636
669
637
670
@ Override
638
671
public void accept (ClientHttpRequestFactory requestFactory ) {
639
672
ClientHttpRequestFactory unwrappedRequestFactory = unwrapRequestFactoryIfNecessary (
640
673
requestFactory );
641
674
if (this .connectTimeout != null ) {
642
- new TimeoutRequestFactoryCustomizer (this .connectTimeout ,
643
- "setConnectTimeout" ).customize (unwrappedRequestFactory );
675
+ setConnectTimeout (unwrappedRequestFactory );
644
676
}
645
677
if (this .readTimeout != null ) {
646
- new TimeoutRequestFactoryCustomizer (this .readTimeout , "setReadTimeout" )
647
- .customize (unwrappedRequestFactory );
678
+ setReadTimeout (unwrappedRequestFactory );
679
+ }
680
+ if (this .bufferRequestBody != null ) {
681
+ setBufferRequestBody (unwrappedRequestFactory );
648
682
}
649
683
}
650
684
@@ -664,35 +698,37 @@ private ClientHttpRequestFactory unwrapRequestFactoryIfNecessary(
664
698
return unwrappedRequestFactory ;
665
699
}
666
700
667
- /**
668
- * {@link ClientHttpRequestFactory} customizer to call a "set timeout" method.
669
- */
670
- private static final class TimeoutRequestFactoryCustomizer {
671
-
672
- private final Duration timeout ;
673
-
674
- private final String methodName ;
701
+ private void setConnectTimeout (ClientHttpRequestFactory factory ) {
702
+ Method method = findMethod (factory , "setConnectTimeout" , int .class );
703
+ int timeout = Math .toIntExact (this .connectTimeout .toMillis ());
704
+ invoke (factory , method , timeout );
705
+ }
675
706
676
- TimeoutRequestFactoryCustomizer (Duration timeout , String methodName ) {
677
- this .timeout = timeout ;
678
- this .methodName = methodName ;
679
- }
707
+ private void setReadTimeout (ClientHttpRequestFactory factory ) {
708
+ Method method = findMethod (factory , "setReadTimeout" , int .class );
709
+ int timeout = Math .toIntExact (this .readTimeout .toMillis ());
710
+ invoke (factory , method , timeout );
711
+ }
680
712
681
- void customize (ClientHttpRequestFactory factory ) {
682
- ReflectionUtils . invokeMethod ( findMethod (factory ), factory ,
683
- Math . toIntExact ( this .timeout . toMillis ()) );
684
- }
713
+ private void setBufferRequestBody (ClientHttpRequestFactory factory ) {
714
+ Method method = findMethod (factory , "setBufferRequestBody" , boolean . class );
715
+ invoke ( factory , method , this .bufferRequestBody );
716
+ }
685
717
686
- private Method findMethod (ClientHttpRequestFactory factory ) {
687
- Method method = ReflectionUtils .findMethod (factory .getClass (),
688
- this .methodName , int .class );
689
- if (method != null ) {
690
- return method ;
691
- }
692
- throw new IllegalStateException ("Request factory " + factory .getClass ()
693
- + " does not have a " + this .methodName + "(int) method" );
718
+ private Method findMethod (ClientHttpRequestFactory requestFactory ,
719
+ String methodName , Class <?>... parameters ) {
720
+ Method method = ReflectionUtils .findMethod (requestFactory .getClass (),
721
+ methodName , parameters );
722
+ if (method != null ) {
723
+ return method ;
694
724
}
725
+ throw new IllegalStateException ("Request factory " + requestFactory .getClass ()
726
+ + " does not have a suitable " + methodName + " method" );
727
+ }
695
728
729
+ private void invoke (ClientHttpRequestFactory requestFactory , Method method ,
730
+ Object ... parameters ) {
731
+ ReflectionUtils .invokeMethod (method , requestFactory , parameters );
696
732
}
697
733
698
734
}
0 commit comments