¿Alguien puede explicar cómo implementar el complemento jQuery File Upload?

116

EDITAR (Oct 2019):

6 años después, jQuery File Upload claramente todavía está volviendo loca a la gente. Si encuentra poco consuelo en las respuestas aquí, intente una búsqueda de NPM para una alternativa moderna. No vale la pena la molestia, lo prometo.

Recomendé Uploadify en la edición anterior pero, como señaló un comentarista, ya no parecen ofrecer una versión gratuita. Uploadify fue tan 2013 de todos modos.


EDITAR:

Esto todavía parece estar recibiendo tráfico, así que explicaré lo que terminé haciendo. Finalmente logré que el complemento funcionara siguiendo el tutorial en la respuesta aceptada. Sin embargo, la carga de archivos jQuery es una verdadera molestia y si está buscando un complemento de carga de archivos más simple, le recomendaría encarecidamente Uploadify . Como se señaló en la respuesta, solo es gratuito para uso no comercial.


Antecedentes

Estoy tratando de usar la carga de archivos jQuery de blueimp para permitir que los usuarios carguen archivos. Fuera de la caja, funciona perfectamente , siguiendo las instrucciones de configuración. Pero para usarlo prácticamente en mi sitio web, quiero poder hacer un par de cosas:

  • Incluir al usuario que subió el video en cualquiera de mis páginas existentes
  • Cambiar el directorio de archivos cargados

Todos los archivos del complemento se encuentran en una carpeta debajo de la raíz.

He intentado...

  • Mover la página de demostración a la raíz y actualizar las rutas de los scripts necesarios
  • Cambiar las opciones "upload_dir" y "upload_url" en el archivo UploadHandler.php como se sugiere aquí .
  • Cambiar la URL en la segunda línea del javascript de demostración

En todos los casos, los espectáculos de vista previa, y se ejecuta la barra de progreso, pero los archivos no pueden cargar y me sale este error en la consola: Uncaught TypeError: Cannot read property 'files' of undefined. No entiendo cómo funcionan todas las partes del complemento, lo que dificulta la depuración.

Código

El javascript en la página de demostración:

$(function () {
'use strict';
// Change this to the location of your server-side upload handler:
var url = 'file_upload/server/php/UploadHandler.php',
    uploadButton = $('<button/>')
        .addClass('btn')
        .prop('disabled', true)
        .text('Processing...')
        .on('click', function () {
            var $this = $(this),
                data = $this.data();
            $this
                .off('click')
                .text('Abort')
                .on('click', function () {
                    $this.remove();
                    data.abort();
                });
            data.submit().always(function () {
                $this.remove();
            });
        });
$('#fileupload').fileupload({
    url: url,
    dataType: 'json',
    autoUpload: false,
    acceptFileTypes: /(\.|\/)(gif|jpe?g|png)$/i,
    maxFileSize: 5000000, // 5 MB
    // Enable image resizing, except for Android and Opera,
    // which actually support image resizing, but fail to
    // send Blob objects via XHR requests:
    disableImageResize: /Android(?!.*Chrome)|Opera/
        .test(window.navigator.userAgent),
    previewMaxWidth: 100,
    previewMaxHeight: 100,
    previewCrop: true
}).on('fileuploadadd', function (e, data) {
    data.context = $('<div/>').appendTo('#files');
    $.each(data.files, function (index, file) {
        var node = $('<p/>')
                .append($('<span/>').text(file.name));
        if (!index) {
            node
                .append('<br>')
                .append(uploadButton.clone(true).data(data));
        }
        node.appendTo(data.context);
    });
}).on('fileuploadprocessalways', function (e, data) {
    var index = data.index,
        file = data.files[index],
        node = $(data.context.children()[index]);
    if (file.preview) {
        node
            .prepend('<br>')
            .prepend(file.preview);
    }
    if (file.error) {
        node
            .append('<br>')
            .append(file.error);
    }
    if (index + 1 === data.files.length) {
        data.context.find('button')
            .text('Upload')
            .prop('disabled', !!data.files.error);
    }
}).on('fileuploadprogressall', function (e, data) {
    var progress = parseInt(data.loaded / data.total * 100, 10);
    $('#progress .bar').css(
        'width',
        progress + '%'
    );
}).on('fileuploaddone', function (e, data) {
    $.each(data.result.files, function (index, file) {
        var link = $('<a>')
            .attr('target', '_blank')
            .prop('href', file.url);
        $(data.context.children()[index])
            .wrap(link);
    });
}).on('fileuploadfail', function (e, data) {
    $.each(data.result.files, function (index, file) {
        var error = $('<span/>').text(file.error);
        $(data.context.children()[index])
            .append('<br>')
            .append(error);
    });
}).prop('disabled', !$.support.fileInput)
    .parent().addClass($.support.fileInput ? undefined : 'disabled');
});


