Загрузка файла в плейфрейм с разными браузерами - PullRequest
7 голосов
/ 05 октября 2010

Я использую playframework для создания веб-сайта.И я также использую расширенный редактор с именем xheditor .

Xheditor поддерживает загрузку ajax-файла, ему нужно, чтобы на стороне сервера было действие, которое принимает параметр 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 работает нормально, данные файла не равны нулю и содержат правильные данные.Но, если я использую chrome или firefox, данные файла будут null !!

Я использую 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.Если он немного больше, например, 12 КБ, метод «IOUtils.copy» сообщит «Ошибка чтения!», Даже следующий код сообщит о такой ошибке:

request.body.available()
request.body.read()
request.body.read(bytes)

Ответы [ 2 ]

1 голос
/ 29 декабря 2010

Попробуйте интегрировать ваш сайт с загрузчиком файлов, который имеет большое количество документации / примеров для разных языков www.uploadify.com/

0 голосов
/ 10 марта 2011

Вам следует взглянуть на класс play.data.parsing.ApacheMultipartParser, который управляет извлечением вложенных файлов из HTTP-запроса.

getFieldName получает имя поля поиска заголовка "content-disposition" и "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-disposition», а затем «form-data» или «attachment», чтобы получить имя файла.

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;
}

Так что, по-видимому, в вашем случае этот код найдет имя файла, но не имя поля, поэтому, возможно, именно поэтому в вашем контроллере установлено значение null для поля filedata.

Почему это так?работать с IE6?(потому что он никогда не был действительно стандартным и делает то, что другие больше не делают ??? :))

Для информации, в модуле Crud fileField.html объявляет загрузку файла следующим образом:

<input id="${field.id}" class="${field.errorClass}" type="file" name="${field.name}" />

С уважением

...