详解spring mvc对异步请求的处理
在springmvc3.2及以上版本增加了对请求的异步处理,是在servlet3的基础上进行封装的。
1、修改web.xml
<?xmlversion="1.0"encoding="UTF-8"?> <web-appversion="3.0"xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"> ... </web-app>
1.1、声明version="3.0",声明web-app_3_0.xsd
1.2、为servlet或者filter设置启用异步支持:<async-supported>true</async-supported>,修改WEB应用的web.xml
<!--springmvc--> <servlet> <servlet-name>SpringMvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>...</param-value> </init-param> <load-on-startup>1</load-on-startup> <async-supported>true</async-supported> </servlet>
2、使controller类支持async
2.1、返回java.util.concurrent.Callable来完成异步处理
packageorg.springframework.samples.mvc.async; importjava.util.concurrent.Callable; importorg.springframework.stereotype.Controller; importorg.springframework.ui.Model; importorg.springframework.web.bind.annotation.ExceptionHandler; importorg.springframework.web.bind.annotation.RequestMapping; importorg.springframework.web.bind.annotation.RequestParam; importorg.springframework.web.bind.annotation.ResponseBody; importorg.springframework.web.context.request.async.WebAsyncTask; @Controller @RequestMapping("/async/callable") publicclassCallableController{ @RequestMapping("/response-body") public@ResponseBodyCallable<String>callable(){ returnnewCallable<String>(){ @Override publicStringcall()throwsException{ Thread.sleep(2000); return"Callableresult"; } }; } @RequestMapping("/view") publicCallable<String>callableWithView(finalModelmodel){ returnnewCallable<String>(){ @Override publicStringcall()throwsException{ Thread.sleep(2000); model.addAttribute("foo","bar"); model.addAttribute("fruit","apple"); return"views/html"; } }; } @RequestMapping("/exception") public@ResponseBodyCallable<String>callableWithException( final@RequestParam(required=false,defaultValue="true")booleanhandled){ returnnewCallable<String>(){ @Override publicStringcall()throwsException{ Thread.sleep(2000); if(handled){ //seehandleExceptionmethodfurtherbelow thrownewIllegalStateException("Callableerror"); } else{ thrownewIllegalArgumentException("Callableerror"); } } }; } @RequestMapping("/custom-timeout-handling") public@ResponseBodyWebAsyncTask<String>callableWithCustomTimeoutHandling(){ Callable<String>callable=newCallable<String>(){ @Override publicStringcall()throwsException{ Thread.sleep(2000); return"Callableresult"; } }; returnnewWebAsyncTask<String>(1000,callable); } @ExceptionHandler @ResponseBody publicStringhandleException(IllegalStateExceptionex){ return"Handledexception:"+ex.getMessage(); } }
2.2、在异步处理完成时返回org.springframework.web.context.request.async.DeferredResult其他线程,例如一个JMS或一个AMQP消息,Redis通知等等:
@RequestMapping("/quotes") @ResponseBody publicDeferredResult<String>quotes(){ DeferredResult<String>deferredResult=newDeferredResult<String>(); //AdddeferredResulttoaQueueoraMap... returndeferredResult; } //Insomeotherthread... deferredResult.setResult(data); //RemovedeferredResultfromtheQueueorMap
3、spring配置文件的修改
springmvc的dtd的声明必须大于等于3.2
<mvc:annotation-driven> <!--可不设置,使用默认的超时时间--> <mvc:async-supportdefault-timeout="3000"/> </mvc:annotation-driven>
实际使用示例:
functiondeferred(){ $.get('quotes.htm',function(data){ console.log(data); deferred();//每次请求完成,再发一次请求,避免客户端定时刷新来获取数据 }); }
这么做的好处避免webserver的连接池被长期占用而引起性能问题,调用后生成一个非web的服务线程来处理,增加web服务器的吞吐量~~
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。