Me sorprende la falta de documentación; parece que debería ser algo sencillo de cambiar. Le agradecería que alguien me explicara cómo hacer esto.

Austen
fuente
10
Buen formato de pregunta. Es bueno ver la organización.
jdero
imprima 'e' y 'datos' en la consola justo antes de la línea de error, ¿cuáles son los valores?
juan 4d5
3
Uploadi fy es una licencia MIT, por ejemplo, es completamente gratis. Sin embargo, Uploadi Five del mismo desarrollador / sitio web cuesta $ 5- $ 100 dependiendo del uso
MartinJH
2
En dos años, la documentación de jQuery-File-Upload no ha mejorado. Argh.
Chuck Le Butt
1
@MartinJH puede haber habido una carga en algún momento, pero a partir de ahora solo hay una: la versión de pago uploadiFive. Y tampoco hay demostración; es solo un video. Mala forma.
Steve Horvath

Respuestas:

72

Hace unos días estaba buscando una funcionalidad similar y encontré un buen tutorial sobre tutorialzine. He aquí un ejemplo práctico. El tutorial completo se puede encontrar aquí .

Forma simple para mantener el diálogo de carga de archivos:

<form id="upload" method="post" action="upload.php" enctype="multipart/form-data">
  <input type="file" name="uploadctl" multiple />
  <ul id="fileList">
    <!-- The file list will be shown here -->
  </ul>
</form>

Y aquí está el código jQuery para cargar los archivos:

$('#upload').fileupload({

  // This function is called when a file is added to the queue
  add: function (e, data) {
    //This area will contain file list and progress information.
    var tpl = $('<li class="working">'+
                '<input type="text" value="0" data-width="48" data-height="48" data-fgColor="#0788a5" data-readOnly="1" data-bgColor="#3e4043" />'+
                '<p></p><span></span></li>' );

    // Append the file name and file size
    tpl.find('p').text(data.files[0].name)
                 .append('<i>' + formatFileSize(data.files[0].size) + '</i>');

    // Add the HTML to the UL element
    data.context = tpl.appendTo(ul);

    // Initialize the knob plugin. This part can be ignored, if you are showing progress in some other way.
    tpl.find('input').knob();

    // Listen for clicks on the cancel icon
    tpl.find('span').click(function(){
      if(tpl.hasClass('working')){
              jqXHR.abort();
      }
      tpl.fadeOut(function(){
              tpl.remove();
      });
    });

    // Automatically upload the file once it is added to the queue
    var jqXHR = data.submit();
  },
  progress: function(e, data){

        // Calculate the completion percentage of the upload
        var progress = parseInt(data.loaded / data.total * 100, 10);

        // Update the hidden input field and trigger a change
        // so that the jQuery knob plugin knows to update the dial
        data.context.find('input').val(progress).change();

        if(progress == 100){
            data.context.removeClass('working');
        }
    }
});
//Helper function for calculation of progress
function formatFileSize(bytes) {
    if (typeof bytes !== 'number') {
        return '';
    }

    if (bytes >= 1000000000) {
        return (bytes / 1000000000).toFixed(2) + ' GB';
    }

    if (bytes >= 1000000) {
        return (bytes / 1000000).toFixed(2) + ' MB';
    }
    return (bytes / 1000).toFixed(2) + ' KB';
}

Y aquí está la muestra de código PHP para procesar los datos:

if($_POST) {
    $allowed = array('jpg', 'jpeg');

    if(isset($_FILES['uploadctl']) && $_FILES['uploadctl']['error'] == 0){

        $extension = pathinfo($_FILES['uploadctl']['name'], PATHINFO_EXTENSION);

        if(!in_array(strtolower($extension), $allowed)){
            echo '{"status":"error"}';
            exit;
        }

        if(move_uploaded_file($_FILES['uploadctl']['tmp_name'], "/yourpath/." . $extension)){
            echo '{"status":"success"}';
            exit;
        }
        echo '{"status":"error"}';
    }
    exit();
}

El código anterior se puede agregar a cualquier formulario existente. Este programa carga imágenes automáticamente, una vez que se agregan. Esta funcionalidad se puede cambiar y puede enviar la imagen, mientras envía su formulario existente.

