【问题标题】:Multipe ModelAttributes of same type in post methodpost方法中相同类型的多个模型属性
【发布时间】:2018-04-04 09:38:52
【问题描述】:

我有这个页面,老师可以邀请学生加入平台。这工作得很好,但现在我想在同一页面上实现多个邀请。简而言之,现在有一种表格可以一次邀请 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>

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

@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.service() 用于路径 [] 上下文中的 servlet [dispatcherServlet] 引发异常 [请求处理失败;嵌套异常是 org.thymeleaf.exceptions.TemplateProcessingException: 在执行处理器 'org.thymeleaf.spring4.processor.attr.SpringInputGeneralFieldAttrProcessor' (teacher/invite:20)] 时出错,根本原因 java.lang.IllegalStateException:Bean 名称“用户”的 BindingResult 和普通目标对象都不能用作请求属性 在 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]: Specified class is an interface] 根本原因 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>

【问题讨论】:

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


    【解决方案1】:

    正如Pandian 所说,“用户”绑定了两次,但在这种情况下,您可以使用简单的数组将字符串列表传递给控制器​​。因为实际的用户必须有许多在您的模板中不存在的字段。所以可以推荐在模板中使用这样的东西:

    <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 必须是这样的:

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

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

    【讨论】:

    • 您好,当两个输入字段为数组时,控制器如何接收列表?我不必事先声明数组吗?目前,页面只是在没有任何信息的情况下抛出错误。
    • Spring 会代替你。您只应该在控制器方法中将 List 作为参数传递。为防止异常,您应该制作一个空列表并将其传递给视图。在模板中你会检查列表大小,如果它是空的,你可以显示空白字段。
    • 嗨@Aleksandrs,我用你的解决方案编辑了我的原始帖子,但我仍然面临一些困难,你知道我做错了什么吗?
    • 你能在github上分享你的项目吗?
    • gitlab.com/KDG-Integratieproject/back-end.git 问题是关于invite.html 页面和/invite 方法可以在RegisterController 中找到。来自 gitlab 的版本可能会有所不同。
    【解决方案2】:

    问题:同一模型“用户”在名称为“电子邮件”的同一元素上绑定了两次

    下面的代码对我来说很好用

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

    【讨论】:

    • 嗨@Pandian,那一点是我必须绑定多个用户模型及其电子邮件字段,所以这对我不起作用。
    猜你喜欢
    • 2021-06-06
    • 1970-01-01
    • 1970-01-01
    • 2016-09-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-02
    • 2022-08-19
    相关资源
    最近更新 更多