Search code examples
javaspringjakarta-ee

Change deferredResult HTTP status code on timeout


I am using deferredResult on Spring MVC, but using this code, the timeout still are sending back the HTTP code 503 to the client.

future.onCompletion(new Runnable() {
    @Override
    public void run() {

        if(future.isSetOrExpired()){
            response.setStatus(HttpServletResponse.SC_NO_CONTENT);
        }
    }
});

Any idea what else to try?


Solution

  • I ran into the same issue. My Spring MVC Controller method originally returned DeferredResult<Object>, but then I realised I wanted to control the HTTP status code. I found the answer here:

    https://www.jayway.com/2014/09/09/asynchronous-spring-service/

    @RequestMapping("/async")
    DeferredResult<ResponseEntity<?>> async(@RequestParam("q") String query) {
    
        DeferredResult<ResponseEntity<?>> deferredResult = new DeferredResult<>();
        ListenableFuture<RepoListDto> repositoryListDto = repoListService.search(query);
        
        repositoryListDto.addCallback(
                new ListenableFutureCallback<RepoListDto>() {
                    @Override
                    public void onSuccess(RepoListDto result) {
                        ResponseEntity<RepoListDto> responseEntity = 
                            new ResponseEntity<>(result, HttpStatus.OK);
                        deferredResult.setResult(responseEntity);
                    }
    
                    @Override
                    public void onFailure(Throwable t) {
                        log.error("Failed to fetch result from remote service", t);
                        ResponseEntity<Void> responseEntity = 
                            new ResponseEntity<>(HttpStatus.SERVICE_UNAVAILABLE);
                        deferredResult.setResult(responseEntity);
                    }
                }
        );
        
        return deferredResult;
    }
    

    Just use DeferredResult<ResponseEntity> and you can set both the response and the Http response code in the ResponseEntity.