首页 > 解决方案 > CompletionException:NPE 试图异步读取 inputStream

问题描述

我正在尝试以异步方式读取从客户端接收到的文件。这个想法是接收文件,验证它,如果验证正常,向客户端发送一个响应,说一切正常,然后在后台处理文件,因此用户不需要等到文件处理完毕.

为此,我在资源中收到文件,例如 inputStrem:

@Override
@POST
@Path("/bulk")
@Consumes("text/csv")
@Produces(MediaType.APPLICATION_JSON)
public Response importEmployees(InputStream inputStream) {
    if(fileIsNotValid(inputStream)){
        throw exceptionFactoryBean.createBadRequestException("there was an error with the file");
    }
try {
        CompletableFuture.runAsync(() -> {
    employeeService.importEmployees(inputStream);
        }).exceptionally(e -> {
            LOG.error(format(ERROR_IMPORTING_FILE, e.getMessage()));
            return null;
        });
    } catch (RuntimeException e) {
        LOG.error(format(ERROR_SENDING_EMAIL, e.getMessage()));
        throw exceptionFactoryBean.createServiceException("payment-method.export.installment-schema.error");
    }
    return Response.ok().build();
}

对于异步部分,我使用了 CompletableFuture 的 runAsync() 方法。但是,在我的 employeeService.importEmployees() 方法中,我尝试读取 inputStream 并得到 java.util.concurrent.CompletionException: java.lang.NullPointerException

public List<ImportResult> importEmployees(final InputStream inputStream) {    
byte[] buffer = new byte[1024];
    int len;
    try {
        while ((len = inputStream.read(buffer)) > -1) {
            baos.write(buffer, NumberUtils.INTEGER_ZERO, len);
        }

inputStream 不为空。并且在低级别进行调试,我可以看到当我尝试读取 inputStream 时,类 Http11InputBuffer 的包装器为空。你能看到我有什么错误,或者我如何设置 Http11InputBuffer 的包装属性来读取 inputStream

标签: javaasynchronousnullpointerexceptioninputstreamcompletable-future

解决方案


你不是在等待结果。所以它会返回Response之前importEmployees执行的。在返回响应之前,您需要等待加入/获取:

public Response importEmployees(InputStream inputStream) {
    ...
    CompletableFuture.runAsync(() -> { ... }).get();
    ...
    return Response.ok().build();
}

但是,使此代码具有反应性可能没有意义。


推荐阅读