3333
3434import org .springframework .beans .BeanUtils ;
3535import org .springframework .http .client .AbstractClientHttpRequestFactoryWrapper ;
36+ import org .springframework .http .client .ClientHttpRequest ;
3637import org .springframework .http .client .ClientHttpRequestFactory ;
3738import org .springframework .http .client .ClientHttpRequestInterceptor ;
39+ import org .springframework .http .client .HttpComponentsClientHttpRequestFactory ;
40+ import org .springframework .http .client .SimpleClientHttpRequestFactory ;
3841import org .springframework .http .converter .HttpMessageConverter ;
3942import org .springframework .util .Assert ;
4043import org .springframework .util .CollectionUtils ;
6063 * @author Andy Wilkinson
6164 * @author Brian Clozel
6265 * @author Dmytro Nosan
66+ * @author Kevin Strijbos
6367 * @since 1.4.0
6468 */
6569public class RestTemplateBuilder {
@@ -506,6 +510,24 @@ public RestTemplateBuilder setReadTimeout(Duration readTimeout) {
506510 this .interceptors );
507511 }
508512
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+
509531 /**
510532 * Build a new {@link RestTemplate} instance and configure it using this builder.
511533 * @return a configured {@link RestTemplate} instance.
@@ -617,34 +639,46 @@ private static class RequestFactoryCustomizer
617639
618640 private final Duration readTimeout ;
619641
642+ private final Boolean bufferRequestBody ;
643+
620644 RequestFactoryCustomizer () {
621- this (null , null );
645+ this (null , null , null );
622646 }
623647
624- private RequestFactoryCustomizer (Duration connectTimeout , Duration readTimeout ) {
648+ private RequestFactoryCustomizer (Duration connectTimeout , Duration readTimeout ,
649+ Boolean bufferRequestBody ) {
625650 this .connectTimeout = connectTimeout ;
626651 this .readTimeout = readTimeout ;
652+ this .bufferRequestBody = bufferRequestBody ;
627653 }
628654
629655 public RequestFactoryCustomizer connectTimeout (Duration connectTimeout ) {
630- return new RequestFactoryCustomizer (connectTimeout , this .readTimeout );
656+ return new RequestFactoryCustomizer (connectTimeout , this .readTimeout ,
657+ this .bufferRequestBody );
631658 }
632659
633660 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 );
635668 }
636669
637670 @ Override
638671 public void accept (ClientHttpRequestFactory requestFactory ) {
639672 ClientHttpRequestFactory unwrappedRequestFactory = unwrapRequestFactoryIfNecessary (
640673 requestFactory );
641674 if (this .connectTimeout != null ) {
642- new TimeoutRequestFactoryCustomizer (this .connectTimeout ,
643- "setConnectTimeout" ).customize (unwrappedRequestFactory );
675+ setConnectTimeout (unwrappedRequestFactory );
644676 }
645677 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 );
648682 }
649683 }
650684
@@ -664,35 +698,37 @@ private ClientHttpRequestFactory unwrapRequestFactoryIfNecessary(
664698 return unwrappedRequestFactory ;
665699 }
666700
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+ }
675706
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+ }
680712
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+ }
685717
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 ;
694724 }
725+ throw new IllegalStateException ("Request factory " + requestFactory .getClass ()
726+ + " does not have a suitable " + methodName + " method" );
727+ }
695728
729+ private void invoke (ClientHttpRequestFactory requestFactory , Method method ,
730+ Object ... parameters ) {
731+ ReflectionUtils .invokeMethod (method , requestFactory , parameters );
696732 }
697733
698734 }
0 commit comments