7

我正在使用 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 中运行良好,文件数据不为空并且包含正确的数据。但是,如果我使用 chrome 或 firefox,则文件数据为

我用firebug来监控firebug提交了什么,发现它提交了这样一个header:

content-disposition
attachment; name="filedata"; filename="051111twdns.zip"

我认为 play 没有正确处理这种情况,所以参数“filedata”为空。

为了使用 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”方法会报“Read Error!”,甚至下面的代码也会报这样的错误:

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

2 回答 2

1

尝试将您的网站与文件上传器集成,该文件上传器有大量不同语言的文档/示例 www.uploadify.com/

于 2010-12-29T18:42:08.693 回答
0

您应该查看 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;
}

所以显然,在你的情况下,这段代码会找到文件名而不是字段名,所以也许这就是你在控制器中将 filedata 字段设置为 null 的原因。

为什么它适用于 IE6?(因为它从来都不是真正的标准,并且做了其他人不再做的事情???:))

有关信息,在 Crud 模块中,fileField.html 声明文件上传如下:

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

问候

于 2011-03-10T10:56:54.673 回答