2

我正在使用 saaj 通过我的 java servlet(由 apache 和 tomcat 托管)获取附件。

尝试调用时message.getAttachments();(其中 message 是 SOAPMessage 对象):

  • 如果附件很小(几 KB) - 它可以工作

  • 如果附件很大(几 MB) - 它会引发以下异常:

     java.lang.RuntimeException: org.jvnet.mimepull.MIMEParsingException: java.io.IOException: The system cannot find the path specified
        at com.sun.xml.messaging.saaj.soap.MessageImpl.getAttachments(MessageImpl.java:826)
        at MyCode.MyServlet.doPost(MyServlet.java:215)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:710)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:263)
        at org.apache.jk.server.JkCoyoteHandler.invoke(JkCoyoteHandler.java:190)
        at org.apache.jk.common.HandlerRequest.invoke(HandlerRequest.java:283)
        at org.apache.jk.common.ChannelSocket.invoke(ChannelSocket.java:767)
        at org.apache.jk.common.ChannelSocket.processConnection(ChannelSocket.java:697)
        at org.apache.jk.common.ChannelSocket$SocketConnection.runIt(ChannelSocket.java:889)
        at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:690)
        at java.lang.Thread.run(Unknown Source)
    Caused by: org.jvnet.mimepull.MIMEParsingException: java.io.IOException: The system cannot find the path specified
        at org.jvnet.mimepull.MemoryData.createNext(MemoryData.java:93)
        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.xml.messaging.saaj.packaging.mime.internet.MimePullMultipart.parseAll(MimePullMultipart.java:118)
        at com.sun.xml.messaging.saaj.packaging.mime.internet.MimePullMultipart.parse(MimePullMultipart.java:129)
        at com.sun.xml.messaging.saaj.packaging.mime.internet.MimeMultipart.getCount(MimeMultipart.java:199)
        at com.sun.xml.messaging.saaj.soap.MessageImpl.initializeAllAttachments(MessageImpl.java:1384)
        at com.sun.xml.messaging.saaj.soap.MessageImpl.getAttachments(MessageImpl.java:824)
        ... 22 more
    Caused by: java.io.IOException: The system cannot find the path specified
        at java.io.WinNTFileSystem.createFileExclusively(Native Method)
        at java.io.File.createTempFile(Unknown Source)
        at java.io.File.createTempFile(Unknown Source)
        at org.jvnet.mimepull.MemoryData.createNext(MemoryData.java:87)
        ... 33 more
    

我该如何解决这个问题?

谢谢!

4

2 回答 2

2

产生异常的 MimePull 的源代码是这样说的:

if (!config.isOnlyMemory() && dataHead.inMemory >= config.memoryThreshold) {
         try {
             String prefix = config.getTempFilePrefix();
             String suffix = config.getTempFileSuffix();
             File dir = config.getTempDir();
             File tempFile = (dir == null)
                     ? File.createTempFile(prefix, suffix) // here your code crashes
                     : File.createTempFile(prefix, suffix, dir);
             LOGGER.fine("Created temp file = "+tempFile);
             dataHead.dataFile = new DataFile(tempFile);
         } catch(IOException ioe) {
             throw new MIMEParsingException(ioe);
         }

它尝试打开一个临时文件,因为已超过内存大小阈值。
它被称为

at MyCode.MyServlet.doPost(MyServlet.java:215)

看起来您正在使用 SAAJ 接收消息并启用了 MimePull 插件(使用-Dsaaj.use.mimepull=true标志)。它应该允许接收更大的文件,因为 MimePull 实现使用临时文件作为后备。

现在似乎坏消息是,您无法通过您的 SAAJ 配置来配置 MimePull 阅读器。好消息可能是您可以File.createTempFile(...)通过系统属性调整逻辑java.io.tmpdir

尝试从-Djava.io.tmpdir=/path/to/tmpdir.

否则可能会尝试使用MimePull直接使用消息,我自己从来没有这样做过,所以不要问我这个问题。;-)

编辑:或者如果您不希望附件吸收所有内存,则
通过设置完全关闭 MimePull 。-Dsaaj.use.mimepull=false

于 2012-12-20T13:42:50.380 回答
0

我们通过将 Jersey-Libs 版本从 1.13 更改为 1.19 解决了这个问题。看来1.13有问题。

于 2015-06-08T06:29:03.747 回答