`NativeWebRequest` 在使用 Spring Boot 的传入请求中为空

Posted

技术标签:

【中文标题】`NativeWebRequest` 在使用 Spring Boot 的传入请求中为空【英文标题】:`NativeWebRequest` is null on incoming requests with 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 作为参数传递给您的控制器方法? 【参考方案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 一起使用

以上是关于`NativeWebRequest` 在使用 Spring Boot 的传入请求中为空的主要内容,如果未能解决你的问题,请参考以下文章

我们啥时候应该在布局中使用 dp 或 sp?

在 SP 回调中确定是 IDP 发起还是 SP 发起?

为啥android在使用小于12sp的尺寸时会发出警告?

使用sp_dbmmonitorresults来监控镜像

什么是堆栈,51单片机堆栈指针SP的使用

使用sp_addlinkedserversp_dropserver sp_addlinkedsrvlogin和sp_droplinkedsrvlogin 远程查询数据