DeferredResult耗时的处理导致异常

时间:2015-01-06 05:27:31

标签: spring spring-mvc deferred

我有一个类扩展了DeferredResults并扩展了Runnable,如下所示

public class EventDeferredObject<T> extends DeferredResult<Boolean> implements Runnable {
private Long customerId;

private String email;

@Override
public void run() {

    RestTemplate restTemplate=new RestTemplate();

    EmailMessageDTO emailMessageDTO=new EmailMessageDTO("dineshshe@gmail.com", "Hi There");

//Very long running call
    Boolean result=restTemplate.postForObject("http://localhost:9080/asycn/sendEmail", emailMessageDTO, Boolean.class);

    this.setResult(result);
}

//Constructor and getter and setters
}

现在我有控制器返回上述类的对象,每当有新请求到达控制器时,我们检查HashMap中是否存在该请求(在该实例中存储未处理的请求)。如果不存在那么我们正在创建对象EventDeferredObject类可以将其存储在HashMap中并在其上调用start()方法。如果此类型请求已经存在,那么我们将从HashMap返回该请求。如果请求完成,我们将从HashMap中删除该请求。

@RequestMapping(value="/sendVerificationDetails")

public class SendVerificationDetailsController {

private ConcurrentMap<String , EventDeferredObject<Boolean>> requestMap=new  ConcurrentHashMap<String , EventDeferredObject<Boolean>>(); 
@RequestMapping(value="/sendEmail",method=RequestMethod.POST)
public EventDeferredObject<Boolean> sendEmail(@RequestBody EmailDTO emailDTO)
{
    EventDeferredObject<Boolean> eventDeferredObject = null;

    System.out.println("Size:"+requestMap.size());

    if(!requestMap.containsKey(emailDTO.getEmail()))
    {
        eventDeferredObject=new EventDeferredObject<Boolean>(emailDTO.getCustomerId(), emailDTO.getEmail());
        requestMap.put(emailDTO.getEmail(), eventDeferredObject);

        Thread t1=new Thread(eventDeferredObject);
        t1.start();

    }
    else
    {
        eventDeferredObject=requestMap.get(emailDTO.getEmail());

    }
    eventDeferredObject.onCompletion(new Runnable() {

        @Override
        public void run() {
            if(requestMap.containsKey(emailDTO.getEmail()))
            {   
                requestMap.remove(emailDTO.getEmail());
            }
        }
    });

    return eventDeferredObject;
}

}

现在由于处理调用线程run()方法需要50000ms的时间,所以这导致异常:

java.lang.IllegalStateException: Cannot forward after response has been committed
    at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:328)
    at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:318)
    at org.apache.catalina.core.StandardHostValve.custom(StandardHostValve.java:433)
    at org.apache.catalina.core.StandardHostValve.status(StandardHostValve.java:299)
    at org.apache.catalina.core.StandardHostValve.throwable(StandardHostValve.java:393)
    at org.apache.catalina.core.AsyncContextImpl.setErrorState(AsyncContextImpl.java:434)
    at org.apache.catalina.connector.CoyoteAdapter.asyncDispatch(CoyoteAdapter.java:310)
    at org.apache.coyote.http11.AbstractHttp11Processor.asyncDispatch(AbstractHttp11Processor.java:1682)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:649)
    at org.apache.coyote.http11.Http11NioProtocol$Http11ConnectionHandler.process(Http11NioProtocol.java:222)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1556)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1513)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:745)

如何解决这种情况..如果处理时间大约是20000ms,代码工作正常。

0 个答案:

没有答案