Merge branch '6.1.x'
This commit is contained in:
commit
e1567b93c2
|
@ -77,7 +77,7 @@ and others) and is equivalent to `required=false`.
|
|||
| For access to a part in a `multipart/form-data` request. Supports reactive types.
|
||||
See xref:web/webflux/controller/ann-methods/multipart-forms.adoc[Multipart Content] and xref:web/webflux/reactive-spring.adoc#webflux-multipart[Multipart Data].
|
||||
|
||||
| `java.util.Map`, `org.springframework.ui.Model`, and `org.springframework.ui.ModelMap`.
|
||||
| `java.util.Map` or `org.springframework.ui.Model`
|
||||
| For access to the model that is used in HTML controllers and is exposed to templates as
|
||||
part of view rendering.
|
||||
|
||||
|
@ -89,9 +89,9 @@ and others) and is equivalent to `required=false`.
|
|||
Note that use of `@ModelAttribute` is optional -- for example, to set its attributes.
|
||||
See "`Any other argument`" later in this table.
|
||||
|
||||
| `Errors`, `BindingResult`
|
||||
| `Errors` or `BindingResult`
|
||||
| For access to errors from validation and data binding for a command object, i.e. a
|
||||
`@ModelAttribute` argument. An `Errors`, or `BindingResult` argument must be declared
|
||||
`@ModelAttribute` argument. An `Errors` or `BindingResult` argument must be declared
|
||||
immediately after the validated method argument.
|
||||
|
||||
| `SessionStatus` + class-level `@SessionAttributes`
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2023 the original author or authors.
|
||||
* Copyright 2002-2024 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -46,7 +46,7 @@ public class ConcurrentModel extends ConcurrentHashMap<String, Object> implement
|
|||
}
|
||||
|
||||
/**
|
||||
* Construct a new {@code ModelMap} containing the supplied attribute
|
||||
* Construct a new {@code ConcurrentModel} containing the supplied attribute
|
||||
* under the supplied name.
|
||||
* @see #addAttribute(String, Object)
|
||||
*/
|
||||
|
@ -55,8 +55,8 @@ public class ConcurrentModel extends ConcurrentHashMap<String, Object> implement
|
|||
}
|
||||
|
||||
/**
|
||||
* Construct a new {@code ModelMap} containing the supplied attribute.
|
||||
* Uses attribute name generation to generate the key for the supplied model
|
||||
* Construct a new {@code ConcurrentModel} containing the supplied attribute.
|
||||
* <p>Uses attribute name generation to generate the key for the supplied model
|
||||
* object.
|
||||
* @see #addAttribute(Object)
|
||||
*/
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Generic support for UI layer concepts.
|
||||
* Provides a generic ModelMap for model holding.
|
||||
* <p>Provides generic {@code Model} and {@code ModelMap} holders for model attributes.
|
||||
*/
|
||||
@NonNullApi
|
||||
@NonNullFields
|
||||
|
|
|
@ -18,11 +18,11 @@ package org.springframework.web.reactive.result.method.annotation;
|
|||
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.testfixture.beans.TestBean;
|
||||
import org.springframework.ui.ModelMap;
|
||||
import org.springframework.web.bind.annotation.SessionAttributes;
|
||||
import org.springframework.web.server.WebSession;
|
||||
import org.springframework.web.testfixture.server.MockWebSession;
|
||||
|
@ -31,7 +31,8 @@ import static java.util.Arrays.asList;
|
|||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Test fixture with {@link SessionAttributesHandler}.
|
||||
* Tests for {@link SessionAttributesHandler}.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
*/
|
||||
class SessionAttributesHandlerTests {
|
||||
|
@ -86,11 +87,11 @@ class SessionAttributesHandlerTests {
|
|||
|
||||
@Test
|
||||
void storeAttributes() {
|
||||
|
||||
ModelMap model = new ModelMap();
|
||||
model.put("attr1", "value1");
|
||||
model.put("attr2", "value2");
|
||||
model.put("attr3", new TestBean());
|
||||
Map<String, Object> model = Map.of(
|
||||
"attr1", "value1",
|
||||
"attr2", "value2",
|
||||
"attr3", new TestBean()
|
||||
);
|
||||
|
||||
WebSession session = new MockWebSession();
|
||||
sessionAttributesHandler.storeAttributes(session, model);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2024 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -20,7 +20,6 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
|
||||
import org.springframework.context.support.GenericApplicationContext;
|
||||
import org.springframework.ui.ModelMap;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
import org.springframework.web.util.UriComponents;
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
|
@ -38,7 +37,7 @@ public class DummyMacroRequestContext {
|
|||
|
||||
private final ServerWebExchange exchange;
|
||||
|
||||
private final ModelMap model;
|
||||
private final Map<String, Object> model;
|
||||
|
||||
private final GenericApplicationContext context;
|
||||
|
||||
|
@ -46,7 +45,7 @@ public class DummyMacroRequestContext {
|
|||
|
||||
private String contextPath;
|
||||
|
||||
public DummyMacroRequestContext(ServerWebExchange exchange, ModelMap model, GenericApplicationContext context) {
|
||||
public DummyMacroRequestContext(ServerWebExchange exchange, Map<String, Object> model, GenericApplicationContext context) {
|
||||
this.exchange = exchange;
|
||||
this.model = model;
|
||||
this.context = context;
|
||||
|
|
|
@ -17,11 +17,10 @@
|
|||
package org.springframework.web.reactive.result.view;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import reactor.test.StepVerifier;
|
||||
|
@ -30,8 +29,6 @@ import org.springframework.core.codec.CharSequenceEncoder;
|
|||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.codec.json.Jackson2JsonEncoder;
|
||||
import org.springframework.http.codec.xml.Jaxb2XmlEncoder;
|
||||
import org.springframework.ui.ExtendedModelMap;
|
||||
import org.springframework.ui.ModelMap;
|
||||
import org.springframework.web.testfixture.http.server.reactive.MockServerHttpRequest;
|
||||
import org.springframework.web.testfixture.server.MockServerWebExchange;
|
||||
|
||||
|
@ -48,7 +45,7 @@ class HttpMessageWriterViewTests {
|
|||
|
||||
private HttpMessageWriterView view = new HttpMessageWriterView(new Jackson2JsonEncoder());
|
||||
|
||||
private final ModelMap model = new ExtendedModelMap();
|
||||
private final Map<String, Object> model = new HashMap<>();
|
||||
|
||||
private final MockServerWebExchange exchange = MockServerWebExchange.from(MockServerHttpRequest.get("/"));
|
||||
|
||||
|
@ -63,18 +60,18 @@ class HttpMessageWriterViewTests {
|
|||
|
||||
@Test
|
||||
void singleMatch() throws Exception {
|
||||
this.view.setModelKeys(Collections.singleton("foo2"));
|
||||
this.model.addAttribute("foo1", Collections.singleton("bar1"));
|
||||
this.model.addAttribute("foo2", Collections.singleton("bar2"));
|
||||
this.model.addAttribute("foo3", Collections.singleton("bar3"));
|
||||
this.view.setModelKeys(Set.of("foo2"));
|
||||
this.model.put("foo1", Set.of("bar1"));
|
||||
this.model.put("foo2", Set.of("bar2"));
|
||||
this.model.put("foo3", Set.of("bar3"));
|
||||
|
||||
assertThat(doRender()).isEqualTo("[\"bar2\"]");
|
||||
}
|
||||
|
||||
@Test
|
||||
void noMatch() throws Exception {
|
||||
this.view.setModelKeys(Collections.singleton("foo2"));
|
||||
this.model.addAttribute("foo1", "bar1");
|
||||
this.view.setModelKeys(Set.of("foo2"));
|
||||
this.model.put("foo1", "bar1");
|
||||
|
||||
assertThat(doRender()).isEmpty();
|
||||
}
|
||||
|
@ -82,18 +79,18 @@ class HttpMessageWriterViewTests {
|
|||
@Test
|
||||
void noMatchBecauseNotSupported() throws Exception {
|
||||
this.view = new HttpMessageWriterView(new Jaxb2XmlEncoder());
|
||||
this.view.setModelKeys(new HashSet<>(Collections.singletonList("foo1")));
|
||||
this.model.addAttribute("foo1", "bar1");
|
||||
this.view.setModelKeys(Set.of("foo1"));
|
||||
this.model.put("foo1", "bar1");
|
||||
|
||||
assertThat(doRender()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void multipleMatches() throws Exception {
|
||||
this.view.setModelKeys(new HashSet<>(Arrays.asList("foo1", "foo2")));
|
||||
this.model.addAttribute("foo1", Collections.singleton("bar1"));
|
||||
this.model.addAttribute("foo2", Collections.singleton("bar2"));
|
||||
this.model.addAttribute("foo3", Collections.singleton("bar3"));
|
||||
this.view.setModelKeys(Set.of("foo1", "foo2"));
|
||||
this.model.put("foo1", Set.of("bar1"));
|
||||
this.model.put("foo2", Set.of("bar2"));
|
||||
this.model.put("foo3", Set.of("bar3"));
|
||||
|
||||
assertThat(doRender()).isEqualTo("{\"foo1\":[\"bar1\"],\"foo2\":[\"bar2\"]}");
|
||||
}
|
||||
|
@ -101,13 +98,13 @@ class HttpMessageWriterViewTests {
|
|||
@Test
|
||||
void multipleMatchesNotSupported() throws Exception {
|
||||
this.view = new HttpMessageWriterView(CharSequenceEncoder.allMimeTypes());
|
||||
this.view.setModelKeys(new HashSet<>(Arrays.asList("foo1", "foo2")));
|
||||
this.model.addAttribute("foo1", "bar1");
|
||||
this.model.addAttribute("foo2", "bar2");
|
||||
this.view.setModelKeys(Set.of("foo1", "foo2"));
|
||||
this.model.put("foo1", "bar1");
|
||||
this.model.put("foo2", "bar2");
|
||||
|
||||
assertThatIllegalStateException().isThrownBy(
|
||||
this::doRender)
|
||||
.withMessageContaining("Map rendering is not supported");
|
||||
assertThatIllegalStateException()
|
||||
.isThrownBy(this::doRender)
|
||||
.withMessageContaining("Map rendering is not supported");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -115,8 +112,8 @@ class HttpMessageWriterViewTests {
|
|||
Map<String, String> pojoData = new LinkedHashMap<>();
|
||||
pojoData.put("foo", "f");
|
||||
pojoData.put("bar", "b");
|
||||
this.model.addAttribute("pojoData", pojoData);
|
||||
this.view.setModelKeys(Collections.singleton("pojoData"));
|
||||
this.model.put("pojoData", pojoData);
|
||||
this.view.setModelKeys(Set.of("pojoData"));
|
||||
|
||||
this.view.render(this.model, MediaType.APPLICATION_JSON, exchange).block(Duration.ZERO);
|
||||
|
||||
|
|
|
@ -37,8 +37,6 @@ import org.springframework.beans.testfixture.beans.TestBean;
|
|||
import org.springframework.context.support.GenericApplicationContext;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.ui.ExtendedModelMap;
|
||||
import org.springframework.ui.ModelMap;
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.reactive.result.view.BindStatus;
|
||||
|
@ -322,7 +320,7 @@ class FreeMarkerMacroTests {
|
|||
names.put("Fred", "Fred Bloggs");
|
||||
names.put("Rob&Harrop", "Rob Harrop");
|
||||
|
||||
ModelMap model = new ExtendedModelMap();
|
||||
Map<String, Object> model = new HashMap<>();
|
||||
DummyMacroRequestContext rc = new DummyMacroRequestContext(this.exchange, model,
|
||||
this.applicationContext);
|
||||
rc.setMessageMap(msgMap);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2023 the original author or authors.
|
||||
* Copyright 2002-2024 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -19,6 +19,7 @@ package org.springframework.web.reactive.result.view.freemarker;
|
|||
import java.nio.charset.StandardCharsets;
|
||||
import java.time.Duration;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import freemarker.template.Configuration;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
|
@ -28,8 +29,6 @@ import reactor.test.StepVerifier;
|
|||
import org.springframework.context.ApplicationContextException;
|
||||
import org.springframework.context.support.GenericApplicationContext;
|
||||
import org.springframework.http.codec.ServerCodecConfigurer;
|
||||
import org.springframework.ui.ExtendedModelMap;
|
||||
import org.springframework.ui.ModelMap;
|
||||
import org.springframework.web.reactive.result.view.ZeroDemandResponse;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
import org.springframework.web.server.adapter.DefaultServerWebExchange;
|
||||
|
@ -125,8 +124,7 @@ class FreeMarkerViewTests {
|
|||
freeMarkerView.setConfiguration(this.freeMarkerConfig);
|
||||
freeMarkerView.setUrl("test.ftl");
|
||||
|
||||
ModelMap model = new ExtendedModelMap();
|
||||
model.addAttribute("hello", "hi FreeMarker");
|
||||
Map<String, Object> model = Map.of("hello", "hi FreeMarker");
|
||||
freeMarkerView.render(model, null, this.exchange).block(Duration.ofMillis(5000));
|
||||
|
||||
StepVerifier.create(this.exchange.getResponse().getBody())
|
||||
|
@ -148,8 +146,7 @@ class FreeMarkerViewTests {
|
|||
freeMarkerView.setConfiguration(this.freeMarkerConfig);
|
||||
freeMarkerView.setUrl("test.ftl");
|
||||
|
||||
ModelMap model = new ExtendedModelMap();
|
||||
model.addAttribute("hello", "hi FreeMarker");
|
||||
Map<String, Object> model = Map.of("hello", "hi FreeMarker");
|
||||
freeMarkerView.render(model, null, exchange).subscribe();
|
||||
|
||||
response.cancelWrite();
|
||||
|
|
Loading…
Reference in New Issue