Reputation: 13
Code:
package com.test.controllers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import java.util.concurrent.TimeUnit;
@RestController
@RequestMapping("/")
public class Controller {
private HttpServletRequest request;
public HttpServletRequest getRequest() {
return request;
}
@Autowired
public void setRequest(HttpServletRequest request) {
this.request = request;
}
@RequestMapping("safe-read")
public void threadSafeRead() throws InterruptedException {
System.out.println(request.getHeader("user-agent"));
Thread.sleep(TimeUnit.MILLISECONDS.convert(5,TimeUnit.SECONDS));
System.out.println(request.getHeader("user-agent"));
}
}
When I do two request in same time ,result of this execution is :
In runtime field have type com.sun.proxy.$Proxy45
.
How spring make it thread-safe for read?
Upvotes: 0
Views: 1629
Reputation: 56
Just to expand a little on the comment by M. Deinum above, there are a few approaches you could use to avoid holding a reference to the request as part of the controller's state.
1) As already mentioned, directly inject the request as part of the method signature.
2) Only work with the request params that you are directly interested in by using the @RequestParam annotations in your method signatures.
3) Take a look at the Spring api doc for the RequestContextHolder class. You can do things like:
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder
.currentRequestAttributes()).getRequest();
which may or may not be useful to you.
Hope this helps :-)
Upvotes: 0