Autowiring HttpServletRequest in Spring controller
if it works that means spring doesn't inject exactly http request but a proxy. the proxy delegates calls to current http request
Spring MVC - Can I autowire HttpServletRequest in RestController
I have used this and it works fine. But unfortunately I did not find any official documentation which mentions that this should work.
Here is the explanation based on my understanding from debugging the code with running multiple requests with different headers/payload etc.:
Whether we autowire on field or through the constructor, servletRequest
acts like a Proxy object which delegates the call to Current HttpServletRequest which is different for each request. Thus, even though it's injected through constructor in a Singleton RestController, it will still have the call delegated to corresponding HttpServletRequest for each new request. This utilizes AutowireUtils.ObjectFactoryDelegatingInvocationHandler to access the current HttpServletRequest object. The java doc for it also says Reflective InvocationHandler for lazy access to the current target object.
Thus even if the autowired Proxy object is always the same for all requests, the underlying target object to which the call is delegated is the current HttpServletRequest object which is per-request.
There is another way you can get HttpServletRequest
is using RequestContextHolder
as mentioned in this answer
HttpServletRequest currentRequest =
((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes())
.getRequest();
Note: As this explanation is based on my understanding, please do share any official documentation about this if anyone has it.
@Autowired HttpServletRequest vs passing as parameter - best practice
Both are ok.@Autowired HttpServletRequest
and passing as a parameter are the same things.
Before passing HttpServletRequest
to invocation method responding to @RequestMapping
function, Spring stores the HttpServletRequest
into a ThreadLocal
type variable.
That ThreadLocal
variable is a thread-safe map that keeps HttpServletRequest
in the current thread context. The @Autowired HttpServletRequest
proxy bean gets the correct request from that ThreadLocal
variable.
Where is autowiring of HttpServletRequest into arbitrary Spring components documented?
That possibility of autowiring the proxy for HttpServletRequest
's is a part of Spring MVC, and sadly it's not documented properly.
The best you can find about it is in some release notes of spring-web:3.0.0
. For example, take a look at the release notes of 3.0.0.M4 and especially at this issue where Juergen Hoeller (one of the main developers of String) talks about how it works since this version.
Also, feel free to check the sources (WebApplicationContextUtils, RequestContextHolder), they're well documented.
Spring: how do I inject an HttpServletRequest into a request-scoped bean?
Request-scoped beans can be autowired with the request object.
private @Autowired HttpServletRequest request;
Can't understand `@Autowired HttpServletRequest` of spring-mvc well
Take a look at the scoped proxy. http://www.java-allandsundry.com/2012/08/spring-scoped-proxy.html
Basically you inject a proxy that keeps a references to the current HttpRequest beans and gives you the right one, selecting it by the request id.
IMHO using HttpRequest outside of the web layer is not a good practice. I would use it only in the controlellrs.
How to inject current HttpServletRequest into any Spring service?
You can get HttpServletRequest
in this way if you don't want to use @Autowired
in the controller:
HttpServletRequest request =
((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes())
.getRequest();
SpringBoot forward request by @Autowired HttpServletRequest result in StackOverFlow Exception
Remove the @Autowired
request/response fields and use your request/response parameters.
@GetMapping(path = "forward")
public void forward(
HttpServletRequest request,
HttpServletResponse response,
@RequestParam String name) {
try {
request.getRequestDispatcher ( "/test/hello" )
.forward (request, response);
} catch (ServletException e) {
e.printStackTrace ();
} catch (IOException e) {
e.printStackTrace ();
}
}
The request/response fields injection is causing an odd behavior due to Spring Beans annotated with @Controller
has scope singleton by default, therefore each request will be handle by a singleton TestController
instance.
Read HttpServletRequest object from Spring Boot controller method
First, remove the @Autowired
field. It's wrong and you're not using it anyway.
Now you have two choices:
Let Spring process the request body for you, by using the
@RequestBody
annotation:@PostMapping(path = "/abc")
public String createAbc(@RequestBody String requestBody) throws IOException {
logger.info("Request body: " + requestBody);
return "abc";
}Process it yourself, i.e. don't use the
@RequestBody
annotation:@PostMapping(path = "/abc")
public String createAbc(HttpServletRequest request) throws IOException {
StringBuilder builder = new StringBuilder();
try (BufferedReader in = request.getReader()) {
char[] buf = new char[4096];
for (int len; (len = in.read(buf)) > 0; )
builder.append(buf, 0, len);
}
String requestBody = builder.toString();
logger.info("Request body: " + requestBody);
return "abc";
}
Don't know why you'd use option 2, but you can if you want.
Related Topics
How to Know Which Tomcat Version Embedded in Spring Boot
How to Wait for All Threads to Finish, Using Executorservice
Java Check If a String Is Valid Json or Valid Xml or Neither
Spring Data Query Method With Optional @Param
At Runtime, Find All Classes in a Java Application That Extend a Base Class
Get Enum Values as List of String in Java 8
Ora-00942 Sqlexception With Hibernate (Unable to Find a Table)
Opening Intent Crashing the App Android Studio
Parsing the Nested Json Array Using Jackson Library in Java
Use a Binary Search on an Int Array Sorted in Descending Order
How to Remove the Slashes from Json Key While Converting Object into String
Spring Boot Not Recognizing Application.Properties File
Random Number Generation Without Repetition in Java
Turning Sonar Off for Certain Code
Automatically Size Jpanel Inside Jframe
Java Error - Illegal Modifier for Parameter - Only Final Permitted