Resteasy 在 GAE 上上传多部分/数据格式文件

发布于 2024-10-15 05:28:34 字数 4963 浏览 6 评论 0原文

我正在尝试使用 Resteasy 2.0.1.GA 将包含文件的表单上传到 GAE 应用程序中,使用 如何使用 jax-rs 进行分段/表单文件上传?

Index.html

<form action="/rest/upload" method="post" enctype="multipart/form-data">
  <input type="text" name="name" />
  <input type="file" name="file" />
  <input type="submit" />
</form>

Rest.java

@Path("")
public class Rest {
    @POST
    @Path("/rest/upload")
    @Consumes("multipart/form-data")
    public String postContent(@MultipartForm UploadForm form) {
        System.out.println(form.getData().length);
        System.out.println(form.getName());
        return "Done";
    }
}

UploadForm.java

public class UploadForm {

    private String name;
    private byte[] data;

    @FormParam("name")
    public void setPath(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    @FormParam("file")
    public void setContentData(byte[] data) {
        this.data = data;
    }

    public byte[] getData() {
        return data;
    }
}

但我收到以下错误消息(可能是由于 RESTEasy Provider 的实现使用临时文件来处理输入流)

HTTP ERROR 500

Problem accessing /files/service/upload. Reason:

    java.io.FileOutputStream is a restricted class. Please see the Google  App Engine developer's guide for more details.

Caused by:

java.lang.NoClassDefFoundError: java.io.FileOutputStream is a restricted class. Please see the Google  App Engine developer's guide for more details.
    at com.google.appengine.tools.development.agent.runtime.Runtime.reject(Runtime.java:51)
    at org.apache.james.mime4j.storage.TempFileStorageProvider$TempFileStorageOutputStream.<init>(TempFileStorageProvider.java:117)
    at org.apache.james.mime4j.storage.TempFileStorageProvider.createStorageOutputStream(TempFileStorageProvider.java:107)
    at org.apache.james.mime4j.storage.ThresholdStorageProvider$ThresholdStorageOutputStream.write0(ThresholdStorageProvider.java:113)
    at org.apache.james.mime4j.storage.StorageOutputStream.write(StorageOutputStream.java:119)
    at org.apache.james.mime4j.codec.CodecUtil.copy(CodecUtil.java:43)
    at org.apache.james.mime4j.storage.AbstractStorageProvider.store(AbstractStorageProvider.java:57)
    at org.apache.james.mime4j.message.BodyFactory.textBody(BodyFactory.java:167)
    at org.apache.james.mime4j.message.MessageBuilder.body(MessageBuilder.java:148)
    at org.apache.james.mime4j.parser.MimeStreamParser.parse(MimeStreamParser.java:101)
    at org.apache.james.mime4j.message.Message.<init>(Message.java:141)
    at org.apache.james.mime4j.message.Message.<init>(Message.java:100)
    at org.jboss.resteasy.plugins.providers.multipart.MultipartInputImpl.parse(MultipartInputImpl.java:76)
    at org.jboss.resteasy.plugins.providers.multipart.MultipartFormAnnotationReader.readFrom(MultipartFormAnnotationReader.java:55)
    at org.jboss.resteasy.core.interception.MessageBodyReaderContextImpl.proceed(MessageBodyReaderContextImpl.java:105)
    at org.jboss.resteasy.plugins.interceptors.encoding.GZIPDecodingInterceptor.read(GZIPDecodingInterceptor.java:46)
    at org.jboss.resteasy.core.interception.MessageBodyReaderContextImpl.proceed(MessageBodyReaderContextImpl.java:108)
    at org.jboss.resteasy.core.messagebody.ReaderUtility.doRead(ReaderUtility.java:111)
    at org.jboss.resteasy.core.messagebody.ReaderUtility.doRead(ReaderUtility.java:93)
    at org.jboss.resteasy.core.MessageBodyParameterInjector.inject(MessageBodyParameterInjector.java:146)
    at org.jboss.resteasy.core.MethodInjectorImpl.injectArguments(MethodInjectorImpl.java:114)
    at org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:137)
    at org.jboss.resteasy.core.ResourceMethod.invokeOnTarget(ResourceMethod.java:252)
    at org.jboss.resteasy.core.ResourceMethod.invoke(ResourceMethod.java:217)
    at org.jboss.resteasy.core.ResourceMethod.invoke(ResourceMethod.java:206)
    at org.jboss.resteasy.core.SynchronousDispatcher.getResponse(SynchronousDispatcher.java:514)
    at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:491)
    at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:120)
    at org.jboss.resteasy.plugins.server.servlet.ServletContainerDispatcher.service(ServletContainerDispatcher.java:200)
    at org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:48)
    at org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:43)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
    ...

