post方法中相同类型的Multipe ModelAttributes

时间:2018-04-04 09:38:53

标签: java spring spring-mvc spring-boot thymeleaf

我有一个教师可以邀请学生加入该平台的页面。这很好用,但现在我想在同一页面上实现多个邀请。简而言之,现在有一种形式可以一次邀请1名学生,但我想用一种方法将其扩展到5名学生。

这是邀请1名学生的页面:

<div class="container">
<div class="wrapper">
    <form class="form-activate" th:action="@{/invite}" method="post" th:object="${user}">
        <h2 class="form-activate-heading" th:text="#{invite.title}">Nodig een student uit</h2>
        <p th:text="#{invite.email}">Vul hier het e-mailadres in van de student die je wil uitnodigen:</p>       
        <div class="form-group">
            <input type="text" name="email" id="email" class="form-control input-lg" data-validation="email"
                   placeholder="Email" tabindex="2" th:attr="placeholder=#{general.email}"/>
        </div>
        <div class="row">
            <div class="col-xs-6 col-sm-6 col-md-6">
                <input type="submit" class="btn btn-secondary" value="Invite"  th:attr="value=#{invite.enter}"/>
            </div>
        </div>
    </form>
</div>

现在我尝试为2位用户修改此页面:

<div class="container">
<div class="wrapper">
    <form class="form-activate" th:action="@{/invite}" method="post">
        <h2 class="form-activate-heading" th:text="#{invite.title}">Nodig een student uit</h2>
        <p th:text="#{invite.email}">Vul hier het e-mailadres in van de student die je wil uitnodigen:</p>
        <div class="form-group" th:object="${user}">
            <input type="text" name="email" th:field="*{email}" class="form-control input-lg" data-validation="email"
                   placeholder="Email" tabindex="2" th:attr="placeholder=#{general.email}"/>
        </div>
        <div class="form-group" th:object="${user}">
            <input type="text" name="email" th:field="*{email}" class="form-control input-lg" data-validation="email"
                   placeholder="Email" tabindex="2" th:attr="placeholder=#{general.email}"/>
        </div>
        <div class="row">
            <div class="col-xs-6 col-sm-6 col-md-6">
                <input type="submit" class="btn btn-secondary" value="Invite"  th:attr="value=#{invite.enter}"/>
            </div>
        </div>
    </form>
</div>

然后在我的帖子方法中,我尝试这样做:

