我有一个接收上传文件的servlet。我们一直遇到某个客户端请求没有附加文件或者servlet认为的问题。上传servlet是旧的servlet的替代品,我们正在使用Apache Commons FileUpload库来解析请求中的文件。旧代码使用JavaZoom库。请求客户端我们在旧代码中完全没问题。
为了解决这个问题,我添加了一堆日志来查看请求标头和部分,以比较来自客户端的请求,该客户端不使用。这是我如何看待这些部分的片段:
Collection<Part> parts = request.getParts();
for(Part part : parts)
{
String partName = part.getName();
log.debug("Part=" + partName);
Collection<String> headerNames = part.getHeaderNames();
for(String headerName : headerNames)
{
String headerValue = part.getHeader(headerName);
log.debug(headerName + "=" + headerValue);
InputStream inputStream = part.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
StringBuilder builder = new StringBuilder();
try
{
for(String line=bufferedReader.readLine(); line!=null; line=bufferedReader.readLine())
{
builder.append(line);
builder.append('\n');
}
}
catch (IOException ignore)
{
// empty
}
finally
{
inputStream.reset();
}
log.debug("InputStream=" + builder.toString());
}
}
所有这些代码都运行正常,我得到了我期待的日志记录。但是,下一段代码没有按预期运行:
if (isMultipart)
{
// Create a factory for disk-based file items
FileItemFactory factory = new DiskFileItemFactory();
// Create a new file upload handler
ServletFileUpload upload = new ServletFileUpload(factory);
@SuppressWarnings("rawtypes")
List items = null;
// Parse the request
try
{
items = upload.parseRequest(request);
log.debug("items=" + items);
}
catch (FileUploadException ex)
{
log.warn("Error parsing request", ex);
response.sendError(HttpServletResponse.SC_BAD_REQUEST, ex.getMessage());
}
items
变量在记录时为空。如果我注释掉用于记录请求部分的代码,则这段代码可以工作,items
变量包含上传的文件。
我只能假设从请求获取/读取部分的行为以某种方式将它们从中移除并且不再可用于进一步处理。是否有某种方法可以将它们用于记录目的,并仍然将它们保留在请求中进行进一步处理?
答案 0 :(得分:2)
Collection<Part> parts = request.getParts();
是一个Sevlet 3.0 API,它取代了Commons Apache File Upload API
。
您应该只使用这两种方法中的一种。两者都支持处理上传的文件和参数。
以下是File Upload Using Servlet 3.0
的示例您遇到的问题是因为您正在调用此Collection<Part> parts = request.getParts();
请求将使用请求输入流。然后您使用Apache Commons API再次读取部件。由于已经读取了流,因此您看不到任何部件可用。
Servlet 3.0文件上传参考: