ServletFileUpload # parseRequest (запрос) возвращает пустой список
У меня есть клиентское приложение на Android, которое использует HttpURLConnection
для отправки файлов на сервер. Сервер использует API Apache Commons FileUpload для анализа значений форм-данных.
HttpURLConnection
отправляет этот запрос:
-----------------------------4912995119421
Content-Disposition: form-data; name="deviceid"
9428103
-----------------------------4912995119421
Content-Disposition: form-data; name="countryid"
598
-----------------------------4912995119421
Content-Disposition: form-data; name="number"
98621360
-----------------------------4912995119421
Content-Disposition: form-data; name="file"; filename="2012-12-08 17.42.18.jpg"
Content-Type: image/jpeg
ÿØÿá1 Exif II*
@ ° ª
² ¼ Ä ( 1 Ì 2 Ø i‡ ì %ˆ \ n SAMSUNG GT-S5360L H H S5360LUHLB1 2012:12:08 17:42:18 š‚ î ?‚ ö "ˆ 'ˆ È ? 0220? þ ? ‘ ’ & ’
’ . 0100 @ ° > £ ¤ ¤ ¤ 6 ¤
2012:12:08 17:42:18 2012:12:08 17:42:18
d R98 0100 ( ¤ T. ÿØÿà JFIF ÿÛ C @@ÿÛ
-----------------------------4912995119421--
Код сервера:
String contentType = request.getContentType();
if ((contentType.indexOf("multipart/form-data") == -1)) {
response.setStatus(HttpServletResponse.SC_NOT_FOUND);
return;
}
long maxFileSize = (2 * 1024 * 1024);
int maxMemSize = (2 * 1024 * 1024);
DiskFileItemFactory factory = new DiskFileItemFactory();
// maximum size that will be stored in memory
factory.setSizeThreshold(maxMemSize);
// Create a new file upload handler
ServletFileUpload upload = new ServletFileUpload(factory);
// maximum file size to be uploaded.
upload.setSizeMax(maxFileSize);
List fileItems = upload.parseRequest(request);
Iterator i = fileItems.iterator();
//leo primero todas las variables.
int deviceID = 0;
int countryID = 0;
String phoneNumber = "";
while (i.hasNext()) {
FileItem fi = (FileItem) i.next();
if (fi.isFormField()) {
String variable = fi.getFieldName();
if (variable.equals("deviceid")) {
deviceID = Integer.parseInt(fi.getString());
} else if (variable.equals("countryid")) {
countryID = Integer.parseInt(fi.getString());
} else if (variable.equals("number")) {
phoneNumber = String.valueOf(Long.parseLong(fi.getString()));
}
}
}
if (deviceID == 0 || countryID == 0 || phoneNumber.equals("")) {
response.setStatus(HttpServletResponse.SC_NOT_FOUND);
return;
}
Проблема находится в строке List fileItems = upload.parseRequest(request);
.
Возвращенный список пуст, и я не могу получить значения данных формы.
Ответы
Ответ 1
Он будет пуст в этой точке, если вы уже (неявно) проанализировали тело запроса заранее. Тело запроса HTTP может быть прочитано/проанализировано только один раз (поскольку клиент отправил его только один раз и не будет отправлять его несколько раз).
Тело запроса будет неявно прочитано/проанализировано, если вы вызывали какой-либо из следующих методов перед подачей запроса в Commons FileUpload:
request.getParameter();
request.getParameterMap();
request.getParameterNames();
request.getParameterValues();
request.getReader();
request.getInputStream();
Вам нужно обязательно убедиться, что вы не вызываете какие-либо из этих методов заранее (также проверяйте все фильтры сервлетов).
Если вы уже убедились, что не делаете этого, единственными возможными причинами могут быть неправильный заголовок границы и/или использование неправильных строк перевода (на самом деле это CR + LF и, следовательно, не один LF), Вы можете найти конкретный и правильный пример внизу Использование java.net.URLConnection для запуска и обработки HTTP-запросов в разделе "Загрузка файлов".
Ответ 2
У меня возникла такая же проблема после попытки найти, что это была несовместимость библиотек, библиотека Apache-сервера с библиотекой файлов, поэтому я удаляю библиотеку и импортирую ее с серверного сервера Apache.
imports:
import org.apache.tomcat.util.http.fileupload.FileItem;
import org.apache.tomcat.util.http.fileupload.disk.DiskFileItemFactory;
import org.apache.tomcat.util.http.fileupload.servlet.ServletFileUpload;
извините мой английский
Ответ 3
Если используется spring, проверьте, есть ли в xml файле. Существует функция
protected HttpServletRequest checkMultipart(HttpServletRequest request) throws MultipartException {
if (this.multipartResolver != null && this.multipartResolver.isMultipart(request)) {
if (request instanceof MultipartHttpServletRequest) {
logger.debug("Request is already a MultipartHttpServletRequest - if not in a forward, " +
"this typically results from an additional MultipartFilter in web.xml");
}
else {
return this.multipartResolver.resolveMultipart(request);
}
}
// If not returned before: return original request.
return request;
}
"ест" многочастные элементы. Это вызывает боль в течение трех часов.
Ответ 4
Я тоже сталкивался с этой проблемой, но я не мог найти ничего, что конкретно связано с чтением объекта запроса. Я, наконец, получил его для работы, удалив этот блок:
@MultipartConfig(
location="/tmp",
fileSizeThreshold=1024*1024,
maxFileSize=1024*1024*5,
maxRequestSize=1024*1024*5*5
)
По-видимому, когда я пытался прочитать запрос с помощью getParts(), я забыл удалить это. Я немного новичок в java, поэтому я не знал, что это конфликтует с ServletFileUpload # parseRequest. Во всяком случае, как только я избавился от него, parseRequest правильно вернул массив.
Ответ 5
моя проблема - apache context.xml на моем Linux-сервере содержит контекст
allowCasualMultipartParsing="true"
и мой HttpServlet содержит
@MultipartConfig(fileSizeThreshold=1024*1024*2,maxFileSize=1024*1024*50,maxRequestSize=1024*1024*50)
Я удаляю его, тогда он работает правильно. Надеюсь, что это поможет вам.