2

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

谁能帮助如何向用户发送响应以传达文件上传成功或失败的状态?

4

3 回答 3

2

对我来说,解决这个问题——我花了一天的大部分时间——非常简单:在 JSON 响应的顶层包含 {"success":true,...} 。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();
}
于 2015-04-10T20:50:25.673 回答
0

像这样更改您的表单面板代码:

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+"}");
}
于 2013-03-30T13:52:27.890 回答
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();
    }

}

附言。此解决方案适用于 Liferay 6.0.6 上的 SpringMVC

于 2013-04-09T11:22:38.873 回答