@RequestMapping(value="/invite", method = RequestMethod.POST)
public ModelAndView SendInvite(ModelAndView modelAndView, @ModelAttribute User user1, @ModelAttribute User user2, BindingResult bindingResult, RedirectAttributes redirectAttributes, HttpServletRequest request){
    List<User> students = new ArrayList<>();
    students.add(user1);
    students.add(user2);
    for (User user : students) {

但页面甚至不再加载,这是我的get方法:

 @RequestMapping(value="/invite", method = RequestMethod.GET)
public ModelAndView showInvitePage(ModelAndView modelAndView, @ModelAttribute User user){
    return modelAndView;
}

这给了我以下错误:

servlet [dispatcherServlet]的Servlet.service()与path []的上下文发生异常[请求处理失败;嵌套异常是org.thymeleaf.exceptions.TemplateProcessingException:执行处理器'org.thymeleaf.spring4.processor.attr.SpringInputGeneralFieldAttrProcessor'(老师/邀请:20)]时出错 java.lang.IllegalStateException:BindingResult和bean名称'user'的普通目标对象都不可用作请求属性     在org.springframework.web.servlet.support.BindStatus。(BindStatus.java:144)

甚至可能我正在尝试做什么?

编辑:我正在尝试实现解决方案Aleksandrs给了我,但Spring抛出了一个错误:

@RequestMapping(value="/invite", method = RequestMethod.GET)
public ModelAndView showInvitePage(ModelAndView modelAndView){
    List<String> emailList = new ArrayList<>();
    modelAndView.addObject(emailList);
    return modelAndView;
}

@RequestMapping(value="/invite", method = RequestMethod.POST)
public ModelAndView SendInvite(ModelAndView modelAndView, List<String> emailList){
    System.out.println(emailList.get(0));

尽管我已经在Get方法中实例化了emailList,但我收到以下错误:

嵌套异常是org.springframework.beans.BeanInstantiationException:无法实例化[java.util.List]:指定的类是一个具有根本原因的接口 org.springframework.beans.BeanInstantiationException:无法实例化[java.util.List]:指定的类是一个接口

EDIT2:

最后得到它的工作,感谢Aleksandrs的帮助!解决方案:

 @RequestMapping(value="/teacher/invite", method = RequestMethod.GET)
public ModelAndView showInvitePage(ModelAndView modelAndView){
    logger.info("Entered showInvitePage function");
    List<String> email = new ArrayList<>();
    modelAndView.addObject("email", email);
    return modelAndView;
}

@RequestMapping(value="/invite", method = RequestMethod.POST)
public ModelAndView SendInvite(ModelAndView modelAndView, @AuthenticationPrincipal User currentUser, @RequestParam List<String> email){
    email.forEach(address -> {
// send the invites
});

邀请页面:

 <form class="form-activate" th:action="@{/invite}" method="post" >            
            <p th:text="#{invite.email}">Vul hier het e-mailadres in van de student die je wil uitnodigen:</p>
        </div>
        <div class="form-group">
            <input type="text" name="email" id="email" class="form-control input-lg" data-validation="email"
                   placeholder="Email" tabindex="2" th:attr="placeholder=#{general.email}"/>
        </div>
        <div class="form-group">
            <input type="text" name="email" id="email2" class="form-control input-lg" data-validation="email"
                   placeholder="Email" tabindex="2" th:attr="placeholder=#{general.email}"/>
        </div>
        <div class="form-group">
            <input type="text" name="email" id="email3" class="form-control input-lg" data-validation="email"
                   placeholder="Email" tabindex="2" th:attr="placeholder=#{general.email}"/>
        </div>
        <div class="row">
            <div class="col-xs-6 col-sm-6 col-md-6">
                <input type="submit" class="btn btn-secondary" value="Invite"  th:attr="value=#{invite.enter}"/>
            </div>
        </div>
    </form>

2 个答案:

答案 0 :(得分:1)

正如潘迪安所说,&#34;用户&#34;绑定两次,但在这种情况下,您可以使用简单数组将String列表传递给控制器​​。因为实际用户必须有许多字段,而这些字段不会出现在您的模板中。因此可以在模板中重新使用类似的东西:

<form class="form-activate" th:action="@{/invite}" method="post">
    <h2 class="form-activate-heading" th:text="#{invite.title}">Nodig een student uit</h2>
    <p th:text="#{invite.email}">Vul hier het e-mailadres in van de student die je wil uitnodigen:</p>
    <div class="form-group">
        <input type="text" name="email[]" class="form-control input-lg" data-validation="email"
               placeholder="Email" tabindex="2" th:attr="placeholder=#{general.email}"/>
    </div>
    <div class="form-group">
        <input type="text" name="email[]" class="form-control input-lg" data-validation="email"
               placeholder="Email" tabindex="2" th:attr="placeholder=#{general.email}"/>
    </div>
    <div class="row">
        <div class="col-xs-6 col-sm-6 col-md-6">
            <input type="submit" class="btn btn-secondary" value="Invite"
                   th:attr="value=#{invite.enter}"/>
        </div>
    </div>
</form>

在控制器中:

@RequestMapping(value = "/invite", method = RequestMethod.POST)
public ModelAndView SendInvite(List<String> emailAddressList) {
    // some stuff here
}

修改

所以,我不确定我的JavaScript代码是否有效,但在您的情况下,HTML必须是likethis:

<form class="form-activate" th:action="@{/invite}" method="post" id="myForm">
    <h2 class="form-activate-heading" th:text="#{invite.title}">Nodig een student uit</h2>
    <p th:text="#{invite.email}">Vul hier het e-mailadres in van de student die je wil uitnodigen:</p>
    <div class="form-group">
        <input type="text" name="email[]" id="email" class="form-control input-lg" data-validation="email"
               placeholder="Email" tabindex="2" th:attr="placeholder=#{general.email}"/>
        <span style="cursor: pointer;"
              onclick="myForm.innerHTML = myForm.innerHTML + '' + this.parentNode.cloneNode(true);">+</span>
    </div>
    <div class="row">
        <div class="col-xs-6 col-sm-6 col-md-6">
            <input type="submit" class="btn btn-secondary" value="Invite"
                   th:attr="value=#{invite.enter}"/>
        </div>
    </div>
</form>

在控制器中,我会尝试这样做:

@RequestMapping(value = "/invite", method = RequestMethod.POST)
public ModelAndView SendInvite(ModelAndView modelAndView, @RequestParam List<String> email) {
    email.stream()
        .forEach(address -> {
            User u = userService.findByEmail(address);
            if (u == null) {
                // send email here for current user;
            }
        });
    // some other stuff
}

如果你能告诉我一些测试密码,我可以尝试在我的电脑上运行它。

答案 1 :(得分:0)

问题:同一型号&#34;用户&#34;在相同元素上绑定两次,名称为&#34;电子邮件&#34;

以下代码对我来说工作正常

    <form action="#" th:action="@{/accessSite}" method="post">
    <div th:object="${userVO}">
        <table>
            <tr>
                <td>Name:</td>
                <td><input type="text" th:field="*{name}" /></td>
                <td th:if="${#fields.hasErrors('name')}" th:errors="*{name}">Name
                    Error</td>
            </tr>


        </table>
    </div>

    <div th:object="${employeeVO}">
        <table>
            <tr>
                <td>Name:</td>
                <td><input type="text" th:field="*{empname}" /></td>
                <td th:if="${#fields.hasErrors('empname')}" th:errors="*{empname}">Name
                    Error</td>
            </tr>

        </table>
    </div>

提交     

  @RequestMapping("/accessSite")
public String accessSite( UserVO userVO, EmployeeVO employeeVO,BindingResult bindingResult) {
    if (bindingResult.hasErrors()) {
        return "form";
    }
    return "result";
}