Extjs文件上传响应和Java spring

时间:2013-02-05 11:05:24

标签: java javascript spring json extjs

我有extjs代码,它将创建表单,并允许用户选择要上传到服务器的文件。下面是extjs代码。

 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...');
        }
        });
    }
}
}]
});

以下是接受请求并将文件存储在数据库中的代码。

@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}";
}

我的问题是即使文件上传功能正常工作也是如此。但响应即成功字符串不会进入ExtJS端,因此在extjs形式中总是失败回调函数正在执行。

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

任何人都可以帮助如何将响应发送给用户以传达文件上传成功或失败的状态吗?

3 个答案:

答案 0 :(得分:2)

对我来说,解决这个问题 - 我一天中大部分时间都在这个问题上 - 非常简单:包括{“成功”:真实,......} 在顶层你的JSON响应。 ExtJS期待它。

这是我的控制器功能:

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

答案 1 :(得分:0)

更改您的formpanel代码,如下所示:

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...');
                            }
                            // ******************************************************
                        }
                    });
                }
            }
        }
    ]
});

像这样更改你的java控制器:

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

答案 2 :(得分:0)

我发布了我的解决方案,这个解决方案适合我。

这是在客户端(jsp文件): 在jsp开始行动映射:

< portlet:actionURL name =“uploadReportTemplate”var =“uploadReportTemplateUrl”/>

和ExtJS操作代码:

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

这是控制器中的方法:

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

从控制器方法帮助类:

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。此解决方案适用于Liferay 6.0.6上的SpringMVC