java servlet 中的 Apache Commons fileUpload 问题
我尝试使用 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
谢谢
I tried doing this with 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);
}
}
and it failed at files = upload.parseRequest(request);
any pointers?
sorry and thank you :)
Sorry I hadn't included these:
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)
I'm using Glassfish
Thank you
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(10)
从堆栈跟踪中可以清楚地看出,您在类的第 156 行取消引用的项目之一为 null。 尽管我们在提供的代码片段中没有行号,但看起来这只有在
upload.parseRequest
行上才可能实现(您自己也已将其识别为失败部分)。奇怪的是,看起来只有当
upload
为 null 时才会发生这种情况 - 但从您给出的代码来看,这似乎是不可能的,因为它从构造函数中分配了一个非空值,仅几行,现在已更改自那以后。如果您可以附加调试器,那么单步执行您的方法并检查对象值将是一个好主意。 否则,可能值得在该点之前放置一些 println 语句来验证哪些对象为空,哪些对象为非空。
From the stacktrace it's clear that one of the items that you dereference on line 156 of your class is null. Although we don't have line numbers in the snippet provided, it looks like this is only really possible on the
upload.parseRequest
line (which you yourself have also identified as the failing part).Strangely enough it looks like this can only happen if
upload
is null - but from the code you have given this seems impossible since it's assigned a non-null value from a constructor just a few lines up and now changed since then.If you can attach a debugger then stepping through your method and inspecting the object values would be a good idea. Otherwise, it might be worth putting a few println statements in just before that point to verify what objects are null and which are non-null.
消息
The log message is null
表示它抱怨以下内容:最好使用:
The message
The log message is null
indicates it is complaining about the following:Better to use:
我会推断此时
upload
在某种程度上是空的。 您确定您提供的源代码和编译的类文件是相同的版本(例如错误行指向不同的指令)?我想您可以使用 IDE 调试应用程序并为 NullPointerException 创建断点。
更新:
您能显示一下内部 catch 块之后是什么吗? 你用
list
做什么? 我猜您忘记了如果没有上传文件并且您刚刚开始迭代它,列表可能会保持为空?I would infer that
upload
is somehow null at that point. Are you sure that the source you gave and the compiled class file are the same version (e.g. the error line points to a different instruction)?I guess you could debug your application with an IDE and create a breakpoint for NullPointerException.
Update:
Could you please show what is after the inner catch block? What do you do with
list
? I guess you forgot that list might remain null if there is no file uploaded and you just start to iterate over it?我怀疑记录器抛出 NullPointerException 因为震惊“日志消息为空”。
其中一个 Log4J 处理程序(Glassfish 处理程序)正在优雅地处理 null 消息并打印“日志消息为 null”,但其他一些 Log4J 处理程序也没有处理这种情况并引发 NullPointerException。
这可以解释为什么您的堆栈跟踪是关于 NullPointerException 而不是您正在捕获的 FileUploadException。 我无法解释为什么 NullPointerException 堆栈跟踪的顶部是您的代码 (ProcessUploadItem.java:156),而不是获取堆栈帧的 Throwable 代码有时可能会被欺骗。
无论如何,我认为问题的关键是,一旦 NullPointerException 触发,FileUploadException ex 就会丢失,因此没有关于导致您进入 catch 块的调试信息。
将正确的日志消息传递给记录器和/或 FileUploadException 以打印其消息和堆栈跟踪以进一步继续。
I suspect that logger is throwing NullPointerException because shock "the log message is null".
One of the Log4J handlers (the Glassfish one) is handling the null message gracefully and printing the "The log message is null", but some other Log4J handler isn't handling the situation as well and throwing a NullPointerException.
This may explain why your stack traces are about a NullPointerException rather than about the FileUploadException that you are catching. I can't explain why the top of the NullPointerException stack trace is your code (ProcessUploadItem.java:156) other than the Throwable code that gets the stack frames can be fooled sometimes.
Regardless, I think the key to the problem, the FileUploadException ex, is getting lost as soon as the NullPointerException triggers, so there is no debug info on what's causing you to enter the catch block.
Pass a proper log message to the logger and/or the FileUploadException to print its message and stack trace to proceed further.
首先 - 粘贴更多!
您粘贴的语法无效。 你有一个悬空的 try 块,没有 catch 或 finally...我宁愿在这里粘贴更多的信息而不是更少的信息...粘贴整个方法并在第 156 行添加注释以表明它是什么。
NPE 是什么意思?
正如其他人所提到的,堆栈跟踪是方法中某处的空取消引用。 您尝试访问的对象之一(成员变量或使用
.
运算符的方法)为 null。 我们可以从您的堆栈跟踪中推断出这一点,但没有意义的是您粘贴的代码。 我们需要更多的东西来帮助解决这个问题。编写一个单元测试来找出 API 调用
另外,在介绍 servlet 和日志记录 API 的复杂性之前,我会编写一个单元测试来了解如何使用此 API。
您可以通过查看他们的测试套件了解他们如何测试 FileUpload API。 您可以重用他们的 MockHttpServletRequest(尽管这实际上是一个假对象,而不是模拟对象)用于类似的测试。
注意:您可能需要向后浏览并查看与 FileUpload jar 版本匹配的这些文件的版本。
调试指针
要进行调试,我将执行以下操作:
在堆栈跟踪顶部的方法中的第一行设置断点,并在单步执行这些方法时查看本地监视变量。 找到并消除 NullPointerException 后,附加 FileUpload 源并进入其中,以确保您在之后碰巧遇到不同的 FileUpload 特定异常时确实输入了该代码。
祝你好运!
First - paste more!
The syntax you've pasted is invalid. You have a dangling try block with no catch or finally... I'd err on the side of pasting more information in here than less... Paste the entire method and put a comment on line 156 to indicate which it is.
What does the NPE mean?
As others have mentioned, the stacktrace is a null dereference from within your method somewhere. One of the objects you've tried to access something on (either a member variable or method using the
.
operator) is null. We can deduce this from your stack trace, but what doesn't make sense is the code you've pasted with it. We need more to be able to help figure it out.Write a unit test to figure out the API calls
Also, I would write a unit test to learn how to work with this API before introducing the complexity of the servlet and logging APIs.
You can see how they tested the FileUpload API by looking at their Test Suite. You can reuse their MockHttpServletRequest (though this is really a fake object, not a mock object) for similar testing.
Note: you may want to browse back and look at versions of these files that match the version of your FileUpload jar.
Debugging pointers
To debug, here's what I'd do:
I'd breakpoint the first line in the method at the top of your stacktrace and take a look at the local watch variables as I step through the methods. Once you find and get rid of the
NullPointerException
, attach the FileUpload source and step into it to make sure you're actually entering that code if you happen to get a different FileUpload specific exception after that.Good luck!
您提交的表单是什么样的? 上面的代码看起来不错,并且反映了我所拥有的。
检查您的表单提交是否为“multipart”类型:
在客户端,您需要将表单编码设置为 multipart。 请参阅 RFC1867。
另请注意,如果在调用
parseRequest()
之前已以任何方式处理/读取请求数据,则parseRequest()
将返回 null(请参阅 Apache Commons 文件上传常见问题解答) )What does your form submission look like ? The above code looks good, and mirrors what I have.
Check your form submission is of the type 'multipart' thus:
On the client side, you need to set the form encoding to multipart. See RFC1867.
Note also that
parseRequest()
will return null if the request data has been processed/read in any fashion prior toparseRequest()
being called (see the Apache Commons File Upload FAQ)问题不完整。
您使用的是哪个版本的 commons-upload?
您的表单使用 multipart/form-data MIME 类型作为编码类型?
这里有一个例子:
The question is incomplet.
Which version of commons-upload are you using?
Your form is using multipart/form-data MIME type as encoding type?
Here an example:
在阅读 DiskFileItemFactory 的文档时,我注意到上传文件时,它会临时保存在系统上的某个位置,默认目录是 System.getProperty(" 返回的 Temp 目录) java.io.tmpdir")。 您确定您有权限写入此目录吗?如果没有,您可以通过调用factory.setRepository(java.io.File yourDir)来设置新的存储库/目录。
不确定这是否有帮助,但这只是一个建议。
When reading the documentation for
DiskFileItemFactory
I noticed that when a file is uploaded it is saved temporarily somewhere on the system and the default directory for that is the Temp directory as returned bySystem.getProperty("java.io.tmpdir")
. Are you sure you have the permissions to write to this directory and if not maybe you can set a new repository/directory by callingfactory.setRepository(java.io.File yourDir)
.Not sure if this would help but it's just a suggestion.
processRequest 行上的 upload 为空,或者您错误地计算了行数。 您还没有发布完整的方法,所以我们都只是猜测。
如果 processRequest 调用实际上非常接近上传实例化,我的猜测是您进行了某种后处理。 您正在编辑的代码可能不是您正在编译的代码。
Either upload is null on the processRequest line or you've miscounted the lines. You haven't posted the entire method, so we're all just guessing.
If the processRequest call is actually that close to the upload instantiation, my guess is you have some kind of post-processing. The code you are editing might not be the code you're compiling.
当您说“and it failed at files = upload.parseRequest(request)”时,您需要指定更多信息。 无论如何,我会尽力回答你的问题。
查看 javadoc,您正在创建一个未初始化的 DiskFileItemFactory 对象。 您需要指定要存储文件的目录。 调用 setRepository() 或通过调用 DiskFileItemFactory(int, File) 创建工厂
You need to specify some more information when you say 'and it failed at files = upload.parseRequest(request)'. I'll take a stab at answering your question anyway.
Looking at the javadoc, you are creating an uninitialized DiskFileItemFactory object. You need to specify the directory where you want to store files. Either call setRepository() or create your factory by calling DiskFileItemFactory(int, File)