:有人在使用 GAE 和 RESTEasy 时遇到过这个问题吗?有人解决了吗?我在任何地方都找不到有关此问题的任何提及。 谢谢!

I'm trying to use resteasy 2.0.1.GA to upload a form with a file in it into GAE application, using the method advised at How do I do a multipart/form file upload with jax-rs?

Index.html

<form action="/rest/upload" method="post" enctype="multipart/form-data">
  <input type="text" name="name" />
  <input type="file" name="file" />
  <input type="submit" />
</form>

Rest.java

@Path("")
public class Rest {
    @POST
    @Path("/rest/upload")
    @Consumes("multipart/form-data")
    public String postContent(@MultipartForm UploadForm form) {
        System.out.println(form.getData().length);
        System.out.println(form.getName());
        return "Done";
    }
}

UploadForm.java

public class UploadForm {

    private String name;
    private byte[] data;

    @FormParam("name")
    public void setPath(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    @FormParam("file")
    public void setContentData(byte[] data) {
        this.data = data;
    }

    public byte[] getData() {
        return data;
    }
}

But I'm getting the following error message (probably due to the RESTEasy Provider's implmenetation that uses temporary files to handle the input stream):

HTTP ERROR 500

Problem accessing /files/service/upload. Reason:

    java.io.FileOutputStream is a restricted class. Please see the Google  App Engine developer's guide for more details.

Caused by:

java.lang.NoClassDefFoundError: java.io.FileOutputStream is a restricted class. Please see the Google  App Engine developer's guide for more details.
    at com.google.appengine.tools.development.agent.runtime.Runtime.reject(Runtime.java:51)
    at org.apache.james.mime4j.storage.TempFileStorageProvider$TempFileStorageOutputStream.<init>(TempFileStorageProvider.java:117)
    at org.apache.james.mime4j.storage.TempFileStorageProvider.createStorageOutputStream(TempFileStorageProvider.java:107)
    at org.apache.james.mime4j.storage.ThresholdStorageProvider$ThresholdStorageOutputStream.write0(ThresholdStorageProvider.java:113)
    at org.apache.james.mime4j.storage.StorageOutputStream.write(StorageOutputStream.java:119)
    at org.apache.james.mime4j.codec.CodecUtil.copy(CodecUtil.java:43)
    at org.apache.james.mime4j.storage.AbstractStorageProvider.store(AbstractStorageProvider.java:57)
    at org.apache.james.mime4j.message.BodyFactory.textBody(BodyFactory.java:167)
    at org.apache.james.mime4j.message.MessageBuilder.body(MessageBuilder.java:148)
    at org.apache.james.mime4j.parser.MimeStreamParser.parse(MimeStreamParser.java:101)
    at org.apache.james.mime4j.message.Message.<init>(Message.java:141)
    at org.apache.james.mime4j.message.Message.<init>(Message.java:100)
    at org.jboss.resteasy.plugins.providers.multipart.MultipartInputImpl.parse(MultipartInputImpl.java:76)
    at org.jboss.resteasy.plugins.providers.multipart.MultipartFormAnnotationReader.readFrom(MultipartFormAnnotationReader.java:55)
    at org.jboss.resteasy.core.interception.MessageBodyReaderContextImpl.proceed(MessageBodyReaderContextImpl.java:105)
    at org.jboss.resteasy.plugins.interceptors.encoding.GZIPDecodingInterceptor.read(GZIPDecodingInterceptor.java:46)
    at org.jboss.resteasy.core.interception.MessageBodyReaderContextImpl.proceed(MessageBodyReaderContextImpl.java:108)
    at org.jboss.resteasy.core.messagebody.ReaderUtility.doRead(ReaderUtility.java:111)
    at org.jboss.resteasy.core.messagebody.ReaderUtility.doRead(ReaderUtility.java:93)
    at org.jboss.resteasy.core.MessageBodyParameterInjector.inject(MessageBodyParameterInjector.java:146)
    at org.jboss.resteasy.core.MethodInjectorImpl.injectArguments(MethodInjectorImpl.java:114)
    at org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:137)
    at org.jboss.resteasy.core.ResourceMethod.invokeOnTarget(ResourceMethod.java:252)
    at org.jboss.resteasy.core.ResourceMethod.invoke(ResourceMethod.java:217)
    at org.jboss.resteasy.core.ResourceMethod.invoke(ResourceMethod.java:206)
    at org.jboss.resteasy.core.SynchronousDispatcher.getResponse(SynchronousDispatcher.java:514)
    at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:491)
    at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:120)
    at org.jboss.resteasy.plugins.server.servlet.ServletContainerDispatcher.service(ServletContainerDispatcher.java:200)
    at org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:48)
    at org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:43)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
    ...

