So fill the Map and send to jsp

@RequestMapping(value = "/addNewProduct", method = RequestMethod.GET) public String addProductView(@RequestParam("categoryId") int categoryId, ModelMap model) { Map<String, String> attributes = new HashMap<String, String>(); //здесь просто заполняю ключами из базы for (Attribute attribute: productService.getCategoryByKey(categoryId).getAttributes()){ attributes.put(attribute.getAttributeName(), null); } model.addAttribute("attributes", attributes); model.addAttribute("attributeSize", attributes.size() - 1); return "addProduct"; } 

So getting

 @RequestMapping(value = "/addNewProduct", method = RequestMethod.POST) public String addProduct(HashMap<String,String> attributes, ModelMap model) { System.err.println(attributes.size()); return "admin"; } 

And jsp herself

 <spring:form action="/addNewProduct" method="post" class="form-horizontal" modelAttribute="attributes"> <c:forEach items="${attributes}" var="attributes" varStatus="status"> <tr> <label class="input-group-addon">${attributes.key} <spring:input path="attributes['${attributes.key}']" class="form-control" value="${attributes.value}"/> </label> </tr> </c:forEach> <div class="form-actions"> <input type="submit" class="btn btn-block btn-primary btn-default" value="Save"/> </div> </spring:form> 
  • What exactly does not work? Is the label on the page getting empty? Or attributes.size() in the POST handler returns 0? - Sergey Gornostaev
  • attributes.size () is 0 - Arthur

1 answer 1

First, it is not necessary in the c:forEach tag to give the var attribute the same value as the items attribute. Secondly, if you look at the html-code of the generated page, you will understand that the spring:input tag spoils the value of the path attribute by removing the square brackets. This happens because, according to the html standard, the name attribute cannot contain square brackets. And because the path attribute is intended to specify the model field in dotted notation, and not access to the elements of the collection by index. Finally, the Map should be wrapped in a model class:

form.jsp (View)

 <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <%@ taglib uri="http://www.springframework.org/tags/form" prefix="form"%> <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <html> <head> <meta charset="utf-8"> </head> <body> <form:form method="post" modelAttribute="nameForm"> <c:forEach items="${nameForm.nameMap}" var="item"> <label>${item.key}</label> <input type="text" name="nameMap['${item.key}']" value="${item.value}"> <br> </c:forEach> <input type="submit" value="Отправить"> </form:form> </body> </html> 

NameForm.java (Model)

 package com.example; import java.util.HashMap; import java.util.Map; public class NameForm { private Map<String, String> nameMap = new HashMap<>(); public NameForm() {} public NameForm(Map<String, String> nameMap) { this.nameMap = nameMap; } public Map<String, String> getNameMap() { return nameMap; } public void setNameMap(Map<String, String> nameMap) { this.nameMap = nameMap; } public String getFullName() { return String.join(" ", nameMap.values()); } } 

FormController.java (Controller)

 package com.example; import java.util.HashMap; import java.util.Map; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.servlet.ModelAndView; @Controller @RequestMapping("/") public class FormController { private static Map<String, String> nameMap = new HashMap<>(); static { nameMap.put("firstname", "Аноним"); nameMap.put("lastname", "Анонимов"); } @RequestMapping(method = RequestMethod.GET) public ModelAndView showForm() { NameForm nameForm = new NameForm(nameMap); return new ModelAndView("form" , "nameForm", nameForm); } @RequestMapping(method = RequestMethod.POST) public ModelAndView handleForm(@ModelAttribute("nameForm") NameForm nameForm) { System.out.println(nameForm.getFullName()); return new ModelAndView("form", "nameForm", nameForm); } } 
  • And why Map wrap in the class? - Arthur