Actualicé mi respuesta con código real. Todos los créditos al autor original del código.

Fuente: http://tutorialzine.com/2013/05/mini-ajax-file-upload-form/

Subrat Pattnaik
fuente
2
¿Puedes copiar las partes importantes de ese tutorial aquí, así que si desaparece tu respuesta sigue siendo útil?
1
pero tenga cuidado de no plagiar
tacaswell
1
ATENCIÓN: Para cualquiera que use el fragmento de código PHP, elimine la if($_POST) declaración. Se supone que POST está vacío en el que se envía el contenido del archivo $_FILES['upfile']['tmp_name']. Con suerte, esto le ahorrará a alguien algo de tiempo.
Edward
1
Encontré otro c-sharpcorner.com/UploadFile/da55bf/…
Rush.2707
¿Alguien puede sugerirme cuáles son los archivos js / jquery necesarios para ejecutar el script anterior
Manasa
28

Acabo de pasar 2 horas luchando con jQuery Upload, pero me rendí debido a la cantidad de dependencias (tenía 13 archivos JS incluidos para obtener todas las comodidades).

Hice un poco más de búsqueda y encontré un proyecto genial llamado Dropzone.js , que no tiene ninguna dependencia.

El autor también ha creado una demostración de bootstrap que se inspiró en el complemento jQuery File Upload.

Espero que esto le ahorre tiempo a alguien más.

Tim
fuente
1
Importante a tener en cuenta: Dropzone.js se ve bien, pero solo es compatible con IE10 y versiones posteriores. La carga de archivos jQuery admite desde IE6;)
Nickvda
11
La carga de archivos jQuery es simplemente imposible para que funcione ... Envié muchas horas intentándolo porque tiene características muy agradables, pero en el último minuto mi alma solo se llenó de agonía !!! ¡¡Qué desesperación !!! Luego vi tu publicación sobre Dropzone.js y en 5 minutos lo hago funcionar y ¡de la manera que quería! Me salvaste ...
Rigon
No puedo agradecerles lo suficiente, he pasado casi 12 horas haciendo que jQuery-FIle-Upload funcione como quiero y finalmente me encontré con esta pregunta. Me salvaste.
ndd
aquí hay un ejemplo de carga de archivo jquery impulsado por una base de datos: github.com/CodeHeight/ImageLibrary
JoshYates1980
Pasé 3 días pero todavía no puedo personalizar su código
May Weather VN
4

También luché con esto, pero lo hice funcionar una vez que descubrí cómo funcionan las rutas en UploadHandler.php: upload_dir y upload_url son las únicas configuraciones que se deben tener en cuenta para que funcione. También consulte los registros de errores de su servidor para obtener información sobre la depuración.

Luis Ferreira
fuente
3

Echa un vistazo al cargador de arrastrar y soltar de imágenes con vista previa de la imagen utilizando el complemento jquery del cuentagotas.

HTML

<div class="target" width="78" height="100"><img /></div>

JS

$(".target").dropper({
    action: "upload.php",

}).on("start.dropper", onStart);
function onStart(e, files){
console.log(files[0]);

    image_preview(files[0].file).then(function(res){
$('.dropper-dropzone').empty();
//$('.dropper-dropzone').css("background-image",res.data);
 $('#imgPreview').remove();        
$('.dropper-dropzone').append('<img id="imgPreview"/><span style="display:none">Drag and drop files or click to select</span>');
var widthImg=$('.dropper-dropzone').attr('width');
        $('#imgPreview').attr({width:widthImg});
    $('#imgPreview').attr({src:res.data});

    })

}

function image_preview(file){
    var def = new $.Deferred();
    var imgURL = '';
    if (file.type.match('image.*')) {
        //create object url support
        var URL = window.URL || window.webkitURL;
        if (URL !== undefined) {
            imgURL = URL.createObjectURL(file);
            URL.revokeObjectURL(file);
            def.resolve({status: 200, message: 'OK', data:imgURL, error: {}});
        }
        //file reader support
        else if(window.File && window.FileReader)
        {
            var reader = new FileReader();
            reader.readAsDataURL(file);
            reader.onloadend = function () {
                imgURL = reader.result;
                def.resolve({status: 200, message: 'OK', data:imgURL, error: {}});
            }
        }
        else {
            def.reject({status: 1001, message: 'File uploader not supported', data:imgURL, error: {}});
        }
    }
    else
        def.reject({status: 1002, message: 'File type not supported', error: {}});
    return def.promise();
}

