您的位置:首页 > 编程语言 > Java开发

springMVC整合异步请求特性

2017-12-08 17:42 323 查看
源自:http://blog.csdn.net/u013755987/article/details/62424001

springMVC中也整合了异步请求的特性,我们只需要配置好支持异步请求特性,然后结合Java自带的回调函数处理就可以实现简单的异步请求,但是这样的异步请求往往是不能满足我们需求的,所以最终我们还是会使用比较完整的异步请求接口,那就是spring的WebAsyncTask和DeferredResult。


首先需要添加配置项:

[html] view
plain copy

springmvc-servlet.xml:  

<mvc:annotation-driven>  

    <mvc:async-support default-timeout="5000"/>  

</mvc:annotation-driven>  

  

web.xml的所有servlet和filter  

<async-supported>true</async-supported>  


使用Callable实现异步请求

[java] view
plain copy

@RequestMapping("/response-body")  

public @ResponseBody Callable<String> callable() {  

  

    Callable<String> asyncTask = new Callable<String>() {  

        @Override  

        public String call() throws Exception {  

            Thread.sleep(4000);  

            return "Callableresult";  

        }  

    };  

    System.out.println("已交给服务线程处理");  

    return asyncTask;  

}  

这种方法可以实现异步请求,但是没有设置超时时间和相关超时回调。只是客户端发起请求,服务端保证执行完成即可,然后将直接成功的结果返回给客户端,客户端根绝返回值判断是否需要发起另一个请求。


使用WebAsyncTask实现异步请求

[java] view
plain copy

@RequestMapping("/response-body2")  

public @ResponseBody WebAsyncTask<String> webAsyncHandle() {  

  

Callable<String> asyncTask = new Callable<String>() {  

    @Override  

    public String call() throws Exception {  

        Thread.sleep(10000);  

        return "Callableresult";//超时之后不会执行返回操作,但是return之前的能够执行完成  

    }  

};  

      System.out.println("已交给服务线程处理");  

      WebAsyncTask<String> webAsyncTask = new WebAsyncTask<String>(5000, asyncTask);  

      webAsyncTask.onCompletion(new CompleteWork(webAsyncTask));  

      webAsyncTask.onTimeout(timeOutCallBack());  

      System.out.println("main over");  

      return webAsyncTask;  

  }  

  

public Callable<String> timeOutCallBack(){  

  

        Callable<String> callback = new Callable<String>() {  

            @Override  

            public String call() throws Exception {  

               System.out.println("我超时了");  

               return "我超时了";  

            }  

        };  

        return callback;  

    }  

  

//内部类  

class CompleteWork<T> implements Runnable{  

  

        private T t;  

        public CompleteWork(T t){  

            this.t = t;  

        }  

  

        @Override  

        public void run() {  

            if (t instanceof WebAsyncTask) {  

                if (((WebAsyncTask) t).getTimeout() > 0) {//没啥用,超时之后返回值也是大于0  

                    System.out.println("WebAsyncTask:我执行完啦!");  

                }  

            }else if (t instanceof DeferredResult) {  

                if(!((DeferredResult) t).isSetOrExpired()){  

                    System.out.println("DeferredResult:我执行完啦!");  

                }  

            }  

        }  

  

    }  

这种方法通过使用spring的WebAsyncTask实现了异步请求,并且可以设置超时时间,以及超时和完成之后的回调函数。需要注意的是,超时之后也会回调onCompletion中设置方法。


使用DeferredResult实现异步请求

@RequestMapping("/response-body3")
@ResponseBody
public DeferredResult<String> quotes(HttpServletResponse response) {
DeferredResult<String> deferredResult = new DeferredResult<String>(5000);
dealInOtherThread(deferredResult);
return deferredResult;
}

public void dealInOtherThread(DeferredResult<String> deferredResult){
deferredResult.onTimeout(new TimeOutWork());
deferredResult.onCompletion(new CompleteWork(deferredResult));
new Thread(new work(deferredResult)).start();
System.out.println("main over");
}

//内部类
class TimeOutWork implements Runnable{
private DeferredResult<String> deferredResult;
public TimeOutWork(DeferredResult<String> deferredResult){
this.deferredResult = deferredResult;
}
@Override
public void run() {
System.out.println("我超时啦!");
deferredResult.setErrorResult("我超时了");
}
}
这种方法跟上面的WebAsyncTask类似,超时之后也会调用onCompletion函数。所以我们需要在回调函数中增加超时的判断。上面的方法中DeferredResult可以通过isSetOrExpired()来判断,但是WebAsyncTask还不知道如何判断。还有一点就是DeferredResult是在设置deferredResult.setResult(…)的时候就响应客户端,而WebAsyncTask是直接return。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: