Javax ClientBuilder post()在发送到Web服务之前删除文件

时间:2016-04-19 09:05:12

标签: java web-services rest file-upload playframework

我正在尝试将临时文件发送到RESTful Web服务。我正在使用以下函数执行此操作:

private static String nlpFileUpload(String filePath) throws IOException {
    // Check is file exists
    File file = new File(filePath);
    if(!file.isFile()) {
        throw new FileNotFoundException();
    }

    // Upload file to web service
    return ClientBuilder.newClient()
        .target(nlprestURL + "upload")
        .request()
        .post(
                Entity.entity(file, MediaType.APPLICATION_OCTET_STREAM)
        ).readEntity(String.class);
}

问题是,在方法.post()中,文件有时会从磁盘中删除,并返回FileNotFound异常:

[ERROR] [04/18/2016 19:04:35.945] [application-akka.actor.default-dispatcher-2] [TaskInvocation] java.io.FileNotFoundException: /tmp/multipartBody3655134388737861177asTemporaryFile (No such file or directory)
javax.ws.rs.ProcessingException: java.io.FileNotFoundException: /tmp/multipartBody3655134388737861177asTemporaryFile (No such file or directory)
at org.glassfish.jersey.client.internal.HttpUrlConnector.apply(HttpUrlConnector.java:287)
at org.glassfish.jersey.client.ClientRuntime.invoke(ClientRuntime.java:255)
at org.glassfish.jersey.client.JerseyInvocation$1.call(JerseyInvocation.java:684)
at org.glassfish.jersey.client.JerseyInvocation$1.call(JerseyInvocation.java:681)
at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
at org.glassfish.jersey.internal.Errors.process(Errors.java:228)
at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:444)
at org.glassfish.jersey.client.JerseyInvocation.invoke(JerseyInvocation.java:681)
at org.glassfish.jersey.client.JerseyInvocation$Builder.method(JerseyInvocation.java:437)
at org.glassfish.jersey.client.JerseyInvocation$Builder.post(JerseyInvocation.java:343)
at pl.edu.pwr.services.serel.SerelServiceRs.nlpFileUpload(SerelServiceRs.java:97)
at pl.edu.pwr.services.serel.SerelServiceRs.processFile(SerelServiceRs.java:181)
at jobs.ProcessDocuments.run(ProcessDocuments.java:54)
at akka.dispatch.TaskInvocation.run(AbstractDispatcher.scala:41)
at akka.dispatch.ForkJoinExecutorConfigurator$AkkaForkJoinTask.exec(AbstractDispatcher.scala:393)
at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260)
at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339)
at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)
at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107)

Caused by: java.io.FileNotFoundException: /tmp/multipartBody3655134388737861177asTemporaryFile (No such file or directory)
at java.io.FileInputStream.open0(Native Method)
at java.io.FileInputStream.open(FileInputStream.java:195)
at java.io.FileInputStream.<init>(FileInputStream.java:138)
at org.glassfish.jersey.message.internal.FileProvider.writeTo(FileProvider.java:115)
at org.glassfish.jersey.message.internal.FileProvider.writeTo(FileProvider.java:67)
at org.glassfish.jersey.message.internal.WriterInterceptorExecutor$TerminalWriterInterceptor.invokeWriteTo(WriterInterceptorExecutor.java:265)
at org.glassfish.jersey.message.internal.WriterInterceptorExecutor$TerminalWriterInterceptor.aroundWriteTo(WriterInterceptorExecutor.java:250)
at org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed(WriterInterceptorExecutor.java:162)
at org.glassfish.jersey.message.internal.MessageBodyFactory.writeTo(MessageBodyFactory.java:1130)
at org.glassfish.jersey.client.ClientRequest.writeEntity(ClientRequest.java:502)
at org.glassfish.jersey.client.internal.HttpUrlConnector._apply(HttpUrlConnector.java:388)
at org.glassfish.jersey.client.internal.HttpUrlConnector.apply(HttpUrlConnector.java:285)
... 19 more

但是此异常并不总是出现。在调试时我发现有时文件被正确发送到服务,但在其他时间出现异常。 我不知道这里有什么问题。该服务能够将文件读取为MediaType.APPLICATION_OCTET_STREAM,但我认为问题出在客户端。为什么.post()方法在将文件发送到Web服务之前将其删除?

我在我的应用程序中使用Play framework 2.3.9。 nlpFileUpload(String filePath)函数由Akka调度程序调用。

1 个答案:

答案 0 :(得分:0)

播放临时文件的问题是,当它们被收集时会被删除。当客户端上载文件并将其作为MultipartFormData处理时,将创建临时文件。这就是你的代码有时会起作用的原因。

要解决此问题,您可以尝试保留对此文件的引用,以便垃圾收集器不会清除它。您可以首先更改函数的定义以使用此引用:

static String nlpFileUpload(File file) throws IOException