基本 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"})
@Slf4j
public class ExceptionInterceptor extends ResponseEntityExceptionHandler {@ExceptionHandler(ClientAbortException.class)
@ResponseBody
ResponseEntity<?> handlerClientAbortException(HttpServletRequest request, HttpServletResponse response, Throwable ex) {
// 日志自己处理
log.warn("in clientAbortException");
// 此处一定要返回 null 了,因为客户端已经断开连接,返回请求没啥用了
return null;
}
}