微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

file-upload – 使用JQuery FileUpload的Vaadin

我想用Vaadin创建FileUploader.但我需要获得超过 normal Vaadin Upload的更多功能.

>美观且易于管理(但可选)
>上传快速且永不失败
>包括进度条
>显示预览
>多文件上传支持
>上传文件大小和类型限制
>拖放
>客户端图像可调整大小(这是我的主要功能,因为我上传的所有文件都是图像)

一个插件MultiFileUpload.是的,它非常适合我的大多数要求,但不适用于客户端大小的图像大小调整.所以我决定使用JQuery FileUpload,因为它支持Client side Image Resizing.

我用vaadin Window上传图片.但是我在创建窗口时遇到了问题,分别很难创建每个HTML元素(可能我的exp少了).所以我使用CustomLayout with HTML轻松创建和编辑我的图像上传窗口的设计.

下面是我的自定义布局HTML文件. (两个脚本是图像预览模板)

<script id="template-upload" type="text/x-tmpl">
{% for (var i=0,file; file=o.files[i]; i++) { %}
<tr class="template-upload">
    <td width="100px" align="center">
        <span class="preview"></span>
    </td>
    <td width="400px" align="center">
        <p class="name">{%=file.name%}</p>
        {% if (!o.files.error) { %}
            <div class="progress progress-success progress-striped active" role="progressbar" aria-valuemin="0" aria-valuemax="100" aria-valueNow="0"><div class="bar" style="width:0%;"></div></div>
        {% } %}
        {% if (file.error) { %}
            <div><span class="label label-important">Error</span> {%=file.error%}</div>
        {% } %}
    </td>
    <td width="100px" align="center">
        {% if (!i) { %}
            <button style="display: none;" class="start" type="button">
                <span>Start</span>
            </button>
            <div class="v-button v-widget cancel" type = "button">
                <span class="v-button-wrap" style="color: red;">
                    <span class="v-button-caption">Cancel</span>
                </span>
            </div>
        {% } %}
        <br>
        {%=o.formatFileSize(file.size)%}
    </td>
</tr>
{% } %}
</script>
<!-- The template to display files available for download -->
<script id="template-download" type="text/x-tmpl">
{% for (var i=0,file; file=o.files[i]; i++) { %}
<tr class="template-download">
    <td width="100px" align="center">
        <span class="preview">
            {% if (file.path) { %}
                <img src="../{%=file.path%}" width="100px">
            {% } %}
        </span>
    </td>
    <td width="400px" align="center">
        <p class="name">
            {%=file.name%}
        </p>
        {% if (file.error) { %}
            <div><span class="label label-important">Error</span> {%=file.error%}</div>
        {% } %}
    </td>
    <td width="100px" align="center">
        <span class="size">{%=o.formatFileSize(file.size)%}</span>
    </td>
</tr>
{% } %}
</script>
<table cellpadding="5" style="width: 100%;">
<colgroup>
<col>
</colgroup>
<tbody>
    <tr>
        <td width="90px">
            <div style="text-align: right; width: 120px;">UploadPhoto :</div>
        </td>
        <td>
            <div id="pnlProgress" aria-valueNow="0" aria-valuemax="100" aria-valuemin="0" style="display: none;" class="progress progressall progress-success progress-striped active">
                <div style="width: 0%;" class="allbar" id="pnlProgressBar">&nbsp;</div>
            </div>
        </td>
    </tr>
    <tr>
        <td colspan="3">
            <div id="imageForm" style="width: 600px;">
                <form id="fileupload">
                    <div style="margin-bottom: 10px; border: 1px solid #DDD; width: 600px; height: 300px; overflow: scroll">
                        <table cellspacing="0" cellpadding="5">
                            <tbody class="files"></tbody>
                        </table>
                    </div>
                    <div style="margin-bottom: 10px;" class="fileupload-buttonbar">
                        <div class="v-button v-widget btnPlus">
                            <span class="v-button-caption">Add Files</span> 
                            <input type="file" multiple="" name="files[]">
                        </div>
                        <div class="v-button v-widget start" type = "submit">
                            <span class="v-button-wrap">
                                <span class="v-button-caption">StartUpload</span>
                            </span>
                        </div>
                        <div class="v-button v-widget cancel" type = "reset">
                            <span class="v-button-wrap">
                                <span class="v-button-caption">Cancel All</span>
                            </span>
                        </div>
                    </div>
                    <div style="border: 1px solid #999; width: 600px; height: 100px;" id="dropZone">
                        <div class="carPhotoDropMsg">
                            Draft &amp; Drop Photos<br>(jpg,jpeg,png,gif only)
                        </div>
                    </div>
                </form>
            </div>
        </td>
    </tr>
</tbody>

下面是ImageUpload窗口

public final class ImageUploadDialog extends CustomComponent {
private Window window;

public void show() {
    UI.getCurrent().addWindow(window);
 // 123 is seq for save in database or other use
    Page.getCurrent().getJavaScript().execute("initimageuploader(123)");
}

public ImageUploadDialog() {
    CustomLayout layout = new CustomLayout("imageUploadLayout");
    window = new Window("Uploading Photos");
    window.center();
    window.setWidth("615px");
    window.setModal(true);
    window.setResizable(false);
    window.setClosable(true);
    window.setContent(layout);
}
}

