最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Extjs File upload response and Java spring - Stack Overflow

programmeradmin0浏览0评论

I have extjs code which will create the form and it allows the user to choose the file to upload to the server. below is the extjs code.

 var fp = new Ext.FormPanel({
    renderTo: 'questionnaire_div',
    id : 'FileuploadID',
    fileUpload: true,
    width: 500,
    frame: true,
    title: 'Upload Audit File',
    autoHeight: true,
    bodyStyle: 'padding: 10px 10px 10px 10px;',
    labelWidth: 50,
    defaults: {
    anchor: '95%',
    allowBlank: false,
    msgTarget: 'side'
},
items: [{
    xtype: 'fileuploadfield',
    id: 'form-file',
    emptyText: 'Select PDF file',
    fieldLabel: 'PDF',
    name: 'file'
}],
buttons: [{
    text: 'Upload',
    handler: function(){
    if(fp.getForm().isValid()){
        fp.getForm().submit({
            url: 'uploadAuditPDF',
            //method : 'POST',
            waitMsg: 'Uploading Audit PDF file...',
            success: function(fp, o){
            msg('Success', 'Processed file "'+o.result.file+'" on the server');
        },
        failure : function() {
            alert('Uploading Audit PDF file failed...');
        }
        });
    }
}
}]
});

Below is the code to accept the request and store the file in database.

