Java Spring MVC 表单 http params 来建模对象映射成员变量

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24034756/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 09:50:22  来源:igfitidea点击:

Spring MVC form http params to model object map member variable

javaspringspring-mvcfreemarker

提问by Stuart

I struggled to name this question. The problem I'm trying to solve is very similar to that described herebut instead of a list of beans I want to submit http request params that represent a map in the model object and let the framework (Spring) take care of building the map from the http request params. Can anyone advise as to best practice/cleanest way to do this please? Any help would be much appreciated.

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

Currently I pass two String arrays that I then convert these into a map before saving into the model object. I think there must be a nicer way to do this.

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

I am using Spring MVC and Freemarker for view rendering.

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

Illustrative code:

说明性代码:

model object:

模型对象:

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

View fremarker template:

查看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>

Controller:

控制器:

@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;
}

采纳答案by Stuart

Thanks to Karibasappa G C and NimChimsky for their answers that helped me a lot and pointed me in the right direction - I upvoted you both. I ended up using Spring's @ModelAtribute annotation which makes this very easy and minimal extra code. Note, the html input field needs to be in a specific format, the name attribute must be of the format mapName[mapKey] and the value attribute is the value you want stored in your map for key mapName[mapKey].

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

Example Solution:

示例解决方案:

Model object:

模型对象:

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;
    }
}

View Freemarker template:

查看 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>

Controller:

控制器:

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

回答by NimChimpsky

Just convert directly to Foo :

只需直接转换为 Foo :

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

chang ethe form to something like this

将形式更改为这样的

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

You'l need to match up foo structure in the form, you can view the required by debuggin the outtputed json of @ResponseBody Foo

您需要匹配表单中的 foo 结构,您可以通过 debuggin 的输出 json 查看所需的 @ResponseBody Foo

回答by Karibasappa G C

use directly map to bind

使用直接映射绑定

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

and put getters and setters in Foo for map.

并将 getter 和 setter 放在 Foo 中作为地图。

then map gets populated automatically

然后地图会自动填充