基本springboot2.2.3.RELEASE版本测试,2.2.5就没有这个问题
java - 如何模拟客户端中止请求?
在有问题的项目里进行测试(SpringBoot有些高版本没有这种异常,所以必须在有问题的项目里)
主要是模拟客户端主动与服务端断开链接
JS 客户端请求,在浏览器console里运行下面代码即可$.ajax({ url : 'http://localhost:8089/clientAbort?timeout=950&numObjects=100000000', timeout : 1100, error : function(xhr,textStatus){ console.log('error:'+textStatus); },});
import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestParam;import org.springframework.web.bind.annotation.ResponseBody;import java.util.ArrayList;import java.util.List;/** * @date 2020/7/5 10:09 */@Controller@RequestMapping("/")public class TestController { @GetMapping("/clientAbort") @ResponseBody public List<String> download(@RequestParam int timeout, int numObjects) throws InterruptedException { Thread.sleep(timeout); List<String> l = new ArrayList<>(); long start = System.currentTimeMillis(); for (int i = 0; i < numObjects; i++) { l.add("l"); } long end = System.currentTimeMillis(); System.out.println("pack use " + (end - start)); return l; }}
解决方案如下: 在拦截器里增加拦截
import org.apache.catalina.connector.ClientAbortException;import org.springframework.web.bind.annotation.ControllerAdvice;import org.springframework.web.bind.annotation.ExceptionHandler;import org.springframework.web.bind.annotation.ResponseBody;import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;@ControllerAdvice(basePackages = {"your.controllers.package.name"})@Slf4jpublic class ExceptionInterceptor extends ResponseEntityExceptionHandler { @ExceptionHandler(ClientAbortException.class) @ResponseBody ResponseEntity<?> handlerClientAbortException(HttpServletRequest request, HttpServletResponse response, Throwable ex) { //日志自己处理 log.warn("in clientAbortException"); //此处一定要返回null了,因为客户端已经断开连接,返回请求没啥用了 return null; }}