@RequestMapping(value="/uploadAuditPDF", method = RequestMethod.POST)     
public @ResponseBody String uploadAuditPDF(WebRequest request, FileUploadBean uploadItem, BindingResult result){

    if (result.hasErrors()){
        for(ObjectError error : result.getAllErrors()){ 
        return "{\"success\":false}";
    }    

    if(uploadItem.getFile() != null){
        String fileName = uploadItem.getFile().getOriginalFilename();
        byte[] file = uploadItem.getFile().getBytes();
        QuestionnaireHandler questionnaireHandler = new QuestionnaireHandler();
        try{
            questionnaireHandler.saveFileAttachment(fileName, file);
        }catch (Exception ex) {
                    throw new VDSQRuntimeException(PropertiesReader.getValue(Constants.ERROR_GENERIC));
        }

    }else{
        return "{\"success\":false}";
    }
    return "{\"success\":true}";
}

Here my problem is even though file uploading functionality is working properly as desired. but the response i.e. success string is not ing to ExtJS side, hence in extjs form always failure callback function is getting executed.

failure : function() {
            alert('Uploading Audit PDF file failed...');
        }

can anyone help how to send the response to the user to convey the status of file upload success or failure ?

I have extjs code which will create the form and it allows the user to choose the file to upload to the server. below is the extjs code.

 var fp = new Ext.FormPanel({
    renderTo: 'questionnaire_div',
    id : 'FileuploadID',
    fileUpload: true,
    width: 500,
    frame: true,
    title: 'Upload Audit File',
    autoHeight: true,
    bodyStyle: 'padding: 10px 10px 10px 10px;',
    labelWidth: 50,
    defaults: {
    anchor: '95%',
    allowBlank: false,
    msgTarget: 'side'
},
items: [{
    xtype: 'fileuploadfield',
    id: 'form-file',
    emptyText: 'Select PDF file',
    fieldLabel: 'PDF',
    name: 'file'
}],
buttons: [{
    text: 'Upload',
    handler: function(){
    if(fp.getForm().isValid()){
        fp.getForm().submit({
            url: 'uploadAuditPDF',
            //method : 'POST',
            waitMsg: 'Uploading Audit PDF file...',
            success: function(fp, o){
            msg('Success', 'Processed file "'+o.result.file+'" on the server');
        },
        failure : function() {
            alert('Uploading Audit PDF file failed...');
        }
        });
    }
}
}]
});

Below is the code to accept the request and store the file in database.

@RequestMapping(value="/uploadAuditPDF", method = RequestMethod.POST)     
public @ResponseBody String uploadAuditPDF(WebRequest request, FileUploadBean uploadItem, BindingResult result){

    if (result.hasErrors()){
        for(ObjectError error : result.getAllErrors()){ 
        return "{\"success\":false}";
    }    

    if(uploadItem.getFile() != null){
        String fileName = uploadItem.getFile().getOriginalFilename();
        byte[] file = uploadItem.getFile().getBytes();
        QuestionnaireHandler questionnaireHandler = new QuestionnaireHandler();
        try{
            questionnaireHandler.saveFileAttachment(fileName, file);
        }catch (Exception ex) {
                    throw new VDSQRuntimeException(PropertiesReader.getValue(Constants.ERROR_GENERIC));
        }

    }else{
        return "{\"success\":false}";
    }
    return "{\"success\":true}";
}

Here my problem is even though file uploading functionality is working properly as desired. but the response i.e. success string is not ing to ExtJS side, hence in extjs form always failure callback function is getting executed.

failure : function() {
            alert('Uploading Audit PDF file failed...');
        }

can anyone help how to send the response to the user to convey the status of file upload success or failure ?

Share Improve this question asked Feb 5, 2013 at 11:05 AGBAGB 431 silver badge6 bronze badges 2
  • Would suggest you read the docs about file uploads: docs.sencha./ext-js/4-1/#!/api/… – Evan Trimboli Commented Feb 5, 2013 at 12:00
  • Hi i am using extjs 3.4 api. can you suggest the solution with respect to extjs version i am using. – AGB Commented Feb 6, 2013 at 10:17
Add a ment  | 

3 Answers 3

Reset to default 2

For me, solving this issue -- which I spent most of the day on -- was insanely simple: include {"success":true,...} in the top-level of your JSON response. ExtJS expects it.

Here's my controller function:

@RequestMapping(value="/convertXLSToJSON", method=RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
public String handleFileUpload(@RequestParam("name") String name, @RequestParam("file") MultipartFile file) 
{
      JSONObject full_jo = null;

      //blah blah blah... process file into JSON

      return full_jo.toString();
}

Change your formpanel code like this:

var fp = new Ext.FormPanel({
    renderTo: 'questionnaire_div',
    id: 'FileuploadID',
    fileUpload: true,
    width: 500,
    frame: true,
    title: 'Upload Audit File',
    autoHeight: true,
    bodyStyle: 'padding: 10px 10px 10px 10px;',
    labelWidth: 50,
    defaults: 
    {
        anchor      : '95%',
        allowBlank  : false,
        msgTarget   : 'side'
    },
    items: [
        {
            xtype: 'fileuploadfield',
            id: 'form-file',
            emptyText: 'Select PDF file',
            fieldLabel: 'PDF',
            name: 'file'
        }
    ],
    buttons: [
        {
            text: 'Upload',
            handler: function () 
            {
                if (fp.getForm().isValid()) 
                {
                    fp.getForm().submit(
                    {
                        url: 'uploadAuditPDF',
                        //method : 'POST',
                        waitMsg: 'Uploading Audit PDF file...',
                        success: function (fp, o) 
                        {
                            // ******************************************************
                            var result = o.result.success;
                            if(success)
                            {
                                msg('Success', 'Processed file "' + o.result.file + '" on the server');
                            }
                            else
                            {
                                alert('Uploading Audit PDF file failed...');
                            }
                            // ******************************************************
                        }
                    });
                }
            }
        }
    ]
});

Change your java controller like this:

@RequestMapping(value="/uploadAuditPDF", method = RequestMethod.POST)     
public @ResponseBody void uploadAuditPDF(WebRequest request, FileUploadBean uploadItem, BindingResult result, HttpServletResponse response)
{
    // I defined global return variable and initialized it
    String successResult = false;

    if (result.hasErrors())
    {

        successResult = false;
    }    

    if(uploadItem.getFile() != null)
    {
        String fileName = uploadItem.getFile().getOriginalFilename();
        byte[] file = uploadItem.getFile().getBytes();
        QuestionnaireHandler questionnaireHandler = new QuestionnaireHandler();
        try
        {
            questionnaireHandler.saveFileAttachment(fileName, file);
        }
        catch (Exception ex) 
        {
            throw new VDSQRuntimeException(PropertiesReader.getValue(Constants.ERROR_GENERIC));
        }

    }
    else
    {
        successResult = false;
    }
    successResult = true;

    // TODO: here is important part
    response.setContentType("text/html");
    response.getWriter().write("{success:"+successResult+"}");
}

I post my solution, this solution works for me.

This is on client(jsp file): on jsp begining action mapping:

<portlet:actionURL name="uploadReportTemplate" var="uploadReportTemplateUrl"/>

and ExtJS action code:

var uploadAct = Ext.create('Ext.Action', {
        text: 'Upload',
        icon: '${CONTEXT_PATH}/images/import.png',
        disabled: true,
        handler: function(widget, event) {
            var uploadWindow = Ext.create('Ext.window.Window', {
            title: 'File Uploader',
            width: 500,
            frame: true,
            items: [{
                    xtype: 'form',
                    bodyPadding: 15,
                    url: '${uploadReportTemplateUrl}',
                    fileUpload: true,
                    method: 'POST',
                    enctype : 'multipart/form-data', 
                    items: [{
                        xtype: 'filefield',
                        id: 'form-file',
                        name: 'reportTemplateFile',
                        fieldLabel: 'File',
                        labelWidth: 50,
                        msgTarget: 'side',
                        allowBlank: false,
                        anchor: '100%',
                        buttonText: 'Select a File...'
                    },
                    {
                        xtype: 'hidden',
                        id: 'form-path',
                        name: 'path',
                        value: selectedElementPath
                    }                   
                    ],
                    buttons: [{
                        text: 'Upload',
                        handler: function(){
                            var form = this.up('form').getForm();
                            if (form.isValid()){
                                form.submit({
                                    waitMsg: 'File uloading...',
                                    success: function(form, action) {
                                        uploadWindow.close();
                                        simpleTree.store.reload();
                                        Ext.example.msg('File uploading', 'File {0} uploaded.', action.result.path);
                                    },
                                    failure: function(form, action) {
                                        Ext.example.msg('File uploading', 'Error during upload report template.');
                                    }   
                                });
                            }
                        }
                    },{
                        text: 'Cancel',
                        handler: function() {
                            uploadWindow.close();
                        }
                    }]  
                }]          
            }).show();
        }
    });

This is method in controller:

@ActionMapping("uploadReportTemplate")
@RequestMapping(method = RequestMethod.POST)
public
@ResponseBody
void create(FileUploadBean uploadItem, BindingResult result, ActionResponse response) {
    boolean success = true;
    try {
        File file = new File(REPORTS_REPOSITORY_PATH + uploadItem.getPath() + "\\" + uploadItem.getReportTemplateFile().getOriginalFilename());
        FileOutputStream fos = new FileOutputStream(file);
        fos.write(uploadItem.getReportTemplateFile().getBytes());
        fos.close();
    } catch (IOException e) {
        e.printStackTrace();
        success = false;
    }

    JsonResponse.create(response)
            .isSuccess(success)
            .add("path", "ROOT\\" + uploadItem.getPath() + "\\" + uploadItem.getReportTemplateFile().getOriginalFilename())
            .create();
}

Helping class from controller method:

public class JsonResponse {

    public static class Builder {
        private Builder() {
            mapper = new ObjectMapper();
            attributeBuilder = createAttribute();
        }

        private HttpServletResponse response;
        private ObjectMapper mapper;
        private AttributeBuilder attributeBuilder;

        public Builder failure() {
            return add("failure", "true");
        }

        public Builder success() {
            return add("success", "true");
        }

        public Builder isSuccess(boolean success) {
            return (success) ? success() : failure();
        }

        public final Builder add(String key, String value) {
            attributeBuilder.add(key, value);
            return this;
        }

        public void create() {
            write(attributeBuilder.create());
        }

        public void from(Object o) {
            write(o);
        }

        private final Builder write(Object o) {
            try {
                mapper.writeValue(response.getWriter(), o);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
            return this;
        }

        public Builder json(String json) {
            response.setContentType("application/json; charset=utf-8");
            try {
                write(mapper.readValue(json, Object.class));
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
            return this;
        }

    }

    public static Builder create(ResourceResponse response) {
        Builder builder = new Builder();
        builder.response = PortalUtil.getHttpServletResponse(response);
        return builder;
    }

    public static Builder create(HttpServletResponse response) {
        Builder builder = new Builder();
        builder.response = response;
        return builder;
    }

    public static Builder create(ActionResponse response) {
        Builder builder = new Builder();
        builder.response = PortalUtil.getHttpServletResponse(response);
        return builder;
    }

    public static class AttributeBuilder {
        private Map<String, Object> attributes = new LinkedHashMap<String, Object>();

        private AttributeBuilder() {

        }

        public AttributeBuilder add(String key, Object value) {
            attributes.put(key, value);
            return this;
        }

        public Map<String, Object> create() {
            return attributes;
        }
    }

    public static AttributeBuilder createAttribute() {
        return new AttributeBuilder();
    }

}

ps. This solution work on SpringMVC on Liferay 6.0.6

发布评论

评论列表(0)

  1. 暂无评论