Skip to content

Commit 0d64c90

Browse files
committed
Move status/header handling into FragmentsRendering
Based on feedback from htmx-spring-boot. It's more generally useful to process those from within DefaultFragmentsRendering rather than in ModelAndViewMethodReturnValueHandler. That way a custom return value handler can create a FragmentsRendering as well and get the same result. See gh-33194
1 parent ce5e247 commit 0d64c90

File tree

4 files changed

+11
-16
lines changed

4 files changed

+11
-16
lines changed

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

-11
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,8 @@
1818

1919
import java.util.Collection;
2020

21-
import jakarta.servlet.http.HttpServletResponse;
22-
2321
import org.springframework.core.MethodParameter;
24-
import org.springframework.http.HttpHeaders;
2522
import org.springframework.lang.Nullable;
26-
import org.springframework.util.Assert;
2723
import org.springframework.util.PatternMatchUtils;
2824
import org.springframework.web.context.request.NativeWebRequest;
2925
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
@@ -100,13 +96,6 @@ public void handleReturnValue(@Nullable Object returnValue, MethodParameter retu
10096
}
10197

10298
if (returnValue instanceof FragmentsRendering rendering) {
103-
mavContainer.setStatus(rendering.status());
104-
HttpHeaders headers = rendering.headers();
105-
if (!headers.isEmpty()) {
106-
HttpServletResponse response = webRequest.getNativeResponse(HttpServletResponse.class);
107-
Assert.state(response != null, "No HttpServletResponse");
108-
headers.forEach((name, values) -> values.forEach(value -> response.addHeader(name, value)));
109-
}
11099
mavContainer.setView(rendering);
111100
return;
112101
}

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

+8
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,14 @@ public void render(
101101
@Nullable Map<String, ?> model, HttpServletRequest request, HttpServletResponse response)
102102
throws Exception {
103103

104+
if (this.status != null) {
105+
response.setStatus(this.status.value());
106+
}
107+
108+
if (!this.headers.isEmpty()) {
109+
this.headers.forEach((name, values) -> values.forEach(value -> response.addHeader(name, value)));
110+
}
111+
104112
if (model != null) {
105113
model.forEach((key, value) ->
106114
this.modelAndViews.forEach(mv -> mv.getModel().putIfAbsent(key, value)));

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

+1-4
Original file line numberDiff line numberDiff line change
@@ -91,13 +91,10 @@ void handleViewInstance() throws Exception {
9191

9292
@Test
9393
void handleFragmentsRendering() throws Exception {
94-
FragmentsRendering rendering = FragmentsRendering.with("viewName")
95-
.header("headerName", "headerValue")
96-
.build();
94+
FragmentsRendering rendering = FragmentsRendering.with("viewName").build();
9795

9896
handler.handleReturnValue(rendering, returnParamModelAndView, mavContainer, webRequest);
9997
assertThat(mavContainer.getView()).isInstanceOf(SmartView.class);
100-
assertThat(this.webRequest.getResponse().getHeader("headerName")).isEqualTo("headerValue");
10198
}
10299

103100
@Test

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

+2-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@
4343
@DisabledForJreRange(min = JAVA_21, disabledReason = "Kotlin doesn't support Java 21+ yet")
4444
public class DefaultFragmentsRenderingTests {
4545

46-
4746
@Test
4847
void render() throws Exception {
4948

@@ -59,11 +58,13 @@ void render() throws Exception {
5958

6059
FragmentsRendering view = FragmentsRendering.with("fragment1", Map.of("foo", "Foo"))
6160
.fragment("fragment2", Map.of("bar", "Bar"))
61+
.header("headerName", "headerValue")
6262
.build();
6363

6464
view.resolveNestedViews(viewResolver, Locale.ENGLISH);
6565
view.render(Collections.emptyMap(), request, response);
6666

67+
assertThat(response.getHeader("headerName")).isEqualTo("headerValue");
6768
assertThat(response.getContentAsString()).isEqualTo("""
6869
<p>
6970
Hello Foo

0 commit comments

Comments
 (0)