Multipart POST 请求不包含上传的文件
Multipart POST request doesn't contain the file uploaded
我想用拖放文件上传功能扩展现有的应用程序。该应用程序基于 Jetty + Wicket 构建。 DropzoneJS 似乎是个不错的选择。 Dropzone 提供所有前端工作,我只需要将它连接到后端即可。
事实证明,说起来容易做起来难。首先,我使用 Wicket quickstart 创建了一个测试应用程序。我将 dropzone 添加到主页:
<!DOCTYPE html>
<html>
<head>
<script src="https://rawgit.com/enyo/dropzone/master/dist/dropzone.js"></script>
<link rel="stylesheet" href="https://rawgit.com/enyo/dropzone/master/dist/dropzone.css">
</head>
<body>
<form action="/upload" class="dropzone"></form>
</body>
</html>
Dropzone 仅包含在其存储库中。在服务器上,我在 /upload:
安装了一个资源引用
public class FileUploadResourceReference extends ResourceReference
{
public FileUploadResourceReference(String name)
{
super(FileUploadResourceReference.class, name);
}
@Override
public IResource getResource()
{
return new FileUploadResource();
}
}
FileUploadResource 将处理上传文件:
public class FileUploadResource extends AbstractResource
{
@Override
protected ResourceResponse newResourceResponse(Attributes attributes)
{
ServletWebRequest request = (ServletWebRequest) attributes.getRequest();
try
{
MultipartServletWebRequest multipartRequest = request
.newMultipartWebRequest(Bytes.megabytes(100), "ignored");
Map<String, List<FileItem>> files = multipartRequest.getFiles();
List<FileItem> fileItems = files.get("file");
for (FileItem fileItem : fileItems)
{
saveFile(fileItem);
}
}
catch (FileUploadException e)
{
e.printStackTrace();
}
return null;
}
private void saveFile(FileItem fileItem)
{
// not implemented
}
}
现在问题来了,上传文件时,Dropzone 向我的http://localhost:8080/upload 发送了一个POST-请求。该请求被识别为多部分请求,但文件参数不存在。进入for循环抛出空指针异常:
java.lang.NullPointerException
at com.test.FileUploadResource.newResourceResponse(FileUploadResource.java:31) ~[classes/:?]
at org.apache.wicket.request.resource.AbstractResource.respond(AbstractResource.java:629) ~[wicket-core-7.4.0.jar:7.4.0]
at org.apache.wicket.request.handler.resource.ResourceRequestHandler.respond(ResourceRequestHandler.java:105) ~[wicket-core-7.4.0.jar:7.4.0]
at org.apache.wicket.request.handler.resource.ResourceReferenceRequestHandler.respond(ResourceReferenceRequestHandler.java:108) ~[wicket-core-7.4.0.jar:7.4.0]
我不知道这里发生了什么。根据 Dropzone 网站,表单声明应该没问题。也许是 Dropzone 中的错误?似乎不太可能。一些拒绝多部分表单请求的 Jetty 配置参数?好像不太可能,至少我没听说过。
您可以在 GitHub.
上找到我的测试应用程序的完整源代码
您错过了一个方法调用 - multipartRequest.parseFileNames()。
您需要在#getFiles() 之前执行此操作。
见http://wicketinaction.com/2012/11/uploading-files-to-wicket-iresource/
我想用拖放文件上传功能扩展现有的应用程序。该应用程序基于 Jetty + Wicket 构建。 DropzoneJS 似乎是个不错的选择。 Dropzone 提供所有前端工作,我只需要将它连接到后端即可。
事实证明,说起来容易做起来难。首先,我使用 Wicket quickstart 创建了一个测试应用程序。我将 dropzone 添加到主页:
<!DOCTYPE html>
<html>
<head>
<script src="https://rawgit.com/enyo/dropzone/master/dist/dropzone.js"></script>
<link rel="stylesheet" href="https://rawgit.com/enyo/dropzone/master/dist/dropzone.css">
</head>
<body>
<form action="/upload" class="dropzone"></form>
</body>
</html>
Dropzone 仅包含在其存储库中。在服务器上,我在 /upload:
安装了一个资源引用public class FileUploadResourceReference extends ResourceReference
{
public FileUploadResourceReference(String name)
{
super(FileUploadResourceReference.class, name);
}
@Override
public IResource getResource()
{
return new FileUploadResource();
}
}
FileUploadResource 将处理上传文件:
public class FileUploadResource extends AbstractResource
{
@Override
protected ResourceResponse newResourceResponse(Attributes attributes)
{
ServletWebRequest request = (ServletWebRequest) attributes.getRequest();
try
{
MultipartServletWebRequest multipartRequest = request
.newMultipartWebRequest(Bytes.megabytes(100), "ignored");
Map<String, List<FileItem>> files = multipartRequest.getFiles();
List<FileItem> fileItems = files.get("file");
for (FileItem fileItem : fileItems)
{
saveFile(fileItem);
}
}
catch (FileUploadException e)
{
e.printStackTrace();
}
return null;
}
private void saveFile(FileItem fileItem)
{
// not implemented
}
}
现在问题来了,上传文件时,Dropzone 向我的http://localhost:8080/upload 发送了一个POST-请求。该请求被识别为多部分请求,但文件参数不存在。进入for循环抛出空指针异常:
java.lang.NullPointerException
at com.test.FileUploadResource.newResourceResponse(FileUploadResource.java:31) ~[classes/:?]
at org.apache.wicket.request.resource.AbstractResource.respond(AbstractResource.java:629) ~[wicket-core-7.4.0.jar:7.4.0]
at org.apache.wicket.request.handler.resource.ResourceRequestHandler.respond(ResourceRequestHandler.java:105) ~[wicket-core-7.4.0.jar:7.4.0]
at org.apache.wicket.request.handler.resource.ResourceReferenceRequestHandler.respond(ResourceReferenceRequestHandler.java:108) ~[wicket-core-7.4.0.jar:7.4.0]
我不知道这里发生了什么。根据 Dropzone 网站,表单声明应该没问题。也许是 Dropzone 中的错误?似乎不太可能。一些拒绝多部分表单请求的 Jetty 配置参数?好像不太可能,至少我没听说过。
您可以在 GitHub.
上找到我的测试应用程序的完整源代码您错过了一个方法调用 - multipartRequest.parseFileNames()。 您需要在#getFiles() 之前执行此操作。
见http://wicketinaction.com/2012/11/uploading-files-to-wicket-iresource/