package org.springframework.samples.mvc.async;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.context.request.async.DeferredResult;
import org.springframework.web.servlet.ModelAndView;
@Controller
@RequestMapping("/async")
public class DeferredResultController {
private final Queue<DeferredResult<String>> responseBodyQueue = new ConcurrentLinkedQueue<DeferredResult<String>>();
private final Queue<DeferredResult<ModelAndView>> mavQueue = new ConcurrentLinkedQueue<DeferredResult<ModelAndView>>();
private final Queue<DeferredResult<String>> exceptionQueue = new ConcurrentLinkedQueue<DeferredResult<String>>();
@RequestMapping("/deferred-result/response-body")
public @ResponseBody DeferredResult<String> deferredResult() {
DeferredResult<String> result = new DeferredResult<String>();
this.responseBodyQueue.add(result);
return result;
}
@RequestMapping("/deferred-result/model-and-view")
public DeferredResult<ModelAndView> deferredResultWithView() {
DeferredResult<ModelAndView> result = new DeferredResult<ModelAndView>();
this.mavQueue.add(result);
return result;
}
@RequestMapping("/deferred-result/exception")
public @ResponseBody DeferredResult<String> deferredResultWithException() {
DeferredResult<String> result = new DeferredResult<String>();
this.exceptionQueue.add(result);
return result;
}
@RequestMapping("/deferred-result/timeout-value")
public @ResponseBody DeferredResult<String> deferredResultWithTimeoutValue() {
// Provide a default result in case of timeout and override the timeout value
// set in src/main/webapp/WEB-INF/spring/appServlet/servlet-context.xml
return new DeferredResult<String>(1000L, "Deferred result after timeout");
}
@Scheduled(fixedRate=2000)
public void processQueues() {
for (DeferredResult<String> result : this.responseBodyQueue) {
result.setResult("Deferred result");
this.responseBodyQueue.remove(result);
}
for (DeferredResult<String> result : this.exceptionQueue) {
result.setErrorResult(new IllegalStateException("DeferredResult error"));
this.exceptionQueue.remove(result);
}
for (DeferredResult<ModelAndView> result : this.mavQueue) {
result.setResult(new ModelAndView("views/html", "javaBean", new JavaBean("bar", "apple")));
this.mavQueue.remove(result);
}
}
@ExceptionHandler
@ResponseBody
public String handleException(IllegalStateException ex) {
return "Handled exception: " + ex.getMessage();
}
}