Skip to content

StringHttpMessageConverter flush out response immediately before execute posthandler [SPR-16046] #20595

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
spring-projects-issues opened this issue Oct 4, 2017 · 2 comments
Assignees
Labels
in: web Issues in web modules (web, webmvc, webflux, websocket) status: declined A suggestion or change that we don't feel we should currently apply

Comments

@spring-projects-issues
Copy link
Collaborator

spring-projects-issues commented Oct 4, 2017

eric wang opened SPR-16046 and commented

the problem is related @RequestBody the ajax request, if the response content-type is text/plain that means the handler method return string directly, the StringHttpMessageConverter will getting used to handler the HTTP message convert. the problem seems in the writeInternal method, it is calling StreamUtils.copy(String in, Charset charset, OutputStream out) which will create a new Write and flush the response content out immediately.

this problem caused all subsequence handlers like posthandler got executed after response return to the client.

the repro steps should be easy, just create a controller with @ResponseBody and return string directly.


Affects: 4.3.11

Issue Links:

@spring-projects-issues
Copy link
Collaborator Author

Elizabeth Hartoog commented

I work with Eric, and I was the one having the issue. I wrote this email to my fellow developers to inform them off the issue:

There is a bug in the spring framework that causes responses using @ResponseBody to not execute interceptor posthandlers before the response is returned to the client. Specifically, if you have a response type of String for your response body, it will use a message converter that is bugged. This mostly applies to calls made by the javascript to [app name], aka [ajax call] request mappings.

So if you have a request mapping that fits this description, be aware that any cookies or response changes made in the posthandler will not be executed until after the response is already returned to the client. Session updates will still execute and will probably still work as expected.

Eric uses Spring 4. I use Spring 3 MVC.

@spring-projects-issues
Copy link
Collaborator Author

spring-projects-issues commented Mar 7, 2018

Brian Clozel commented

Hello eric wang, Elizabeth Hartoog,

Thanks for reaching out!
This is in fact working as designed (or a known limitation of the WebRequestInterceptor, depending on how you see it).

As explained in the WebRequestInterceptor javadoc:

This interface assumes MVC-style request processing: A handler gets executed,
exposes a set of model objects, then a view gets rendered based on that model.
Alternatively, a handler may also process the request completely, with no
view to be rendered.

In the case of @ResponseBody methods, no view rendering is involved and the whole response is rendered by the handler. So it's not technically about this HttpMessageConverter, but more:

  • if a HttpMessageConverter flushes (like the String one, or the Jackson library itself for JSON payloads), the response is committed
  • if the response buffer fills up, the container may flush the response anyway

Your only choice here is to consider a different infrastructure, like using a ContentCachingResponseWrapper in a Servlet Filter (see ShallowEtagHeaderFilter. You can also get more background information about that in the comments section of #13864.

Feel free to comment here with specifics about your use case so that we can discuss your best options here.

Thanks!

@spring-projects-issues spring-projects-issues added type: bug A general bug status: declined A suggestion or change that we don't feel we should currently apply in: web Issues in web modules (web, webmvc, webflux, websocket) labels Jan 11, 2019
@spring-projects-issues spring-projects-issues removed the type: bug A general bug label Jan 12, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: web Issues in web modules (web, webmvc, webflux, websocket) status: declined A suggestion or change that we don't feel we should currently apply
Projects
None yet
Development

No branches or pull requests

2 participants