使用jersey-1.7在Google Appengine上进行多部分文件上传

Qam*_*tra 11 java google-app-engine jersey

我用Jersey在Google Appengine上写了一个应用程序来处理简单的文件上传.在球衣1.2上运行时效果很好.在更高版本(当前1.7)中,引入了@FormDataParam来处理多部分/表单输入.我正在使用jersey-multipart和mimepull依赖.似乎新的做法是在appengine中创建临时文件,我们都知道这是非法的......

我在这里错过了什么或做错了什么,因为现在认为Jersey与AppEngine兼容?

@POST 
@Path("upload") 
@Consumes(MediaType.MULTIPART_FORM_DATA) 
public void upload(@FormDataParam("file") InputStream in) { .... }
Run Code Online (Sandbox Code Playgroud)

使用这些例外调用时,上述操作将失败...

/upload
java.lang.SecurityException: Unable to create temporary file
    at java.io.File.checkAndCreate(File.java:1778)
    at java.io.File.createTempFile(File.java:1870)
    at java.io.File.createTempFile(File.java:1907)
    at org.jvnet.mimepull.MemoryData.createNext(MemoryData.java:87)
    at org.jvnet.mimepull.Chunk.createNext(Chunk.java:59)
    at org.jvnet.mimepull.DataHead.addBody(DataHead.java:82)
    at org.jvnet.mimepull.MIMEPart.addBody(MIMEPart.java:192)
    at org.jvnet.mimepull.MIMEMessage.makeProgress(MIMEMessage.java:235)
    at org.jvnet.mimepull.MIMEMessage.parseAll(MIMEMessage.java:176)
    at org.jvnet.mimepull.MIMEMessage.getAttachments(MIMEMessage.java:101)
    at com.sun.jersey.multipart.impl.MultiPartReaderClientSide.readMultiPart(MultiPartReaderClientSide.java:177)
    at com.sun.jersey.multipart.impl.MultiPartReaderServerSide.readMultiPart(MultiPartReaderServerSide.java:80)
    at com.sun.jersey.multipart.impl.MultiPartReaderClientSide.readFrom(MultiPartReaderClientSide.java:139)
    at com.sun.jersey.multipart.impl.MultiPartReaderClientSide.readFrom(MultiPartReaderClientSide.java:77)
    at com.sun.jersey.spi.container.ContainerRequest.getEntity(ContainerRequest.java:474)
    at com.sun.jersey.spi.container.ContainerRequest.getEntity(ContainerRequest.java:538)
Run Code Online (Sandbox Code Playgroud)

有人有线索吗?有没有办法在阻止mimepull创建临时文件的同时做某事?

yve*_*lem 17

对于超出其默认大小的文件,multipart将创建一个临时文件.要避免这种情况 - 在gae上创建文件是不可能的 - 您可以jersey-multipart-config.properties在项目的资源文件夹中创建一个文件并将此行添加到它:

bufferThreshold = -1
Run Code Online (Sandbox Code Playgroud)

然后,代码就是您给出的代码:

@POST
@Consumes(MediaType.MULTIPART_FORM_DATA)
public Response post(@FormDataParam("file") InputStream stream, @FormDataParam("file") FormDataContentDisposition disposition) throws IOException {
  post(file, disposition.getFileName());
  return Response.ok().build();
}
Run Code Online (Sandbox Code Playgroud)

  • 谢谢你的解决方案.只是一个FYI,如果您使用的是Jersey 2+,则需要使用`jersey.config.multipart.bufferThreshold`作为您的属性名称. (7认同)
  • 你可以帮我找一下`resources`文件夹的位置.它在`\ war`或`\ WEB-INF`或其他地方?谢谢. (3认同)

Flo*_*ris 11

为了让那些在使用Eclipse和GPE(谷歌插件为Eclipse)时苦苦挣扎的人们,我给出了这个稍微修改过的解决方案,该解决方案源于@yves的回答.

我用App Engine SDK 1.9.10和测试过它Jersey 2.12.由于不同的问题,它不会与App Engine SDK 1.9.6 -> 1.9.9其他人合作.

在您的\war\WEB-INF\classes文件夹下创建一个名为的新文件jersey-multipart-config.properties.编辑文件以使其包含该行jersey.config.multipart.bufferThreshold = -1.

请注意,该\classes文件夹在Eclipse中隐藏,因此请在操作系统的文件资源管理器中查找该文件夹(例如Windows资源管理器).

现在,当multipart功能初始化(在Jersey servlet初始化时)和文件上传完成时(在Jersey servlet post请求上),将不再创建临时文件,GAE也不会抱怨.