3

I am attempting to send a large AJAX request of type POST through Spring MVC. The request contains data representing IDs of rows that are selected in a grid. The request looks something like this, where N is about 30,000:

POST /foo/view? HTTP/1.1
Host: localhost:8443
Connection: keep-alive
Content-Length: 618953
Accept: text/html, */*; q=0.01
Origin: https://localhost:8443
X-Requested-With: XMLHttpRequest
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Referer: https://localhost:8443/
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8

And the form data contains encoded selections:

selection=1 selection=2 selection=... selection=n

The controller method that is mapped to handle this request is annotated as follows:

@RequestMapping(method = RequestMethod.POST, value = "/foo/view")
public void controllerMethod(User user, @ModelAttribute CustomModelMap inModel, BindingResult result) {
...
}

Where CustomModelMap simply contains accessors/mutators to map the selections to a collection.

The problem I am running into is that as soon as I hit the controller, the ModelMap is populated with only 9,997 selections (it's always this number when the request contains over 9,997 selections). I triple checked the AJAX request I am sending to ensure that there are indeed 30,000 selections.

I thought maybe that my webserver didn't like the large amount of data in the request headers, but the request totals about 600k, whereas Tomcat seems to allow up to 2mb by default for POSTs.

Any ideas on what else I can check?

Ben Siver
  • 2,758
  • 1
  • 25
  • 42
  • 2
    Are you doing a GET request? Those have limits on URLS that change depending on your web server. Putting those values in the body of POST request should work however. – thatidiotguy Jul 09 '13 at 19:31
  • @thatidiotguy based on the URL he used it looks like GET. This is likely the answer. Make it one and I'll give you an upvote. – digitaljoel Jul 09 '13 at 19:37
  • also see http://stackoverflow.com/questions/2659952/maximum-length-of-http-get-request – digitaljoel Jul 09 '13 at 19:38
  • Sorry, I'm not sure it was clear from my controller method annotation alone, but the request type is currently a POST. I modified the actual URL with all of its actual parameters and left only the relevant bit. – Ben Siver Jul 09 '13 at 19:48
  • How long does this request take? Is it returning sucessfully or is your web server cutting it off because it is taking too long to run? (or maybe spring mvc has a time limit?) – thatidiotguy Jul 10 '13 at 14:53
  • Total time to hit the controller in only a couple seconds. There doesn't seem to be any unusual slowness in the request, it also seems odds that after playing with the number of selections in the request, the ModelMap always contains exactly 9,997 objects if the request as over this number. – Ben Siver Jul 10 '13 at 15:08

2 Answers2

1

If you are making a GET request, then there is a limit on the length of the URL which is dependent on your HTTP server/application server. If you change this request to a form encoded POST request and put that info in the body you will probably avoid that problem.

thatidiotguy
  • 8,701
  • 13
  • 60
  • 105
  • Sorry, I'm not sure it was clear from my controller method annotation alone, but the request type is currently a POST. – Ben Siver Jul 09 '13 at 19:47
  • @BenSiver Then are you are you passing the information in the URL? You should use `application/x-www-form-urlencoded` as the content-type and put that info in the HTTP body. – thatidiotguy Jul 09 '13 at 19:54
  • The content-type is currently set to application/x-www-form-urlencoded, and the info is being passed as encoded form data. I will edit my question to include this, thought I'd simplify matters originally but that's probably important :) – Ben Siver Jul 09 '13 at 20:00
0

For those interested, I spent a while debugging in Spring MVC and was unable to locate exactly where my request was being truncated. It seems even from the root Tomcat request handler received a truncated version of my request. It is likely there was some webserver setting preventing the entire request from being sent.

My solution was simply to change the content-type to JSON, and change my request processing to deal with this. Not ideal, but it works.

Ben Siver
  • 2,758
  • 1
  • 25
  • 42