Has anyone encountered this issue with GAE and RESTEasy? Has anyone solved it? I couldn't find any mentioning for this issue anywhere.
Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

是你 2024-10-22 05:28:34

我刚刚遇到这个问题并查看了 mime4j 的 Message 构造函数的源代码。它通过调用 DefaultStorageProvider.getInstance() 获取 TempFileStorageProvider。您可以通过调用以下命令将默认值更改为不写入文件系统:

DefaultStorageProvider.setInstance(new MemoryStorageProvider());

That's org.apache.james.mime4j.storage.DefaultStorageProvider。

感谢您使用@MultipartForm 的简洁示例!

I just ran into this problem and looked in the source code for mime4j's Message constructor. It gets the TempFileStorageProvider by calling DefaultStorageProvider.getInstance(). You can change the default to one that doesn't write to the filesystem by calling:

DefaultStorageProvider.setInstance(new MemoryStorageProvider());

That's org.apache.james.mime4j.storage.DefaultStorageProvider.

Thanks for the concise example of using @MultipartForm!

森罗 2024-10-22 05:28:34

好吧,我找到了解决方法 - 我将 apache commons-upload 与 RESTEasy 结合使用,通过将 HttpServletRequest 注入 RESTEasy 方法(并使用 commons-IO 将流转换为字节数组/字符串)。所有软件包均受应用程序引擎支持。

@Path("")
public class Rest {
    @POST
    @Path("/rest/upload")
    public String postContent(@Context HttpServletRequest request) {
        ServletFileUpload upload = new ServletFileUpload();
        FileItemIterator fileIterator = upload.getItemIterator(request);
        while (fileIterator.hasNext()) {
            FileItemStream item = fileIterator.next();
            if ("file".equals(item.getFieldName())){
                byte[] content = IOUtils.toByteArray(item.openStream())
                // Save content into datastore
                // ... 
            } else if ("name".equals(item.getFieldName())){
                String name=IOUtils.toString(item.openStream());
                // Do something with the name string
                // ...
            }
        }
        return "Done";
    } 
}

我仍然宁愿找到一个 RESTEasy 解决方案,以避免 fileIterator 周围的烧烤代码。

Well, I've found a walk-around for it - I'm using apache commons-upload with RESTEasy, by injecting the HttpServletRequest into a RESTEasy method (and transforming the streams into byte array/string using commons-IO). All packages are app engine supported.

@Path("")
public class Rest {
    @POST
    @Path("/rest/upload")
    public String postContent(@Context HttpServletRequest request) {
        ServletFileUpload upload = new ServletFileUpload();
        FileItemIterator fileIterator = upload.getItemIterator(request);
        while (fileIterator.hasNext()) {
            FileItemStream item = fileIterator.next();
            if ("file".equals(item.getFieldName())){
                byte[] content = IOUtils.toByteArray(item.openStream())
                // Save content into datastore
                // ... 
            } else if ("name".equals(item.getFieldName())){
                String name=IOUtils.toString(item.openStream());
                // Do something with the name string
                // ...
            }
        }
        return "Done";
    } 
}