$('.dropper-dropzone').mouseenter(function() {
 $( '.dropper-dropzone>span' ).css("display", "block");
});

$('.dropper-dropzone').mouseleave(function() {
 $( '.dropper-dropzone>span' ).css("display", "none");
});

CSS

.dropper-dropzone{
    width:78px;
padding:3px;
    height:100px;
position: relative;
}
.dropper-dropzone>img{
    width:78px;
    height:100px;
margin-top=0;
}

.dropper-dropzone>span {
    position: absolute;
    right: 10px;
    top: 20px;
color:#ccc;


}

.dropper .dropper-dropzone{

padding:3px !important    
}

Demo Jsfiddle

tvshajeer
fuente
Ésta es una solución extremadamente simple.
Miron
2

Este es un buen complemento de Angular para cargar archivos, ¡y es gratis!

carga de archivo angular

Sahip
fuente
2
Hola. No publique enlaces como respuestas, si el sitio se desconecta o el enlace cambia, su respuesta será inútil. En su lugar, use la información del sitio para crear su respuesta y use el enlace solo como referencia. Gracias.
Cthulhu
1

Luché con este complemento durante un tiempo en Rails, y luego alguien lo gemificó dejando obsoleto todo el código que había creado.

Aunque parece que no está usando esto en Rails, sin embargo, si alguien lo está usando, consulte esta joya . La fuente está aquí -> jQueryFileUpload Rails .

Actualizar:

Para satisfacer al comentarista, actualicé mi respuesta. Esencialmente " usa esta joya , aquí está el código fuente ". Si desaparece, hazlo por el camino largo.

ingeniero Dave
fuente
1

Droply.js es perfecto para esto. Es simple y viene empaquetado con un sitio de demostración que funciona desde el primer momento.

Geremia
fuente
0

Puedes usar uploadify este es el mejor complemento jquery de carga múltiple que he usado.

La implementación es fácil, el soporte del navegador es perfecto.

CORSARIO
fuente
7
requiere flash ... :(
Eva
2
Puede utilizar la versión HTML 5 :)
CORSAIR
5
Si no me equivoco, la versión html5 de uploadify no es gratuita. Cuesta $ 5. uploadify.com/download
0112
2
Pero, esto es solo 5 $, no 500.
CORSAIR
7
Tenga en cuenta que si desea utilizar uploadify con fines comerciales, debe comprar la licencia comercial ($ 100) uploadify.com/download/download-uploadifive-commercial
Tim
0

Para el complemento UI, con página jsp y Spring MVC ..

Ejemplo de HTML . Debe estar dentro de un elemento de formulario con un atributo id de fileupload

    <!-- The fileupload-buttonbar contains buttons to add/delete files and start/cancel the upload -->
<div class="fileupload-buttonbar">
    <div>
        <!-- The fileinput-button span is used to style the file input field as button -->
        <span class="btn btn-success fileinput-button">
            <i class="glyphicon glyphicon-plus"></i>
            <span>Add files</span>
            <input id="fileuploadInput" type="file" name="files[]" multiple>
        </span>
        <%-- https://stackoverflow.com/questions/925334/how-is-the-default-submit-button-on-an-html-form-determined --%>
        <button type="button" class="btn btn-primary start">
            <i class="glyphicon glyphicon-upload"></i>
            <span>Start upload</span>
        </button>
        <button type="reset" class="btn btn-warning cancel">
            <i class="glyphicon glyphicon-ban-circle"></i>
            <span>Cancel upload</span>
        </button>
        <!-- The global file processing state -->
        <span class="fileupload-process"></span>
    </div>
    <!-- The global progress state -->
    <div class="fileupload-progress fade">
        <!-- The global progress bar -->
        <div class="progress progress-striped active" role="progressbar" aria-valuemin="0" aria-valuemax="100">
            <div class="progress-bar progress-bar-success" style="width:0%;"></div>
        </div>
        <!-- The extended global progress state -->
        <div class="progress-extended">&nbsp;</div>
    </div>
</div>
<!-- The table listing the files available for upload/download -->
<table role="presentation" class="table table-striped"><tbody class="files"></tbody></table>

<link rel="stylesheet" type="text/css" href="${pageContext.request.contextPath}/js/jquery-file-upload-9.14.2/css/jquery.fileupload.css">
<link rel="stylesheet" type="text/css" href="${pageContext.request.contextPath}/js/jquery-file-upload-9.14.2/css/jquery.fileupload-ui.css">

