0

I have a simple POJO Java class (getters and setters is not shown)

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 controller with next method

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

and jQuery post request

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

where "vacationInfos" is a array with JSON objects, which represent VacationInfo class:

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

But when I do request - i got a HTTP 400 error.

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
VladislavLysov
  • 651
  • 1
  • 11
  • 25
  • In jQuery AJAX, the `dataType` option signifies the type of the response expected from the server, not the type of data being sent. In addition, the `data` option is expected to either be an object of key-value pairs, or the query string for the request; I don't think passing an array of objects would be handled correctly. You could try: `data: {vacationInfos : vacationInfos}, then modify your server-side code to use that single parameter. – Anthony Grist Jan 22 '13 at 13:06
  • I tried to do this before, but did not work. I change my ajax request data, but i don't understand - how change controller method to make it work. – VladislavLysov Jan 22 '13 at 13:23
  • Possible duplicate of [Passing in JSON array to spring MVC Controller](http://stackoverflow.com/questions/21834180/passing-in-json-array-to-spring-mvc-controller) – Andrei Epure Mar 23 '17 at 10:20

4 Answers4

2

This code is written to get all the form's which are checked and post them all to Spring controller

jquery method::

        $('#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);
                    }

                }
            });

        });

whereas jquery provide two level's of serialization like serialize() and serializeArray().But this is custome method for serialize a

User defined Object.

$.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;
};

in spring controller

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

where TestList is an another class which is written to handle form post with a array of Test in mvc controller for test method

public  class TestList extends ArrayList<Test> {}
Ravi Kant
  • 4,785
  • 2
  • 24
  • 23
0

try using @RequestBody instead of @RequestParam

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

The @RequestBody method parameter annotation indicates that a method parameter should be bound to the value of the HTTP request body, which is the JSON data in your case.

Vinay
  • 2,667
  • 1
  • 18
  • 21
  • With @RequestBody I got a 415 (Unsupported Media Type) error from server. – VladislavLysov Jan 22 '13 at 13:36
  • add header `'Content-Type':'application/json'` to your POST request. see [here](http://stackoverflow.com/questions/11492325/post-json-fails-with-415-unsupported-media-type-spring-3-mvc) – Vinay Jan 22 '13 at 13:51
  • I'm add this parameter in ajax request, but for now I got another error - "Failed to load resource: the server responded with a status of 400 (Bad Request)". – VladislavLysov Jan 22 '13 at 14:17
  • vacationInfos is a javascript object and you need to convert it to JSON before sending to server. Use `data: JSON.stringify(data)` in your `$.ajax()`. Add [json2.js](https://github.com/douglascrockford/JSON-js/blob/master/json2.js) file to your application – Vinay Jan 23 '13 at 14:57
0

I answered my question. Form client I send Date as timestamp. Because server should not know anything about what time zone is the client and should not depend on a specific date format(it's one of the best practice). And after that I'm add JsonDeserializer annotation on VacationInfo date fields and this is work.

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 request

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

If you need to send Date as string in specific format("mm-dd-yyyy" for example) - you need to define own JsonDesiarilizer(org.codehaus.jackson.map package in Jackson) class, which extends frpm JsonDeserializer class and implement your logic.

VladislavLysov
  • 651
  • 1
  • 11
  • 25
0

You can create your own formatter to parse incoming request. Read here. The code below is a little trimmed.

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)
    ...
});

Spring controller:

@RequestParam List<Link> links

And don't forget to register it in application context:

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