spring - 处理同一类型的多种形式 - 不可能?

标签 spring spring-mvc

考虑以下场景:

  • 我的表单模型
    public class PersonForm {
        @NotNull
        private String name;
    
        /*usual getters and setters*/
    }
    
  • 我的 Controller :
    @Controller
    @SessionAttribute(types={ PersonForm.class })
    public class MyController {
    
        @RequestAttribute(...)
        public String render(final ModelMap map) {
            /* get list of info and for each info 
             * create a PersonForm and put it in the modelmap
             * under key p0, p1, p2, ..., pn
             */
        }
    
        public String submit(final ModelMap map,
                             @Valid final PersonForm form,
                             final BindingResult result) {
    
            if (result.hasErrors()) {
                // return to page
            } else {
                // do necessary logic and proceed to next page
            }
        }
    }
    
  • 最后是我的 JSP View
    ...
    <c:forEach ...>
        <form:form commandName="p${counter}">
            ... other form:elements and submit button goes here
        </form:form>
    </c:forEach>
    ...
    

  • 如您所见,我正在尝试处理同一类类型的多种形式。提交工作——它让我很好地使用了 submit(...) 方法,验证也是如此。但是重新渲染页面并没有向我显示预期的错误消息!

    更糟糕的是——我检查了提交 header 中传递的内容,没有任何迹象表明提交了哪个表单,因此无法区分一个表单和另一个表单。这让我相信同一类类型的多种形式是不可能的......

    有没有其他方法可以做到这一点(除了 Ajax)?

    非常感谢。

    最佳答案

    我设法让这个“黑客”发挥作用。正如果冻所推荐的那样,这一切都归功于他。

    简单来说,这个概念是使用传统的 <c:forEach> 预先填充您的 View 。构造。棘手的部分是每当按下相应行的“提交”按钮时,所有信息都必须注入(inject)隐藏表单并强制提交给 Controller 。如果屏幕再次出现一些错误,则脚本必须负责将值注入(inject)包括错误在内的相应行。

    1)我的模型

        public class PersonForm {
    
            private String id;
    
            @NotNull
            private String name;
    
            /*usual getters and setters*/
        }
    

    2)我的 Controller
        @Controller
        @SessionAttribute(/* the hidden form name, the person list */)
        public class MyController {
    
            @RequestAttribute(...)
            public String render(final ModelMap map) {
                /* get list of info and for each info 
                 * create a PersonForm and put it in the modelmap
                 * under key p0, p1, p2, ..., pn
                 */
            }
    
            public String submit(final ModelMap map,
                                 @Valid final PersonForm form,
                                 final BindingResult result) {
    
                if (result.hasErrors()) {
                    // return to page
                } else {
                    // do necessary logic and proceed to next page
                }
            }
        }
    

    3) 我的看法
        ...
    
        <form:form commandName="personForm" cssStyle="display: none;">
            <form:hidden path="id"/>
            <form:hidden path="name" />
            <form:errors path="name" cssStyle="display: none;" />
        </form:form>
    
        ...
    
        <c:forEach var="p" items="${pList}">
            <input type="text" id="${ p.id }Name" value="${ p.name }" />
            <!-- to be filled in IF the hidden form returns an error for 'name' -->
            <span id="${ p.id }nameErrorSpan"></span>
            <button type="button" value="Submit" onclick="injectValuesAndForceSubmit('${ p.id }');" />
        </c:forEach>
    
        ...
    
        <script type="text/javascript">
    
        injectValuesAndForceSubmit = function(id) {
    
            $('#id').val( id ); // fill in the hidden form's id
            $('#name').val( $('#'+id+'name').val() ); //fill in the hidden form's name
    
            $('#personForm').submit(); //submit!
        }
    
    
    
        $(document).ready(function() {
    
            var id = $('#id').val();    
            if (id.trim().length == 0) {
                //Empty. Nothing to do here as this is a simple render.
            } else {
    
                //The page seems to be returning from some sort of error ... pre-fill the respective row!
                $('#'+id+'name').val($('#name').val());
                var hiddenNameErrorSpan = $('#name.errors');
                if (hiddenNameErrorSpan) {
                    $('#'+id+'nameErrorSpan').text(hiddenNameErrorSpan.html());
                }
            } //else
        }
        </script>
    

    正如您所看到的,该 View 具有最毛茸茸的部分——希望它仍然对任何(不幸地)遇到与我相同情况的人有用。干杯!

    关于spring - 处理同一类型的多种形式 - 不可能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11859967/

    相关文章:

    java - 在 Spring 宠物诊所切换数据库

    java - RestTemplate x Feign Client 有什么区别?

    java - 你怎么能找出java应用程序是建立在Spring或Spring Boot或Spring MVC上的

    java - 分页和排序

    java - Hibernate 不会通过合并或更新来更新实体

    Spring 规范 - 谓词的结合

    java - Spring 、Tomcat、Java

    spring - 为什么需要 Autowiring ? Autowiring 的概念如何解释?

    java - CORS Spring Security 配置 - 404 请求的资源上不存在 'Access-Control-Allow-Origin' header

    java - 无法添加或更新子行 : a foreign key constraint fails Hibernate