javaWeb 集成ckeditor5实现上传图片

一开始用官方的上传图片的代码

ClassicEditor.create(document.querySelector('#editor'), {
            ckfinder: {
                uploadUrl:"" + rootPath + "/qiNiu/uploadFile.json" //图片上传url
            }
        }
    ).then(editor => {
 
    } )
    .catch(error => {
        console.log(error);
    } );

后台可以收到图片,并返回json数据。返回到前端会报错,提示Cannot upload file:xxx.png 

直到今天看了CKEditor中ckfinder的源码才发现问题。阅读ckeditor5-adapter-ckfinder发现,ckfinder也定义了UploadAdapter,同样实现了upload()和 abort() 方法。而问题就出现在upload()方法中。下面贴出upload()方法的源码:

upload() {
        return new Promise( ( resolve, reject ) => {
            this._initRequest();
            this._initListeners( resolve, reject );
            this._sendRequest();
        } );
    }

_initListeners( resolve, reject ) {
        const xhr = this.xhr;
        const loader = this.loader;
        const t = this.t;
        const genericError = t( 'Cannot upload file:' ) + ` ${ loader.file.name }.`;

        xhr.addEventListener( 'error', () => reject( genericError ) );
        xhr.addEventListener( 'abort', () => reject() );
        xhr.addEventListener( 'load', () => {
            const response = xhr.response;

            if ( !response || !response.uploaded ) {
                return reject( response && response.error && response.error.message ? response.error.message : genericError );
            }

            resolve( {
                default: response.url
            } );
        } );

        // Upload progress when it's supported.
        /* istanbul ignore else */
        if ( xhr.upload ) {
            xhr.upload.addEventListener( 'progress', evt => {
                if ( evt.lengthComputable ) {
                    loader.uploadTotal = evt.total;
                    loader.uploaded = evt.loaded;
                }
            } );
        }
    }

从上面源码中可以发现,ckfinder请求之后的返回体response应该不为空,且还要包括uploaded和url字段,所以返回数据实际格式应该是{"uploaded":1,"url":"/"},如此就不会出错了。所以,返回的数据并不是按照“教程“”说的那样。

upload.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>上传图片测试</title>
</head>
<body>
    <div>
      <textarea name="content" id="editor">
          <p>这里写内容</p>
      </textarea>
    </div>
</body>
<script type="text/javascript" src="${pageContext.request.contextPath}/ckeditor/ckeditor.js"></script>
<script type="text/javascript" src="${pageContext.request.contextPath}/javascript/editor_common.js"></script>
</html>

editor_common.js

ClassicEditor.create(document.querySelector('#detailContent'), {})
    .then(editor => {
        editor.plugins.get('FileRepository').createUploadAdapter  = (loader) => {
            return new UploadAdapter(loader);
        };
        console.log('Editor was initialized');
})
.catch(error => {
    console.log(error)
});
//自定义适配器
class UploadAdapter {
    constructor(loader) {
        this.loader = loader;
    }
    upload() {
        return new Promise((resolve, reject) => {
            const data = new FormData();
        data.append('file', this.loader.file);
        data.append('allowSize', 10);//允许图片上传的大小/兆
        $.ajax({
            url:  "" + rootPath + "/qiNiu/uploadFile.json",//上传图片的url
            type: 'POST',
            data: data,
            dataType: 'json',
            processData: false,
            contentType: false,
            success: function (data) {
                var tempObj = data.data;
                var status = data.success;
                if (status==true) {
                    resolve({
                        default: tempObj.imageUrl
                    });
                } else {
                    reject(data.msg);
                }
            }
        });
    });
    }
    abort() {
    }
}

后台Controller

@Controller
@RequestMapping("/test")
public class TestController {

    @RequestMapping(value = "/demo")
    public String demo() {
        return "/ui/demo";
    }
}

上传文件的Controller

@RestController
@RequestMapping(value = "qiNiu")
public class QiNiuUploadController {

    public String getUpToken() {
        String ACCESS_KEY = Constant.QINIU_ACCESS_KEY;
        String SECRET_KEY = Constant.QINIU_SECRET_KEY;
        String bucketname = Constant.QINIU_BUCKETNAME;
        Auth auth = Auth.create(ACCESS_KEY, SECRET_KEY);
        return auth.uploadToken(bucketname);
    }

    @RequestMapping(value = "/uploadFile")
    @ResponseBody
    public ResultSupport upload(@RequestParam("file") MultipartFile file) {
        ResultSupport resultSupport=new ResultSupport();
        //构造一个带指定Zone对象的配置类
        Configuration cfg = new Configuration(Zone.zone0());
        //...其他参数参考类注释
        UploadManager uploadManager = new UploadManager(cfg);
        //...生成上传凭证,然后准备上传

        //默认不指定key的情况下,以文件内容的hash值作为文件名
        SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyyMMdd");
        String folderName=simpleDateFormat.format(new Date());
        String key = folderName+"/"+System.currentTimeMillis()+file.getOriginalFilename();
        try {
            StringMap stringMap=new StringMap();
            Response response = uploadManager.put(file.getInputStream(), key, getUpToken(),stringMap,"image/jpeg");
            //解析上传成功的结果
            DefaultPutRet putRet = new Gson().fromJson(response.bodyString(), DefaultPutRet.class);
            System.out.println(putRet.key);
            System.out.println(putRet.hash);
        } catch (QiniuException ex) {
            Response r = ex.response;
            System.err.println(r.toString());
            resultSupport.failSupport("上传文件失败",ResultCode.FAIL_YEWU);
            try {
                System.err.println(r.bodyString());
            } catch (QiniuException ex2) {
                //ignore
                resultSupport.failSupport("上传文件失败",ResultCode.FAIL_YEWU);
            }
        } catch (IOException e) {
            e.printStackTrace();
            resultSupport.failSupport("上传文件失败",ResultCode.FAIL_YEWU);
        }
        Map<String,Object> map=new HashMap<>();
        map.put("imageUrl",Constant.ROOT_QINIU+key);
        map.put("fileName",key);
        return resultSupport.successQuery("上传文件成功",map);
    }
}

807dbbda0fc0d26f99540b7eca2ace5d07b.jpg

参考:

https://www.jianshu.com/p/47e25447b771

 

转载于:https://my.oschina.net/u/3568600/blog/1832939

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值