>>分享流行的Java框架以及开源软件,对孙卫琴的《精通Spring:Java Web开发技术详解》提供技术支持 书籍支持  卫琴直播  品书摘要  在线测试  资源下载  联系我们
发表一个新主题 开启一个新投票 回复文章 您是本文章第 19008 个阅读者 刷新本主题
 * 贴子主题:  springmvc处理异步请求的示例 回复文章 点赞(0)  收藏  
作者:flybird    发表时间:2024-04-06 06:50:59     消息  查看  搜索  好友  邮件  复制  引用


这篇文章主要介绍了springmvc处理异步请求的示例,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
springmvc 3.2开始就支持servlet3.0的异步请求。平常我们请求一个controller一般都是同步的,如果在代码执行中,遇到耗时的业务操作,那servlet容器线程就会被锁死,当有其他请求进来的时候就会受堵了。

springmvc3.2之后支持异步请求,能够在controller中返回一个Callable或者DeferredResult。当返回Callable的时候,大概的执行过程如下:

当controller返回值是Callable的时候,springmvc就会启动一个线程将Callable交给TaskExecutor去处理
然后DispatcherServlet还有所有的spring拦截器都退出主线程,然后把response保持打开的状态
当Callable执行结束之后,springmvc就会重新启动分配一个request请求,然后DispatcherServlet就重新调用和处理Callable异步执行的返回结果,然后返回视图
DeferredResult的执行过程和Callable差不多,唯一不同的时候,DeferredResult是由应用程序其他线程执行返回结果,而Callable是由TaskExecutor执行返回结果。

springmvc配置异步请求

1.需要在web.xml加上servlet3.0的scheme库
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
...
</web-app>

2.在web.xml的servlet还有filter添加<asyncsupported>true</async-supported>子节点

<!-- springMVC的Servlet配置 -->
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:META-INF/dispatcher-context.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
<async-supported>true</async-supported>
</servlet>

<!-- 编码拦截 -->
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<async-supported>true</async-supported>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>

3.然后就可以在controller中执行异步请求了

利用Callable执行异步请求,并返回视图

@RequestMapping("/mvc25")
public Callable<String> mvc25() {

return new Callable<String>() {
@Override
public String call() throws Exception {
Thread.sleep(2000);
return "task/task";
}
};

}

利用Callable执行异步请求,并把请求结果通过@response由httpmessageconverter进行转化返回客户端

@RequestMapping("/mvc26")
@ResponseBody
public Callable<String> mvc26() {

return new Callable<String>() {
@Override
public String call() throws Exception {
Thread.sleep(2000);
return "hello task";
}
};

}

可以自定义客户端超时间

@RequestMapping("/mvc27")
@ResponseBody
public WebAsyncTask<String> mvc27() {

Callable<String> callable = new Callable<String>() {
@Override
public String call() throws Exception {
Thread.sleep(10000);
return "hello task";
}
};

return new WebAsyncTask<String>(10000, callable);
}

如果在线程的执行过程中,遇到异常,处理过程和普通请求的一样,你可以用@ExceptionHandler来处理或者定义全局的HandlerExceptionResolver来处理

@RequestMapping("/mvc28")
@ResponseBody
public Callable<String> mvc28() {

Callable<String> callable = new Callable<String>() {
@Override
public String call() throws Exception {
Thread.sleep(2000);
throw new RuntimeException();
}
};

return callable;

}

@ExceptionHandler(RuntimeException.class)
@ResponseBody
public JSONObject handlerException(){

JSONObject jsonObject = new JSONObject();
jsonObject.put("aaa", 123);

return jsonObject ;
}

还可以通过返回DeferredResult返回,DeferredResult的作用是返回一个实例给其他线程来处理这个异步请求。

@RequestMapping("/mvc29")
@ResponseBody
public DeferredResult<String> mvc29() {

DeferredResult<String> deferredResult = new DeferredResult<String>();
dealInOtherThread(deferredResult);
return deferredResult;

}

private void dealInOtherThread(DeferredResult<String> deferredResult) {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

deferredResult.setResult("hello task");
}

dealInOtherThread处理完成,setResult的时候就会触发springmvc分配一个request到DispatcherServlet,然后DispatcherServlet处理DeferredResult的返回结果,并返回视图。

DeferredResult还提供了其他返回来处理线程请求,例如onTimeout(Runnable) 还有onCompletion(Runnable),onTimeout可以注册一个线程回调,当请求延时的时候的回调函数,onCompletion可以注册一个请求完成的回调函数。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

转自: http://www.cppcns.com/ruanjian/java/177994.html



程序猿的技术大观园:www.javathinker.net
  Java面向对象编程-->输入与输出(上)
  JavaWeb开发-->Web运作原理(Ⅲ)
  JSP与Hibernate开发-->使用JPA和注解
  Java网络编程-->通过JavaMail API收发邮件
  精通Spring-->创建综合购物网站应用
  Vue3开发-->绑定CSS样式
  Redis为什么单线程能够支持高并发
  面试官问什么是Spring循环依赖,该如何回答?
  Redis夺命连环11问
  Spring 5 webflux响应式编程 - 但时间也偷换概念
  重新理解响应式编程
  Spring MVC SSE服务器端推送
  在Spring MVC中配置线程池,进行异步请求处理
  Spring MVC实现国际化的几种方式
  【项目实践】后端接口统一规范的同时,如何优雅地扩展规范
  Spring MVC国际化
  Spring Cloud与Dubbo的完美融合之手「Spring Cloud Alibaba
  SpringCloud Gateway-整体流程
  Spring+JPA+ehcache开启二级本地缓存
  3分钟让你明白JSON是什么
  Spring Boot整合WebSocket及Spring Security实例
  更多...
 IPIP: 已设置保密
树形列表:   
逃逸速度为5.6m/s(20km/h)。它是火星较小... 发货33 2024-04-06 06:50:59
1页 2条记录 当前第1
发表一个新主题 开启一个新投票 回复文章


中文版权所有: JavaThinker技术网站 Copyright 2016-2026 沪ICP备16029593号-2
荟萃Java程序员智慧的结晶,分享交流Java前沿技术。  联系我们
如有技术文章涉及侵权,请与本站管理员联系。