2016-02-01 4 views
0

Я новичок фьючерсу, и я пытаюсь понять, как я могу обрабатывать Listenable будущее в этой Senario:Асинхронный Spring Rest Controller - Процесс будущего результата

@Controller 
@EnableAutoConfiguration 
public class ListenableFutureAsyncController { 

    @Autowired 
    IHeavyLiftingService heavyLiftingService; 

    @RequestMapping("/") 
    @ResponseBody 
    DeferredResult<String> home() { 
     // Create DeferredResult 
     final DeferredResult<String> result = new DeferredResult<>(); 

     //Call to the async service 
     ListenableFuture<ResponseEntity<String>> future = heavyLiftingService.heavyLifting(); 

     future.addCallback(
      new ListenableFutureCallback<ResponseEntity<String>>() { 
      @Override 
      public void onSuccess(ResponseEntity<String> response) { 
       result.setResult(response.getBody()); 
      } 

      @Override 
      public void onFailure(Throwable t) { 
       result.setErrorResult(t.getMessage()); 
      } 
     }); 
     // Return the thread to servlet container, 
     // the response will be processed by another thread. 
     return result; 
    } 

} 

Как я могу обрабатывать будущее здесь, кроме передавая его обратно контроллеру. Ex. Что делать, если я хочу сохранить будущую строку в db?

@Service 
public class HeavyLiftingServiceImpl implements IHeavyLiftingService { 

    public ListenableFuture<String> heavyLifting() { 
     AsyncRestTemplate asycTemp = new AsyncRestTemplate(); 
     ListenableFuture<String> future = asycTemp.execute(url, method, requestCallback, responseExtractor, urlVariable); 
     /** 
     /Save future string to db 
     **/ 
     return future; 
    } 
} 
+0

Почему вы хотите использовать будущее здесь? Вы хотите, чтобы запрос вернулся сразу, а затем сохранить, чтобы он появился позже? – aglassman

+0

Представьте, что вызов асинхронного шаблона занял 10 секунд. Я не хочу, чтобы поток сервлета удерживался в потоке так долго. –

+0

Ожидаете ли вы, что клиент должен будет сделать второй звонок, чтобы вернуть результат? Я не уверен, что есть способ вернуть результат, не блокируя поток сервлета. – aglassman

ответ

2

Я нашел способ сделать это с помощью Spring, ListenableFutureAdapter

@Service 
public class HeavyLiftingServiceImpl implements IHeavyLiftingService { 

    public ListenableFuture<String> heavyLifting() { 
     AsyncRestTemplate asycTemp = new AsyncRestTemplate(); 
     ListenableFuture<String> future = asycTemp.execute(url, method, requestCallback, responseExtractor, urlVariable); 

     ListenableFutureAdapter<String, String> chainedFuture; 
     chainedFuture = new ListenableFutureAdapter<String, String>(future) { 

      @Override 
      protected String adapt(String adapteeResult) 
        throws ExecutionException { 
         String parsedString = parse(adapteeResult); 
         return adapteeResult; 
      } 
     }; 

     return chainedFuture; 
    } 

} 

Я рекомендовал бы использовать реализацию гуавы по Listenable будущего. Я считаю, что это более читаемо, и документация по их объединению легче найти.

Смежные вопросы