以下是我的upload.js文件,用于初始化我的图像上传

function initimageuploader(seq) {
$('#fileupload').fileupload({
    url : 'photo/upload.html?s=' + seq,sequentialUploads : true,disableImageResize : false,imageMaxWidth : 1024,imageMaxHeight : 1024,previewCrop : true,dropZone : $("#dropZone"),acceptFileTypes : /(\.|\/)(gif|jpe?g|png)$/i,progress : function(e,data) {
        if (data.context) {
            var progress = data.loaded / data.total * 100;
            progress = Math.floor(progress);
            $('.progress').attr('aria-valueNow',progress);
            $('.progress').css('display','block');
            $('.bar').css('width',progress + '%');
        }
    },progressall : function(e,data) {
        var progress = data.loaded / data.total * 100;
        progress = Math.floor(progress);
        $('.progressall').attr('aria-valueNow',progress);
        $('.progressall').css('display','block');
        $('.allbar').css('width',progress + '%');
        if (progress > 20) {
            $('.allbar').text(progress + '% Completed');
        }
    },stop: function (e) {
        return;
    }
});
}

你需要额外的javascripts文件用于图像上传器,我在我的UI类中导入它们,如下所示

@JavaScript({ "vaadin://themes/myproject/js/load-image.min.js","vaadin://themes/myproject/js/tmpl.min.js","vaadin://themes/myproject/js/jquery/jquery-1.10.1.min.js","vaadin://themes/myproject/js/jquery/vendor/jquery.ui.widget.js","vaadin://themes/myproject/js/jquery/jquery.iframe-transport.js","vaadin://themes/myproject/js/jquery/jquery.fileupload.js","vaadin://themes/myproject/js/jquery/jquery.fileupload-ui.js","vaadin://themes/myproject/js/jquery/jquery.fileupload-process.js","vaadin://themes/myproject/js/jquery/jquery.fileupload-image.js","vaadin://themes/myproject/js/jquery/jquery.fileupload-validate.js","vaadin://themes/myproject/js/canvas-to-blob.min.js","vaadin://themes/myproject/js/upload.js" })
@StyleSheet({ "vaadin://themes/myproject/css/jquery-ui-1.10.3.custom.min.css","vaadin://themes/myproject/css/imageUpload.css" })
public class EntryPoint extends UI {
..............
}

Please Notice for JS Files Order !

下面是我的图像上传窗口的自定义CSS文件(imageUpload.css)

