我正在尝试实现非阻塞调用。在 spring 4,但不幸的是它抛出了以下错误。
类型不匹配:无法从 String 转换为 ListenableFuture
并且同样的错误无法从 Map 转换为 ListenableFuture>。
我的方法调用堆栈如下。
ListenableFuture<Map<String,String>> unusedQuota = doLogin(userIdentity,request,"0");
doLogin 登录只需返回 Map
是否需要任何转换器?
需要什么改变?
谢谢。
public class MyController {
final DeferredResult<Map<String,String>> deferredResult = new DeferredResult<Map<String,String>>(5000l);
private final Logger log = LoggerFactory.getLogger(MyController.class);
@Inject
RestTemplate restTemplate;
@RequestMapping(value = "/loginservice", method = RequestMethod.GET)
@Timed
public DeferredResult<Map<String,String>> loginRequestService(@RequestParam String userIdentity,HttpServletRequest request) throws Exception {
deferredResult.onTimeout(new Runnable() {
@Override
public void run() { // Retry on timeout
deferredResult.setErrorResult(ResponseEntity.status(HttpStatus.REQUEST_TIMEOUT).body("Request timeout occurred."));
}
});
@SuppressWarnings("unchecked")
ListenableFuture<Map<String,String>> unusedQuota = doLogin(userIdentity,request);
unusedQuota.addCallback(new ListenableFutureCallback<Map<String,String>>() {
@SuppressWarnings("unchecked")
@Override
public void onSuccess(Map<String, String> result) {
// TODO Auto-generated method stub
deferredResult.setResult((Map<String, String>) ResponseEntity.ok(result));
}
@Override
public void onFailure(Throwable t) {
// TODO Auto-generated method stub
deferredResult.setErrorResult(ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(t));
}
});
return deferredResult;
}
private Map<String,String> doLogin(String userIdentity,HttpServletRequest request) throws Exception{
Map<String,String> unusedQuota=new HashMap<String,String>();
unusedQuota.put("quota", "100");
return unusedQuota;
}
}
}
最佳答案
您没有通过 Map
当存在导致问题的异常时对象,因此您的 Controller 方法需要更改如下所示,同时移动 deferredResult
Controller 方法中的对象,因为您应该共享 deferredResult
的相同实例针对不同的用户要求。
public class MyController {
@Autowired
private TaskExecutor asyncTaskExecutor;
@RequestMapping(value = "/loginservice", method = RequestMethod.GET)
@Timed
public DeferredResult<Map<String,String>> loginRequestService(@RequestParam String userIdentity,HttpServletRequest request) throws Exception {
final DeferredResult<Map<String,String>> deferredResult = new DeferredResult<Map<String,String>>(5000l);
deferredResult.onTimeout(new Runnable() {
@Override
public void run() { // Retry on timeout
Map<String, String> map = new HashMap<>();
//Populate map object with error details with Request timeout occurred.
deferredResult.setErrorResult(new ResponseEntity
<Map<String, String>>(map, null,
HttpStatus.REQUEST_TIMEOUT));
}
});
ListenableFuture<String> task = asyncTaskExecutor.submitListenable(new Callable<String>(){
@Override
public Map<String,String> call() throws Exception {
return doLogin(userIdentity,request);
}
});
unusedQuota.addCallback(new ListenableFutureCallback<Map<String,String>>() {
@SuppressWarnings("unchecked")
@Override
public void onSuccess(Map<String, String> result) {
// TODO Auto-generated method stub
deferredResult.setResult((Map<String, String>) ResponseEntity.ok(result));
}
@Override
public void onFailure(Throwable t) {
Map<String, String> map = new HashMap<>();
//Populate map object with error details
deferredResult.setErrorResult(new ResponseEntity<Map<String, String>>(
map, null, HttpStatus.INTERNAL_SERVER_ERROR));
}
});
return deferredResult;
}
}
此外,您需要确保您正在配置
ThreadPoolTaskExecutor
如示例中所述 here .
关于spring - 类型不匹配 : cannot convert from String to ListenableFuture<String>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40838547/