【发布时间】:2012-12-26 18:45:30
【问题描述】:
我使用 Servlet 3 @MultiPartConfig 注释在我的应用程序中实现文件上传。我需要在运行时设置 multipart-config 位置参数(不是注释参数中的硬编码)。是否有任何 API 用于以编程方式访问 servlet 的 multipart-config?
谢谢
【问题讨论】:
标签: java jakarta-ee multipartform-data servlet-3.0
我使用 Servlet 3 @MultiPartConfig 注释在我的应用程序中实现文件上传。我需要在运行时设置 multipart-config 位置参数(不是注释参数中的硬编码)。是否有任何 API 用于以编程方式访问 servlet 的 multipart-config?
谢谢
【问题讨论】:
标签: java jakarta-ee multipartform-data servlet-3.0
@MultiPartConfig 实际上只是容器的标记接口。当 servlet 初始化时,提供的注释值通过代理对象映射到它。当传入的请求是 multipart/form-data 时,上传的部分将映射到请求,并且容器根据注释中的值和请求中的部分执行必要的工作。您无法拦截此过程,因为这一切都发生在容器的内部。但是,还有一种选择。它需要第二次执行文件系统操作。由于您拥有所有部分,因此您可以重建文件并将其“重新上传”到您选择的位置。它可能看起来像下面的方法。请记住,尽管我在自己的 servlet 中对此进行了快速测试以演示概念,但显然还没有完成代码:
@Override
protected void doPost(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse)
throws ServletException, IOException {
httpServletResponse.setContentType("text/html");
PrintWriter printWriter = httpServletResponse.getWriter();
InputStream inputStream;
FileOutputStream fileOutputStream;
for (Part part : httpServletRequest.getParts()) {
inputStream = httpServletRequest.getPart(part.getName()).getInputStream();
int i = inputStream.available();
byte[] b = new byte[i];
inputStream.read(b);
String fileName = "";
for (String temp : part.getHeader("content-disposition").split(";")) {
if (temp.trim().startsWith("filename")) {
fileName = temp.substring(temp.indexOf('=') + 1).trim().replace("\"", "");
}
}
String uploadDir = "/temp";
fileOutputStream = new FileOutputStream(uploadDir + "/" + fileName);
fileOutputStream.write(b);
inputStream.close();
fileOutputStream.close();
printWriter.write("Uploaded file " + uploadDir + "/" + fileName + ".");
}
}
【讨论】:
我也遇到了同样的问题,解决方案很简单:标准 Servlet 3.0 文件上传是不够的:只需从 Apache FileUpload Commons 获取 jar 即可完成
看看这个带有 Streaming API 的清晰示例
ServletFileUpload upload = new ServletFileUpload();
// Parse the request
FileItemIterator iter = upload.getItemIterator(request);
while (iter.hasNext()) {
FileItemStream item = iter.next();
String name = item.getFieldName();
InputStream stream = item.openStream();
if ( item.isFormField() == false)
System.out.println("File field " + name + " with file name "
+ item.getName() + " detected.");
FileOutputStream fos = new FileOutputStream("your_location");
Streams.copy ( stream, fos, true);
}
}
【讨论】: