I am using spring-webmvc 5.2.3.

I want to use Spring's Default MethodArgumentResolver to resolve the json payload into multiple beans. But I am not able to do that right now because AbstractMessageConverterMethodArgumentResolver.EmptyBodyCheckingHttpInputMessage(httpRequest)is passed the HttpRequest object and is used directly. While attempting to resolve the second argument the HttpRequest's inputStream is closed, so I get an exception saying that the input stream is closed. Ergo I am able to annotate only one argument with @RequestBody.

    @PostMapping("/endpoint")
    public void  method(@Valid @RequestBody CustomBean bean1, 
                                @Valid @RequestBody CustomBean2 bean2) 
    {
        // using both beans.
    }

Why not use a ContentCachingRequestWrapper instead of the actual HttpRequest for argument resolution ?

Comment From: juzerali

I think the problem is in AbstractJackson2HttpMessageConverter#readJavaType.

The converter passes requestBody of type InputStream directly to Jackson's ObjectReader#readValue, which closes the stream after parsing the JSON literal.

A temporary fix for you could be disabling the global JsonParser.Feature.AUTO_CLOSE_SOURCE flag in your env.

This can be fixed in Spring by adding .without(JsonParser.Feature.AUTO_CLOSE_SOURCE) in the call chain mentioned above. I can contribute with a PR.

Comment From: adiSuper94

@juzerali , Agreed that marking JsonParser.Feature.AUTO_CLOSE_SOURCE as false will prevent the inputStream from being closed. But data that has been read once from a stream cannot be read again, right? How will adding AUTO_CLOSE_SOURCE = false help with this?

Comment From: sbrannen

I want to use Spring's Default MethodArgumentResolver to resolve the json payload into multiple beans.

When you say "multiple beans", do you perhaps mean multiple beans of different types?

I ask, because your example shows two beans of the exact same type (CustomBean) which doesn't seem to make much sense.

Comment From: adiSuper94

@sbrannen , yes I mean multiple beans of different types. I'll change the code snippet for better clarity.

Comment From: juzerali

You are right, it was a lame attempt. What do you think could be a solution?

Comment From: rstoyanchev

So presumably the input is a JSON object that contains the data for both CustomBean1 and CustomBean2, in which case you could create one top-level object that contains both. Using a caching request wrapper could be another way to go, but that is not something we are going to do out of the box.