SPR-6464 Add RedirectAttributes and SmartView interfaces.
This commit is contained in:
parent
bd7fd57ad2
commit
baea01ac90
|
|
@ -0,0 +1,32 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2002-2011 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.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.springframework.web.servlet;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface to be implemented by Views that perform a redirect.
|
||||||
|
*
|
||||||
|
* @author Rossen Stoyanchev
|
||||||
|
* @since 3.1
|
||||||
|
*/
|
||||||
|
public interface SmartView extends View {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether the view performs a redirect.
|
||||||
|
*/
|
||||||
|
boolean isRedirectView();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -74,8 +74,6 @@ import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
|
||||||
import org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite;
|
import org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite;
|
||||||
import org.springframework.web.method.support.InvocableHandlerMethod;
|
import org.springframework.web.method.support.InvocableHandlerMethod;
|
||||||
import org.springframework.web.method.support.ModelAndViewContainer;
|
import org.springframework.web.method.support.ModelAndViewContainer;
|
||||||
import org.springframework.web.servlet.FlashMap;
|
|
||||||
import org.springframework.web.servlet.FlashMapManager;
|
|
||||||
import org.springframework.web.servlet.ModelAndView;
|
import org.springframework.web.servlet.ModelAndView;
|
||||||
import org.springframework.web.servlet.View;
|
import org.springframework.web.servlet.View;
|
||||||
import org.springframework.web.servlet.mvc.LastModified;
|
import org.springframework.web.servlet.mvc.LastModified;
|
||||||
|
|
@ -85,7 +83,7 @@ import org.springframework.web.servlet.mvc.method.annotation.support.DefaultMeth
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.support.HttpEntityMethodProcessor;
|
import org.springframework.web.servlet.mvc.method.annotation.support.HttpEntityMethodProcessor;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.support.ModelAndViewMethodReturnValueHandler;
|
import org.springframework.web.servlet.mvc.method.annotation.support.ModelAndViewMethodReturnValueHandler;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.support.PathVariableMethodArgumentResolver;
|
import org.springframework.web.servlet.mvc.method.annotation.support.PathVariableMethodArgumentResolver;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.support.RedirectModelMethodArgumentResolver;
|
import org.springframework.web.servlet.mvc.method.annotation.support.RedirectAttributesMethodArgumentResolver;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.support.RequestPartMethodArgumentResolver;
|
import org.springframework.web.servlet.mvc.method.annotation.support.RequestPartMethodArgumentResolver;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.support.RequestResponseBodyMethodProcessor;
|
import org.springframework.web.servlet.mvc.method.annotation.support.RequestResponseBodyMethodProcessor;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.support.ServletCookieValueMethodArgumentResolver;
|
import org.springframework.web.servlet.mvc.method.annotation.support.ServletCookieValueMethodArgumentResolver;
|
||||||
|
|
@ -93,7 +91,7 @@ import org.springframework.web.servlet.mvc.method.annotation.support.ServletMode
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.support.ServletRequestMethodArgumentResolver;
|
import org.springframework.web.servlet.mvc.method.annotation.support.ServletRequestMethodArgumentResolver;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.support.ServletResponseMethodArgumentResolver;
|
import org.springframework.web.servlet.mvc.method.annotation.support.ServletResponseMethodArgumentResolver;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.support.ViewMethodReturnValueHandler;
|
import org.springframework.web.servlet.mvc.method.annotation.support.ViewMethodReturnValueHandler;
|
||||||
import org.springframework.web.servlet.mvc.support.RedirectModel;
|
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
|
||||||
import org.springframework.web.servlet.support.RequestContextUtils;
|
import org.springframework.web.servlet.support.RequestContextUtils;
|
||||||
import org.springframework.web.util.WebUtils;
|
import org.springframework.web.util.WebUtils;
|
||||||
|
|
||||||
|
|
@ -369,7 +367,7 @@ public class RequestMappingHandlerAdapter extends AbstractHandlerMethodAdapter i
|
||||||
argumentResolvers.addResolver(new ServletRequestMethodArgumentResolver());
|
argumentResolvers.addResolver(new ServletRequestMethodArgumentResolver());
|
||||||
argumentResolvers.addResolver(new ServletResponseMethodArgumentResolver());
|
argumentResolvers.addResolver(new ServletResponseMethodArgumentResolver());
|
||||||
argumentResolvers.addResolver(new HttpEntityMethodProcessor(messageConverters));
|
argumentResolvers.addResolver(new HttpEntityMethodProcessor(messageConverters));
|
||||||
argumentResolvers.addResolver(new RedirectModelMethodArgumentResolver());
|
argumentResolvers.addResolver(new RedirectAttributesMethodArgumentResolver());
|
||||||
argumentResolvers.addResolver(new ModelMethodProcessor());
|
argumentResolvers.addResolver(new ModelMethodProcessor());
|
||||||
argumentResolvers.addResolver(new ErrorsMethodArgumentResolver());
|
argumentResolvers.addResolver(new ErrorsMethodArgumentResolver());
|
||||||
|
|
||||||
|
|
@ -530,15 +528,13 @@ public class RequestMappingHandlerAdapter extends AbstractHandlerMethodAdapter i
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ModelMap model = mavContainer.getModel();
|
ModelMap model = mavContainer.getModel();
|
||||||
ModelAndView mav = new ModelAndView().addAllObjects(model);
|
ModelAndView mav = new ModelAndView(mavContainer.getViewName(), model);
|
||||||
mav.setViewName(mavContainer.getViewName());
|
|
||||||
if (!mavContainer.isViewReference()) {
|
if (!mavContainer.isViewReference()) {
|
||||||
mav.setView((View) mavContainer.getView());
|
mav.setView((View) mavContainer.getView());
|
||||||
}
|
}
|
||||||
if (model instanceof RedirectModel) {
|
if (model instanceof RedirectAttributes) {
|
||||||
RedirectModel redirectModel = (RedirectModel) model;
|
Map<String, ?> flashAttributes = ((RedirectAttributes) model).getFlashAttributes();
|
||||||
FlashMap flashMap = RequestContextUtils.getOutputFlashMap(request);
|
RequestContextUtils.getOutputFlashMap(request).putAll(flashAttributes);
|
||||||
flashMap.putAll(redirectModel.getFlashAttributes());
|
|
||||||
}
|
}
|
||||||
return mav;
|
return mav;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,8 @@
|
||||||
|
|
||||||
package org.springframework.web.servlet.mvc.method.annotation.support;
|
package org.springframework.web.servlet.mvc.method.annotation.support;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import org.springframework.core.MethodParameter;
|
import org.springframework.core.MethodParameter;
|
||||||
import org.springframework.ui.Model;
|
import org.springframework.ui.Model;
|
||||||
import org.springframework.ui.ModelMap;
|
import org.springframework.ui.ModelMap;
|
||||||
|
|
@ -25,21 +27,22 @@ import org.springframework.web.context.request.NativeWebRequest;
|
||||||
import org.springframework.web.method.annotation.support.ModelMethodProcessor;
|
import org.springframework.web.method.annotation.support.ModelMethodProcessor;
|
||||||
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
|
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
|
||||||
import org.springframework.web.method.support.ModelAndViewContainer;
|
import org.springframework.web.method.support.ModelAndViewContainer;
|
||||||
import org.springframework.web.servlet.mvc.support.RedirectModel;
|
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
|
||||||
|
import org.springframework.web.servlet.mvc.support.RedirectAttributesModelMap;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resolves {@link RedirectModel} method arguments.
|
* Resolves {@link RedirectAttributesModelMap} method arguments.
|
||||||
*
|
*
|
||||||
* <p>This resolver must be listed ahead of the {@link ModelMethodProcessor},
|
* <p>This resolver must be listed ahead of the {@link ModelMethodProcessor},
|
||||||
* which also resolves arguments of type {@link Model}.
|
* which also resolves arguments of type {@link Map} and {@link Model}.
|
||||||
*
|
*
|
||||||
* @author Rossen Stoyanchev
|
* @author Rossen Stoyanchev
|
||||||
* @since 3.1
|
* @since 3.1
|
||||||
*/
|
*/
|
||||||
public class RedirectModelMethodArgumentResolver implements HandlerMethodArgumentResolver {
|
public class RedirectAttributesMethodArgumentResolver implements HandlerMethodArgumentResolver {
|
||||||
|
|
||||||
public boolean supportsParameter(MethodParameter parameter) {
|
public boolean supportsParameter(MethodParameter parameter) {
|
||||||
return RedirectModel.class.equals(parameter.getParameterType());
|
return RedirectAttributes.class.isAssignableFrom(parameter.getParameterType());
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object resolveArgument(MethodParameter parameter,
|
public Object resolveArgument(MethodParameter parameter,
|
||||||
|
|
@ -47,10 +50,9 @@ public class RedirectModelMethodArgumentResolver implements HandlerMethodArgumen
|
||||||
NativeWebRequest webRequest,
|
NativeWebRequest webRequest,
|
||||||
WebDataBinderFactory binderFactory) throws Exception {
|
WebDataBinderFactory binderFactory) throws Exception {
|
||||||
DataBinder dataBinder = binderFactory.createBinder(webRequest, null, null);
|
DataBinder dataBinder = binderFactory.createBinder(webRequest, null, null);
|
||||||
ModelMap implicitModel = mavContainer.getModel();
|
ModelMap attributes = new RedirectAttributesModelMap(dataBinder);
|
||||||
RedirectModel redirectModel = new RedirectModel(dataBinder, implicitModel);
|
mavContainer.setRedirectModel(attributes);
|
||||||
mavContainer.setRedirectModel(redirectModel);
|
return attributes;
|
||||||
return redirectModel;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -23,6 +23,7 @@ import org.springframework.web.context.request.NativeWebRequest;
|
||||||
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
|
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
|
||||||
import org.springframework.web.method.support.ModelAndViewContainer;
|
import org.springframework.web.method.support.ModelAndViewContainer;
|
||||||
import org.springframework.web.servlet.RequestToViewNameTranslator;
|
import org.springframework.web.servlet.RequestToViewNameTranslator;
|
||||||
|
import org.springframework.web.servlet.SmartView;
|
||||||
import org.springframework.web.servlet.View;
|
import org.springframework.web.servlet.View;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -60,14 +61,14 @@ public class ViewMethodReturnValueHandler implements HandlerMethodReturnValueHan
|
||||||
String viewName = (String) returnValue;
|
String viewName = (String) returnValue;
|
||||||
mavContainer.setViewName(viewName);
|
mavContainer.setViewName(viewName);
|
||||||
if (isRedirectViewName(viewName)) {
|
if (isRedirectViewName(viewName)) {
|
||||||
mavContainer.useRedirectModel();
|
mavContainer.setRedirectModelEnabled();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (returnValue instanceof View){
|
else if (returnValue instanceof View){
|
||||||
View view = (View) returnValue;
|
View view = (View) returnValue;
|
||||||
mavContainer.setView(view);
|
mavContainer.setView(view);
|
||||||
if (isRedirectView(view)) {
|
if (isRedirectView(view)) {
|
||||||
mavContainer.useRedirectModel();
|
mavContainer.setRedirectModelEnabled();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
@ -94,7 +95,12 @@ public class ViewMethodReturnValueHandler implements HandlerMethodReturnValueHan
|
||||||
* "false" otherwise.
|
* "false" otherwise.
|
||||||
*/
|
*/
|
||||||
protected boolean isRedirectView(View view) {
|
protected boolean isRedirectView(View view) {
|
||||||
return "RedirectView".equals(view.getClass().getSimpleName());
|
if (SmartView.class.isAssignableFrom(view.getClass())) {
|
||||||
|
return ((SmartView) view).isRedirectView();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,89 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2002-2011 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.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.springframework.web.servlet.mvc.support;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.springframework.ui.Model;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A {@link Model} that can also store attributes candidate for flash storage.
|
||||||
|
*
|
||||||
|
* @author Rossen Stoyanchev
|
||||||
|
* @since 3.1
|
||||||
|
*/
|
||||||
|
public interface RedirectAttributes extends Model {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add the supplied attribute under the supplied name.
|
||||||
|
* @param attributeName the name of the model attribute (never <code>null</code>)
|
||||||
|
* @param attributeValue the model attribute value (can be <code>null</code>)
|
||||||
|
*/
|
||||||
|
RedirectAttributes addAttribute(String attributeName, Object attributeValue);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add the supplied attribute to this <code>Map</code> using a
|
||||||
|
* {@link org.springframework.core.Conventions#getVariableName generated name}.
|
||||||
|
* <p><emphasis>Note: Empty {@link java.util.Collection Collections} are not added to
|
||||||
|
* the model when using this method because we cannot correctly determine
|
||||||
|
* the true convention name. View code should check for <code>null</code> rather
|
||||||
|
* than for empty collections as is already done by JSTL tags.</emphasis>
|
||||||
|
* @param attributeValue the model attribute value (never <code>null</code>)
|
||||||
|
*/
|
||||||
|
RedirectAttributes addAttribute(Object attributeValue);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy all attributes in the supplied <code>Collection</code> into this
|
||||||
|
* <code>Map</code>, using attribute name generation for each element.
|
||||||
|
* @see #addAttribute(Object)
|
||||||
|
*/
|
||||||
|
RedirectAttributes addAllAttributes(Collection<?> attributeValues);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy all attributes in the supplied <code>Map</code> into this <code>Map</code>.
|
||||||
|
* @see #addAttribute(String, Object)
|
||||||
|
*/
|
||||||
|
Model addAllAttributes(Map<String, ?> attributes);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy all attributes in the supplied <code>Map</code> into this <code>Map</code>,
|
||||||
|
* with existing objects of the same name taking precedence (i.e. not getting
|
||||||
|
* replaced).
|
||||||
|
*/
|
||||||
|
RedirectAttributes mergeAttributes(Map<String, ?> attributes);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add the given attribute as a candidate for flash storage.
|
||||||
|
* @param attributeName the flash attribute name; never null
|
||||||
|
* @param attributeValue the flash attribute value; may be null
|
||||||
|
*/
|
||||||
|
RedirectAttributes addFlashAttribute(String attributeName, Object attributeValue);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add the given attribute value as a candidate for flash storage using a
|
||||||
|
* {@link org.springframework.core.Conventions#getVariableName generated name}.
|
||||||
|
* @param attributeValue the flash attribute value; never null
|
||||||
|
*/
|
||||||
|
RedirectAttributes addFlashAttribute(Object attributeValue);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the attributes candidate for flash storage.
|
||||||
|
*/
|
||||||
|
Map<String, ?> getFlashAttributes();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,157 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2002-2011 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.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.springframework.web.servlet.mvc.support;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.springframework.ui.ModelMap;
|
||||||
|
import org.springframework.validation.DataBinder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A {@link ModelMap} that implements the {@link RedirectAttributes} interface.
|
||||||
|
*
|
||||||
|
* <p>Attributes are formatted and stored as Strings so they can be used as URI
|
||||||
|
* variables or as query parameters in the redirect URL. Alternatively,
|
||||||
|
* attributes may also be added as flash attributes in order to request storing
|
||||||
|
* them until the next request without affecting the redirect URL.
|
||||||
|
*
|
||||||
|
* @author Rossen Stoyanchev
|
||||||
|
* @since 3.1
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("serial")
|
||||||
|
public class RedirectAttributesModelMap extends ModelMap implements RedirectAttributes {
|
||||||
|
|
||||||
|
private final DataBinder dataBinder;
|
||||||
|
|
||||||
|
private final ModelMap flashAttributes = new ModelMap();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default constructor without a DataBinder.
|
||||||
|
* Redirect attribute values will be formatted via {@link #toString()}.
|
||||||
|
*/
|
||||||
|
public RedirectAttributesModelMap() {
|
||||||
|
this(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor with a DataBinder to use to format redirect attribute values.
|
||||||
|
* @param dataBinder a DataBinder for converting attribute values to String.
|
||||||
|
*/
|
||||||
|
public RedirectAttributesModelMap(DataBinder dataBinder) {
|
||||||
|
this.dataBinder = dataBinder;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the attributes candidate for flash storage.
|
||||||
|
*/
|
||||||
|
public Map<String, ?> getFlashAttributes() {
|
||||||
|
return flashAttributes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Format the attribute value as a String and add it. If the value is
|
||||||
|
* {@code null} it is not be added.
|
||||||
|
* @param attributeName the attribute name; never null
|
||||||
|
* @param attributeValue the attribute value; skipped if null
|
||||||
|
*/
|
||||||
|
public RedirectAttributesModelMap addAttribute(String attributeName, Object attributeValue) {
|
||||||
|
if (attributeValue != null) {
|
||||||
|
super.addAttribute(attributeName, formatValue(attributeValue));
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String formatValue(Object value) {
|
||||||
|
return (dataBinder != null) ? dataBinder.convertIfNecessary(value, String.class) : value.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add an attribute using a
|
||||||
|
* {@link org.springframework.core.Conventions#getVariableName generated name}.
|
||||||
|
* Before being added the attribute value is formatted as a String.
|
||||||
|
* @param attributeValue the attribute value; never null
|
||||||
|
*/
|
||||||
|
public RedirectAttributesModelMap addAttribute(Object attributeValue) {
|
||||||
|
super.addAttribute(attributeValue);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy all attributes in the supplied <code>Collection</code> into this
|
||||||
|
* Model using attribute name generation for each element.
|
||||||
|
* @see #addAttribute(Object)
|
||||||
|
*/
|
||||||
|
public RedirectAttributesModelMap addAllAttributes(Collection<?> attributeValues) {
|
||||||
|
super.addAllAttributes(attributeValues);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy all supplied attributes into this model.
|
||||||
|
* @see #addAttribute(String, Object)
|
||||||
|
*/
|
||||||
|
public RedirectAttributesModelMap addAllAttributes(Map<String, ?> attributes) {
|
||||||
|
if (attributes != null) {
|
||||||
|
for (String key : attributes.keySet()) {
|
||||||
|
addAttribute(key, attributes.get(key));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy all supplied attributes into this model with with existing
|
||||||
|
* attributes of the same name taking precedence (i.e. not getting replaced).
|
||||||
|
* @see #addAttribute(String, Object)
|
||||||
|
*/
|
||||||
|
public RedirectAttributesModelMap mergeAttributes(Map<String, ?> attributes) {
|
||||||
|
if (attributes != null) {
|
||||||
|
for (String key : attributes.keySet()) {
|
||||||
|
if (!containsKey(key)) {
|
||||||
|
addAttribute(key, attributes.get(key));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, Object> asMap() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add the given attribute as a candidate for flash storage.
|
||||||
|
* @param attributeName the flash attribute name; never null
|
||||||
|
* @param attributeValue the flash attribute value; may be null
|
||||||
|
*/
|
||||||
|
public RedirectAttributes addFlashAttribute(String attributeName, Object attributeValue) {
|
||||||
|
this.flashAttributes.addAttribute(attributeName, attributeValue);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add the given attribute value as a candidate for flash storage using a
|
||||||
|
* {@link org.springframework.core.Conventions#getVariableName generated name}.
|
||||||
|
* @param attributeValue the flash attribute value; never null
|
||||||
|
*/
|
||||||
|
public RedirectAttributes addFlashAttribute(Object attributeValue) {
|
||||||
|
this.flashAttributes.addAttribute(attributeValue);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -1,199 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2002-2011 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.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.springframework.web.servlet.mvc.support;
|
|
||||||
|
|
||||||
import java.beans.PropertyEditor;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import org.springframework.core.convert.converter.Converter;
|
|
||||||
import org.springframework.format.Formatter;
|
|
||||||
import org.springframework.ui.ExtendedModelMap;
|
|
||||||
import org.springframework.ui.Model;
|
|
||||||
import org.springframework.ui.ModelMap;
|
|
||||||
import org.springframework.util.Assert;
|
|
||||||
import org.springframework.validation.DataBinder;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A {@link Model} implementation that controllers can use when they wish to
|
|
||||||
* redirect. For a redirect a controller needs to use an empty model and
|
|
||||||
* only add those attributes that will be used in the redirect URL --
|
|
||||||
* either embedded as URI template variables or appended as query parameters.
|
|
||||||
* To be used in the URL such attributes need to be formatted as String
|
|
||||||
* values. Alternatively a controller may choose to keep attributes in
|
|
||||||
* flash storage instead for the duration of the redirect.
|
|
||||||
*
|
|
||||||
* <p>A RedirectModel serves the above needs as follows:
|
|
||||||
* <ul>
|
|
||||||
* <li>Formats attribute values as Strings before adding them using a
|
|
||||||
* registered {@link Converter}, {@link Formatter}, {@link PropertyEditor},
|
|
||||||
* or the attribute's {@link #toString()} method.
|
|
||||||
* <li>Wraps the the model of the current request and provides a method to
|
|
||||||
* copy attributes from it (see {@link #addModelAttributes(String...)}).
|
|
||||||
* <li>Provides methods to store attributes candidate for flash storage.
|
|
||||||
* </ul>
|
|
||||||
*
|
|
||||||
* <p>Note that a RedirectModel will not be used unless the controller decides
|
|
||||||
* to redirect.
|
|
||||||
*
|
|
||||||
* @author Rossen Stoyanchev
|
|
||||||
* @since 3.1
|
|
||||||
*/
|
|
||||||
@SuppressWarnings("serial")
|
|
||||||
public class RedirectModel extends ExtendedModelMap {
|
|
||||||
|
|
||||||
private final DataBinder dataBinder;
|
|
||||||
|
|
||||||
private final ModelMap flashAttributes = new ModelMap();
|
|
||||||
|
|
||||||
private final ModelMap implicitModel;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new instance without a DataBinder. Attribute values will be
|
|
||||||
* formatted via {@link #toString()}.
|
|
||||||
*/
|
|
||||||
public RedirectModel() {
|
|
||||||
this(null, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new instance providing a DataBinder to use for formatting
|
|
||||||
* attribute values.
|
|
||||||
* @param dataBinder a DataBinder for converting attribute values to String.
|
|
||||||
* @param implicitModel the implicit model for the current request;
|
|
||||||
* used in conjunction with {@link #addModelAttributes(String...)}
|
|
||||||
* to copy attributes from the implicit model to the redirect model.
|
|
||||||
*/
|
|
||||||
public RedirectModel(DataBinder dataBinder, ModelMap implicitModel) {
|
|
||||||
this.dataBinder = dataBinder;
|
|
||||||
this.implicitModel = implicitModel;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the attributes candidate for flash storage.
|
|
||||||
*/
|
|
||||||
public Map<String, ?> getFlashAttributes() {
|
|
||||||
return flashAttributes;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add an attribute. Before being added the attribute value is formatted as
|
|
||||||
* a String in preparation for use in the redirect URL. If the attribute
|
|
||||||
* value is null it is not be added to the model.
|
|
||||||
* @param attributeName the attribute name; never null
|
|
||||||
* @param attributeValue the attribute value; skipped if null
|
|
||||||
*/
|
|
||||||
public RedirectModel addAttribute(String attributeName, Object attributeValue) {
|
|
||||||
if (attributeValue != null) {
|
|
||||||
super.addAttribute(attributeName, formatValue(attributeValue));
|
|
||||||
}
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
private String formatValue(Object value) {
|
|
||||||
return (dataBinder != null) ? dataBinder.convertIfNecessary(value, String.class) : value.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add an attribute using a
|
|
||||||
* {@link org.springframework.core.Conventions#getVariableName generated name}.
|
|
||||||
* Before being added the attribute value is formatted as a String.
|
|
||||||
* @param attributeValue the attribute value; never null
|
|
||||||
*/
|
|
||||||
public RedirectModel addAttribute(Object attributeValue) {
|
|
||||||
super.addAttribute(attributeValue);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Copy all attributes in the supplied <code>Collection</code> into this
|
|
||||||
* Model using attribute name generation for each element.
|
|
||||||
* @see #addAttribute(Object)
|
|
||||||
*/
|
|
||||||
public RedirectModel addAllAttributes(Collection<?> attributeValues) {
|
|
||||||
super.addAllAttributes(attributeValues);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Copy all supplied attributes into this redirect model.
|
|
||||||
* @see #addAttribute(String, Object)
|
|
||||||
*/
|
|
||||||
public RedirectModel addAllAttributes(Map<String, ?> attributes) {
|
|
||||||
if (attributes != null) {
|
|
||||||
for (String key : attributes.keySet()) {
|
|
||||||
addAttribute(key, attributes.get(key));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Copy all supplied attributes into this redirect model with with existing
|
|
||||||
* attributes of the same name taking precedence (i.e. not getting replaced).
|
|
||||||
* @see #addAttribute(String, Object)
|
|
||||||
*/
|
|
||||||
public RedirectModel mergeAttributes(Map<String, ?> attributes) {
|
|
||||||
if (attributes != null) {
|
|
||||||
for (String key : attributes.keySet()) {
|
|
||||||
if (!containsKey(key)) {
|
|
||||||
addAttribute(key, attributes.get(key));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Copy the attributes specified by name from the "implicit" model of the
|
|
||||||
* current request to this redirect model instance.
|
|
||||||
* @param attributeNames the names of attributes present in the implicit model.
|
|
||||||
* attribute names are required to be present; if an attribute is present
|
|
||||||
* but is null, it is skipped
|
|
||||||
* @see #addAttribute(String, Object)
|
|
||||||
*/
|
|
||||||
public RedirectModel addModelAttributes(String... attributeNames) {
|
|
||||||
Assert.notNull(this.implicitModel, "The implicit model has not been set.");
|
|
||||||
for (String name : attributeNames) {
|
|
||||||
Assert.isTrue(this.implicitModel.containsAttribute(name), name + " not found in implicit model");
|
|
||||||
Object value = this.implicitModel.get(name);
|
|
||||||
addAttribute(name, value);
|
|
||||||
}
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add the given attribute as a candidate for flash storage.
|
|
||||||
* @param attributeName the flash attribute name; never null
|
|
||||||
* @param attributeValue the flash attribute value; may be null
|
|
||||||
*/
|
|
||||||
public RedirectModel addFlashAttribute(String attributeName, Object attributeValue) {
|
|
||||||
this.flashAttributes.addAttribute(attributeName, attributeValue);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add the given attribute value as a candidate for flash storage using a
|
|
||||||
* {@link org.springframework.core.Conventions#getVariableName generated name}.
|
|
||||||
* @param attributeValue the flash attribute value; never null
|
|
||||||
*/
|
|
||||||
public RedirectModel addFlashAttribute(Object attributeValue) {
|
|
||||||
this.flashAttributes.addAttribute(attributeValue);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -40,6 +40,7 @@ import org.springframework.util.CollectionUtils;
|
||||||
import org.springframework.util.ObjectUtils;
|
import org.springframework.util.ObjectUtils;
|
||||||
import org.springframework.web.servlet.FlashMap;
|
import org.springframework.web.servlet.FlashMap;
|
||||||
import org.springframework.web.servlet.HandlerMapping;
|
import org.springframework.web.servlet.HandlerMapping;
|
||||||
|
import org.springframework.web.servlet.SmartView;
|
||||||
import org.springframework.web.servlet.View;
|
import org.springframework.web.servlet.View;
|
||||||
import org.springframework.web.servlet.support.RequestContextUtils;
|
import org.springframework.web.servlet.support.RequestContextUtils;
|
||||||
import org.springframework.web.util.UriTemplate;
|
import org.springframework.web.util.UriTemplate;
|
||||||
|
|
@ -85,7 +86,7 @@ import org.springframework.web.util.WebUtils;
|
||||||
* @see #setExposeModelAttributes
|
* @see #setExposeModelAttributes
|
||||||
* @see javax.servlet.http.HttpServletResponse#sendRedirect
|
* @see javax.servlet.http.HttpServletResponse#sendRedirect
|
||||||
*/
|
*/
|
||||||
public class RedirectView extends AbstractUrlBasedView {
|
public class RedirectView extends AbstractUrlBasedView implements SmartView {
|
||||||
|
|
||||||
private boolean contextRelative = false;
|
private boolean contextRelative = false;
|
||||||
|
|
||||||
|
|
@ -216,6 +217,13 @@ public class RedirectView extends AbstractUrlBasedView {
|
||||||
this.statusCode = statusCode;
|
this.statusCode = statusCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns "true" indicating this view performs a redirect.
|
||||||
|
*/
|
||||||
|
public boolean isRedirectView() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert model to request parameters and redirect to the given URL.
|
* Convert model to request parameters and redirect to the given URL.
|
||||||
* @see #appendQueryProperties
|
* @see #appendQueryProperties
|
||||||
|
|
|
||||||
|
|
@ -138,7 +138,7 @@ import org.springframework.web.servlet.View;
|
||||||
import org.springframework.web.servlet.ViewResolver;
|
import org.springframework.web.servlet.ViewResolver;
|
||||||
import org.springframework.web.servlet.mvc.annotation.ModelAndViewResolver;
|
import org.springframework.web.servlet.mvc.annotation.ModelAndViewResolver;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.support.ServletWebArgumentResolverAdapter;
|
import org.springframework.web.servlet.mvc.method.annotation.support.ServletWebArgumentResolverAdapter;
|
||||||
import org.springframework.web.servlet.mvc.support.RedirectModel;
|
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
|
||||||
import org.springframework.web.servlet.support.RequestContextUtils;
|
import org.springframework.web.servlet.support.RequestContextUtils;
|
||||||
import org.springframework.web.servlet.view.InternalResourceViewResolver;
|
import org.springframework.web.servlet.view.InternalResourceViewResolver;
|
||||||
|
|
||||||
|
|
@ -2816,13 +2816,13 @@ public class ServletAnnotationControllerHandlerMethodTests extends AbstractServl
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping(value = "/messages", method = RequestMethod.POST)
|
@RequestMapping(value = "/messages", method = RequestMethod.POST)
|
||||||
public String sendMessage(TestBean testBean, BindingResult result, RedirectModel redirectModel) {
|
public String sendMessage(TestBean testBean, BindingResult result, RedirectAttributes redirectAttrs) {
|
||||||
if (result.hasErrors()) {
|
if (result.hasErrors()) {
|
||||||
return "messages/new";
|
return "messages/new";
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
redirectModel.addAttribute("id", "1").addAttribute("name", "value");
|
redirectAttrs.addAttribute("id", "1").addAttribute("name", "value")
|
||||||
redirectModel.addFlashAttribute("successMessage", "yay!");
|
.addFlashAttribute("successMessage", "yay!");
|
||||||
return "redirect:/messages/{id}";
|
return "redirect:/messages/{id}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,10 +26,12 @@ import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.springframework.core.MethodParameter;
|
import org.springframework.core.MethodParameter;
|
||||||
import org.springframework.mock.web.MockHttpServletRequest;
|
import org.springframework.mock.web.MockHttpServletRequest;
|
||||||
|
import org.springframework.ui.ModelMap;
|
||||||
import org.springframework.web.context.request.ServletWebRequest;
|
import org.springframework.web.context.request.ServletWebRequest;
|
||||||
import org.springframework.web.method.support.ModelAndViewContainer;
|
import org.springframework.web.method.support.ModelAndViewContainer;
|
||||||
import org.springframework.web.servlet.View;
|
import org.springframework.web.servlet.View;
|
||||||
import org.springframework.web.servlet.mvc.support.RedirectModel;
|
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
|
||||||
|
import org.springframework.web.servlet.mvc.support.RedirectAttributesModelMap;
|
||||||
import org.springframework.web.servlet.view.InternalResourceView;
|
import org.springframework.web.servlet.view.InternalResourceView;
|
||||||
import org.springframework.web.servlet.view.RedirectView;
|
import org.springframework.web.servlet.view.RedirectView;
|
||||||
|
|
||||||
|
|
@ -70,7 +72,7 @@ public class ViewMethodReturnValueHandlerTests {
|
||||||
@Test
|
@Test
|
||||||
public void returnViewRedirect() throws Exception {
|
public void returnViewRedirect() throws Exception {
|
||||||
RedirectView redirectView = new RedirectView("testView");
|
RedirectView redirectView = new RedirectView("testView");
|
||||||
RedirectModel redirectModel = new RedirectModel();
|
ModelMap redirectModel = new RedirectAttributesModelMap();
|
||||||
mavContainer.setRedirectModel(redirectModel);
|
mavContainer.setRedirectModel(redirectModel);
|
||||||
handler.handleReturnValue(redirectView, createMethodParam("view"), mavContainer, webRequest);
|
handler.handleReturnValue(redirectView, createMethodParam("view"), mavContainer, webRequest);
|
||||||
|
|
||||||
|
|
@ -87,7 +89,7 @@ public class ViewMethodReturnValueHandlerTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void returnViewNameRedirect() throws Exception {
|
public void returnViewNameRedirect() throws Exception {
|
||||||
RedirectModel redirectModel = new RedirectModel();
|
ModelMap redirectModel = new RedirectAttributesModelMap();
|
||||||
mavContainer.setRedirectModel(redirectModel);
|
mavContainer.setRedirectModel(redirectModel);
|
||||||
handler.handleReturnValue("redirect:testView", createMethodParam("viewName"), mavContainer, webRequest);
|
handler.handleReturnValue("redirect:testView", createMethodParam("viewName"), mavContainer, webRequest);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -28,57 +28,53 @@ import org.springframework.beans.TestBean;
|
||||||
import org.springframework.core.convert.converter.Converter;
|
import org.springframework.core.convert.converter.Converter;
|
||||||
import org.springframework.format.support.DefaultFormattingConversionService;
|
import org.springframework.format.support.DefaultFormattingConversionService;
|
||||||
import org.springframework.format.support.FormattingConversionService;
|
import org.springframework.format.support.FormattingConversionService;
|
||||||
import org.springframework.ui.ModelMap;
|
|
||||||
import org.springframework.validation.DataBinder;
|
import org.springframework.validation.DataBinder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Test fixture for RedirectModel tests.
|
* Test fixture for {@link RedirectAttributesModelMap} tests.
|
||||||
*
|
*
|
||||||
* @author Rossen Stoyanchev
|
* @author Rossen Stoyanchev
|
||||||
* @since 3.1
|
* @since 3.1
|
||||||
*/
|
*/
|
||||||
public class RedirectModelTests {
|
public class RedirectAttributesModelMapTests {
|
||||||
|
|
||||||
private RedirectModel redirectModel;
|
private RedirectAttributesModelMap redirectAttributes;
|
||||||
|
|
||||||
private FormattingConversionService conversionService;
|
private FormattingConversionService conversionService;
|
||||||
|
|
||||||
private ModelMap implicitModel;
|
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setup() {
|
public void setup() {
|
||||||
this.conversionService = new DefaultFormattingConversionService();
|
this.conversionService = new DefaultFormattingConversionService();
|
||||||
DataBinder dataBinder = new DataBinder(null);
|
DataBinder dataBinder = new DataBinder(null);
|
||||||
dataBinder.setConversionService(conversionService);
|
dataBinder.setConversionService(conversionService);
|
||||||
|
|
||||||
this.implicitModel = new ModelMap();
|
this.redirectAttributes = new RedirectAttributesModelMap(dataBinder);
|
||||||
this.redirectModel = new RedirectModel(dataBinder, implicitModel);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void addAttributePrimitiveType() {
|
public void addAttributePrimitiveType() {
|
||||||
this.redirectModel.addAttribute("speed", 65);
|
this.redirectAttributes.addAttribute("speed", 65);
|
||||||
assertEquals("65", this.redirectModel.get("speed"));
|
assertEquals("65", this.redirectAttributes.get("speed"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void addAttributeCustomType() {
|
public void addAttributeCustomType() {
|
||||||
String attrName = "person";
|
String attrName = "person";
|
||||||
this.redirectModel.addAttribute(attrName, new TestBean("Fred"));
|
this.redirectAttributes.addAttribute(attrName, new TestBean("Fred"));
|
||||||
|
|
||||||
assertEquals("ConversionService should have invoked toString()", "Fred", this.redirectModel.get(attrName));
|
assertEquals("ConversionService should have invoked toString()", "Fred", this.redirectAttributes.get(attrName));
|
||||||
|
|
||||||
this.conversionService.addConverter(new TestBeanConverter());
|
this.conversionService.addConverter(new TestBeanConverter());
|
||||||
this.redirectModel.addAttribute(attrName, new TestBean("Fred"));
|
this.redirectAttributes.addAttribute(attrName, new TestBean("Fred"));
|
||||||
|
|
||||||
assertEquals("Type converter should have been used", "[Fred]", this.redirectModel.get(attrName));
|
assertEquals("Type converter should have been used", "[Fred]", this.redirectAttributes.get(attrName));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void addAttributeToString() {
|
public void addAttributeToString() {
|
||||||
String attrName = "person";
|
String attrName = "person";
|
||||||
RedirectModel model = new RedirectModel();
|
RedirectAttributesModelMap model = new RedirectAttributesModelMap();
|
||||||
model.addAttribute(attrName, new TestBean("Fred"));
|
model.addAttribute(attrName, new TestBean("Fred"));
|
||||||
|
|
||||||
assertEquals("toString() should have been used", "Fred", model.get(attrName));
|
assertEquals("toString() should have been used", "Fred", model.get(attrName));
|
||||||
|
|
@ -86,17 +82,17 @@ public class RedirectModelTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void addAttributeValue() {
|
public void addAttributeValue() {
|
||||||
this.redirectModel.addAttribute(new TestBean("Fred"));
|
this.redirectAttributes.addAttribute(new TestBean("Fred"));
|
||||||
|
|
||||||
assertEquals("Fred", this.redirectModel.get("testBean"));
|
assertEquals("Fred", this.redirectAttributes.get("testBean"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void addAllAttributesList() {
|
public void addAllAttributesList() {
|
||||||
this.redirectModel.addAllAttributes(Arrays.asList(new TestBean("Fred"), new Integer(5)));
|
this.redirectAttributes.addAllAttributes(Arrays.asList(new TestBean("Fred"), new Integer(5)));
|
||||||
|
|
||||||
assertEquals("Fred", this.redirectModel.get("testBean"));
|
assertEquals("Fred", this.redirectAttributes.get("testBean"));
|
||||||
assertEquals("5", this.redirectModel.get("integer"));
|
assertEquals("5", this.redirectAttributes.get("integer"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -104,10 +100,10 @@ public class RedirectModelTests {
|
||||||
Map<String, Object> map = new HashMap<String, Object>();
|
Map<String, Object> map = new HashMap<String, Object>();
|
||||||
map.put("person", new TestBean("Fred"));
|
map.put("person", new TestBean("Fred"));
|
||||||
map.put("age", 33);
|
map.put("age", 33);
|
||||||
this.redirectModel.addAllAttributes(map);
|
this.redirectAttributes.addAllAttributes(map);
|
||||||
|
|
||||||
assertEquals("Fred", this.redirectModel.get("person"));
|
assertEquals("Fred", this.redirectAttributes.get("person"));
|
||||||
assertEquals("33", this.redirectModel.get("age"));
|
assertEquals("33", this.redirectAttributes.get("age"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -116,27 +112,11 @@ public class RedirectModelTests {
|
||||||
map.put("person", new TestBean("Fred"));
|
map.put("person", new TestBean("Fred"));
|
||||||
map.put("age", 33);
|
map.put("age", 33);
|
||||||
|
|
||||||
this.redirectModel.addAttribute("person", new TestBean("Ralph"));
|
this.redirectAttributes.addAttribute("person", new TestBean("Ralph"));
|
||||||
this.redirectModel.mergeAttributes(map);
|
this.redirectAttributes.mergeAttributes(map);
|
||||||
|
|
||||||
assertEquals("Ralph", this.redirectModel.get("person"));
|
assertEquals("Ralph", this.redirectAttributes.get("person"));
|
||||||
assertEquals("33", this.redirectModel.get("age"));
|
assertEquals("33", this.redirectAttributes.get("age"));
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void addModelAttributes() {
|
|
||||||
this.implicitModel.addAttribute("person", new TestBean("Ralph"));
|
|
||||||
this.implicitModel.addAttribute("age", 33);
|
|
||||||
|
|
||||||
this.redirectModel.addModelAttributes("person", "age");
|
|
||||||
|
|
||||||
assertEquals("Ralph", this.redirectModel.get("person"));
|
|
||||||
assertEquals("33", this.redirectModel.get("age"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected=IllegalArgumentException.class)
|
|
||||||
public void addModelAttributesInvalidName() {
|
|
||||||
this.redirectModel.addModelAttributes("person");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class TestBeanConverter implements Converter<TestBean, String> {
|
public static class TestBeanConverter implements Converter<TestBean, String> {
|
||||||
Loading…
Reference in New Issue