详解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服务器的吞吐量~~
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。