>>分享流行的Java框架以及开源软件,对孙卫琴的《精通Spring:Java Web开发技术详解》提供技术支持 书籍支持  卫琴直播  品书摘要  在线测试  资源下载  联系我们
发表一个新主题 开启一个新投票 回复文章 您是本文章第 19009 个阅读者 刷新本主题
 * 贴子主题:  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开发-->JSP中使用JavaBean(Ⅰ)
  JSP与Hibernate开发-->通过JPA API检索数据
  Java网络编程-->Socket用法详解
  精通Spring-->Vue CLI脚手架工具
  Vue3开发-->CSS过渡和动画
  教你手撸一个Spring框架,从Spring.xml解析到注册Bean对象!
  Spring MVC的@ExceptionHandler注解的用法
  Spring Boot JPA @OneToOne
  从零搭建一个基于 ELK 的日志、指标收集与监控系统
  Spring Cloud Config 客户端的高可用实现
  RESTful API 设计最佳实践
  【Web服务开发】基于Java开发代驾定位系统,2天完成脚手架
  Spring Boot集成EHCache实现缓存机制
  网红框架SpringBoot2.x之定制参数浅析
  使用idea和gradle编译spring5源码
  酒店评论数据分析和挖掘-展现数据分析全流程:报告展示篇
  Spring @Transactional注解失效解决方案
  Spring MVC Controller单例陷阱
  Spring如何实现AOP,请不要再说cglib了!
  MyBatis解析和运行原理
  更多...
 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前沿技术。  联系我们
如有技术文章涉及侵权,请与本站管理员联系。