I would still rather find a RESTEasy solution, to avoid the broil-up code around the fileIterator.

我的奇迹 2024-10-22 05:28:34

要将 MemoryStorageProvider 与 RESTEasy 一起使用,您可以设置以下系统属性:

-Dorg.apache.james.mime4j.defaultStorageProvider=org.apache.james.mime4j.storage.MemoryStorageProvider

我尝试使用 RESTEasy 2.3.1.GA 和 jboss-as-7.1.0.Final。

之前的 RESTEasy 版本中还存在一个错误,即临时文件未删除(https://issues.jboss .org/browse/RESTEASY-681)。使用 MemoryStorageProvider 是解决此问题的方法。

To use the MemoryStorageProvider with RESTEasy you can set the following system property:

-Dorg.apache.james.mime4j.defaultStorageProvider=org.apache.james.mime4j.storage.MemoryStorageProvider

I tried it with RESTEasy 2.3.1.GA and jboss-as-7.1.0.Final.

There also was a bug in prior RESTEasy versions where temporary files where not deleted (https://issues.jboss.org/browse/RESTEASY-681). Using the MemoryStorageProvider is a workaround for that.

熊抱啵儿 2024-10-22 05:28:34

看起来 mime4j 库正在尝试写出临时文件,这在应用程序引擎上是不允许的。 mime4j 可以配置为使用内存存储提供程序,但我不知道它的 RESTeasy 使用是否允许该配置。

It looks like the mime4j library is trying to write out temporary files, which is not allowed on app engine. mime4j can be configured to use a memory storage provider, but I don't know if the RESTeasy use of it allows that configuration.

悲凉≈ 2024-10-22 05:28:34

我尝试使用MemoryStorageProvider。但看起来它不适用于除较小文件之外的大多数文件。

我想出了另一个解决方案,它使用谷歌云存储扩展 AbstractStorageProvider,并且效果很好。

https://gist.github.com/azimbabu/0aef75192c385c6d4461118583b6d22f

import com.google.appengine.tools.cloudstorage.GcsFileOptions;
import com.google.appengine.tools.cloudstorage.GcsFilename;
import com.google.appengine.tools.cloudstorage.GcsInputChannel;
import com.google.appengine.tools.cloudstorage.GcsOutputChannel;
import com.google.appengine.tools.cloudstorage.GcsService;
import lombok.extern.slf4j.Slf4j;
import org.apache.james.mime4j.storage.AbstractStorageProvider;
import org.apache.james.mime4j.storage.Storage;
import org.apache.james.mime4j.storage.StorageOutputStream;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.channels.Channels;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.UUID;

/**
 * A {@link org.apache.james.mime4j.storage.StorageProvider} that stores the data in google cloud storage files. The files
 * are stored in a user specified bucket. User of this class needs to supply the google cloud storage service and bucket name.
 *
 * This implementation is based on {@link org.apache.james.mime4j.storage.TempFileStorageProvider}
 * <p>
 * Example usage:
 *
 * <pre>
 * final String bucketName = "my-bucket";
 * DefaultStorageProvider.setInstance(new GcsStorageProvider(gcsService, bucketName));
 * </pre>
 */
@Slf4j
public class GcsStorageProvider extends AbstractStorageProvider {

    private static final int FETCH_SIZE_MB = 4 * 1024 * 1024;

    private static final String PUBLIC_READ = "public-read";

    private static final GcsFileOptions gcsFileOpts = new GcsFileOptions.Builder().acl(PUBLIC_READ).mimeType("text/csv").build();

    private final GcsService gcsService;

    private final String bucketName;

    /**
     * Creates a new <code>GcsStorageProvider</code> using the given
     * values.
     *
     * @param gcsService an implementation of {@link GcsService}
     * @param bucketName google cloud storage bucket name to use.
     */
    public GcsStorageProvider(final GcsService gcsService, final String bucketName) {
        this.gcsService = gcsService;
        this.bucketName = bucketName;
    }

    @Override
    public StorageOutputStream createStorageOutputStream() throws IOException {
        return new GcsStorageProvider.GcsStorageOutputStream(gcsService, bucketName);
    }

    private static final class GcsStorage implements Storage {

        private final GcsService gcsService;

        private GcsFilename gcsFilename;

        private static final Set<GcsFilename> filesToDelete = new HashSet();

        public GcsStorage(final GcsService gcsService, final GcsFilename gcsFilename) {
            this.gcsService = gcsService;
            this.gcsFilename = gcsFilename;
        }

        @Override
        public InputStream getInputStream() throws IOException {
            if (this.gcsFilename == null) {
                throw new IllegalStateException("storage has been deleted");
            } else {
                final GcsInputChannel readChannel = gcsService.openPrefetchingReadChannel(gcsFilename, 0, FETCH_SIZE_MB);
                return Channels.newInputStream(readChannel);
            }
        }

        @Override
        public void delete() {
            synchronized(filesToDelete) {
                if (this.gcsFilename != null) {
                    filesToDelete.add(this.gcsFilename);
                    this.gcsFilename = null;
                }

                final Iterator iterator = filesToDelete.iterator();

                while(iterator.hasNext()) {
                    GcsFilename filename = (GcsFilename)iterator.next();
                    try {
                        if (gcsService.delete(filename)) {
                            iterator.remove();
                        }
                    } catch (final IOException ex) {
                        log.error(ex.getMessage(), ex);
                    }
                }

            }
        }
    }

    private static final class GcsStorageOutputStream extends StorageOutputStream {

        private final GcsService gcsService;

        private GcsFilename gcsFilename;

        private final OutputStream outputStream;

        public GcsStorageOutputStream(final GcsService gcsService, final String bucketName) throws IOException {
            this.gcsService = gcsService;

            final String fileName = UUID.randomUUID().toString();
            this.gcsFilename = new GcsFilename(bucketName, fileName);

            GcsOutputChannel gcsOutputChannel = gcsService.createOrReplace(gcsFilename, gcsFileOpts);
            this.outputStream = Channels.newOutputStream(gcsOutputChannel);
        }

        @Override
        protected void write0(byte[] buffer, int offset, int length) throws IOException {
            this.outputStream.write(buffer, offset, length);
        }

        @Override
        protected Storage toStorage0() throws IOException {
            return new GcsStorage(gcsService, gcsFilename);
        }

        @Override
        public void close() throws IOException {
            super.close();
            this.outputStream.close();
        }
    }
}

I tried to use MemoryStorageProvider. But looks like it does not work for most files other than smaller ones.

I came up with another solution which is extending AbstractStorageProvider using google cloud storage and it works nicely.

https://gist.github.com/azimbabu/0aef75192c385c6d4461118583b6d22f

import com.google.appengine.tools.cloudstorage.GcsFileOptions;
import com.google.appengine.tools.cloudstorage.GcsFilename;
import com.google.appengine.tools.cloudstorage.GcsInputChannel;
import com.google.appengine.tools.cloudstorage.GcsOutputChannel;
import com.google.appengine.tools.cloudstorage.GcsService;
import lombok.extern.slf4j.Slf4j;
import org.apache.james.mime4j.storage.AbstractStorageProvider;
import org.apache.james.mime4j.storage.Storage;
import org.apache.james.mime4j.storage.StorageOutputStream;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.channels.Channels;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.UUID;

/**
 * A {@link org.apache.james.mime4j.storage.StorageProvider} that stores the data in google cloud storage files. The files
 * are stored in a user specified bucket. User of this class needs to supply the google cloud storage service and bucket name.
 *
 * This implementation is based on {@link org.apache.james.mime4j.storage.TempFileStorageProvider}
 * <p>
 * Example usage:
 *
 * <pre>
 * final String bucketName = "my-bucket";
 * DefaultStorageProvider.setInstance(new GcsStorageProvider(gcsService, bucketName));
 * </pre>
 */
@Slf4j
public class GcsStorageProvider extends AbstractStorageProvider {

    private static final int FETCH_SIZE_MB = 4 * 1024 * 1024;

    private static final String PUBLIC_READ = "public-read";

    private static final GcsFileOptions gcsFileOpts = new GcsFileOptions.Builder().acl(PUBLIC_READ).mimeType("text/csv").build();

    private final GcsService gcsService;

    private final String bucketName;

    /**
     * Creates a new <code>GcsStorageProvider</code> using the given
     * values.
     *
     * @param gcsService an implementation of {@link GcsService}
     * @param bucketName google cloud storage bucket name to use.
     */
    public GcsStorageProvider(final GcsService gcsService, final String bucketName) {
        this.gcsService = gcsService;
        this.bucketName = bucketName;
    }

    @Override
    public StorageOutputStream createStorageOutputStream() throws IOException {
        return new GcsStorageProvider.GcsStorageOutputStream(gcsService, bucketName);
    }

    private static final class GcsStorage implements Storage {

        private final GcsService gcsService;

        private GcsFilename gcsFilename;

        private static final Set<GcsFilename> filesToDelete = new HashSet();

        public GcsStorage(final GcsService gcsService, final GcsFilename gcsFilename) {
            this.gcsService = gcsService;
            this.gcsFilename = gcsFilename;
        }

        @Override
        public InputStream getInputStream() throws IOException {
            if (this.gcsFilename == null) {
                throw new IllegalStateException("storage has been deleted");
            } else {
                final GcsInputChannel readChannel = gcsService.openPrefetchingReadChannel(gcsFilename, 0, FETCH_SIZE_MB);
                return Channels.newInputStream(readChannel);
            }
        }

        @Override
        public void delete() {
            synchronized(filesToDelete) {
                if (this.gcsFilename != null) {
                    filesToDelete.add(this.gcsFilename);
                    this.gcsFilename = null;
                }

                final Iterator iterator = filesToDelete.iterator();

                while(iterator.hasNext()) {
                    GcsFilename filename = (GcsFilename)iterator.next();
                    try {
                        if (gcsService.delete(filename)) {
                            iterator.remove();
                        }
                    } catch (final IOException ex) {
                        log.error(ex.getMessage(), ex);
                    }
                }

            }
        }
    }

    private static final class GcsStorageOutputStream extends StorageOutputStream {

        private final GcsService gcsService;

        private GcsFilename gcsFilename;

        private final OutputStream outputStream;

        public GcsStorageOutputStream(final GcsService gcsService, final String bucketName) throws IOException {
            this.gcsService = gcsService;

            final String fileName = UUID.randomUUID().toString();
            this.gcsFilename = new GcsFilename(bucketName, fileName);

            GcsOutputChannel gcsOutputChannel = gcsService.createOrReplace(gcsFilename, gcsFileOpts);
            this.outputStream = Channels.newOutputStream(gcsOutputChannel);
        }

        @Override
        protected void write0(byte[] buffer, int offset, int length) throws IOException {
            this.outputStream.write(buffer, offset, length);
        }

        @Override
        protected Storage toStorage0() throws IOException {
            return new GcsStorage(gcsService, gcsFilename);
        }

        @Override
        public void close() throws IOException {
            super.close();
            this.outputStream.close();
        }
    }
}
安静被遗忘 2024-10-22 05:28:34

我刚刚将resteasy-multipart-provider jar从 2.2.0.GA 升级到 3.1.4.Final 。
我们必须显式调用 close 方法。它将负责删除 m4jxxxx.tmp 文件。

请参阅@docs http:// docs.jboss.org/resteasy/docs/3.1.4.Final/userguide/html_single/index.html

package org.jboss.resteasy.plugins.providers.multipart;
public interface MultipartInput {
List<InputPart> getParts();
String getPreamble();
// You must call close to delete any temporary files created
// Otherwise they will be deleted on garbage collection or on JVM exit
void close();
}

I just upgraded resteasy-multipart-provider jar from 2.2.0.GA to 3.1.4.Final .
We have to call close method explicitly . It will take care of deleting m4jxxxx.tmp files.

see @docs http://docs.jboss.org/resteasy/docs/3.1.4.Final/userguide/html_single/index.html

package org.jboss.resteasy.plugins.providers.multipart;
public interface MultipartInput {
List<InputPart> getParts();
String getPreamble();
// You must call close to delete any temporary files created
// Otherwise they will be deleted on garbage collection or on JVM exit
void close();
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文