Browse Source

Rename methods in FragmentsRendering

Previous commit 81ea35c726 in main for 7.0
should have been applied in 6.2.x first for 6.2.1.

This commit applies the changes in 6.2.x as intended,
effective as of 6.2.13.

Closes gh-33974
pull/35732/head
rstoyanchev 2 months ago
parent
commit
715bc68c16
  1. 4
      framework-docs/modules/ROOT/pages/web/webflux-view.adoc
  2. 4
      framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-fragments.adoc
  3. 18
      spring-webflux/src/main/java/org/springframework/web/reactive/result/view/DefaultFragmentsRenderingBuilder.java
  4. 135
      spring-webflux/src/main/java/org/springframework/web/reactive/result/view/FragmentsRendering.java
  5. 4
      spring-webflux/src/main/java/org/springframework/web/reactive/result/view/ViewResolutionResultHandler.java
  6. 4
      spring-webflux/src/test/java/org/springframework/web/reactive/result/view/FragmentViewResolutionResultHandlerTests.java
  7. 2
      spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ModelAndViewMethodReturnValueHandler.java
  8. 2
      spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ResponseBodyEmitterReturnValueHandler.java
  9. 85
      spring-webmvc/src/main/java/org/springframework/web/servlet/view/FragmentsRendering.java
  10. 2
      spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/ModelAndViewMethodReturnValueHandlerTests.java
  11. 2
      spring-webmvc/src/test/java/org/springframework/web/servlet/view/DefaultFragmentsRenderingTests.java

4
framework-docs/modules/ROOT/pages/web/webflux-view.adoc

@ -448,7 +448,7 @@ Java::
---- ----
@GetMapping @GetMapping
FragmentsRendering handle() { FragmentsRendering handle() {
return FragmentsRendering.with("posts").fragment("comments").build(); return FragmentsRendering.fragment("posts").fragment("comments").build();
} }
---- ----
@ -458,7 +458,7 @@ Kotlin::
---- ----
@GetMapping @GetMapping
fun handle(): FragmentsRendering { fun handle(): FragmentsRendering {
return FragmentsRendering.with("posts").fragment("comments").build() return FragmentsRendering.fragment("posts").fragment("comments").build()
} }
---- ----
====== ======

4
framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-fragments.adoc

@ -48,7 +48,7 @@ Java::
---- ----
@GetMapping @GetMapping
FragmentsRendering handle() { FragmentsRendering handle() {
return FragmentsRendering.with("posts").fragment("comments").build(); return FragmentsRendering.fragment("posts").fragment("comments").build();
} }
---- ----
@ -58,7 +58,7 @@ Kotlin::
---- ----
@GetMapping @GetMapping
fun handle(): FragmentsRendering { fun handle(): FragmentsRendering {
return FragmentsRendering.with("posts").fragment("comments").build() return FragmentsRendering.fragment("posts").fragment("comments").build()
} }
---- ----
====== ======

18
spring-webflux/src/main/java/org/springframework/web/reactive/result/view/DefaultFragmentsRenderingBuilder.java

