Vaadin与JQuery FileUpload [英] Vaadin with JQuery FileUpload

查看:210
本文介绍了Vaadin与JQuery FileUpload的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想用 Vaadin 创建 FileUploader 。但是我需要通过正常的Vaadin上传获得更多功能。
$ b


  1. 美丽且易于管理(但是可选)

  2. li>
  3. 包含进度条
  4. 显示预览
  5. 多文件上传支持>上传文件大小和类型限制

  6. 拖放

  7. 客户端图像可调整大小我上传的文件是图片)

有一个插件 MultiFileUpload 。是的,这对于我的大部分要求来说都是完美的,但对于客户端大小的图片大小调整不是。所以我决定使用 JQuery FileUpload ,因为它支持客户端图片大小调整

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



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

 < script id =template-upload类型= 文本/ X-TMPL > 
{%for(var i = 0,file; file = o.files [i]; i ++){%}
< tr class =template-upload>
< td width =100pxalign =center>
< span class =preview>< / span>
< / td>
< td width =400pxalign =center>
< p class =name> {%= file.name%}< / p>
{%if(!o.files.error){%}
< div class =progress progress-success progress-striped activerole =progressbararia-valuemin =0aria -valuemax =100aria-valuenow =0>< div class =barstyle =width:0%;>< / div>< / div>
{%}%}
{%if(file.error){%}
< div>< span class =label label-important>错误< / span> {(%)= file.error%}< / DIV>
{%}%}
< / td>
< td width =100pxalign =center>
{%if(!i){%}
< button style =display:none; class =starttype =button>
< span>开始< / span>
< / button>
< div class =v-button v-widget canceltype =button>
< span class =v-button-wrapstyle =color:red;>
< span class =v-button-caption>取消< / span>
< / span>
< / div>
{%}%}
< br>
{%= o.formatFileSize(file.size)%}
< / td>
< / tr>
{%}%}
< / script>
<! - 显示可下载文件的模板 - >
< script id =template-downloadtype =text / x-tmpl>
{%for(var i = 0,file; file = o.files [i]; i ++){%}
< tr class =template-download>
< td width =100pxalign =center>
< span class =preview>
{%if(file.path){%}
< img src =../{%= file.path%}width =100px>
{%}%}
< / span>
< / td>
< td width =400pxalign =center>
< p class =name>
{%= file.name%}
< / p>
{%if(file.error){%}
< div>< span class =label label-important>错误< / span> {(%)= file.error%}< / DIV>
{%}%}
< / td>
< td width =100pxalign =center>
< span class =size> {%= o.formatFileSize(file.size)%}< / span>
< / td>
< / tr>
{%}%}
< / script>
< table cellpadding =5style =width:100%;>
< colgroup>
< col>
< / colgroup>
< tbody>
< tr>
< td width =90px>
< div style =text-align:right; width:120px;> UploadPhoto:< / div>
< / td>
< td>

< div style =width:0%; class =allbarid =pnlProgressBar>& nbsp;< / div>
< / div>
< / td>
< / tr>
< tr>
< td colspan =3>
< div id =imageFormstyle =width:600px;>
< form id =fileupload>
< div style =margin-bottom:10px; border:1px solid #DDD; width:600px; height:300px; overflow:scroll>
< table cellspacing =0cellpadding =5>
< tbody class =files>< / tbody>
< / table>
< / div>
< div style =margin-bottom:10px;类= 文件上传-按钮栏 >
< div class =v-button v-widget btnPlus>
< span class =v-button-caption>添加文件< / span>
< input type =filemultiple =name =files []>
< / div>
< div class =v-button v-widget starttype =submit>
< span class =v-button-wrap>
< span class =v-button-caption> StartUpload< / span>
< / span>
< / div>
< div class =v-button v-widget canceltype =reset>
< span class =v-button-wrap>
< span class =v-button-caption>全部取消< / span>
< / span>
< / div>
< / div>
< div style =border:1px solid#999; width:600px; height:100px; ID = 悬浮窗 >
< div class =carPhotoDropMsg>
草案& amp; amp; amp; 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是seq保存在数据库或其他用途
Page.getCurrent()。getJavaScript()。execute(initImageuploader(123));

