21

I'm looking for a way to autowire HttpServletResponse. It doesn't work with spring out of the box, but I've found this description. This works but is sort of annoying, in that spring obviously has a mechanism to make objects request scoped (i.e. HttpServletRequest) and this seems to be a hack bolted on top.

Is there a way to hook into the same mechanism that spring uses for HttpServletRequest? And, any idea why spring team decided to only make HttpServletRequest autowire capable (and excluded HttpServletResponse)?

skaffman
  • 398,947
  • 96
  • 818
  • 769
Kevin
  • 24,871
  • 19
  • 102
  • 158

2 Answers2

13

Perhaps there is some workaround, but it's not that obvious, because it's not the way it's meant to be. Spring MVC is meant to have singleton @Controller beans that provide @RequestMapping methods which take the request and response as arguments.

If you need the response in another place (the service layer) - don't do it. The response should not go beyond the web (controller) layer.

To inject the response, you need: - to store the response in a ThreadLocal - to make a factory bean that returns the current response

About the example code you showed - I'm not sure if you are not going to need the factory bean to return a proxy (implementing HttpServletResponse), which in turn to return the current response. And it gets rather complicated.

But ultimately - you should not do that. If you need to intercept multiple controller invocations, use an mvc-interceptor. If you really need to use an aspect, you can get the response if it is passed as argument to the intercepted method.

Bozho
  • 588,226
  • 146
  • 1,060
  • 1,140
  • 1
    Not so fast: What about an `@Aspect` that that is meant to wrap the `@Controller`. The "not the way it's meant to be" argument doesn't explain why HttpServletRequest is autowire capable and HttpServletResponse is not either. – Kevin Aug 08 '11 at 15:13
  • Use interceptors for that. They see the response – Bozho Aug 08 '11 at 15:16
  • The request - I don't know why they made it injectable. I'll look for a way to inject response and will let ypu know – Bozho Aug 08 '11 at 15:18
  • Are you saying that spring's AOP support is insufficient for the specific use case of wrapping controllers that want access to the response?! – Kevin Aug 08 '11 at 15:18
  • First, there are interceptors. Then you can get the method arguments (hence the response) – Bozho Aug 08 '11 at 15:28
  • The link you provided was the one I provided originally in my question. I think it's a hack. Spring could easily make the response available in the same way as it makes the request available. My question was, can I hook into that mechanism somehow, rather than re-invent it. – Kevin Aug 08 '11 at 15:57
  • @Kevin - I don't think you can. – Bozho Aug 08 '11 at 16:23
  • I'll mark your answer correct--not because I like it, but because it accurately reflects the way it is. – Kevin Aug 25 '11 at 17:04
  • 2
    you said that "The response should not go beyond the web" But what if i need to alter response coockie by my inner logic ? – voipp Nov 20 '18 at 11:47
  • An example like voipp's: you need to refresh the OAuth2 token. If you use RestTemplate you can catch the unauthorized failure, request a new token and update your cookie that stores that. – Virmundi Jan 20 '19 at 03:41
  • What about 'request' scoped beans? Shouldn't be able to autowire response? They are web layer specific. – cdalxndr Jan 24 '20 at 14:52
5

Can you simply include the request in the method handle?

@RequestMapping(method=Method.GET, value="myUrl")
public String doGet(HttpServletResponse response){//spring will put the response in for you
  ... 
}
cowls
  • 24,013
  • 8
  • 48
  • 78
John Vint
  • 39,695
  • 7
  • 78
  • 108