1

我尝试使用 Apache Commons FileUpload 执行此操作:

protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException {

    PrintWriter out = null;

    try {

        response.setContentType("text/html;charset=UTF-8");
        //MultipartFormDataRequest dataRequest = new MultipartFormDataRequest(request);
        //get uploaded files
        FileItemFactory factory = new DiskFileItemFactory();
        // Create a new file upload handler
        ServletFileUpload upload = new ServletFileUpload(factory);
        List files = null;
        try {
            files = upload.parseRequest(request);
        } catch (FileUploadException ex) {
            Logger.getLogger(ProcessUploadItem.class.getName()).log(Level.SEVERE, null, ex);
    }
}

它失败了files = upload.parseRequest(request);

任何指针?

对不起,谢谢你:)

对不起,我没有包括这些:

The log message is null.
java.lang.NullPointerException
    at web.ProcessUploadItem.processRequest(ProcessUploadItem.java:156)
    at web.ProcessUploadItem.doPost(ProcessUploadItem.java:193)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:738)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:831)
    at org.apache.catalina.core.ApplicationFilterChain.servletService(ApplicationFilterChain.java:411)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:290)
    at org.apache.catalina.core.StandardContextValve.invokeInternal(StandardContextValve.java:271)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:202)
    at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:632)
    at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:577)
    at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:94)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:206)
    at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:632)
    at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:577)
    at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:571)
    at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:1080)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:150)
    at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:632)
    at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:577)
    at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:571)
    at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:1080)
    at org.apache.coyote.tomcat5.CoyoteAdapter.service(CoyoteAdapter.java:272)
    at com.sun.enterprise.web.connector.grizzly.DefaultProcessorTask.invokeAdapter(DefaultProcessorTask.java:637)
    at com.sun.enterprise.web.connector.grizzly.DefaultProcessorTask.doProcess(DefaultProcessorTask.java:568)
    at com.sun.enterprise.web.connector.grizzly.DefaultProcessorTask.process(DefaultProcessorTask.java:813)
    at com.sun.enterprise.web.connector.grizzly.DefaultReadTask.executeProcessorTask(DefaultReadTask.java:341)
    at com.sun.enterprise.web.connector.grizzly.DefaultReadTask.doTask(DefaultReadTask.java:263)
    at com.sun.enterprise.web.connector.grizzly.DefaultReadTask.doTask(DefaultReadTask.java:214)
    at com.sun.enterprise.web.connector.grizzly.TaskBase.run(TaskBase.java:265)
    at com.sun.enterprise.web.connector.grizzly.ssl.SSLWorkerThread.run(SSLWorkerThread.java:106)
java.lang.NullPointerException
    at web.ProcessUploadItem.processRequest(ProcessUploadItem.java:156)
    at web.ProcessUploadItem.doPost(ProcessUploadItem.java:193)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:738)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:831)
    at org.apache.catalina.core.ApplicationFilterChain.servletService(ApplicationFilterChain.java:411)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:290)
    at org.apache.catalina.core.StandardContextValve.invokeInternal(StandardContextValve.java:271)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:202)
    at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:632)
    at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:577)
    at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:94)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:206)
    at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:632)
    at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:577)
    at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:571)
    at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:1080)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:150)
    at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:632)
    at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:577)
    at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:571)
    at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:1080)
    at org.apache.coyote.tomcat5.CoyoteAdapter.service(CoyoteAdapter.java:272)
    at com.sun.enterprise.web.connector.grizzly.DefaultProcessorTask.invokeAdapter(DefaultProcessorTask.java:637)
    at com.sun.enterprise.web.connector.grizzly.DefaultProcessorTask.doProcess(DefaultProcessorTask.java:568)
    at com.sun.enterprise.web.connector.grizzly.DefaultProcessorTask.process(DefaultProcessorTask.java:813)
    at com.sun.enterprise.web.connector.grizzly.DefaultReadTask.executeProcessorTask(DefaultReadTask.java:341)
    at com.sun.enterprise.web.connector.grizzly.DefaultReadTask.doTask(DefaultReadTask.java:263)
    at com.sun.enterprise.web.connector.grizzly.DefaultReadTask.doTask(DefaultReadTask.java:214)
    at com.sun.enterprise.web.connector.grizzly.TaskBase.run(TaskBase.java:265)
    at com.sun.enterprise.web.connector.grizzly.ssl.SSLWorkerThread.run(SSLWorkerThread.java:106)

我正在使用 Glassfish

谢谢

4

10 回答 10

2

从堆栈跟踪中可以清楚地看出,您在类的第 156 行取消引用的项目之一为空。尽管我们在提供的代码段中没有行号,但看起来这只有upload.parseRequest在线上才是真正可能的(您自己也将其确定为失败的部分)。

奇怪的是,这看起来只有在upload为 null 时才会发生 - 但从你给出的代码来看,这似乎是不可能的,因为它从构造函数中分配了一个非 null 值,只是几行之后,现在发生了变化。

如果您可以附加调试器,那么单步执行您的方法并检查对象值将是一个好主意。否则,可能值得在该点之前放入一些 println 语句来验证哪些对象是空的,哪些是非空的。

于 2009-06-17T10:37:49.523 回答
2

