基本springboot2.2.3.RELEASE版本测试,2.2.5就没有这个问题
在有问题的项目里进行测试(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;
}
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。