【问题标题】:Spring MVC and jquery post request with array of POJO带有 POJO 数组的 Spring MVC 和 jquery 发布请求
【发布时间】:2013-01-22 13:01:00
【问题描述】:

我有一个简单的 POJO Java 类(getter 和 setter 没有显示)

public class VacationInfo {

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

@Temporal(TemporalType.TIMESTAMP)
private Date vacationFrom;

@Temporal(TemporalType.TIMESTAMP)
private Date vacationTo;

,带有下一个方法的 Spring MVC 控制器

@RequestMapping(value = "updateVacations", method = RequestMethod.POST)
public String updateVacations(@RequestParam VacationInfo[] vacationInfos) {
    ...
}

和 jQuery 发布请求

    $.ajax({
      type: "POST",
      url: "updateVacations",
      dataType: 'json',
      data: vacationInfos
    });

其中“vacationInfos”是一个包含 JSON 对象的数组,代表 VacationInfo 类:

[
 {
  vacationFrom: "01-01-2013",
  vacationTo: "01-01-2013"
 },
 {
  vacationFrom: "01-01-2013",
  vacationTo: "01-01-2013"
 }
]

但是当我请求时 - 我收到了 HTTP 400 错误。

【问题讨论】:

  • 在 jQuery AJAX 中,dataType 选项表示来自服务器的预期响应类型,而不是发送的数据类型。此外,data 选项预计要么是键值对的对象,要么是请求的查询字符串;我认为传递对象数组不会得到正确处理。您可以尝试:`data: {vacationInfos :vacationInfos},然后修改您的服务器端代码以使用该单个参数。
  • 我之前尝试过这样做,但没有成功。我更改了我的 ajax 请求数据,但我不明白 - 如何更改控制器方法以使其工作。

标签: java jquery spring-mvc


【解决方案1】:

编写此代码是为了获取所有已检查的表单并将它们全部发布到 Spring 控制器

jquery 方法::

        $('#testButton').click(function(){
               var testList= [];

            $('.submit').filter(':checked').each(function() {
            var checkedFrom= $(this).closest('form');
            var testPojo= checkedFrom.serializeObject();
            testList.push(testPojo);
            });

            $.ajax({
            'type': 'POST',
                'url':"testMethod",
                'contentType': 'application/json',
                'data': JSON.stringify(testList),
                'dataType': 'json',
                success: function(data) {

                if (data == 'SUCCESS')
                {
                alert(data);
                }
                else
                    {
                    alert(data);
                    }

                }
            });

        });

而 jquery 提供了两个级别的序列化,如 serialize() 和 serializeArray()。但这是序列化的自定义方法

用户定义的对象。

$.fn.serializeObject = function() {
    var o = {};
    var a = this.serializeArray();
    $.each(a, function() {
        if (o[this.name]) {
            if (!o[this.name].push) {
                o[this.name] = [o[this.name]];
            }
            o[this.name].push(this.value || '');
        } else {
            o[this.name] = this.value || '';
        }
    });
    return o;
};

在弹簧控制器中

@RequestMapping(value = "/testMethod", method = RequestMethod.POST)
    public @ResponseBody ResponseStatus testMethod(HttpServletRequest request,
            @RequestBody TestList testList)
            throws Exception {
..............
}

其中 TestList 是另一个类,用于处理表单发布,其中包含用于测试方法的 mvc 控制器中的 Test 数组

public  class TestList extends ArrayList<Test> {}

【讨论】:

    【解决方案2】:

    尝试使用@RequestBody 而不是@RequestParam

    @RequestMapping(value = "updateVacations", method = RequestMethod.POST)
        public String updateVacations(@RequestBody  VacationInfo[] vacationInfos) {
        ...
    }
    

    @RequestBody 方法参数注解表示方法参数应绑定到 HTTP 请求正文的值,在您的情况下为 JSON 数据。

    【讨论】:

    • 使用 @RequestBody 我从服务器收到 415(不支持的媒体类型)错误。
    • 在您的 POST 请求中添加标头 'Content-Type':'application/json'。见here
    • 我在 ajax 请求中添加了这个参数,但现在我得到了另一个错误 - “加载资源失败:服务器响应状态为 400(错误请求)”。
    • vacationInfos 是一个 javascript 对象,您需要在发送到服务器之前将其转换为 JSON。在您的$.ajax() 中使用data: JSON.stringify(data)。将json2.js 文件添加到您的应用程序
    【解决方案3】:

    我回答了我的问题。 表单客户端我将日期作为时间戳发送。因为服务器不应该知道客户端是什么时区,也不应该依赖于特定的日期格式(这是最佳实践之一)。然后我在 VacationInfo 日期字段上添加 JsonDeserializer 注释,这是工作。

    public class VacationInfo {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    @JsonDeserialize(using=DateDeserializer.class)
    @Temporal(TemporalType.TIMESTAMP)
    private Date vacationFrom;
    
    @JsonDeserialize(using=DateDeserializer.class)
    @Temporal(TemporalType.TIMESTAMP)
    private Date vacationTo;
    

    Ajax POST 请求

    [
      {
        vacationFrom: "1359197567033",
        vacationTo: "1359197567043"
      },
      {
        vacationFrom: "1359197567033",
        vacationTo: "1359197567043"
      }
    ]
    

    如果您需要以特定格式将日期作为字符串发送(例如“mm-dd-yyyy”) - 您需要定义自己的 JsonDesiarilizer(org.codehaus.jackson.map package in Jackson) 类,它扩展frpm JsonDeserializer 类并实现您的逻辑。

    【讨论】:

      【解决方案4】:

      您可以创建自己的格式化程序来解析传入的请求。阅读here。下面的代码略有删减。

      public class LinkFormatter implements Formatter<List<Link>> {
          @Override
          public List<Link> parse(String linksStr, Locale locale) throws ParseException {
              return new ObjectMapper().readValue(linksStr, new TypeReference<List<Link>>() {});
          }
      }
      

      jquery:

      $.ajax({
          type: "POST",
          data: JSON.stringify(collection)
          ...
      });
      

      弹簧控制器:

      @RequestParam List<Link> links
      

      并且不要忘记在应用程序上下文中注册它:

      <bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
      <property name="formatters">
        <set>
          <bean class="LinkFormatter"/>
        </set>
      </property>
      

      【讨论】:

        猜你喜欢
        • 2015-05-04
        • 1970-01-01
        • 1970-01-01
        • 2014-05-17
        • 2014-03-07
        • 1970-01-01
        • 1970-01-01
        • 2017-12-04
        • 2014-04-01
        相关资源
        最近更新 更多