Search code examples
javajsonspring-bootopenresty

Spring Boot POST parameter size limit


I seem to be butting heads with a limiter somewhere. One of my Spring-Boot REST endpoint (POST) parameters (surveyResults) is looking for a string of JSON:


    private static final String SURVEY_RESULTS_ENDPOINT = "/survey/results";

    @PostMapping(
        value = SURVEY_RESULTS_ENDPOINT, 
        produces = { "application/hal+json", "application/json" }
    )   
    @ApiOperation(value = "Save one survey results")
    public Resource<SurveyResult> createSurveyResults(

            @ApiParam(value = "who/what process created this record", required = true) @Valid 
                @RequestParam(value = "recordCreatedBy", required = true) String createdBy,

            @ApiParam(value = "was an issue identified", required = true) 
                @RequestParam(value = "hadFailure", required = true) Boolean hadFailure,

            @ApiParam(value = "JSON representation of the results", required = true) 
                @RequestParam(value = "surveyResults", required = true) String surveyResult

    ) ...

If I post to this with about 1500 characters, it works. Somewhere just over that and it will fail with a HTTP 400 error bad request. The whole payload is less than 2K with the other parameters.

I just moved from Wildfly to a new server setup. My company is adopting continuous deployment to cloud servers so i don't have much control nor visibility to this new load balanced server. The server is "server": "openresty/1.13.6.2" - any idea what limit I am running into?


Solution

  • Please use @RequestBody instead of @RequestParam.

    @RequestBody annotation maps the HTTP request's body to an object. @RequestParam maps the request parameter in the request, which is in the URL and not in the body.

    Most browsers have a limitation to the number of characters supported in a request parameter, and you just hit that limit.

    What I would suggest is to create a POJO that looks like this

    public class Body {
       private String createdBy; 
       private Boolean hadFailure;  
       private String surveyResult;
    
    // getters and setters
    }
    

    Now your controller will be simpler

    @PostMapping(
            value = SURVEY_RESULTS_ENDPOINT, 
            produces = { "application/hal+json", "application/json" }
        )   
    public Resource<SurveyResult> createSurveyResults(@RequestBody Body body) {
    
    }
    

    Wherever you are posting, you will have to now post a JSON (Content-Type = application/json) that looks like the following

    { "createdBy" : "foo", "hadFailure" : false, "surveyResult" : "the foo bar"}