spring - 如何在请求上传期间处理客户端中止?

标签 spring spring-mvc tomcat spring-boot spring-4

给定以下应用程序,基于 Spring Initializr模板

@SpringBootApplication
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }

    public static class Payload {
        public String field1;
        public String field2;
    }

    @RestController
    public static class MyController {
        @RequestMapping("/echo")
        public ResponseEntity<Payload> echo(@RequestBody Payload payload) {
            return new ResponseEntity<>(payload, HttpStatus.OK);
        }
    }
}

如果我在发送 header 后中止连接

$ nc 192.168.56.1 8080
POST /echo HTTP/1.1
Host: 192.168.56.1:8080
Content-Type: application/json
Content-Length: 42

^C

然后服务器尝试用 400 响应并记录以下内容

2016-05-03 16:56:28.916  WARN 5776 --- [nio-8080-exec-2] .w.s.m.s.DefaultHandlerExceptionResolver : Failed to read HTTP message: org.springframework.http.converter.HttpMessageNotReadableException: Could not read document: Unexpected EOF read on the socket; nested exception is java.io.EOFException: Unexpected EOF read on the socket
2016-05-03 16:56:28.997 ERROR 5776 --- [nio-8080-exec-2] o.a.c.c.C.[Tomcat].[localhost]           : Exception Processing ErrorPage[errorCode=0, location=/error] org.apache.catalina.connector.ClientAbortException: java.io.IOException: An established connection was aborted by the software in your host machine

如果客户端在发送请求后中止,则默认情况下不会记录任何内容,并且生成的 ClientAbortException 可通过 ErrorAttributes#getError 在过滤器中使用。

如何以相同的方式处理请求期间的中止?也就是说,默认情况下不记录任何警告/错误,并启用自定义过滤器以告知客户端已中止。

最佳答案

我找到了一个解决方案,但还没有找到它做错事的案例。

@Autowired
private DefaultErrorAttributes defaultExceptionResolver;
    
@ExceptionHandler(HttpMessageNotReadableException.class)
public void checkForAbort(HttpServletRequest request, HttpServletResponse response, RuntimeException exception) {
    if (exception.getCause() instanceof EOFException) {
        ClientAbortException abortException = new ClientAbortException(exception.getCause());
        abortException.addSuppressed(exception);
        try {
            response.getOutputStream().close();
        }
        catch (IOException ex) {
            abortException.addSuppressed(ex);
        }

        defaultExceptionResolver.resolveException(request, response, null, abortException);
    }
    else {
        throw exception;
    }
}

这可能会进入,例如,@ControllerAdvice

关于spring - 如何在请求上传期间处理客户端中止?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37009285/

相关文章:

java - log4j2 RollingFile Appender 不更改 Tomcat 上的文件名?

java - 将子域重定向到工作 HTTPS-Tomcat(使用 NGINX)

java - JdbcTemplate 类型中的方法 query(String, ResultSetExtractor<T>) 不适用于参数 (String, BeanPropertyRowMapper)

java - 有什么办法在Spring(Boot)中使用@RequestMapping和@PathVariable来捕获变量路径?

spring - 通过 @RequestMapping 名称构建的 URL 无法按自定义名称的预期工作

java - Spring MVC 3.0 访问 session 变量

java - 如何在tomcat 7中加密server.xml的密码

java - 为什么 JDBC 身份验证在 Spring Boot 和 React 中因 CORS 失败?

java - Spring MVC 3.0 下划线绑定(bind)请求参数

java - 您可以在数据库表或类似表上放置一个监听器吗