SpringMVC(十):SpringMVC 处理输出模型数据之Map及Model

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 }
View Code

当页面返回时,该入参会被加载到Request请求域。

 

posted @ 2018-01-05 13:41  cctext  阅读(3327)  评论(0编辑  收藏  举报