【问题标题】:`NativeWebRequest` is null on incoming requests with Spring Boot`NativeWebRequest` 在使用 Spring Boot 的传入请求中为空
【发布时间】:2021-10-31 09:00:40
【问题描述】:

我设置了一个 Spring Boot 服务器,它可以成功接收请求。它已使用OpenAPI 进行设置,以生成处理参数转换的端点定义。

现在,我的问题是我现在想检查不属于请求参数的标头,而只是将标头作为请求的一部分。

在我设置的另一个 Spring Boot 应用程序中,我通过添加到控制器来实现这一点

@Autowired
NativeWebRequest request;

允许访问传入请求。

但是,在我当前的应用程序中,这始终是 null - 我无法获得任何标题数据。我怀疑我在 SpringBoot 应用程序设置中做错了什么。

// 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

【问题讨论】:

  • 您是否尝试过将@RequestHeader Map<String, String> headers 作为参数传递给您的控制器方法?

标签: java spring-boot openapi


【解决方案1】:

在 Spring 应用程序中,将请求注入 Bean 并不常见。

改为向您的请求处理程序方法添加一个参数。有不同的受支持类型和注释可以访问请求标头。一些例子:

@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) {
      ...
   }
}

"Spring Framework Documentation"部分"Web Servlet"章节“Method Arguments"


你写道:

但是,在我当前的应用程序中,这始终为 null ...

您在此字段中有一个@Autowired 注释。如果 Spring 无法自动装配它,则通常会引发异常,因此请仔细检查该类的实例是否由 Spring 创建,而不是与正常的 new 一起偶然创建的@

【讨论】:

    【解决方案2】:

    NativeWebRequest bean 应该从 Spring 2.5.2 开始可用。在我的示例中,我需要它作为我的控制器的构造函数参数。 Spring 将在创建 Controller bean 时为其注入一个代理。每个收到的 HTTP 请求都会更新具体实例值。

    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();
        }
    }
    

    【讨论】:

    • 所以,在我删除 @RequestScope 之后,这很有效——这有点奇怪,因为我怀疑 NativeWebRequest 应该与标记为 @RequestScope 的其他 bean 一起使用
    猜你喜欢
    • 2021-10-18
    • 1970-01-01
    • 2022-10-07
    • 2021-04-20
    • 1970-01-01
    • 2023-04-09
    • 2019-12-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多