SpringBoot的DeferredResult案例:DeferredResult的超时处理方式

DeferredResult的超时处理,采用委托机制,也就是在实例DeferredResult时给予一个超时时长(毫秒),同时在onTimeout中委托(传入)一个新的处理线程(我们可以认为是超时线程);当超时时间到来,DeferredResult启动超时线程,超时线程处理业务,封装返回数据,给DeferredResult赋值(正确返回的或错误返回的)。

这个实例可以对上一个实例的代码稍作改动即可。

一、增加超时处理任务TimeOutWork

package com.example; 
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.context.request.async.DeferredResult;
 
public class TimeOutWork implements Runnable{ 
 private final Logger logger = LoggerFactory.getLogger(this.getClass());
 private DeferredResult> deferredResult;
 
 public TimeOutWork(DeferredResult> deferredResult) {
 this.deferredResult = deferredResult;
 }
 
 @Override
 public void run() {
 logger.debug("我超时啦!");
 ResponseMsg msg = new ResponseMsg();
 msg.fail("我超时啦!");
 //deferredResult.setResult(msg);
 deferredResult.setErrorResult(msg);
 }
}

二、DeferredResult请求中注册超时任务处理

修改第一个请求,修改了两处,请自己比较

package com.example; 
import java.util.HashMap;
import java.util.Map; 
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.async.DeferredResult;
 
@RestController
@RequestMapping("/api")
public class DeferredRestController {
 
 private final Logger logger = LoggerFactory.getLogger(this.getClass()); 
 private final Map>> responseBodyMap = new HashMap>>();
 private final Map requestBodyMap = new HashMap();
 
 /**
 * 第一个请求
 * 
 * @param req
 * @return
 */
 @RequestMapping("/request1")
 @ResponseBody
 public DeferredResult> request1(RequestMsg req) {
 logger.debug("request1:请求参数{}", req.getParam());
 DeferredResult> result =new DeferredResult>(10000l);//10秒
 result.onTimeout(new TimeOutWork(result));//超时任务
 requestBodyMap.put(1, req);// 把请求放到第一个请求map中
 responseBodyMap.put(1, result);// 把请求响应的DeferredResult实体放到第一个响应map中
 return result;
 }
 
 /**
 * 第二个请求
 * 
 * @param req
 * @return
 */
 @RequestMapping("/request2")
 @ResponseBody
 public DeferredResult> request2(RequestMsg req) {
 logger.debug("request2:请求参数{}", req.getParam());
 DeferredResult> result = new DeferredResult>();
 requestBodyMap.put(2, req);// 把请求放到第二个请求map中
 responseBodyMap.put(2, result);// 把请求响应的DeferredResult实体放到第二个响应map中
 return result;
 }
 
 /**
 * 第三个请求
 * 
 * @param req
 * @return
 */
 @RequestMapping("/request3")
 @ResponseBody
 public DeferredResult> request3(RequestMsg req) {
 logger.debug("request3:请求参数{}", req.getParam());
 DeferredResult> result = new DeferredResult>();
 requestBodyMap.put(3, req);// 把请求放到第三个请求map中
 responseBodyMap.put(3, result);// 把请求响应的DeferredResult实体放到第三个响应map中
 return result;
 }
 
 /**
 * 控制第x个请求执行返回操作,同时自己也返回同样的值
 * 
 * @param x
 * @return
 */
 @RequestMapping(value = "/requestXReturn", method = RequestMethod.POST)
 @ResponseBody
 public ResponseMsg request1Return(Integer x) {
 ResponseMsg msg = new ResponseMsg();
 logger.debug("requestXReturn--1:请求参数{}", x);
 DeferredResult> result = responseBodyMap.get(x);
 if (result == null) {
 msg.fail("錯誤!请求已经释放");
 return msg;
 }
 String resultStr = "result" + x.toString() + ". Received:" + requestBodyMap.get(x).getParam();
 msg.success("成功", resultStr);
 result.setResult(msg);// 设置DeferredResult的结果值,设置之后,它对应的请求进行返回处理
 responseBodyMap.remove(x);// 返回map删除
 logger.debug("requestXReturn--2:请求参数{}", x);
 logger.debug("requestXReturn--3:返回参数{}", msg);
 return msg;
 }
}

三、修改页面index.html


 
                    
                    

你可能感兴趣的:(SpringBoot的DeferredResult案例:DeferredResult的超时处理方式)