[英]Java Servlet JSP delete file using apache commons FileUpload
[英]Apache Commons fileUpload problem in java servlet
我尝试使用 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
谢谢
从堆栈跟踪中可以明显看出,您在类的第 156 行取消引用的项目之一为空。 尽管我们在提供的代码段中没有行号,但看起来这仅在upload.parseRequest
行(您自己也将其确定为失败部分)上才真正可能。
奇怪的是,这似乎只有在upload
为空时才会发生 - 但从您给出的代码来看,这似乎是不可能的,因为它从构造函数中分配了一个非空值,仅几行就可以了,从那时起就发生了变化。
如果您可以附加调试器,那么逐步执行您的方法并检查对象值将是一个好主意。 否则,可能值得在该点之前放置一些 println 语句来验证哪些对象是空的,哪些是非空的。
消息The log message is null
表示它正在抱怨以下内容:
log(Level.SEVERE, null, ex);
更好地使用:
log(Level.SEVERE, "Failed to parse upload request", ex);
我会推断upload
在那时以某种方式为空。 您确定您提供的源代码和编译后的类文件是同一版本(例如,错误行指向不同的指令)?
我想您可以使用 IDE 调试您的应用程序并为 NullPointerException 创建断点。
更新:您能否展示一下内部 catch 块之后是什么? 你用list
做什么? 我猜您忘记了如果没有上传文件并且您只是开始对其进行迭代,该列表可能会保持为空?
我怀疑记录器正在抛出 NullPointerException 因为震惊“日志消息为空”。
Logger.getLogger(...).log(Level.SEVERE, >>>null<<<, ex);
Log4J 处理程序之一(Glassfish 处理程序)正在优雅地处理空消息并打印“日志消息为空”,但其他一些 Log4J 处理程序也没有处理这种情况并抛出 NullPointerException。
这可以解释为什么您的堆栈跟踪是关于 NullPointerException 而不是关于您正在捕获的 FileUploadException。 我无法解释为什么 NullPointerException 堆栈跟踪的顶部是您的代码 (ProcessUploadItem.java:156),而不是获取堆栈帧的 Throwable 代码有时会被愚弄。
无论如何,我认为问题的关键, FileUploadException ex ,一旦 NullPointerException 触发就会丢失,因此没有关于导致您进入 catch 块的调试信息。
将正确的日志消息传递给记录器和/或 FileUploadException 以打印其消息和堆栈跟踪以进一步进行。
您粘贴的语法无效。 你有一个悬空的 try 块,没有捕获或 finally ......我会错误地在此处粘贴更多信息而不是更少......粘贴整个方法并在第 156 行添加注释以表明它是哪个。
正如其他人所提到的,堆栈跟踪是您方法中某处的空引用。 您尝试访问的对象之一(成员变量或使用.
运算符的方法)为空。 我们可以从您的堆栈跟踪中推断出这一点,但没有意义的是您粘贴的代码。 我们需要更多来帮助解决这个问题。
此外,在介绍 servlet 和日志 API 的复杂性之前,我会编写一个单元测试来学习如何使用这个 API。
您可以通过查看他们的Test Suite来了解他们如何测试 FileUpload API。 您可以重用他们的MockHttpServletRequest (尽管这确实是一个假对象,而不是模拟对象)进行类似的测试。
注意:您可能希望返回并查看与 FileUpload jar 版本匹配的这些文件的版本。
要调试,这是我要做的:
我会在堆栈跟踪顶部的方法中的第一行断点,并在逐步执行这些方法时查看本地监视变量。 一旦您找到并摆脱了NullPointerException
,请附加 FileUpload 源并进入它以确保您在此之后碰巧遇到不同的 FileUpload 特定异常时实际输入了该代码。
祝你好运!
问题不完整。
您使用的是哪个版本的 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>
在阅读DiskFileItemFactory
的文档时,我注意到当一个文件被上传时,它会临时保存在系统的某个地方,默认目录是System.getProperty("java.io.tmpdir")
返回的 Temp 目录。 你确定你有权限写入这个目录,如果没有,你可以通过调用factory.setRepository(java.io.File yourDir)
来设置一个新的存储库/目录。
不确定这是否会有所帮助,但这只是一个建议。
要么上载在 processRequest 行上为空,要么您误算了行数。 你还没有发布整个方法,所以我们都只是猜测。
如果 processRequest 调用实际上与上传实例化那么接近,我猜你有某种后处理。 您正在编辑的代码可能不是您正在编译的代码。
你的表单提交是什么样的? 上面的代码看起来不错,并且反映了我所拥有的。
检查您的表单提交是否属于“多部分”类型,因此:
boolean isMultipart = ServletFileUpload.isMultipartContent(request);
在客户端,您需要将表单编码设置为 multipart。 请参阅RFC1867 。
另请注意,如果在调用parseRequest()
之前以任何方式处理/读取了请求数据,则parseRequest()
将返回 null(请参阅 Apache Commons File Upload FAQ)
当你说“and it failed at files = upload.parseRequest(request)”时,你需要指定更多信息。 反正我会尽量回答你的问题。
查看 javadoc,您正在创建一个未初始化的 DiskFileItemFactory 对象。 您需要指定要存储文件的目录。 调用 setRepository() 或通过调用 DiskFileItemFactory(int, File) 创建您的工厂
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.