如何模拟客户端中止请求?

dwj*_*ton 9 java apache tomcat http

我的任务是解决报告的错误,日志显示

org.apache.catalina.connector.ClientAbortException: java.io.IOException
...
Caused by: java.io.IOException
    at org.apache.coyote.http11.InternalAprOutputBuffer.flushBuffer(InternalAprOutputBuffer.java:205)
Run Code Online (Sandbox Code Playgroud)

这里有几个关于 ClientAbortException 的问题,我通过阅读它们以及Tomcat javadoc 的理解是,当客户端中止 HTTP 请求时,Tomcat 会抛出异常。

我无法重现该错误。如何模拟客户端中止?

我尝试过的

  • 在请求处理程序中添加 a Thread.sleep(10000),然后在请求运行时关闭浏览器 - 但这并不起作用。

  • 使用 Angular技术取消来自客户端的 HTTP 请求。

dwj*_*ton 8

好吧,经过一些实验——我找到了一种方法。

它看起来是这样的 - 如果在服务器写入/刷新输出时客户端取消/超时http 请求,则会抛出错误。(注意。似乎响应的大小也很重要 - 请参阅最后我的注释)。

可能发生三种情况:


条件 1:服务器在客户端超时之前写入并刷新输出。

响应被发送回客户端。

情况 2:客户端在服务器写入和刷新输出之前超时。

客户端没有收到响应,服务器没有错误。

情况 3:服务器写入输出时客户端超时。

客户端没有收到响应。服务器抛出ClientAbortException( java.io.IOException)。


为了模拟这三个条件,我们使用三个变量:

  1. 客户端超时所需的时间
  2. 时间服务器燃烧以获得其结果。
  3. 服务器响应的大小。

这是模拟它的测试代码:

服务器端(这是一个 Spring MVC 控制器)。

@RequestMapping(value = { "/debugGet" }, method = RequestMethod.GET)
@ResponseBody
public List<String> debugGet(@RequestParam int timeout, int numObjects) throws InterruptedException {
    Thread.sleep(timeout);

    List<String> l = new ArrayList<String>();

    for (int i =0; i< numObjects; i++){
        l.add(new String());
    }


    return l;

}
Run Code Online (Sandbox Code Playgroud)

客户端(角度)

this.debugGet = function(server, client, numObjects){       

    var httpProm = $http({
        method: "GET",
        url: "debugGet",
        timeout: client,
        params : {
            timeout: server,
            numObjects: numObjects}
    });             

    httpProm.then(function(data){
        console.log(data);
    }, function(data){
        console.log("error");
        console.log(data);
    });     
};
Run Code Online (Sandbox Code Playgroud)

使用它,我可以使用以下参数模拟三种条件:

              Client Timeout     Server Burn Time      Num Strings
Condition 1:   1000                900                   10000
Condition 2:   1000                2000                  100 
Condition 3:   1000                950                   10000
Run Code Online (Sandbox Code Playgroud)

注意:响应的大小似乎也很重要。

例如:

              Client Timeout     Server Burn Time      Num Strings
Condition 2:  1000               2000                  100 
Condition 3:  1000               2000                  10000 
Run Code Online (Sandbox Code Playgroud)

在这里,对于 10000 个字符串,我们得到java.io.IOException即使刷新发生在客户端超时之后,但对于 100 个字符串则不然。