$ b $ public ImageUploadDialog(){
CustomLayout layout = new CustomLayout(imageUploadLayout);
窗口=新窗口(上传照片);
window.center();
window.setWidth(615px);
window.setModal(true);
window.setResizable(false);
window.setClosable(true);
window.setContent(layout);






下面是我的upload.js文件,用于初始化我的图片上传器
$ b $ pre $ 函数initImageuploader(seq){
$('#fileupload')。fileupload({
url:'photo / upload.html?s ='+ seq,
sequentialUploads:true,
disableImageResize:false,
imageMaxWidth:1024,$ b $ 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')。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',进度);
$('。progressall')。css('display','block');
$('。allbar')。css('width',progress +'%');
if(progress> 20){
$('。allbar')。text(progress +'%Completed');
}
},
stop:function(e){
return;
}
});



$ b $ p
$ b你需要额外的javascripts文件来存放图片,类如下

  @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} )
公共类EntryPoint扩展UI {
..............
}



请注意JS文件订购!

以下是我的图片上传窗口的自定义CSS文件( imageUpload.css

  table.upld-status {
display:none;
}
.fileupload-buttonbar .btnPlus {
float:left;
position:relative;
overflow:hidden;
颜色:蓝色;
text-align:center;
margin-right:10px;
}
.fileupload-buttonbar .btnPlus input {
margin:0px;
position:absolute;
top:0px;
right:0px;
line-height:30px;
font-size:23px;
方向:ltr;
opacity:0;
}
.carPhotoDropMsg {
color:#DDD;
font-size:20pt;
身高:82%;
padding:9px;
text-align:center;
}
.progress {
background-color:#F7F7F7;
background-image:线性渐变(至底部,#F5F5F5,#F9F9F9);
background-repeat:repeat-x;
border-radius:4px 4px 4px 4px;
box-shadow:0 1px 2px rgba(0,0,0,0.1)inset;
height:17px;
overflow:hidden;

.progress-success.progress-striped .bar,.progress-success.progress-striped .allbar,.progress
条纹.bar-success {
background-color :#62C462;
background-image:线性渐变(45deg,rgba(255,255,255,0.15)25%,透明25%,透明50%,rgba(255,255,255,0.15)50%,rgba 255,255,255,0.15)75%,透明75%,透明);
}
.progress.active .bar,.progress.active .allbar {
动画:2s线性0s正常none无限进度条stripes;
}
.progress-success .bar,.progress-success .allbar,.progress .bar-success {
background-color:#5EB95E;
background-image:线性渐变(到底部,#62C462,#57A957);
background-repeat:repeat-x;
}
.progress-striped .bar,.progress-striped .allbar {
background-color:#149BDF;
background-image:线性渐变(45deg,rgba(255,255,255,0.15)25%,透明25%,透明50%,rgba(255,255,255,0.15)50%,rgba 255,255,255,0.15)75%,透明75%,透明);
background-size:40px 40px;
}
.progress .bar,.progress .allbar {
-moz-box-sizing:border-box;
背景颜色:#0E90D2;
background-image:线性渐变(到底部,#149BDF,#0480BE);
background-repeat:repeat-x;
box-shadow:0 -1px 0 rgba(0,0,0,0.15)inset;
颜色:#FFFFFF;
float:left;
font-size:12px;
身高:100%;
text-align:center;
text-shadow:0 -1px 0 rgba(0,0,0,0.25);
转换:宽度0.4s缓解0s;
width:0;



$ b我需要服务器端的控制来保存图像。你需要两个jar apache-common-io apache-common-fileupload 。下面是这两个jar的maven仓库。

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

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

最后,下面是服务器端控件的代码。

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

response.setContentType(application / json);
PrintWriter out = response.getWriter();
FileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
列表< FileItem> fields = null;
尝试{
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);

$ b public final String uploadPhoto(final HttpServletRequest request,
final List< FileItem> sessionFiles){

List< Map< String,对象>> ret = new ArrayList< Map< String,Object>>();
for(FileItem item:sessionFiles){
if(!item.isFormField()){
Long seq = Long.parseLong(request.getParameter(s));
//从vm参数获得(例如:-DstaticDir = / Applications / springsource / workspace / myproject / src / main / webapp)
String staticDir = System.getProperty(staticDir);

今天的日期= 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){
//无所事事!


String fileName = seq +_+ fmtHMS.format(today)+ format;
地图< String,Object> res = new HashMap< String,Object>();
//将图像保存在指定位置
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);
}
}
映射< 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();
}
文件imageFile =新文件(file,fileName);
尝试{
item.write(imageFile);
}
catch(Exception e){
e.printStackTrace();
}
item.setFieldName(filePath + fileName);
return item.toString();




$ b我知道我的代码可能有风险和弱点。每个建议都受到欢迎。但是我相信这对新手来说有一些帮助(我也是一个新手)。抱歉,格式太长而且格式不对。



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

为什么预览图片(上传之后没有上传之前)自动包含 url 而不是文件路径?没有找到图像错误

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

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

解决方案

我修复了 src 上传图片为...

 < script id =template-downloadtype =text / x-tmpl> ; 
{%for(var i = 0,file; file = o.files [i]; i ++){; %}
< tr class =template-download>
< td width =100pxalign =center>
< span class =preview>
{%if(file.path){%}
< img src =/ myproject / {%= file.path%}width =100px>
{%}%}
< / span>
< / td>
< td width =400pxalign =center>
< p class =name>
{%= file.name%}
< / p>
{%if(file.error){%}
< div>< span class =label label-important>错误< / span> {(%)= file.error%}< / DIV>
{%}%}
< / td>
< td width =100pxalign =center>
< span class =size> {%= o.formatFileSize(file.size)%}< / span>
< / td>
< / tr>
{%}%}
< / script>

现在一切都很好。如果您没有立即看到图片,请检查您的IDE(Eclipse或STS)设置,如下所示:


首选项>常规>工作区

并勾选复选框刷新访问使用原生钩子或轮询刷新


I would like to create FileUploader with Vaadin . But I need to get more features over normal Vaadin Upload.

  1. beautiful and easy to manage (but optional)
  2. fast and never failed while uploading
  3. include progress bar
  4. show preview
  5. multi file upload support
  6. upload file size and type restriction
  7. drag and drop
  8. client-side image resizable (it is main feature for me because all of my uploaded files were images)

There has an addon MultiFileUpload. Yes , it is perfect for most of my requirements but not for client-size image resizing. So I decided to use JQuery FileUpload because it is support for Client side Image Resizing.

I used vaadin Window for upload image. But I got a problem while creating my window , very hard to create each HTML elements respectively (may be I have less exp). So I used CustomLayout with HTML for easy to create and edit design of my image uploader window.

Below is my custom layout HTML file. (two scripts were templates for image preview)

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

Below is for ImageUpload window

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

And below is my upload.js file for initialize my image uploader

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

And you need additional javascripts files for image uploader and I imported them at my UI class as below

@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 !

Below is my Custom CSS file for image upload window (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, 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, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 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, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, 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, 0, 0.15) inset;
color: #FFFFFF;
float: left;
font-size: 12px;
height: 100%;
text-align: center;
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
transition: width 0.4s ease 0s;
width: 0;
}

I need server-side control for save image . You need two jars apache-common-io and apache-common-fileupload. Below is for maven repository of these two jars.

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

Finally , below is codes for server-side control .

@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();
}
}

I know my codes may have risks and some weakpoints . Every suggestions were welcome . But I believe there has some useful for newbie (I am also a newbie). Sorry for too long and bad format.

The last thing is my problem ....

Why preview image (after upload not before upload) automatically include url instead of filepath ? I got image not found error

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

Actually this image path should be data/photo/20140723/23/111_235918346.jpg. I have no idea why prefix url http://localhost:8080/myproject/VAADIN/themes/myTheme/ was automatically include (may be due to my CustomLayout HTML file path) ? File paths were got from HTTP response (with JSON). I think it is due to VAADIN because it works on my GWT project or may be I am wrong. Any suggestions ? Thanks for reading my question.

解决方案

I fixed it by repairing src value of preview template for after upload image as ...

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

Now everythings were fine. If you didn't see image immidiately , please check your IDE (Eclipse or STS) setting as below

Preference > General > Workspace

and check checkboxes Refresh on access and Refresh using native hooks or polling.

这篇关于Vaadin与JQuery FileUpload的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