该消息The log message is null表明它正在抱怨以下内容:

log(Level.SEVERE, null, ex);

更好地使用:

log(Level.SEVERE, "Failed to parse upload request", ex);
于 2009-06-21T06:59:49.877 回答
1

我会推断那upload在某种程度上是空的。您确定您提供的源代码和编译的类文件是相同的版本(例如错误行指向不同的指令)吗?

我想您可以使用 IDE 调试您的应用程序并为 NullPointerException 创建一个断点。

更新: 您能否展示一下内部 catch 块之后的内容?你做什么list?我猜您忘记了如果没有上传文件并且您刚刚开始迭代它,该列表可能仍然为空?

于 2009-06-17T10:19:39.747 回答
1

我怀疑记录器抛出 NullPointerException 因为震惊“日志消息为空”。

Logger.getLogger(...).log(Level.SEVERE, >>>null<<<, ex);

Log4J 处理程序之一(Glassfish 处理程序)正在优雅地处理空消息并打印“日志消息为空”,但其他一些 Log4J 处理程序也没有处理这种情况并抛出 NullPointerException。

这可以解释为什么您的堆栈跟踪是关于 NullPointerException 而不是关于您正在捕获的 FileUploadException。我无法解释为什么 NullPointerException 堆栈跟踪的顶部是您的代码 (ProcessUploadItem.java:156),而不是获取堆栈帧的 Throwable 代码有时会被愚弄。

无论如何,我认为问题的关键,FileUploadException ex,一旦 NullPointerException 触发就会丢失,因此没有关于导致您进入 catch 块的调试信息。

将适当的日志消息传递给记录器和/或 FileUploadException 以打印其消息和堆栈跟踪以进一步进行。

于 2009-06-18T23:58:30.867 回答
1

首先 - 粘贴更多!

您粘贴的语法无效。你有一个悬空的try块,没有catch或finally...我宁愿在这里粘贴更多信息而不是less...粘贴整个方法并在第156行添加注释以指示它是哪个。

NPE 是什么意思?

正如其他人所提到的,堆栈跟踪是您方法中某处的空取消引用。您尝试访问的对象之一(成员变量或使用.运算符的方法)为空。我们可以从您的堆栈跟踪中推断出这一点,但没有意义的是您粘贴的代码。我们需要更多来帮助解决这个问题。

编写单元测试以找出 API 调用

另外,在介绍 servlet 和日志 API 的复杂性之前,我会编写一个单元测试来学习如何使用这个 API。

您可以通过查看他们的Test Suite来了解他们如何测试 FileUpload API 。您可以重用他们的MockHttpServletRequest(尽管这实际上是一个对象,而不是模拟对象)进行类似的测试。

注意:您可能需要返回并查看与您的 FileUpload jar 版本匹配的这些文件的版本。

调试指针

要调试,这就是我要做的:

我会在你的堆栈跟踪顶部的方法的第一行断点,并在我逐步执行这些方法时查看本地监视变量。一旦你找到并摆脱了NullPointerException,附加 FileUpload 源并进入它,以确保你确实输入了该代码,如果你碰巧在那之后得到一个不同的 FileUpload 特定异常。

祝你好运!

于 2009-06-19T21:31:56.160 回答
0

您提交的表单是什么样的?上面的代码看起来不错,并且反映了我所拥有的。

检查您的表单提交是否属于“多部分”类型,因此:

boolean isMultipart = ServletFileUpload.isMultipartContent(request);

在客户端,您需要将表单编码设置为多部分。请参阅RFC1867

另请注意,parseRequest()如果请求数据在parseRequest()被调用之前已以任何方式处理/读取,则将返回 null(请参阅 Apache Commons File Upload FAQ)

于 2009-06-05T13:02:51.323 回答
0

问题不完整。

您使用的是哪个版本的 commons-upload?您的表单使用multipart/form-data MIME 类型作为编码类型?

这里有一个例子:

<form action="/uploadServlet" enctype="multipart/form-data" method="post">
  <input type="file" name="file" size="40">
  <input type="submit" value="Send">
</form>
于 2009-06-17T10:18:51.403 回答
0

在阅读文档时,DiskFileItemFactory我注意到当一个文件被上传时,它会临时保存在系统的某个地方,默认目录是System.getProperty("java.io.tmpdir"). 你确定你有权限写入这个目录吗?如果没有,你可以通过调用来设置一个新的存储库/目录factory.setRepository(java.io.File yourDir)

不确定这是否会有所帮助,但这只是一个建议。

于 2009-06-17T21:31:20.107 回答
0

要么在 processRequest 行上上传为空,要么您数错了行数。你还没有发布整个方法,所以我们都只是猜测。

如果 processRequest 调用实际上接近于上传实例化,我猜你有某种后处理。您正在编辑的代码可能不是您正在编译的代码。

于 2009-06-23T12:29:24.787 回答
-1

当您说“文件失败 = upload.parseRequest(request)”时,您需要指定更多信息。无论如何,我会尽力回答你的问题。

查看 javadoc,您正在创建一个未初始化的 DiskFileItemFactory 对象。您需要指定要存储文件的目录。调用 setRepository() 或通过调用 DiskFileItemFactory(int, File) 创建工厂

于 2009-06-05T12:41:18.917 回答