table.upld-status {
display: none;
}
.fileupload-buttonbar .btnPlus {
float: left;
position: relative;
overflow: hidden;
color: blue;
text-align: center;
margin-right : 10px;
}
.fileupload-buttonbar .btnPlus input {
margin: 0px;
position: absolute;
top: 0px;
right: 0px;
line-height: 30px;
font-size: 23px;
direction: ltr;
opacity: 0;
}
.carPhotoDropMsg {
color: #DDD;
font-size: 20pt;
height: 82%;
padding: 9px;
text-align: center;
}
.progress {
background-color: #F7F7F7;
background-image: linear-gradient(to bottom,#F5F5F5,#F9F9F9);
background-repeat: repeat-x;
border-radius: 4px 4px 4px 4px;
Box-shadow: 0 1px 2px rgba(0,0.1) inset;
height: 17px;
overflow: hidden;
}
.progress-success.progress-striped .bar,.progress-success.progress-striped .allbar,.progress
striped .bar-success {
background-color: #62C462;
background-image: linear-gradient(45deg,rgba(255,255,0.15) 25%,transparent 25%,transparent 50%,0.15) 50%,0.15) 75%,transparent 75%,transparent);
}
.progress.active .bar,.progress.active .allbar {
animation: 2s linear 0s normal none infinite progress-bar-stripes;
}
.progress-success .bar,.progress-success .allbar,.progress .bar-success {
background-color: #5EB95E;
background-image: linear-gradient(to bottom,#62C462,#57A957);
background-repeat: repeat-x;
}
.progress-striped .bar,.progress-striped .allbar {
background-color: #149BDF;
background-image: linear-gradient(45deg,transparent);
background-size: 40px 40px;
}
.progress .bar,.progress .allbar {
-moz-Box-sizing: border-Box;
background-color: #0E90D2;
background-image: linear-gradient(to bottom,#149BDF,#0480BE);
background-repeat: repeat-x;
Box-shadow: 0 -1px 0 rgba(0,0.15) inset;
color: #FFFFFF;
float: left;
font-size: 12px;
height: 100%;
text-align: center;
text-shadow: 0 -1px 0 rgba(0,0.25);
transition: width 0.4s ease 0s;
width: 0;
}

我需要服务器端控制来保存图像.你需要两个罐子apache-common-ioapache-common-fileupload.下面是这两个罐子的maven存储库.

<dependency>
        <groupId>commons-fileupload</groupId>
        <artifactId>commons-fileupload</artifactId>
        <version>1.2.2</version>
    </dependency>

    <dependency>
        <groupId>commons-io</groupId>
        <artifactId>commons-io</artifactId>
        <version>2.4</version>
    </dependency>

最后,下面是服务器端控制的代码.

@WebServlet(value = "/photo/upload.html")
public class UploadServletController extends HttpServlet {
protected final void doPost(final HttpServletRequest request,final HttpServletResponse response) throws servletexception,IOException {

    response.setContentType("application/json");
    PrintWriter out = response.getWriter();
    FileItemFactory factory = new diskFileItemFactory();
    ServletFileUpload upload = new ServletFileUpload(factory);
    List<FileItem> fields = null;
    try {
        fields = upload.parseRequest(request);
    }
    catch (FileUploadException e) {
        throw new RuntimeException("Error Parsing File Item " + e.getMessage(),e);
    }
    if (fields != null) {
        String message = uploadPhoto(request,fields);
        out.write(message);
    }
}
public final synchronized String uploadPhoto(final HttpServletRequest request,final List<FileItem> sessionFiles) {

    List<Map<String,Object>> ret = new ArrayList<Map<String,Object>>();
    for (FileItem item : sessionFiles) {
        if (!item.isFormField()) {
            Long seq = Long.parseLong(request.getParameter("s"));
// get from vm arguments (eg:-DstaticDir=/Applications/springsource/workspace/myproject/src/main/webapp)
            String staticDir = System.getProperty("staticDir");

            Date today = new Date();
            SimpleDateFormat fmtYMD = new SimpleDateFormat("/yyyyMMdd/HH");
            SimpleDateFormat fmtHMS = new SimpleDateFormat("HHmmssS");

            String saveDir = "data/photo" + fmtYMD.format(today);
            String format = ".jpg";
            try {
                format = item.getName().substring(item.getName().lastIndexOf("."),item.getName().length())
                        .toLowerCase();
            }
            catch (Exception e) {
                // nothing to do!
            }

            String fileName = seq + "_" + fmtHMS.format(today) + format;
            Map<String,Object> res = new HashMap<String,Object>();
            // Save image in specify location
            String filePath = staticDir + "/" + saveDir;
            saveFile(filePath,fileName,item);

            res.put("seq",seq);
            res.put("path",saveDir + "/" + fileName);
            res.put("ext",format.substring(1));

            res.put("name",item.getName());
            res.put("size",item.getSize());
            ret.add(res);
        }
    }
    Map<String,Object> result = new HashMap<String,Object>();
    result.put("files",ret);
    JSONObject obj = new JSONObject(result);

    return obj.toString();
}
public static String saveFile(final String filePath,final String fileName,final FileItem item) {
    File file = new File(filePath);
    if (!file.exists()) {
        file.mkdirs();
    }
    File imageFile = new File(file,fileName);
    try {
        item.write(imageFile);
    }
    catch (Exception e) {
        e.printstacktrace();
    }
    item.setFieldName(filePath + fileName);
    return item.toString();
}
}

我知道我的代码可能有风险和一些弱点.欢迎提出任何建议.但我相信新手有一些用处(我也是新手).抱歉格式太长,不好.

最后一件事是我的问题….

为什么预览图像(上传后不上传之前)自动包含url而不是filepath?我找不到图像错误

"NetworkError: 404 Not Found - http://localhost:8080/myproject/VAADIN/themes/myTheme/data/photo/20140723/23/123_235918346.jpg"

实际上这个图像路径应该是data / photo / 20140723/23 / 111_235918346.jpg.我不知道为什么前缀url http:// localhost:8080 / myproject / VAADIN / themes / myTheme /是自动包含的(可能是由于我的CustomLayout HTML文件路径)?文件路径来自HTTP响应(使用JSON).我认为这是由于VAADIN,因为它适用于我的GWT项目,或者可能是我错了.有什么建议么 ?感谢您阅读我的问题.

解决方法

我通过修复上传图像的预览模板的src值来修复它…
<script id="template-download" type="text/x-tmpl">
{% for (var i=0,file; file=o.files[i]; i++) {; %}
<tr class="template-download">
    <td width="100px" align="center">
        <span class="preview">
            {% if (file.path) { %}
                <img src="/myproject/{%=file.path%}" width="100px">
            {% } %}
        </span>
    </td>
    <td width="400px" align="center">
        <p class="name">
            {%=file.name%}
        </p>
        {% if (file.error) { %}
            <div><span class="label label-important">Error</span> {%=file.error%}</div>
        {% } %}
    </td>
    <td width="100px" align="center">
        <span class="size">{%=o.formatFileSize(file.size)%}</span>
    </td>
</tr>
{% } %}
</script>

现在每个人都很好.如果您没有立即看到图像,请检查您的IDE(Eclipse或STS)设置如下

Preference > General > Workspace

并选中复选框访问时刷新和使用本机挂钩或轮询刷新.

原文地址:https://www.jb51.cc/jquery/180558.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