上节课我们学了这样的一个结构(这个结构也是在我们实际开发时经常使用的异步请求方式,当我们有些业务比较耗时的时候,我们应该异步处理)


这节课我们首先模拟下超时的过程(需要对上节课异步代码做下简单的修改)
上节课我们修改了tomcat最大线程数(改成了很小)
在我们进行异步提交的同时,依然可以进行同步提交 因为当前的线程已经释放掉了(tomcat可以继续接纳客人(请求)继续进行相应 只不过一些耗时的处理需要放在Callable里面)
比如上节课我们模拟的延时3s

这个接口对应我们异步按钮(test1.html)

当我们点击异步(async)按钮时 延时3s后弹出结果
这里面的细节我们看下文档
我们在官网手册里搜索SimpleAsyncTaskExecutor
可以定位到说明如下

Spring MVC默认使用SimpleAsyncTaskExecutor类来处理多线程(高并发)可以定义拦截器进行处理拦截
SimpleAsyncTaskExecutor在并发并不是很高的情况下(服务器压力不是很大情况下)可以直接使用
SimpleAsyncTaskExecutor并不是Spring MVC里面的内容 它在Spring主目录里的Integration下

来到文档https://docs.spring.io/spring/docs/current/spring-framework-reference/integration.html#spring-integration
搜索SimpleAsyncTaskExecutor(异步任务执行器)
可以看见如下

它分为几种类型 简单列举如下

一般我们不用SimpleAsyncTaskExecutor而使用ThreadPoolTaskExecutor (是一个比较常用的线程池执行器,一般使用它设置一些线程的大小,设置缓冲 等待队列 空闲线程 存活时间等)
那么我们这节课介绍下另外一种方式WebAsyncTask

实际上我们在做异步请求的时候,经常会碰到超时的过程 也就是如下图 浏览器发起请求 tomcat线程处理不发生阻塞 因为把任务交给另外一个单独线程处理 那么这时候这个单独线程在这里出现了问题(比如说超时了)那么是否让我们前端不断的去等待,这时其实我们应该对超时做出处理 因此官方提供了WebAsyncTask

下面代码演示下对超时做出处理 (WebAsyncTask)
为了演示前台请求超时处理
我们修改下代码
在NewsController中(上节课代码)

前台代码test1.html

做异步请求时 加入参数t 控制延时多少秒
下面我们修改下NewsController中addUser 使其返回WebAsyncTask(处理超时)

修改完代码 我们编译运行下代码
编译完成来到前端页面

我们测试下
点击async_submit按钮
可以发现很准确的3s弹出对话框
然后我们点击async_submit(timeout)按钮
由于我们在前台设置4s才能完成请求

我们点击按钮
结果如下

必定会返回超时的内容(因为我们后台设置了超时的处理)

接下来我们学下异常(exceptionHandler)文档中搜索https://docs.spring.io/spring/docs/5.0.1.BUILD-SNAPSHOT//spring-framework-reference/web.html#mvc-ann-rest-exceptions
异常处理只需要在方法前面加上@exceptionHandler注即可

在异步请求里的异常的处理方式和处理普通异常是一样的
下面代码演示下
比如我们超时后直接throw 一个新的异常

重新发布代码
再次运行localhost:8080/test1/html
点击 async_submit(timeout)按钮

表示请求处理超时了
我们在处理异常的时候 可以把异常进行定义 如果拦截到超时异常 我们专门做一些返回值的处理或者日志的记录
网友评论