表单

时间:2016-11-14 13:38:44

标签: java spring forms hashmap thymeleaf

我有一个HashMap,提供某些文档的数据:

 Key   |   Value
 ----------------
 Name  |   test1
 Type  |   type1
 ...

未指定行数,键和值两者首先是字符串。

现在我想编辑这个动态数据。 Therfor i创建了这个模板:

<form action="#" th:action="@{/documents/{id}(id=${doc_id})}" th:object="${properties}" method="post">
    <h1 th:text="${document_h1_text}">Documents</h1>
    <table class="table table-striped">
        <tr>
            <th>Property</th>
            <th>Value</th>
        </tr>
        <tr th:each="property : ${document_properties}">
            <td th:text="${property.key}">Property</td>
            <td>
                <input name="${property.key}" th:value="${property.value}" />
            </td>
        </tr>
    </table>
    <button type="submit" class="btn btn-default">Submit</button>
</form>

document_propertiesHashMap<String,String>

相关

当我使用

获取此Web服务时,此工作正常
@RequestMapping(path = "documents/{doc_id}", method = RequestMethod.GET)
public String document(@PathVariable long doc_id, Model model) { ... }

现在我想在前端编辑此输出并提交更改:

@PostMapping("documents/{doc_id}")
public String editDocument(@PathVariable long doc_id, @ModelAttribute HashMap<String, String> properties,Model model) { ... }

不幸的是,当我通过点击&#34;提交&#34;来调用它时,HashMap properties是空的。按钮。你们中的任何人都知道如何解决这个问题吗?仅供参考:我故意选择不使用传统的类绑定。原因是我希望得到一个动态的解决方案,使用任意类。

2 个答案:

答案 0 :(得分:1)

  1. 您至少需要在地图上使用包装器(我不认为您可以按照您希望的方式直接绑定到地图上)。
  2. 你应该总是使用th:field而不是th:name和th:值尽可能。
  3. 这是一个应该按照你想要的方式运作的快速示例。

    包装

    public class MapWrapper {
        private Map<String, String> map = new HashMap<>();
    
        public Map<String, String> getMap() {
            return map;
        }
    
        public void setMap(Map<String, String> map) {
            this.map = map;
        }
    }
    

    控制器

    @Controller
    public class MapController {
        @GetMapping("map.html")
        public String get(Map<String, Object> model) throws Exception {
            MapWrapper wrapper = new MapWrapper();
            wrapper.getMap().put("1", "One");
            wrapper.getMap().put("2", "Two");
            wrapper.getMap().put("3", "Three");
    
            model.put("wrapper", wrapper);
            return "map";
        }
    
        @PostMapping("map.html")
        public String post(Map<String, Object> model, @ModelAttribute("wrapper") MapWrapper wrapper) throws Exception {
            return "map";
        }
    }
    

    表格

    <form action="map.html" th:object="${wrapper}" method="post">
        <table class="table table-striped">
            <tr>
                <th>Property</th>
                <th>Value</th>
            </tr>
    
            <tr th:each="key : ${wrapper.map.keySet()}">
                <td th:text="${key}" />
                <td>
                    <input th:field="*{map[__${key}__]}" />
                </td>
            </tr>
        </table>
    
        <button type="submit" class="btn btn-default">Submit</button>
    </form>
    

答案 1 :(得分:0)

它有过高的支持对象而且似乎不是一个好方法,我认为我们需要一些通用的模式:

public class GenericEntity {
protected Map<String, Object> properties = new LinkedHashMap<String, Object>(); 
//setter getter
}

其中entity extends GenericEntity 并在控制器

  <tr th:each=" key : ${wrapper.map.keySet()}">
       <td th:text="${key}" />
       <td>
        <input th:field="*{properties[__${key}__]}" />
       </td>
  </tr>

但你应该找到一种在超类中设置属性映射的方法,它是如此硬编码,另一种方式可能会写下thymleafe v3的自定义方言。