将某个类的Set的布尔属性绑定到复选框

时间:2016-05-24 07:48:29

标签: spring spring-mvc model-binding

我希望将每个大洲的国家/地区列表(来自我的数据库)作为带有复选框的标签,以便在我的网络应用中显示/使用特定国家/地区。

以下是视觉效果。

enter image description here

因此我使用Continent类:

@Entity
public class Continent implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;

    private String name;

    @OneToMany(mappedBy = "continent")
    private Set<Country> countries;

    // Getters, equals, hashCode...
}

还有Country课程:

@Entity
public class Country implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;

    private String name;

    @ManyToOne(fetch = FetchType.LAZY, optional = false)
    @JoinColumn(name = "continentid")
    private Continent continent;

    private boolean enabled; // THE CHECKBOX

    // Getters, equals, hashCode...
}

然后我在适当的控制器中初始化Continent的绑定器,并将请求的大陆(使用参数的干净URL)添加为ModelAndView(GET)的对象:

@Controller
@RequestMapping("/continent")
public class LocaleController {

    private final LocaleService localeService;

    @Autowired
    LocaleController(LocaleService localeService) {
        this.localeService = localeService;
    }

    @InitBinder("continent")
    void initBinderContinent(WebDataBinder binder) {
        binder.initDirectFieldAccess();
    }

    @RequestMapping(path="{continent}", method = RequestMethod.GET)
    ModelAndView readContinent(@PathVariable Continent continent) {
        return new ModelAndView("continent",
                "continent", continent);
    }

    @RequestMapping(path="{continent}", method = RequestMethod.POST)
    String editContinent(@PathVariable Continent continent) {
        //TODO hasErrors etc.
        localeService.updateContinent(continent);
        return "redirect:/continents";
    }
}

在我写的JSP文件的body内(使用Spring Forms的taglib和JSTL核心):

<form:form commandName='continent' id='continentform'>

</form:form>
  <h1>${continent.name}</h1>
  <!-- SelectAll and UnselectAll buttons, other HTML tags -->
  <c:forEach var="country" items="${continent.countries}" varStatus="loop">
    <form:checkbox path="countries['${loop.index}'].enabled"/>
    <form:label path="countries['${loop.index}'].enabled">
      ${country.name}
    </form:label>
  </c:forEach>

但这不起作用:

首先: loop.index与循环中当前Set<Country> countries的{​​{1}}索引不对应;我知道,因为country不等于country.name

第二:标签countries['${loop.index}'].name属性与相应的复选框属性for=不对应。

第三次 id=来电localeService.updateContinent(continent) continentDAO.save(continent)是一个扩展ContinentDAO的接口,但不会更新该国家/地区的已启用状态。< / p>

我的错误是什么?

1 个答案:

答案 0 :(得分:0)

要解决第一个问题,我不再在Set<Country> countries类中返回Continent的TreeSet(我只返回countries)。

要解决第二个问题,我已编辑了我的JSP <c:forEach>内容:

<c:forEach var="country" items="${continent.countries}" varStatus="loop">
  <form:checkbox path="countries['${loop.index}'].enabled" cssClass="medium"
          label="${country.name}"/>
</c:forEach>

要解决第三个问题,我已在editContinent内修改了LocaleController功能,现在可以正常使用了:

 @RequestMapping(path="{continent}", method = RequestMethod.POST)
    String editContinent(@Valid Continent continent, BindingResult bindingResult) {
        //TODO hasErrors etc.
        localeService.updateContinent(continent);
        return "redirect:/continents";
 }

感谢M. Deinum提供了非常有用的评论。