Rossen Stoyanchev
13 years ago
15 changed files with 1104 additions and 540 deletions
@ -0,0 +1,112 @@ |
|||||||
|
/* |
||||||
|
* 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.method.annotation; |
||||||
|
|
||||||
|
import static junit.framework.Assert.assertNotNull; |
||||||
|
|
||||||
|
import javax.servlet.ServletException; |
||||||
|
|
||||||
|
import org.junit.After; |
||||||
|
import org.springframework.beans.factory.support.RootBeanDefinition; |
||||||
|
import org.springframework.context.ApplicationContextInitializer; |
||||||
|
import org.springframework.mock.web.MockServletConfig; |
||||||
|
import org.springframework.web.context.WebApplicationContext; |
||||||
|
import org.springframework.web.context.support.GenericWebApplicationContext; |
||||||
|
import org.springframework.web.servlet.DispatcherServlet; |
||||||
|
import org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver; |
||||||
|
import org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver; |
||||||
|
|
||||||
|
/** |
||||||
|
* Base class for tests using on the DispatcherServlet and HandlerMethod infrastructure classes: |
||||||
|
* <ul> |
||||||
|
* <li>RequestMappingHandlerMapping |
||||||
|
* <li>RequestMappingHandlerAdapter |
||||||
|
* <li>ExceptionHandlerExceptionResolver |
||||||
|
* </ul> |
||||||
|
* |
||||||
|
* @author Rossen Stoyanchev |
||||||
|
*/ |
||||||
|
public class AbstractServletHandlerMethodTests { |
||||||
|
|
||||||
|
private DispatcherServlet servlet; |
||||||
|
|
||||||
|
@After |
||||||
|
public void tearDown() { |
||||||
|
this.servlet = null; |
||||||
|
} |
||||||
|
|
||||||
|
protected DispatcherServlet getServlet() { |
||||||
|
assertNotNull("DispatcherServlet not initialized", servlet); |
||||||
|
return servlet; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Initialize a DispatcherServlet instance registering zero or more controller classes. |
||||||
|
*/ |
||||||
|
protected WebApplicationContext initServletWithControllers(final Class<?>... controllerClasses) |
||||||
|
throws ServletException { |
||||||
|
return initServlet(null, controllerClasses); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Initialize a DispatcherServlet instance registering zero or more controller classes |
||||||
|
* and also providing additional bean definitions through a callback. |
||||||
|
*/ |
||||||
|
@SuppressWarnings("serial") |
||||||
|
protected WebApplicationContext initServlet( |
||||||
|
final ApplicationContextInitializer<GenericWebApplicationContext> initializer, |
||||||
|
final Class<?>... controllerClasses) throws ServletException { |
||||||
|
|
||||||
|
final GenericWebApplicationContext wac = new GenericWebApplicationContext(); |
||||||
|
|
||||||
|
servlet = new DispatcherServlet() { |
||||||
|
@Override |
||||||
|
protected WebApplicationContext createWebApplicationContext(WebApplicationContext parent) { |
||||||
|
for (Class<?> clazz : controllerClasses) { |
||||||
|
wac.registerBeanDefinition(clazz.getSimpleName(), new RootBeanDefinition(clazz)); |
||||||
|
} |
||||||
|
|
||||||
|
Class<?> mappingType = RequestMappingHandlerMapping.class; |
||||||
|
wac.registerBeanDefinition("handlerMapping", new RootBeanDefinition(mappingType)); |
||||||
|
|
||||||
|
Class<?> adapterType = RequestMappingHandlerAdapter.class; |
||||||
|
wac.registerBeanDefinition("handlerAdapter", new RootBeanDefinition(adapterType)); |
||||||
|
|
||||||
|
Class<?> resolverType = ExceptionHandlerExceptionResolver.class; |
||||||
|
wac.registerBeanDefinition("requestMappingResolver", new RootBeanDefinition(resolverType)); |
||||||
|
|
||||||
|
resolverType = ResponseStatusExceptionResolver.class; |
||||||
|
wac.registerBeanDefinition("responseStatusResolver", new RootBeanDefinition(resolverType)); |
||||||
|
|
||||||
|
resolverType = DefaultHandlerExceptionResolver.class; |
||||||
|
wac.registerBeanDefinition("defaultResolver", new RootBeanDefinition(resolverType)); |
||||||
|
|
||||||
|
if (initializer != null) { |
||||||
|
initializer.initialize(wac); |
||||||
|
} |
||||||
|
|
||||||
|
wac.refresh(); |
||||||
|
return wac; |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
servlet.init(new MockServletConfig()); |
||||||
|
|
||||||
|
return wac; |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,215 @@ |
|||||||
|
/* |
||||||
|
* 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.method.annotation; |
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals; |
||||||
|
import static org.junit.Assert.assertNull; |
||||||
|
|
||||||
|
import java.util.Locale; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
import javax.servlet.ServletException; |
||||||
|
import javax.servlet.http.HttpServletRequest; |
||||||
|
import javax.servlet.http.HttpServletResponse; |
||||||
|
|
||||||
|
import org.junit.Test; |
||||||
|
import org.springframework.beans.factory.support.RootBeanDefinition; |
||||||
|
import org.springframework.context.ApplicationContextInitializer; |
||||||
|
import org.springframework.mock.web.MockHttpServletRequest; |
||||||
|
import org.springframework.mock.web.MockHttpServletResponse; |
||||||
|
import org.springframework.stereotype.Controller; |
||||||
|
import org.springframework.ui.Model; |
||||||
|
import org.springframework.web.bind.annotation.FlashAttributes; |
||||||
|
import org.springframework.web.bind.annotation.RequestMapping; |
||||||
|
import org.springframework.web.bind.annotation.RequestMethod; |
||||||
|
import org.springframework.web.bind.support.FlashStatus; |
||||||
|
import org.springframework.web.context.WebApplicationContext; |
||||||
|
import org.springframework.web.context.support.GenericWebApplicationContext; |
||||||
|
import org.springframework.web.method.annotation.FlashAttributesHandler; |
||||||
|
import org.springframework.web.servlet.View; |
||||||
|
import org.springframework.web.servlet.ViewResolver; |
||||||
|
|
||||||
|
/** |
||||||
|
* Test controllers with @{@link FlashAttributes} through the DispatcherServlet. |
||||||
|
* |
||||||
|
* @author Rossen Stoyanchev |
||||||
|
*/ |
||||||
|
public class FlashAttributesServletTests extends AbstractServletHandlerMethodTests { |
||||||
|
|
||||||
|
private static final String MESSAGE_KEY = "message"; |
||||||
|
|
||||||
|
@Test |
||||||
|
public void successMessage() throws Exception { |
||||||
|
|
||||||
|
initServletWithModelExposingViewResolver(MessageController.class); |
||||||
|
|
||||||
|
MockHttpServletRequest req = new MockHttpServletRequest("GET", "/message"); |
||||||
|
MockHttpServletResponse res = new MockHttpServletResponse(); |
||||||
|
getServlet().service(req, res); |
||||||
|
|
||||||
|
assertEquals(200, res.getStatus()); |
||||||
|
assertNull(getModelAttribute(req, MESSAGE_KEY)); |
||||||
|
assertNull(getFlashAttribute(req, MESSAGE_KEY)); |
||||||
|
|
||||||
|
req.setMethod("POST"); |
||||||
|
getServlet().service(req, res); |
||||||
|
|
||||||
|
assertEquals(200, res.getStatus()); |
||||||
|
assertEquals("Yay!", ((Message) getModelAttribute(req, MESSAGE_KEY)).getText()); |
||||||
|
assertEquals("Yay!", ((Message) getFlashAttribute(req, MESSAGE_KEY)).getText()); |
||||||
|
|
||||||
|
req.setMethod("GET"); |
||||||
|
getServlet().service(req, res); |
||||||
|
|
||||||
|
assertEquals(200, res.getStatus()); |
||||||
|
assertEquals("Yay!", ((Message) getModelAttribute(req, MESSAGE_KEY)).getText()); |
||||||
|
assertNull(getFlashAttribute(req, MESSAGE_KEY)); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void successMessageAcrossControllers() throws Exception { |
||||||
|
|
||||||
|
initServletWithModelExposingViewResolver(MessageController.class, SecondMessageController.class); |
||||||
|
|
||||||
|
MockHttpServletRequest req = new MockHttpServletRequest("POST", "/message"); |
||||||
|
MockHttpServletResponse res = new MockHttpServletResponse(); |
||||||
|
getServlet().service(req, res); |
||||||
|
|
||||||
|
req.setParameter("another", "true"); |
||||||
|
getServlet().service(req, res); |
||||||
|
|
||||||
|
assertEquals(200, res.getStatus()); |
||||||
|
assertEquals("Nay!", ((Message) getModelAttribute(req, MESSAGE_KEY)).getText()); |
||||||
|
assertEquals("Nay!", ((Message) getFlashAttribute(req, MESSAGE_KEY)).getText()); |
||||||
|
|
||||||
|
req.setMethod("GET"); |
||||||
|
req.setRequestURI("/second/message"); |
||||||
|
getServlet().service(req, res); |
||||||
|
|
||||||
|
assertEquals(200, res.getStatus()); |
||||||
|
assertEquals("Nay!", ((Message) getModelAttribute(req, MESSAGE_KEY)).getText()); |
||||||
|
assertNull(getFlashAttribute(req, MESSAGE_KEY)); |
||||||
|
} |
||||||
|
|
||||||
|
@Controller |
||||||
|
@FlashAttributes("message") |
||||||
|
static class MessageController { |
||||||
|
|
||||||
|
@RequestMapping(value="/message", method=RequestMethod.GET) |
||||||
|
public void message(Model model) { |
||||||
|
} |
||||||
|
|
||||||
|
@RequestMapping(value="/message", method=RequestMethod.POST) |
||||||
|
public String sendMessage(Model model, FlashStatus status) { |
||||||
|
status.setActive(); |
||||||
|
model.addAttribute(Message.success("Yay!")); |
||||||
|
return "redirect:/message"; |
||||||
|
} |
||||||
|
|
||||||
|
@RequestMapping(value="/message", method=RequestMethod.POST, params="another") |
||||||
|
public String sendMessageToSecondController(Model model, FlashStatus status) { |
||||||
|
status.setActive(); |
||||||
|
model.addAttribute(Message.error("Nay!")); |
||||||
|
return "redirect:/second/message"; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Controller |
||||||
|
static class SecondMessageController { |
||||||
|
|
||||||
|
@RequestMapping(value="/second/message", method=RequestMethod.GET) |
||||||
|
public void message(Model model) { |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private static class Message { |
||||||
|
|
||||||
|
private final MessageType type; |
||||||
|
|
||||||
|
private final String text; |
||||||
|
|
||||||
|
private Message(MessageType type, String text) { |
||||||
|
this.type = type; |
||||||
|
this.text = text; |
||||||
|
} |
||||||
|
|
||||||
|
public static Message success(String text) { |
||||||
|
return new Message(MessageType.success, text); |
||||||
|
} |
||||||
|
|
||||||
|
public static Message error(String text) { |
||||||
|
return new Message(MessageType.error, text); |
||||||
|
} |
||||||
|
|
||||||
|
public MessageType getType() { |
||||||
|
return type; |
||||||
|
} |
||||||
|
|
||||||
|
public String getText() { |
||||||
|
return text; |
||||||
|
} |
||||||
|
|
||||||
|
public String toString() { |
||||||
|
return type + ": " + text; |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
private static enum MessageType { |
||||||
|
info, success, warning, error |
||||||
|
} |
||||||
|
|
||||||
|
@SuppressWarnings("unchecked") |
||||||
|
private Object getModelAttribute(MockHttpServletRequest req, String key) { |
||||||
|
Map<String, ?> model = (Map<String, ?>) req.getAttribute(ModelExposingViewResolver.REQUEST_ATTRIBITE_MODEL); |
||||||
|
return model.get(key); |
||||||
|
} |
||||||
|
|
||||||
|
@SuppressWarnings("unchecked") |
||||||
|
private Object getFlashAttribute(MockHttpServletRequest req, String key) { |
||||||
|
String flashAttributesKey = FlashAttributesHandler.FLASH_ATTRIBUTES_SESSION_KEY; |
||||||
|
Map<String, Object> attrs = (Map<String, Object>) req.getSession().getAttribute(flashAttributesKey); |
||||||
|
return (attrs != null) ? attrs.get(key) : null; |
||||||
|
} |
||||||
|
|
||||||
|
private WebApplicationContext initServletWithModelExposingViewResolver(Class<?>... controllerClasses) |
||||||
|
throws ServletException { |
||||||
|
|
||||||
|
return initServlet(new ApplicationContextInitializer<GenericWebApplicationContext>() { |
||||||
|
public void initialize(GenericWebApplicationContext wac) { |
||||||
|
wac.registerBeanDefinition("viewResolver", new RootBeanDefinition(ModelExposingViewResolver.class)); |
||||||
|
} |
||||||
|
}, controllerClasses); |
||||||
|
} |
||||||
|
|
||||||
|
static class ModelExposingViewResolver implements ViewResolver { |
||||||
|
|
||||||
|
static String REQUEST_ATTRIBITE_MODEL = "ModelExposingViewResolver.model"; |
||||||
|
|
||||||
|
public View resolveViewName(final String viewName, Locale locale) throws Exception { |
||||||
|
return new View() { |
||||||
|
public void render(Map<String, ?> model, HttpServletRequest request, HttpServletResponse response) throws Exception { |
||||||
|
request.setAttribute(REQUEST_ATTRIBITE_MODEL, model); |
||||||
|
} |
||||||
|
public String getContentType() { |
||||||
|
return null; |
||||||
|
} |
||||||
|
}; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
File diff suppressed because it is too large
Load Diff
189
org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/method/annotation/UriTemplateServletHandlerMethodTests.java → org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/method/annotation/UriTemplateServletAnnotationControllerHandlerMethodTests.java
189
org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/method/annotation/UriTemplateServletHandlerMethodTests.java → org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/method/annotation/UriTemplateServletAnnotationControllerHandlerMethodTests.java
@ -0,0 +1,56 @@ |
|||||||
|
/* |
||||||
|
* Copyright 2002-2010 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.bind.annotation; |
||||||
|
|
||||||
|
import java.lang.annotation.Documented; |
||||||
|
import java.lang.annotation.ElementType; |
||||||
|
import java.lang.annotation.Inherited; |
||||||
|
import java.lang.annotation.Retention; |
||||||
|
import java.lang.annotation.RetentionPolicy; |
||||||
|
import java.lang.annotation.Target; |
||||||
|
|
||||||
|
/** |
||||||
|
* Annotation that indicates what attributes should be stored in the session or in |
||||||
|
* some conversational storage in order to survive a client-side redirect. |
||||||
|
* |
||||||
|
* TODO ... |
||||||
|
* |
||||||
|
* @author Rossen Stoyanchev |
||||||
|
* @since 3.1 |
||||||
|
* |
||||||
|
* @see org.springframework.web.bind.support.FlashStatus |
||||||
|
*/ |
||||||
|
@Target({ElementType.TYPE}) |
||||||
|
@Retention(RetentionPolicy.RUNTIME) |
||||||
|
@Inherited |
||||||
|
@Documented |
||||||
|
public @interface FlashAttributes { |
||||||
|
|
||||||
|
/** |
||||||
|
* The names of flash attributes in the model to be stored. |
||||||
|
* |
||||||
|
* TODO ... |
||||||
|
*/ |
||||||
|
String[] value() default {}; |
||||||
|
|
||||||
|
/** |
||||||
|
* TODO ... |
||||||
|
* |
||||||
|
*/ |
||||||
|
Class[] types() default {}; |
||||||
|
|
||||||
|
} |
@ -0,0 +1,51 @@ |
|||||||
|
/* |
||||||
|
* 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.bind.support; |
||||||
|
|
||||||
|
import org.springframework.web.bind.annotation.FlashAttributes; |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* Simple interface to pass into controller methods to allow them to activate |
||||||
|
* a mode in which model attributes identified as "flash attributes" are |
||||||
|
* temporarily stored in the session to make them available to the next |
||||||
|
* request. The most common scenario is a client-side redirect. |
||||||
|
* |
||||||
|
* <p>In active mode, model attributes that match the attribute names or |
||||||
|
* types declared via @{@link FlashAttributes} are saved in the session. |
||||||
|
* On the next request, any flash attributes found in the session are |
||||||
|
* automatically added to the model of the target controller method and |
||||||
|
* are also cleared from the session. |
||||||
|
* |
||||||
|
* TODO ... |
||||||
|
* |
||||||
|
* @author Rossen Stoyanchev |
||||||
|
* @since 3.1 |
||||||
|
*/ |
||||||
|
public interface FlashStatus { |
||||||
|
|
||||||
|
/** |
||||||
|
* TODO ... |
||||||
|
*/ |
||||||
|
void setActive(); |
||||||
|
|
||||||
|
/** |
||||||
|
* TODO ... |
||||||
|
*/ |
||||||
|
boolean isActive(); |
||||||
|
|
||||||
|
} |
@ -0,0 +1,37 @@ |
|||||||
|
/* |
||||||
|
* 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.bind.support; |
||||||
|
|
||||||
|
/** |
||||||
|
* TODO ... |
||||||
|
* |
||||||
|
* @author Rossen Stoyanchev |
||||||
|
* @since 3.1 |
||||||
|
*/ |
||||||
|
public class SimpleFlashStatus implements FlashStatus { |
||||||
|
|
||||||
|
private boolean active = false; |
||||||
|
|
||||||
|
public void setActive() { |
||||||
|
this.active = true; |
||||||
|
} |
||||||
|
|
||||||
|
public boolean isActive() { |
||||||
|
return this.active; |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,108 @@ |
|||||||
|
/* |
||||||
|
* 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.method.annotation; |
||||||
|
|
||||||
|
import java.util.Arrays; |
||||||
|
import java.util.HashSet; |
||||||
|
import java.util.LinkedHashMap; |
||||||
|
import java.util.Map; |
||||||
|
import java.util.Set; |
||||||
|
|
||||||
|
import org.springframework.core.annotation.AnnotationUtils; |
||||||
|
import org.springframework.web.bind.annotation.FlashAttributes; |
||||||
|
import org.springframework.web.context.request.WebRequest; |
||||||
|
|
||||||
|
/** |
||||||
|
* Manages flash attributes declared via @{@link FlashAttributes}. |
||||||
|
* |
||||||
|
* TODO ... |
||||||
|
* |
||||||
|
* @author Rossen Stoyanchev |
||||||
|
* @since 3.1 |
||||||
|
*/ |
||||||
|
public class FlashAttributesHandler { |
||||||
|
|
||||||
|
public static final String FLASH_ATTRIBUTES_SESSION_KEY = FlashAttributesHandler.class.getName() + ".attributes"; |
||||||
|
|
||||||
|
private final Set<String> attributeNames = new HashSet<String>(); |
||||||
|
|
||||||
|
private final Set<Class<?>> attributeTypes = new HashSet<Class<?>>(); |
||||||
|
|
||||||
|
/** |
||||||
|
* TODO ... |
||||||
|
*/ |
||||||
|
public FlashAttributesHandler(Class<?> handlerType) { |
||||||
|
FlashAttributes annotation = AnnotationUtils.findAnnotation(handlerType, FlashAttributes.class); |
||||||
|
if (annotation != null) { |
||||||
|
this.attributeNames.addAll(Arrays.asList(annotation.value())); |
||||||
|
this.attributeTypes.addAll(Arrays.<Class<?>>asList(annotation.types())); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Whether the controller represented by this handler has declared flash |
||||||
|
* attribute names or types via @{@link FlashAttributes}. |
||||||
|
*/ |
||||||
|
public boolean hasFlashAttributes() { |
||||||
|
return ((this.attributeNames.size() > 0) || (this.attributeTypes.size() > 0)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* TODO ... |
||||||
|
*/ |
||||||
|
public boolean isFlashAttribute(String attributeName, Class<?> attributeType) { |
||||||
|
return (this.attributeNames.contains(attributeName) || this.attributeTypes.contains(attributeType)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* TODO ... |
||||||
|
*/ |
||||||
|
public void storeAttributes(WebRequest request, Map<String, ?> attributes) { |
||||||
|
Map<String, Object> filtered = filterAttributes(attributes); |
||||||
|
if (!filtered.isEmpty()) { |
||||||
|
request.setAttribute(FLASH_ATTRIBUTES_SESSION_KEY, filtered, WebRequest.SCOPE_SESSION); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private Map<String, Object> filterAttributes(Map<String, ?> attributes) { |
||||||
|
Map<String, Object> result = new LinkedHashMap<String, Object>(); |
||||||
|
for (String name : attributes.keySet()) { |
||||||
|
Object value = attributes.get(name); |
||||||
|
Class<?> type = (value != null) ? value.getClass() : null; |
||||||
|
if (isFlashAttribute(name, type)) { |
||||||
|
result.put(name, value); |
||||||
|
} |
||||||
|
} |
||||||
|
return result; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* TODO ... |
||||||
|
*/ |
||||||
|
@SuppressWarnings("unchecked") |
||||||
|
public Map<String, Object> retrieveAttributes(WebRequest request) { |
||||||
|
return (Map<String, Object>) request.getAttribute(FLASH_ATTRIBUTES_SESSION_KEY, WebRequest.SCOPE_SESSION); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* TODO ... |
||||||
|
*/ |
||||||
|
public void cleanupAttributes(WebRequest request) { |
||||||
|
request.removeAttribute(FLASH_ATTRIBUTES_SESSION_KEY, WebRequest.SCOPE_SESSION); |
||||||
|
} |
||||||
|
|
||||||
|
} |
Loading…
Reference in new issue