基本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;
    }


}


lingkong
28 声望3 粉丝