【问题标题】:handle form post with a array of items in spring MVC在spring MVC中处理带有一系列项目的表单帖子
【发布时间】:2013-03-08 00:34:32
【问题描述】:

我正在尝试将一些数据从客户端发送到服务器,并将其处理为文件下载。 我正在使用一个简单的 HTML 表单,因为我想初始化文件下载(而不是 AJAX)。 其中一个表单字段是一个项目数组。 (另外两个是名称和描述字符串)。 在提交表单之前,我将此字段序列化为字符串 (JSON.stringify)。

在服务器端,我尝试了上百万种技术(@ModelAttribute 与 @RequestBody,不同的杰克逊映射 bean 配置)将其转换为单一类型或三种单独的类型(字符串 + 字符串 + 列表/数组)。

我找到的示例仅适用于 AJAX... 任何人都可以提供一个工作示例或描述吗?

=======

更新: 我已经通过 JSON.stringify-ing 集合并将其传递到其中一个输入中实现了一种解决方法, 在服务器端我有:

@RequestMapping(method = RequestMethod.POST, value = "exportSectionsToExcel")
  public HttpEntity<byte[]> createExcelWorkBook(@ModelAttribute ExportSectionsListForm exportSectionsListForm) {
Section[] sectionObjects = gson.fromJson(exportSectionsListForm.getSections(), Section[].class);
...

ExportSectionsListForm 对象仅包含字符串:

public class ExportSectionsListForm {
private String name;
private String url;
private String rssUrl;
private String sections;
...
(omitting ctor, getters and setters)

此外,我发现了这个有希望的链接: http://viralpatel.net/blogs/spring-mvc-multi-row-submit-java-list/ 但没有尝试过 - 似乎我需要动态生成输入元素才能工作,但它实际上可能是正确的解决方案。有人试过吗?

【问题讨论】:

  • 请问您的控制器代码好吗?
  • 我尝试了多种技术 - 每种技术都会导致不同的问题,但都没有奏效 - 所以我正在寻找一个可行的例子......
  • 因为我不在办公室,所以不能提供我的代码,但我建议你在你的控制器方法中添加断点,并检查请求中存储了哪些类型的数据?
  • 谢谢。我通常要么得到几个例外之一,要么得到一个空数组/列表。我正在寻找一种解决方案,其中包括(1)客户端序列化(json?方括号数组项,如 item[1]、item[2] 等?)和(2)带注释的控制器方法签名 + bean配置。
  • 您可以使用 firebug 来检查您发送给控制器的数据。

标签: spring-mvc deserialization forms


【解决方案1】:

我一直在研究同样的问题。如果我有几个输入名称相同,例如:

<input name="somename"/>
<input name="somename"/>
<input name="somename"/> 

我有一个映射到我的方法的表单,如下所示:

@ModelAttribute("ReturnsAndExchangesForm") ReturnsAndExchangesForm    returnsAndExchangesForm

在这种形式中,我有一个名为的属性的 getter 和 setter: String[] somename ,spring 很好地将这些值传递到该数组中!

【讨论】:

    【解决方案2】:

    @ModelAttribute 标签将尝试根据表单发布构建对象。由于您将表单值序列化为 JSON,因此这不起作用。 @RequestBody 只是为您提供一个表示请求正文的字符串。因此,您可以获得表示传入 JSON 的字符串,然后使用 FlexJSON 的 Jackson(或您使用的任何 JSON 库)对 JSON 进行解组。不过,我不确定这是不是最好的方法。

    我会质疑为什么您需要将表单序列化为 JSON。 Spring 可以很好地处理带有 Lists/Maps 的表单。只需使用@ModelAttribute 提交表单,在控制器上创建您的“数组”和列表,或者您期望的任何内容。因此,如果我正确解释了您的示例,我的 ModelAttribute 将如下所示:

    public class ExportSectionsFormBean {
      private String name;
      private String url;
      private String rssUrl;
      private List<String> sections;
      /* getters/setters */
    }
    

    那么我的 Controller 方法将如下所示:

    @RequestMapping(method = RequestMethod.POST, value = "exportSectionsToExcel")
    public HttpEntity<byte[]> createExcelWorkBook(@ModelAttribute ExportSectionsFormBean exportSectionsFormBean ) {
      /* Do whatever with your  */
    }
    

    在表单方面,使用 Spring JSTL 标记,只需使您的“部分”字段看起来像:

    <form:input path="sections[0]" />
    <form:input path="sections[1]" />
    

    或者,如果您更愿意使用 HTML,那么

    <input type="text" name="sections[0]" id="sections0" />
    <input type="text" name="sections[1]" id="sections1" />
    

    这是由上述 JSTL 标记生成的。只要将“sections”的值作为 'section[#]=value' 放入 HTTP 请求中,就可以完成所有设置。

    【讨论】:

    • 谢谢,这就是我一直在寻找的东西——我在链接的文章中也看到了这一点——但我没有测试它(因为我使用了更丑陋的解决方法)。
    • Spring MVC 中的 Lists/Maps 与允许添加/删除的表单的唯一区别是,如果您将 ModelAttribute 放入会话中,您必须以某种方式跟踪您删除的那些。问题是 ModelAttribute 被创建一次,因此设置了列表/地图。后续帖子不会重新构建列表/地图,仅修改/插入您在表单帖子中具体引用的项目。因此,例如,如果您的列表中有 10 个项目,并且您在视图侧删除了第 5 个项目,Spring 将设置 1-4 和 6-10,并且 5 仍然是帖子没有的旧值携带#5。
    猜你喜欢
    • 1970-01-01
    • 2017-07-09
    • 1970-01-01
    • 1970-01-01
    • 2014-11-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多