【问题标题】:Spring MVC form http params to model object map member variableSpring MVC 形式 http 参数对对象映射成员变量进行建模
【发布时间】:2014-06-04 10:15:07
【问题描述】:

我很难说出这个问题的名字。我要解决的问题与here 所描述的问题非常相似,但是我想提交代表模型对象中映射的http请求参数而不是bean列表,并让框架(Spring)负责构建来自 http 请求参数的地图。任何人都可以建议最好的做法/最干净的方法吗?任何帮助将不胜感激。

目前我传递了两个字符串数组,然后将它们转换为地图,然后保存到模型对象中。我认为必须有更好的方法来做到这一点。

我正在使用 Spring MVC 和 Freemarker 进行视图渲染。

示例代码:

模型对象:

public class Foo {
    private Map<String, String> barMap;
    // other member variables...
}

查看fremarker模板:

<#list foo.barMap?keys as currKey>
    <tr id="barList_${currKey_index}">
        <td><input name="key" type="text" value="${currKey}"/></td>
        <td><input name="value" type="text" value="${foo.barMap[currKey]}"/></td>
    </tr>
</#list>

控制器:

@RequestMapping(value = "/foo", method = RequestMethod.POST)
public String foo (Model model,
                   @RequestParam(value="key", required=false) String[] keys, 
                   @RequestParam(value="value", required=false) String[] values) {

    Foo foo = new Foo();
    Map<String, String> barMap = new HashMap<String, String>();

    if (keys != null && values != null && keys.length == values.length) {
        for (int i = 0; i < keys.length; i++) {
            if (keys[i] != null 
                && !keys[i].isEmpty() 
                && values[i] != null 
                && !values[i].isEmpty()) {

                barMap.put(keys[i], values[i]);
            }
        }
    }

    foo.setBarMap(map);

    return WebConstants.VIEW_FOO;
}

【问题讨论】:

    标签: java spring spring-mvc freemarker


    【解决方案1】:

    直接使用map绑定

    @RequestMapping(value = "/foo", method = RequestMethod.POST)
    public String foo (@RequestParam Map<String,String> allRequestParams ,Model model){
    }
    

    并将 getter 和 setter 放入 Foo 用于 map。

    然后地图会自动填充

    【讨论】:

    • html 表单也必须更改...否则地图将无法工作
    • 我可以让它工作。但我真正想要的是直接使用 html 表单中的地图填充 Foo 对象,如果可能的话,使用 Spring 的 @ModelAttribute 标记。我正在尝试如何做到这一点,但还没有快乐。有什么想法吗?
    【解决方案2】:

    直接转换为 Foo :

    @RequestMapping(value = "/foo", method = RequestMethod.POST)
    public String foo (@RequestBody Foo foo){
    }
    

    把表格改成这样的

    <input name="${currKey}" type="text" value="${foo.barMap[currKey]}"/>
    

    你需要在表单中匹配foo结构,你可以通过调试@ResponseBody Foo的输出json来查看所需

    【讨论】:

    • 我很难让这个解决方案发挥作用。我收到带有消息“服务器拒绝此请求,因为请求实体的格式不受所请求方法 () 的请求资源支持的格式”的 http 415。
    【解决方案3】:

    感谢 Karibasappa G C 和 NimChimsky 的回答,他们给了我很大帮助,并为我指明了正确的方向 - 我对你们俩都投了赞成票。我最终使用了 Spring 的 @ModelAtribute 注释,这使得这个非常简单和最少的额外代码。请注意,html 输入字段需要采用特定格式,name 属性必须采用 mapName[mapKey] 格式,value 属性是您希望存储在地图中的键 mapName[mapKey] 的值。

    示例解决方案:

    模型对象:

    public class Foo {
        private Map<String, String> barMap;
    
        public Map<String, String> getTagMap() {
            return tagMap;
        }
    
        public void setTagMap(Map<String, String> tagMap) {
            this.tagMap = tagMap;
        }
    }
    

    查看 Freemarker 模板:

    <#if foo ??>
        <#if foo.barMap ??>
            <#list foo.barMap?keys as barKey>
                <tr>
                    <td>
                        <!-- this input field is for display purposes only -->
                        <input name="tagKey" type="text" value="${tagKey}"/>
                    </td>
                    <td>
                        <!-- this input field populates the map -->
                        <input name="tagMap[${tagKey}]" type="text" value="${foo.tagMap[tagKey]}"/>
                    </td>
                </tr>
            </#list>
        </#if>
    </#if>
    

    控制器:

    @RequestMapping(value = "/foo", method = RequestMethod.POST)
    public String update (Model model, @ModelAttribute("foo") Foo foo) {
        // other code omitted
        return "foo";
    }
    

    【讨论】:

      猜你喜欢
      • 2018-11-14
      • 1970-01-01
      • 2017-06-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-22
      • 1970-01-01
      • 2013-09-01
      相关资源
      最近更新 更多