<script type="text/javascript" src="${pageContext.request.contextPath}/js/jquery-file-upload-9.14.2/js/vendor/jquery.ui.widget.js"></script>
<script type="text/javascript" src="${pageContext.request.contextPath}/js/jquery-file-upload-9.14.2/js/jquery.iframe-transport.js"></script>
<script type="text/javascript" src="${pageContext.request.contextPath}/js/jquery-file-upload-9.14.2/js/jquery.fileupload.js"></script>
<script type="text/javascript" src="${pageContext.request.contextPath}/js/jquery-file-upload-9.14.2/js/jquery.fileupload-process.js"></script>
<script type="text/javascript" src="${pageContext.request.contextPath}/js/jquery-file-upload-9.14.2/js/jquery.fileupload-validate.js"></script>
<script type="text/javascript" src="${pageContext.request.contextPath}/js/jquery-file-upload-9.14.2/js/jquery.fileupload-ui.js"></script>

<script type="text/javascript">
    $(document).ready(function () {
            var maxFileSizeBytes = ${maxFileSizeBytes};
        if (maxFileSizeBytes < 0) {
            //-1 or any negative value means no size limit
            //set to undefined
            ///programming/5795936/how-to-set-a-javascript-var-as-undefined
            maxFileSizeBytes = void 0;
        }

        //https://github.com/blueimp/jQuery-File-Upload/wiki/Options
        ///programming/34063348/jquery-file-upload-basic-plus-ui-and-i18n
        ///programming/11337897/how-to-customize-upload-download-template-of-blueimp-jquery-file-upload
        $('#fileupload').fileupload({
            url: '${pageContext.request.contextPath}/app/uploadResources.do',
            fileInput: $('#fileuploadInput'),
            acceptFileTypes: /(\.|\/)(jrxml|png|jpe?g)$/i,
            maxFileSize: maxFileSizeBytes,
            messages: {
                acceptFileTypes: '${fileTypeNotAllowedText}',
                maxFileSize: '${fileTooLargeMBText}'
            },
            filesContainer: $('.files'),
            uploadTemplateId: null,
            downloadTemplateId: null,
            uploadTemplate: function (o) {
                var rows = $();
                $.each(o.files, function (index, file) {
                    var row = $('<tr class="template-upload fade">' +
                            '<td><p class="name"></p>' +
                            '<strong class="error text-danger"></strong>' +
                            '</td>' +
                            '<td><p class="size"></p>' +
                            '<div class="progress progress-striped active" role="progressbar" aria-valuemin="0" aria-valuemax="100" aria-valuenow="0">' +
                            '<div class="progress-bar progress-bar-success" style="width:0%;"></div></div>' +
                            '</td>' +
                            '<td>' +
                            (!index && !o.options.autoUpload ?
                                    '<button class="btn btn-primary start" disabled>' +
                                    '<i class="glyphicon glyphicon-upload"></i> ' +
                                    '<span>${startText}</span>' +
                                    '</button>' : '') +
                            (!index ? '<button class="btn btn-warning cancel">' +
                                    '<i class="glyphicon glyphicon-ban-circle"></i> ' +
                                    '<span>${cancelText}</span>' +
                                    '</button>' : '') +
                            '</td>' +
                            '</tr>');
                    row.find('.name').text(file.name);
                    row.find('.size').text(o.formatFileSize(file.size));
                    if (file.error) {
                        row.find('.error').text(file.error);
                    }
                    rows = rows.add(row);
                });
                return rows;
            },
            downloadTemplate: function (o) {
                var rows = $();
                $.each(o.files, function (index, file) {
                    var row = $('<tr class="template-download fade">' +
                            '<td><p class="name"></p>' +
                            (file.error ? '<strong class="error text-danger"></strong>' : '') +
                            '</td>' +
                            '<td><span class="size"></span></td>' +
                            '<td>' +
                            (file.deleteUrl ? '<button class="btn btn-danger delete">' +
                                    '<i class="glyphicon glyphicon-trash"></i> ' +
                                    '<span>${deleteText}</span>' +
                                    '</button>' : '') +
                            '<button class="btn btn-warning cancel">' +
                            '<i class="glyphicon glyphicon-ban-circle"></i> ' +
                            '<span>${clearText}</span>' +
                            '</button>' +
                            '</td>' +
                            '</tr>');
                    row.find('.name').text(file.name);
                    row.find('.size').text(o.formatFileSize(file.size));
                    if (file.error) {
                        row.find('.error').text(file.error);
                    }
                    if (file.deleteUrl) {
                        row.find('button.delete')
                                .attr('data-type', file.deleteType)
                                .attr('data-url', file.deleteUrl);
                    }
                    rows = rows.add(row);
                });
                return rows;
            }
        });

    });
