Spring MVC提供了以下幾種途徑輸出模型數據:
1)ModelAndView:處理方法返回值類型為ModelAndView時,方法體即可通過該對象添加模型數據;
2)Map及Model:處理方法入參為org.springframework.ui.Model、org.springframework.ui.ModelMap或java.util.Map時,處理方法返回時,Map中的數據會自動被添加到模型中;
3)@SessionAttributes:將模型中的某個屬性暫存到HttpSeession中,以便多個請求之間可以共享這個屬性;
4)@ModelAttribute:方法入參標注該注解后,入參的對象就會放到數據模型中。
Map及Model
使用示例:
在TestModelData.java類中追加方法:
1 @RequestMapping("/testMap") 2 public String testMap(Map<String, Object> map) { 3 map.put("mapTestKey", "mapTestValue"); 4 return SUCCESS; 5 }
修改/WEB-INF/views/success.jsp頁面,中
測試地址:http://localhost:8080/SpringMVC_02/testMap
返回頁面打印信息:
SUCCESS PAGE
current time:
testMap mapTestKey:mapTestValue
查看此時入參Map實際什么類型,修改TestModelData.java代碼:
@RequestMapping("/testMap") public String testMap(Map<String, Object> map) { map.put("mapTestKey", "mapTestValue"); System.out.println(map); System.out.println(map.getClass()); return SUCCESS; }
打印結果:
{mapTestKey=mapTestValue} class org.springframework.validation.support.BindingAwareModelMap
從打印結果發現,實際上入參Map是BildingAwareModelMap
public class BindingAwareModelMap extends ExtendedModelMap
public class ExtendedModelMap extends ModelMap implements Model
由於BildingAwareModelMap繼承了ExtendedModelMap,而ExtendedModelMap又繼承了ModeMap和實現了Model接口,因此,這里Map入參可以替換為ModelMap和Model。
調試:設置斷點在“ map.put("mapTestKey", "mapTestValue");”行處
從調試跟蹤發現,入參map最終被解析的類是MapMethodProcessor.java
MapMethodProcessor.java

1 /* 2 * Copyright 2002-2017 the original author or authors. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package org.springframework.web.method.annotation; 18 19 import java.util.Map; 20 21 import org.springframework.core.MethodParameter; 22 import org.springframework.lang.Nullable; 23 import org.springframework.util.Assert; 24 import org.springframework.web.bind.support.WebDataBinderFactory; 25 import org.springframework.web.context.request.NativeWebRequest; 26 import org.springframework.web.method.support.HandlerMethodArgumentResolver; 27 import org.springframework.web.method.support.HandlerMethodReturnValueHandler; 28 import org.springframework.web.method.support.ModelAndViewContainer; 29 30 /** 31 * Resolves {@link Map} method arguments and handles {@link Map} return values. 32 * 33 * <p>A Map return value can be interpreted in more than one ways depending 34 * on the presence of annotations like {@code @ModelAttribute} or 35 * {@code @ResponseBody}. Therefore this handler should be configured after 36 * the handlers that support these annotations. 37 * 38 * @author Rossen Stoyanchev 39 * @since 3.1 40 */ 41 public class MapMethodProcessor implements HandlerMethodArgumentResolver, HandlerMethodReturnValueHandler { 42 43 @Override 44 public boolean supportsParameter(MethodParameter parameter) { 45 return Map.class.isAssignableFrom(parameter.getParameterType()); 46 } 47 48 @Override 49 @Nullable 50 public Object resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer, 51 NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) throws Exception { 52 53 Assert.state(mavContainer != null, "ModelAndViewContainer is required for model exposure"); 54 return mavContainer.getModel(); 55 } 56 57 @Override 58 public boolean supportsReturnType(MethodParameter returnType) { 59 return Map.class.isAssignableFrom(returnType.getParameterType()); 60 } 61 62 @Override 63 @SuppressWarnings({ "unchecked", "rawtypes" }) 64 public void handleReturnValue(@Nullable Object returnValue, MethodParameter returnType, 65 ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception { 66 67 if (returnValue instanceof Map){ 68 mavContainer.addAllAttributes((Map) returnValue); 69 } 70 else if (returnValue != null) { 71 // should not happen 72 throw new UnsupportedOperationException("Unexpected return type: " + 73 returnType.getParameterType().getName() + " in method: " + returnType.getMethod()); 74 } 75 } 76 77 }
當頁面返回時,該入參會被加載到Request請求域。