我有一个可观察的,因为它可能需要很长时间我才能返回 spring 的DeferredResult
。
这是我正在使用的控制器逻辑:
public DeferredResult<ResponseEntity<InputStreamResource>> getSomeFile() {
DeferredResult<ResponseEntity<InputStreamResource>> deferredResult = new DeferredResult<>(TIMEOUT);
Observable<File> observableFile = fileService.getSomeFile();
observableFile
.map(this::fileToInputStreamResource)
.map(resource -> ResponseEntity.ok().cacheControl(CacheControl.maxAge(1, TimeUnit.HOURS).cachePublic()).body(resource))
.subscribe(deferredResult::setResult, ex -> {
deferredResult.setErrorResult(ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null));
});
return deferredResult;
}
这是我的测试用例:
@Test
public void getSomeFile() throws Exception {
this.mockMvc.perform(get("/somefile").accept(MediaType.parseMediaType("application/xml;charset=UTF-8")))
.andExpect(request().asyncStarted())
.andExpect(status().isOk())
.andDo(result -> {
ResponseEntity<InputStreamResource> fileResource = (ResponseEntity<InputStreamResource>) result.getAsyncResult();
InputStream fileResourceInputStream = fileResource.getBody().getInputStream();
FooBar foobar = (FooBar) jaxb2Marshaller.unmarshal(new StreamSource(fileResourceInputStream));
assertThat(foobar.getFoos(), is(not(empty())));
});
}
当我在没有设置超时的情况下实例化 DeferredResult 时,此测试失败,因为它使用为休息模板设置的通用超时(10 秒)。如果我明确设置超时new DefferredResult(Long.MAX_VALUE)
,它会失败并出现相同的异常:
java.lang.IllegalStateException: Async result for handler [public org.springframework.web.context.request.async.DeferredResult<org.springframework.http.ResponseEntity<org.springframework.core.io.InputStreamResource>> com.example.controller.FileController.getSomeFile()] was not set during the specified timeToWait=9223372036854775807
at org.springframework.test.web.servlet.DefaultMvcResult.getAsyncResult(DefaultMvcResult.java:145)
at org.springframework.test.web.servlet.DefaultMvcResult.getAsyncResult(DefaultMvcResult.java:121)
at org.springframework.test.web.servlet.result.RequestResultMatchers$4.match(RequestResultMatchers.java:114)
at org.springframework.test.web.servlet.MockMvc$1.andExpect(MockMvc.java:171)
那么应该如何配置超时或哪里有问题?