</script>

Controladores de solicitud de carga y eliminación de muestra

    @PostMapping("/app/uploadResources")
public @ResponseBody
Map<String, List<FileUploadResponse>> uploadResources(MultipartHttpServletRequest request,
        Locale locale) {
    //https://github.com/jdmr/fileUpload/blob/master/src/main/java/org/davidmendoza/fileUpload/web/ImageController.java
    //https://github.com/blueimp/jQuery-File-Upload/wiki/Setup#using-jquery-file-upload-ui-version-with-a-custom-server-side-upload-handler
    Map<String, List<FileUploadResponse>> response = new HashMap<>();
    List<FileUploadResponse> fileList = new ArrayList<>();

    String deleteUrlBase = request.getContextPath() + "/app/deleteResources.do?filename=";

    //http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/multipart/MultipartRequest.html
    Iterator<String> itr = request.getFileNames();
    while (itr.hasNext()) {
        String htmlParamName = itr.next();
        MultipartFile file = request.getFile(htmlParamName);
        FileUploadResponse fileDetails = new FileUploadResponse();
        String filename = file.getOriginalFilename();
        fileDetails.setName(filename);
        fileDetails.setSize(file.getSize());
        try {
            String message = saveFile(file);
            if (message != null) {
                String errorMessage = messageSource.getMessage(message, null, locale);
                fileDetails.setError(errorMessage);
            } else {
                //save successful
                String encodedFilename = URLEncoder.encode(filename, "UTF-8");
                String deleteUrl = deleteUrlBase + encodedFilename;
                fileDetails.setDeleteUrl(deleteUrl);
            }
        } catch (IOException ex) {
            logger.error("Error", ex);
            fileDetails.setError(ex.getMessage());
        }

        fileList.add(fileDetails);
    }

    response.put("files", fileList);

    return response;
}

@PostMapping("/app/deleteResources")
public @ResponseBody
Map<String, List<Map<String, Boolean>>> deleteResources(@RequestParam("filename") List<String> filenames) {
    Map<String, List<Map<String, Boolean>>> response = new HashMap<>();
    List<Map<String, Boolean>> fileList = new ArrayList<>();

    String templatesPath = Config.getTemplatesPath();
    for (String filename : filenames) {
        Map<String, Boolean> fileDetails = new HashMap<>();

        String cleanFilename = ArtUtils.cleanFileName(filename);
        String filePath = templatesPath + cleanFilename;

        File file = new File(filePath);
        boolean deleted = file.delete();

        if (deleted) {
            fileDetails.put(cleanFilename, true);
        } else {
            fileDetails.put(cleanFilename, false);
        }

        fileList.add(fileDetails);
    }

    response.put("files", fileList);

    return response;
}

Clase de muestra para generar la respuesta json requerida

    public class FileUploadResponse {
    //https://github.com/blueimp/jQuery-File-Upload/wiki/Setup#using-jquery-file-upload-ui-version-with-a-custom-server-side-upload-handler

    private String name;
    private long size;
    private String error;
    private String deleteType = "POST";
    private String deleteUrl;

    /**
     * @return the name
     */
    public String getName() {
        return name;
    }

    /**
     * @param name the name to set
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * @return the size
     */
    public long getSize() {
        return size;
    }

    /**
     * @param size the size to set
     */
    public void setSize(long size) {
        this.size = size;
    }

    /**
     * @return the error
     */
    public String getError() {
        return error;
    }

    /**
     * @param error the error to set
     */
    public void setError(String error) {
        this.error = error;
    }

    /**
     * @return the deleteType
     */
    public String getDeleteType() {
        return deleteType;
    }

    /**
     * @param deleteType the deleteType to set
     */
    public void setDeleteType(String deleteType) {
        this.deleteType = deleteType;
    }

    /**
     * @return the deleteUrl
     */
    public String getDeleteUrl() {
        return deleteUrl;
    }

    /**
     * @param deleteUrl the deleteUrl to set
     */
    public void setDeleteUrl(String deleteUrl) {
        this.deleteUrl = deleteUrl;
    }

}

Ver https://pitipata.blogspot.co.ke/2017/01/using-jquery-file-upload-ui.html

Timothy Anyona
fuente