[英]Get request attribute with Spring webflux and WebTestClient
我不能綁定的屬性我是從一個設置WebTestClient
成RestController
使用Spring WebFlux時。
我嘗試了我能想到的兩種方法。
首先使用@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();
}
}
在我的實際應用程序中,我有一個 SecurityContextRepository,它從(解碼的)標頭值設置一些屬性,我想獲取這些屬性。
在服務器端和客戶端,請求屬性都應視為類似於Map的數據結構,可用於在客戶端/服務器內傳輸信息(用於過濾器,編解碼器等)。
該信息不會通過網絡發送。
如果要將信息從客戶端發送到服務器,則應查看請求參數或請求主體本身。
我在之前使用 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);
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.