Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

`NativeWebRequest` is null on incoming requests with Spring Boot

I have a Spring Boot server set up, and it can successfully receive requests. It has been set up using OpenAPI to generate the endpoint definitions, which handle the argument conversions.

Now, my problem is I now want to inspect headers that are not part of the request arguments, but just headers as part of the request.

In another Spring Boot application I have set up, I achieved this by adding to the controller

@Autowired
NativeWebRequest request;

Which allowed access to the incoming request.

However, in my current application, this is always null - and I can't get any of the header data. I suspect I have done something incorrectly in the SpringBoot application setup.

// Athena pulled in KeycloakAutoConfiguration when KeycloakAuthorization was added. However, the class
// is not part of the Athena application - so exclude by name since we cannot reference the class here.
@EnableAutoConfiguration(
        excludeName = { "org.keycloak.adapters.springboot.KeycloakAutoConfiguration"},
        exclude = {
                DataSourceAutoConfiguration.class,
                ErrorMvcAutoConfiguration.class,
                HttpEncodingAutoConfiguration.class,
                PropertyPlaceholderAutoConfiguration.class,
                ThymeleafAutoConfiguration.class,
                WebSocketMessagingAutoConfiguration.class,
                OAuth2ClientAutoConfiguration.class,
})
@SpringBootConfiguration
public class AthenaApplication extends SpringBootServletInitializer
like image 684
Mike Welsh Avatar asked Sep 07 '25 06:09

Mike Welsh


2 Answers

NativeWebRequest bean should be available since Spring 2.5.2. In my example, I have it required as a constructor argument for my controller. Spring will inject a proxy for it at Controller bean creation. The concrete instance value will be updated for each HTTP request received.

import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.NativeWebRequest;
import javax.annotation.Nonnull;

@RestController
public class FooController {

    @Nonnull
    private final NativeWebRequest nativeWebRequest;

    public FooController(@Nonnull NativeWebRequest nativeWebRequest) {
        this.nativeWebRequest = nativeWebRequest;
    }

    @GetMapping("/foo")
    public ResponseEntity<Void> foo() {
        String headerValue = nativeWebRequest.getHeader("Host");
        System.out.println("[Request Header] Host: " + headerValue);

        return ResponseEntity.noContent().build();
    }
}
like image 107
Poulad Avatar answered Sep 10 '25 11:09

Poulad


In a Spring Application it is not common to inject a Request in an Bean.

Instead add a parameter to your request handler method. There are different supported types and annotations to access the request headers. Some examples:

@RestController
public class MyController() {

   @PostMapping("/example")
   public Something doSomething(@RequestBody Payload body,
                                HttpServletRequest request) {
      //use request to access the parameter and everything else
   }

   //or

   @PostMapping("/example2")
   public Something doSomethingOtherWay(@RequestBody Payload body,
                          @RequestHeader("Accept-Encoding") String acceptEncodingHeader,
                          @RequestHeader("Keep-Alive") long keepAlive) {
      ...
   }

   //or
   @PostMapping("/example3")
   public Something doSomethingOtherWay2(@RequestBody Payload body,
                                         @RequestHeader HttpHeaders headers) {
      ...
   }
}

see "Spring Framework Documentation" part "Web Servlet" chapter "Method Arguments"


You wrote:

However, in my current application, this is always null ...

You have a @Autowired annotation at this field. Spring typical rise an exception if it is not able to autowire it, so double check that the instance of this class is create by Spring, not by accident with a normal new

like image 43
Ralph Avatar answered Sep 10 '25 11:09

Ralph