我使用RxJava编写了一个Spring Boot微服务,你可以在这里找到project。一切都很完美。现在我正在将我的Controller / Resource类中的RxJava Observable
转换为DeferredResult
。我听说可以使用HandlerMethodReturnValueHandler
和Observable
到DeferredResult
的简单适配器来完成此操作。我开始实现这一点。首先,我写了HandlerMethodReturnValueHandler
这样的内容。
package com.example.handlers;
public class ObservableReturnValueHandler implements AsyncHandlerMethodReturnValueHandler {
@Override
public boolean isAsyncReturnValue(Object returnValue, MethodParameter returnType) {
return returnValue != null && supportsReturnType(returnType);
}
@Override
public boolean supportsReturnType(MethodParameter returnType) {
return Observable.class.isAssignableFrom(returnType.getParameterType());
}
@Override
public void handleReturnValue(Object returnValue, MethodParameter returnType, ModelAndViewContainer mavContainer,
NativeWebRequest webRequest) throws Exception {
if (returnValue == null) {
mavContainer.setRequestHandled(true);
return;
}
final Observable<?> observable = Observable.class.cast(returnValue);
WebAsyncUtils.getAsyncManager(webRequest)
.startDeferredResultProcessing(new ObservableAdapter<>(observable), mavContainer);
}
public class ObservableAdapter<T> extends DeferredResult<T> {
public ObservableAdapter(Observable<T> observable) {
observable.subscribe(this::setResult, this::setErrorResult);
}
}
}
然后我编写了一个配置类,将ObservableReturnValueHandler
添加到拦截器链中,以便它可以处理响应。代码如下。
package com.example.config;
@Configuration
@ComponentScan(basePackages = { "com.example.*" })
public class WebConfig extends WebMvcConfigurerAdapter {
@Override
public void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> returnValueHandlers) {
returnValueHandlers.add(new ObservableReturnValueHandler());
}
}
现在我的资源/控制器类看起来像这样。
package com.example;
@Controller
@RequestMapping("/api/currencyconverter")
public class CurrencyResource {
private static final Logger log = LoggerFactory.getLogger(CurrencyConverter.class);
@Autowired
private CurrencyConverterService currencyConverterService;
@RequestMapping(value = "/rates", method = RequestMethod.GET, produces = { MediaType.APPLICATION_JSON_UTF8_VALUE })
public Observable<CurrencyRatesDTO> getCurrencyRates(
@RequestParam("symbol") Set<String> currencyRates) {
log.debug("Retrieving currency rates.");
return currencyConverterService.getCurrencyRates(currencyRates);
}
}
下面给出了作为微服务入口点的主要类。
package com.example;
@SpringBootApplication
public class JavaRxDemoApplication {
public static void main(String[] args) {
SpringApplication.run(JavaRxDemoApplication.class, args);
}
问题是当我发送GET请求http://localhost:8080/api/currencyconverter/rates?symbol=USD时,我收到以下有线错误。控制台中也没有任何错误消息或异常跟踪。
{
"timestamp": 1485742987017,
"status": 404,
"error": "Not Found",
"message": "No message available",
"path": "/api/currencyconverter/rates"
}
然后我调试了代码并发现调用了控制器方法,从控制器成功调用了REST端点。订阅Observable,收到结果并在DeferredResult
内成功设置为ObservableReturnValueHandler
。之后发生的事情会导致此错误。
您可以在returnvaluehandler branch of the project找到当前代码。启动和运行项目的所有必要步骤都在项目附带的自述文件中给出。我在这里失踪了什么。任何帮助表示赞赏。
答案 0 :(得分:0)
您
@ComponentScan(basePackages = { "com.example.*" })
应该是
@ComponentScan(basePackages = { "com.example" })
404是因为组件扫描没有拾取您的控制器。