@ -49,8 +49,8 @@ class DefaultFragmentsRenderingBuilder implements FragmentsRendering.Builder {
@Nullable @Nullable
private HttpHeaders headers; private HttpHeaders headers;
DefaultFragmentsRenderingBuilder(Collection<Fragment> fragments) { DefaultFragmentsRenderingBuilder() {
this.fragmentsCollection = new ArrayList<>(fragments); this.fragmentsCollection = null;
this.fragmentsFlux = null; this.fragmentsFlux = null;
} }
@ -85,13 +85,13 @@ class DefaultFragmentsRenderingBuilder implements FragmentsRendering.Builder {
} }
@Override @Override
public FragmentsRendering.Builder fragment(String viewName, Map<String, Object> model) { public FragmentsRendering.Builder fragment(String viewName) {
return fragment(Fragment.create(viewName, model)); return fragment(Fragment.create(viewName));
} }
@Override @Override
public FragmentsRendering.Builder fragment(String viewName) { public FragmentsRendering.Builder fragment(String viewName, Map<String, Object> model) {
return fragment(Fragment.create(viewName)); return fragment(Fragment.create(viewName, model));
} }
@Override @Override
@ -100,6 +100,12 @@ class DefaultFragmentsRenderingBuilder implements FragmentsRendering.Builder {
return this; return this;
} }
@Override
public FragmentsRendering.Builder fragments(Collection<Fragment> fragments) {
initFragmentsCollection().addAll(fragments);
return this;
}
private Collection<Fragment> initFragmentsCollection() { private Collection<Fragment> initFragmentsCollection() {
if (this.fragmentsCollection == null) { if (this.fragmentsCollection == null) {
this.fragmentsCollection = new ArrayList<>(); this.fragmentsCollection = new ArrayList<>();

135
spring-webflux/src/main/java/org/springframework/web/reactive/result/view/FragmentsRendering.java

@ -17,7 +17,6 @@
package org.springframework.web.reactive.result.view; package org.springframework.web.reactive.result.view;
import java.util.Collection; import java.util.Collection;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.function.Consumer; import java.util.function.Consumer;
@ -32,13 +31,16 @@ import org.springframework.lang.Nullable;
import org.springframework.util.Assert; import org.springframework.util.Assert;
/** /**
* Public API for HTML rendering of a collection of fragments each with a view * Public API to render HTML fragments. A fragment is a portion of an HTML page.
* and independent model. For use with frontends technologies such as * Normally HTML is rendered with a single model and view. This API allows
* using multiple model and view pairs, one for each HTML fragment.
*
* <p>For use with frontends technologies such as
* <a href="https://htmx.org/">htmx</a> where multiple page fragments may be * <a href="https://htmx.org/">htmx</a> where multiple page fragments may be
* rendered in one response. Supported as a return value from Spring WebFlux * rendered in one response.
* controller methods.
* *
* <p>For full page rendering with a single model and view, use {@link Rendering}. * <p>Supported as a return value from annotated controller methods.
* For full page rendering with a single model and view, use {@link Rendering}.
* *
* @author Rossen Stoyanchev * @author Rossen Stoyanchev
* @since 6.2 * @since 6.2
@ -63,59 +65,107 @@ public interface FragmentsRendering {
/** /**
* Create a builder and add a fragment with a view name and a model. * Create a builder with one HTML fragment, also inheriting attributes from
* the shared model for the request.
* @param viewName the name of the view for the fragment * @param viewName the name of the view for the fragment
* @param model attributes for the fragment in addition to model
* attributes inherited from the model for the request
* @return this builder * @return this builder
* @since 6.2.13
*/ */
static Builder with(String viewName, Map<String, Object> model) { static Builder fragment(String viewName) {
return withCollection(List.of(Fragment.create(viewName, model))); return new DefaultFragmentsRenderingBuilder().fragment(viewName);
} }
/** /**
* Variant of {@link #with(String, Map)} with a view name only, but also * Create a builder with one HTML fragment.
* inheriting model attributes from the shared model for the request. * @param viewName the view name for the fragment
* @param viewName the name of the view for the fragment * @param model attributes for the fragment, in addition to attributes from the
* shared model for the request
* @return this builder * @return this builder
* @since 6.2.13
*/ */
static Builder with(String viewName) { static Builder fragment(String viewName, Map<String, Object> model) {
return withCollection(List.of(Fragment.create(viewName))); return new DefaultFragmentsRenderingBuilder().fragment(viewName, model);
} }
/** /**
* Variant of {@link #with(String, Map)} with a collection of fragments. * Create a builder with multiple HTML fragments.
* @param fragments the fragments to add; each fragment also inherits model * @param fragments the fragments to add; each fragment also inherits
* attributes from the shared model for the request * attributes from the shared model for the request
* @return the created builder * @return the created builder
* @since 6.2.13
*/ */
static Builder withCollection(Collection<Fragment> fragments) { static Builder fragments(Collection<Fragment> fragments) {
return new DefaultFragmentsRenderingBuilder(fragments); return new DefaultFragmentsRenderingBuilder().fragments(fragments);
} }
/** /**
* Variant of {@link #with(String, Map)} with a {@link Publisher} of fragments. * Create a builder with a {@link Publisher} of fragments.
* @param fragmentsPublisher the fragments to add; each fragment also * @param fragmentsPublisher the fragments to add; each fragment also
* inherits model attributes from the shared model for the request * inherits model attributes from the shared model for the request
* @return the created builder * @return the created builder
* @since 6.2.13
*/ */
static <P extends Publisher<Fragment>> Builder withPublisher(P fragmentsPublisher) { static <P extends Publisher<Fragment>> Builder fragmentsPublisher(P fragmentsPublisher) {
return new DefaultFragmentsRenderingBuilder(fragmentsPublisher); return new DefaultFragmentsRenderingBuilder(fragmentsPublisher);
} }
/** /**
* Variant of {@link #withPublisher(Publisher)} that allows using any * Variant of {@link #fragmentsPublisher(Publisher)} that allows using any
* producer that can be resolved to {@link Publisher} via * producer that can be resolved to {@link Publisher} via
* {@link ReactiveAdapterRegistry}. * {@link ReactiveAdapterRegistry}.
* @since 6.2.13
*/ */
static Builder withProducer(Object fragmentsProducer) { static Builder fragmentsProducer(Object fragmentsProducer) {
return new DefaultFragmentsRenderingBuilder(adaptProducer(fragmentsProducer)); ReactiveAdapter adapter = ReactiveAdapterRegistry.getSharedInstance().getAdapter(fragmentsProducer.getClass());
Assert.isTrue(adapter != null, "Unknown producer " + fragmentsProducer.getClass());
Publisher<Fragment> publisher = adapter.toPublisher(fragmentsProducer);
return fragmentsPublisher(publisher);
} }
private static Publisher<Fragment> adaptProducer(Object producer) {
ReactiveAdapter adapter = ReactiveAdapterRegistry.getSharedInstance().getAdapter(producer.getClass()); /**
Assert.isTrue(adapter != null, "Unknown producer " + producer.getClass()); * The same as {@link #fragment(String, Map)}.
return adapter.toPublisher(producer); * @deprecated in favor of {@link #fragment(String, Map)}
*/
@Deprecated(since = "6.2.13", forRemoval = true)
static Builder with(String viewName, Map<String, Object> model) {
return fragment(viewName, model);
}
/**
* The same as {@link #fragments(Collection)}.
* @deprecated in favor of {@link #fragments(Collection)}
*/
@Deprecated(since = "6.2.13", forRemoval = true)
static Builder with(String viewName) {
return fragment(viewName);
}
/**
* The same as {@link #fragments(Collection)}.
* @deprecated in favor of {@link #fragments(Collection)}
*/
@Deprecated(since = "6.2.13", forRemoval = true)
static Builder withCollection(Collection<Fragment> fragments) {
return fragments(fragments);
}
/**
* The same as {@link #fragmentsPublisher(Publisher)}.
* @deprecated in favor of {@link #fragmentsPublisher(Publisher)}
*/
@Deprecated(since = "6.2.13", forRemoval = true)
static <P extends Publisher<Fragment>> Builder withPublisher(P fragmentsPublisher) {
return fragmentsPublisher(fragmentsPublisher);
}
/**
* The same as {@link #fragmentsProducer(Object)}.
* @deprecated in favor of {@link #fragmentsProducer(Object)}
*/
@Deprecated(since = "6.2.13", forRemoval = true)
static Builder withProducer(Object fragmentsProducer) {
return fragmentsProducer(fragmentsProducer);
} }
@ -148,30 +198,39 @@ public interface FragmentsRendering {
Builder headers(Consumer<HttpHeaders> headersConsumer); Builder headers(Consumer<HttpHeaders> headersConsumer);
/** /**
* Add a fragment with a view name and a model. * Add an HTML fragment.
* @param viewName the name of the view for the fragment * @param viewName the view name for the fragment
* @param model attributes for the fragment in addition to model * @param model fragment attributes in addition to attributes from the
* attributes inherited from the model for the request * shared model for the request
* @return this builder * @return this builder
*/ */
Builder fragment(String viewName, Map<String, Object> model); Builder fragment(String viewName, Map<String, Object> model);
/** /**
* Variant of {@link #fragment(String, Map)} with a view name only, where * Add an HTML fragment. The fragment will use attributes from the shared
* the fragment model also inherits model attributes from the shared
* model for the request. * model for the request.
* @param viewName the name of the view for the fragment * @param viewName the view name for the fragment
* @return this builder * @return this builder
*/ */
Builder fragment(String viewName); Builder fragment(String viewName);
/** /**
* Variant of {@link #fragment(String, Map)} with a {@link Fragment}. * Add an HTML fragment.
* @param fragment the fragment to add * @param fragment the fragment to add; the fragment also inherits
* attributes from the shared model for the request
* @return this builder * @return this builder
*/ */
Builder fragment(Fragment fragment); Builder fragment(Fragment fragment);
/**
* Add HTML fragments.
* @param fragments the fragments to add; each fragment also inherits
* attributes from the shared model for the request
* @return this builder
* @since 6.2.13
*/
Builder fragments(Collection<Fragment> fragments);
/** /**
* Build the {@link FragmentsRendering} instance. * Build the {@link FragmentsRendering} instance.
*/ */

4
spring-webflux/src/main/java/org/springframework/web/reactive/result/view/ViewResolutionResultHandler.java

@ -220,7 +220,7 @@ public class ViewResolutionResultHandler extends HandlerResultHandlerSupport imp
} }
valueMono = (result.getReturnValue() != null ? valueMono = (result.getReturnValue() != null ?
Mono.just(FragmentsRendering.withPublisher(adapter.toPublisher(result.getReturnValue())).build()) : Mono.just(FragmentsRendering.fragmentsPublisher(adapter.toPublisher(result.getReturnValue())).build()) :
Mono.empty()); Mono.empty());
valueType = ResolvableType.forClass(FragmentsRendering.class); valueType = ResolvableType.forClass(FragmentsRendering.class);
@ -252,7 +252,7 @@ public class ViewResolutionResultHandler extends HandlerResultHandlerSupport imp
} }
if (Collection.class.isAssignableFrom(clazz)) { if (Collection.class.isAssignableFrom(clazz)) {
returnValue = FragmentsRendering.withCollection((Collection<Fragment>) returnValue).build(); returnValue = FragmentsRendering.fragments((Collection<Fragment>) returnValue).build();
clazz = FragmentsRendering.class; clazz = FragmentsRendering.class;
} }

4
spring-webflux/src/test/java/org/springframework/web/reactive/result/view/FragmentViewResolutionResultHandlerTests.java

@ -66,9 +66,9 @@ public class FragmentViewResolutionResultHandlerTests {
static Stream<Arguments> arguments() { static Stream<Arguments> arguments() {
Flux<Fragment> fragmentFlux = Flux.just(fragment1, fragment2).subscribeOn(Schedulers.boundedElastic()); Flux<Fragment> fragmentFlux = Flux.just(fragment1, fragment2).subscribeOn(Schedulers.boundedElastic());
return Stream.of( return Stream.of(
Arguments.of(FragmentsRendering.withPublisher(fragmentFlux).build(), Arguments.of(FragmentsRendering.fragmentsPublisher(fragmentFlux).build(),
on(Handler.class).resolveReturnType(FragmentsRendering.class)), on(Handler.class).resolveReturnType(FragmentsRendering.class)),
Arguments.of(FragmentsRendering.withCollection(List.of(fragment1, fragment2)).build(), Arguments.of(FragmentsRendering.fragments(List.of(fragment1, fragment2)).build(),
on(Handler.class).resolveReturnType(FragmentsRendering.class)), on(Handler.class).resolveReturnType(FragmentsRendering.class)),
Arguments.of(fragmentFlux, Arguments.of(fragmentFlux,
on(Handler.class).resolveReturnType(Flux.class, Fragment.class)), on(Handler.class).resolveReturnType(Flux.class, Fragment.class)),

2
spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ModelAndViewMethodReturnValueHandler.java

@ -92,7 +92,7 @@ public class ModelAndViewMethodReturnValueHandler implements HandlerMethodReturn
} }
if (returnValue instanceof Collection<?> mavs) { if (returnValue instanceof Collection<?> mavs) {
returnValue = FragmentsRendering.with((Collection<ModelAndView>) mavs).build(); returnValue = FragmentsRendering.fragments((Collection<ModelAndView>) mavs).build();
} }
if (returnValue instanceof FragmentsRendering rendering) { if (returnValue instanceof FragmentsRendering rendering) {

2
spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ResponseBodyEmitterReturnValueHandler.java

@ -398,7 +398,7 @@ public class ResponseBodyEmitterReturnValueHandler implements HandlerMethodRetur
FragmentHttpServletResponse fragmentResponse = FragmentHttpServletResponse fragmentResponse =
new FragmentHttpServletResponse(this.response, this.charset); new FragmentHttpServletResponse(this.response, this.charset);
FragmentsRendering render = FragmentsRendering.with(List.of(modelAndView)).build(); FragmentsRendering render = FragmentsRendering.fragments(List.of(modelAndView)).build();
render.resolveNestedViews(this::resolveViewName, this.locale); render.resolveNestedViews(this::resolveViewName, this.locale);
render.render(modelAndView.getModel(), this.request, fragmentResponse); render.render(modelAndView.getModel(), this.request, fragmentResponse);

85
spring-webmvc/src/main/java/org/springframework/web/servlet/view/FragmentsRendering.java

@ -27,11 +27,15 @@ import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.SmartView; import org.springframework.web.servlet.SmartView;
/** /**
* Public API for HTML rendering of a collection of fragments each with a view * Public API to render HTML fragments. A fragment is a portion of an HTML page.
* and independent model. For use with frontends technologies such as * Normally HTML is rendered with a single model and view. This API allows
* using multiple model and view pairs, one for each HTML fragment.
*
* <p>For use with frontends technologies such as
* <a href="https://htmx.org/">htmx</a> where multiple page fragments may be * <a href="https://htmx.org/">htmx</a> where multiple page fragments may be
* rendered in one response. Supported as a return value from Spring MVC * rendered in one response.
* controller methods. *
* <p>Supported as a return value from controller methods.
* *
* @author Rossen Stoyanchev * @author Rossen Stoyanchev
* @since 6.2 * @since 6.2
@ -51,37 +55,68 @@ public interface FragmentsRendering extends SmartView {
/** /**
* Create a builder and add a fragment with a view name and a model. * Create a builder with one HTML fragment, also inheriting attributes from
* the shared model for the request.
* @param viewName the name of the view for the fragment * @param viewName the name of the view for the fragment
* @param model attributes for the fragment in addition to model
* attributes inherited from the shared model for the request
* @return the created builder * @return the created builder
* @since 6.2.13
*/ */
static Builder with(String viewName, Map<String, Object> model) { static Builder fragment(String viewName) {
return new DefaultFragmentsRenderingBuilder().fragment(viewName, model); return new DefaultFragmentsRenderingBuilder().fragment(viewName);
} }
/** /**
* Variant of {@link #with(String, Map)} with a view name only, but also * Create a builder with one HTML fragment.
* inheriting model attributes from the shared model for the request. * @param viewName the view name for the fragment
* @param viewName the name of the view for the fragment * @param model attributes for the fragment, in addition to attributes from the
* shared model for the request
* @return the created builder * @return the created builder
* @since 6.2.13
*/ */
static Builder with(String viewName) { static Builder fragment(String viewName, Map<String, Object> model) {
return new DefaultFragmentsRenderingBuilder().fragment(viewName); return new DefaultFragmentsRenderingBuilder().fragment(viewName, model);
} }
/** /**
* Variant of {@link #with(String, Map)} with a collection of fragments. * Create a builder with multiple HTML fragments.
* @param fragments the fragments to add; each fragment also inherits model * @param fragments the fragments to add; each fragment also inherits
* attributes from the shared model for the request * attributes from the shared model for the request
* @return the created builder * @return the created builder
* @since 6.2.13
*/ */
static Builder with(Collection<ModelAndView> fragments) { static Builder fragments(Collection<ModelAndView> fragments) {
return new DefaultFragmentsRenderingBuilder().fragments(fragments); return new DefaultFragmentsRenderingBuilder().fragments(fragments);
} }
/**
* The same as {@link #fragment(String, Map)}.
* @deprecated in favor of {@link #fragment(String, Map)}
*/
@Deprecated(since = "6.2.13", forRemoval = true)
static Builder with(String viewName, Map<String, Object> model) {
return fragment(viewName, model);
}
/**
* The same as {@link #fragment(String)}.
* @deprecated in favor of {@link #fragment(String)}
*/
@Deprecated(since = "6.2.13", forRemoval = true)
static Builder with(String viewName) {
return fragment(viewName);
}
/**
* The same as {@link #fragments(Collection)}.
* @deprecated in favor of {@link #fragments(Collection)}
*/
@Deprecated(since = "6.2.13", forRemoval = true)
static Builder with(Collection<ModelAndView> fragments) {
return fragments(fragments);
}
/** /**
* Defines a builder for {@link FragmentsRendering}. * Defines a builder for {@link FragmentsRendering}.
*/ */
@ -111,32 +146,32 @@ public interface FragmentsRendering extends SmartView {
Builder headers(Consumer<HttpHeaders> headersConsumer); Builder headers(Consumer<HttpHeaders> headersConsumer);
/** /**
* Add a fragment with a view name and a model. * Add an HTML fragment.
* @param viewName the name of the view for the fragment * @param viewName the name of the view for the fragment
* @param model attributes for the fragment in addition to model * @param model fragment attributes in addition to attributes from the
* attributes inherited from the shared model for the request * shared model for the request
* @return this builder * @return this builder
*/ */
Builder fragment(String viewName, Map<String, Object> model); Builder fragment(String viewName, Map<String, Object> model);
/** /**
* Variant of {@link #fragment(String, Map)} with a view name only, but * Add an HTML fragment. The fragment will use attributes from the shared
* also inheriting model attributes from the shared model for the request. * model for the request.
* @param viewName the name of the view for the fragment * @param viewName the name of the view for the fragment
* @return this builder * @return this builder
*/ */
Builder fragment(String viewName); Builder fragment(String viewName);
/** /**
* Variant of {@link #fragment(String, Map)} with a {@link ModelAndView}. * Add an HTML fragment.
* @param fragment the fragment to add; the fragment also inherits model * @param fragment the fragment to add; the fragment also inherits
* attributes from the shared model for the request * attributes from the shared model for the request
* @return this builder * @return this builder
*/ */
Builder fragment(ModelAndView fragment); Builder fragment(ModelAndView fragment);
/** /**
* Variant of {@link #fragment(String, Map)} with a collection of {@link ModelAndView}s. * Add multiple HTML fragments.
* @param fragments the fragments to add; each fragment also inherits model * @param fragments the fragments to add; each fragment also inherits model
* attributes from the shared model for the request * attributes from the shared model for the request
* @return this builder * @return this builder

2
spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/ModelAndViewMethodReturnValueHandlerTests.java

@ -91,7 +91,7 @@ class ModelAndViewMethodReturnValueHandlerTests {
@Test @Test
void handleFragmentsRendering() throws Exception { void handleFragmentsRendering() throws Exception {
FragmentsRendering rendering = FragmentsRendering.with("viewName").build(); FragmentsRendering rendering = FragmentsRendering.fragment("viewName").build();
handler.handleReturnValue(rendering, returnParamModelAndView, mavContainer, webRequest); handler.handleReturnValue(rendering, returnParamModelAndView, mavContainer, webRequest);
assertThat(mavContainer.getView()).isInstanceOf(SmartView.class); assertThat(mavContainer.getView()).isInstanceOf(SmartView.class);

2
spring-webmvc/src/test/java/org/springframework/web/servlet/view/DefaultFragmentsRenderingTests.java

@ -56,7 +56,7 @@ public class DefaultFragmentsRenderingTests {
MockHttpServletRequest request = new MockHttpServletRequest(); MockHttpServletRequest request = new MockHttpServletRequest();
MockHttpServletResponse response = new MockHttpServletResponse(); MockHttpServletResponse response = new MockHttpServletResponse();
FragmentsRendering view = FragmentsRendering.with("fragment1", Map.of("foo", "Foo")) FragmentsRendering view = FragmentsRendering.fragment("fragment1", Map.of("foo", "Foo"))
.fragment("fragment2", Map.of("bar", "Bar")) .fragment("fragment2", Map.of("bar", "Bar"))
.header("headerName", "headerValue") .header("headerName", "headerValue")
.build(); .build();

Loading…
Cancel
Save