Загрузить файл в PlayFramework с разными браузерами
-
27-09-2019 - |
Вопрос
Я использую PlayFramework, чтобы построить веб-сайт. И я также использую богатый редактор имени XHEDITOR.
XHEDITOR Поддержка Ajax-Fileuploading, ему нужна сторона сервера имеет действие, которое принимает параметр «FileData», который содержит файл загрузки.
Поэтому я написал действие загрузки:
public class Application extends Controller {
public static void upload(File filedata) {
// the filedata should not be null
renderText("{'err':'', 'msg':{'ur':'/uploaded/xxx.zip'}}");
}
}
Он работает нормально в IE6, FileData не является NULL и содержит правильные данные. Но, если я использую Chrome или Firefox, FileData нулевой!!
Я использую Firebug для мониторинга того, что Firebug отправляет, и обнаружил, что он отправляет такой заголовок:
content-disposition
attachment; name="filedata"; filename="051111twdns.zip"
Я думаю, что Play не обрабатывает этот случай правильно, поэтому параметр «FileData» NULL.
Для того, чтобы работать с Chrome и Firefox, я изменил это действие:
public class Application extends Controller {
public static void upload(File filedata) {
if(filedata!=null) {
// ok, it's IE6
renderText("{'err':'', 'msg':{'ur':'/uploaded/xxx.zip'}}");
} else {
// it's chrome or firefox, the data is in request.body
File targetFile = new File("upload/test.zip");
IOUtils.copy(request.body, new FileOutputStream(targetFile));
}
}
}
Это работает в IE6, Chrome и Firefox сейчас, НО, только если файл загрузки очень маленький. Например, менее 4k. Если это немного больше, например, 12K, метод «IOUTILS.COPY» будет сообщать «Прочитать ошибку!», Даже следующий код сообщит о такой ошибке:
request.body.available()
request.body.read()
request.body.read(bytes)
Решение
Вы должны посмотреть на Play.data.parsing.apachemultiPartParser Class, который управляет удалением вложения файла из HTTP-запроса.
GetFieldName получает имя поля поиска в поисках «контент-нём» и «Form-data». В вашем случае это нет.
private String getFieldName(Map /* String, String */ headers) {
String fieldName = null;
String cd = getHeader(headers, CONTENT_DISPOSITION);
if (cd != null && cd.toLowerCase().startsWith(FORM_DATA)) {
ParameterParser parser = new ParameterParser();
parser.setLowerCaseNames(true);
// Parameter parser can handle null input
Map params = parser.parse(cd, ';');
fieldName = (String) params.get("name");
if (fieldName != null) {
fieldName = fieldName.trim();
}
}
return fieldName;
}
В GetFileName он ищет заголовок «Content-Distance», а затем «Form-Data» или «Приложение», чтобы получить имя файла.
private String getFileName(Map /* String, String */ headers) {
String fileName = null;
String cd = getHeader(headers, CONTENT_DISPOSITION);
if (cd != null) {
String cdl = cd.toLowerCase();
if (cdl.startsWith(FORM_DATA) || cdl.startsWith(ATTACHMENT)) {
ParameterParser parser = new ParameterParser();
parser.setLowerCaseNames(true);
// Parameter parser can handle null input
Map params = parser.parse(cd, ';');
if (params.containsKey("filename")) {
fileName = (String) params.get("filename");
if (fileName != null) {
fileName = fileName.trim();
// IE7 returning fullpath name (#300920)
if (fileName.indexOf('\\') != -1) {
fileName = fileName.substring(fileName.lastIndexOf('\\') + 1);
}
} else {
// Even if there is no value, the parameter is present,
// so we return an empty file name rather than no file
// name.
fileName = "";
}
}
}
}
return fileName;
}
Так что, по-видимому, в вашем случае, этот код найдет имя файла, но не имени поля, поэтому, возможно, именно поэтому у вас есть поле FileData, установленным на NULL в вашем контроллере.
Почему это работает с IE6? (Потому что это никогда не было очень стандартным и делает что-то, что другие не делают больше ??? :))
Для получения информации, в модуле CRUD, файлфилд.html объявляет загрузку файлов в следующем:
<input id="${field.id}" class="${field.errorClass}" type="file" name="${field.name}" />
С Уважением
Другие советы
Попробуйте интегрировать свой сайт с файлом Uploader, который имеет LOF документации / образцы для разных языков www.uploadify.com/