Get request attribute with Spring webflux and WebTestClient(使用Spring WebFlux和WebTestClient获取请求属性)
问题描述
使用Spring WebFlux时,我无法将我正在设置的属性从WebTestClient绑定到RestController。
我试了我能想到的两种方法。
首先使用@RequestAttribute注释,我得到:
无法处理请求[Get/Attributes/Annotation]:响应状态为400,原因为"缺少字符串类型的请求属性‘ATTRIBUTE’"
然后我尝试使用ServerWebExchange,结果null。
这是我的控制器:
@RestController
@RequestMapping("/attributes")
public class MyController {
    @GetMapping("/annotation")
    public Mono<String> getUsingAnnotation(@RequestAttribute("attribute") String attribute) {
        return Mono.just(attribute);
    }
    @GetMapping("/exchange")
    public Mono<String> getUsingExchange(ServerWebExchange exchange) {
        return Mono.just(exchange.getRequiredAttribute("attribute"));
    }
}
这是我的失败测试:
@RunWith(SpringRunner.class)
@SpringBootTest
public class MyControllerTest {
    @Autowired
    ApplicationContext context;
    WebTestClient webClient;
    @Before
    public void setup() {
        webClient = WebTestClient.bindToApplicationContext(context)
                .configureClient()
                .build();
    }
    @Test
    public void testGetAttributeUsingAnnotation() {
        webClient.get()
                .uri("/attributes/annotation")
                .attribute("attribute", "value")
                .exchange()
                .expectStatus()
                .isOk();
    }
    @Test
    public void testGetAttributeUsingExchange() {
        webClient.get()
                .uri("/attributes/exchange")
                .attribute("attribute", "value")
                .exchange()
                .expectStatus()
                .isOk();
    }
}
在我的实际应用程序中,我有一个SecurityConextRepository,它从(解码的)标头值设置一些属性,我想要获取这些属性。
推荐答案
我在一个测试中遇到了同样的问题,该测试以前使用MockMvc,后来不得不转换为使用WebClient。像@jcfandino一样,我希望WebClient上的.attribute()方法的工作方式类似于MockMvc的requestAttribute()。
我还没有发现.attribute()应该如何使用,但我已经通过添加自定义测试筛选器绕过了整个问题。我不确定此方法是否正确,但由于此问题尚未回答,下面的方法可能对遇到相同问题的人有帮助。
@WebFluxTest(controllers = SomeController.class)
@ComponentScan({ "com.path1", "com.path2" })
class SomeControllerTest {
    // define a test filter emulating the server's filter (assuming there is one)
    private class AttributeFilter implements WebFilter {
        String attributeValue;
        
        public AttributeFilter(String filterAttributeValue) {
            attributeValue = filterAttributeValue;
        }
        
        @Override
        public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
            // add the desired attributes 
            exchange.getAttributes().put(SomeController.ATTR_NAME, attributeValue);   
            return chain.filter(exchange);
        }
    }
   
    // mock the service the controller is dependend on
    @MockBean
    AppService appService; 
    // define the test where the controller handles a get() operation 
    @Test
    void testMethod() {
        
        // mock the app service
        when(appService.executeService(anyString(), anyString())).thenAnswer(input -> {
            // ... return some dummy appData
        });
        var testClient= WebTestClient.bindToController(new SomeController(appService))                
                .webFilter(new SomeControllerTest.AttributeFilter("someValue"))
                .build();
        try {            
            var response = testClient
                .get()               
                .uri("someroute")
                .accept(MediaType.APPLICATION_JSON)
                .exchange()
                .expectStatus().isOk()
                .expectBody(AppData.class);                             
                
        } catch (Exception e) {
            fail("exception caught in testMethod", e);
        }
    }
}
                        这篇关于使用Spring WebFlux和WebTestClient获取请求属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:使用Spring WebFlux和WebTestClient获取请求属性
				
        
 
            
        - Eclipse 的最佳 XML 编辑器 2022-01-01
 - 将 Java Swing 桌面应用程序国际化的最佳实践是什么? 2022-01-01
 - 未找到/usr/local/lib 中的库 2022-01-01
 - java.lang.IllegalStateException:Bean 名称“类别"的 BindingResult 和普通目标对象都不能用作请求属性 2022-01-01
 - 在 Java 中,如何将 String 转换为 char 或将 char 转换 2022-01-01
 - GC_FOR_ALLOC 是否更“严重"?在调查内存使用情况时? 2022-01-01
 - 如何指定 CORS 的响应标头? 2022-01-01
 - 转换 ldap 日期 2022-01-01
 - 获取数字的最后一位 2022-01-01
 - 如何使 JFrame 背景和 JPanel 透明且仅显示图像 2022-01-01
 
						
						
						
						
						
				
				
				
				