解决:百度编辑器Ueditor跨域上传图片

问题:百度编辑器上传图片到本项目的时候,没有问题,一旦跨域上传图片的时候就会导致图片上传错误,原因是因为百度编辑器使用的编辑区域是IFrame,而父窗口和主窗口的数据不可跨域调用.

解决方案:将百度编辑器的图片数据提交到本项目,获取到图片的字节文件,接着使用远程方法调用将字节数据发送到图片项目存储到硬盘,存储成功之后,将图片的引用URL及其他信息以RMI的返回值返回,在本项目中将接收的上传成功的数据翻译到前端

所用技术:Ueditor、spring3.0+springMVC、spring3.0+hessian3.0

思想:

具体代码:

1、Ueditor demo.html

<!DOCTYPE HTML>
<html lang="en-US">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
    <title>ueditor demo</title>
</head>

<body>
<!-- 加载编辑器的容器 -->
<script id="UContainer" name="content" type="text/plain" style="margin-top: 300px">
        这里写你的初始化内容





</script>
<!-- 配置文件 -->
<script type="text/javascript" src="ueditor.config.js"></script>
<!-- 编辑器源码文件 -->
<script type="text/javascript" src="ueditor.all.js"></script>
<!-- 实例化编辑器 -->
<script type="text/javascript">
    //test************windows
    var uploadImageUrl = 'http://127.0.0.1/ueditor/upload';



    UE.Editor.prototype._bkGetActionUrl = UE.Editor.prototype.getActionUrl;
    UE.Editor.prototype.getActionUrl = function (action) {
//        if (action == 'uploadimage' || action == 'uploadscrawl' || action == 'uploadimage') {
        if (action == 'uploadimage') {
            return uploadImageUrl;
        } else if (action == 'uploadvideo') {
            return 'http://a.b.com/video.php';
        } else {
            return this._bkGetActionUrl.call(this, action);
        }
    }

    var toolbarsItems = [
        [
            'anchor', //锚点
            'undo', //撤销
            'redo', //重做
            'bold', //加粗
            'indent', //首行缩进
            'snapscreen', //截图
            'italic', //斜体
            'underline', //下划线
            'strikethrough', //删除线
            'subscript', //下标
            'fontborder', //字符边框
            'superscript', //上标
            'formatmatch', //格式刷
            //'source', //源代码
            'blockquote', //引用
            'pasteplain', //纯文本粘贴模式
            'selectall', //全选
            //'print', //打印
            'preview', //预览
            'horizontal', //分隔线
            'removeformat', //清除格式
            'time', //时间
            'date', //日期
            'unlink', //取消链接
            'insertrow', //前插入行
            'insertcol', //前插入列
            'mergeright', //右合并单元格
            'mergedown', //下合并单元格
            'deleterow', //删除行
            'deletecol', //删除列
            'splittorows', //拆分成行
            'splittocols', //拆分成列
            'splittocells', //完全拆分单元格
            'deletecaption', //删除表格标题
            'inserttitle', //插入标题
            'mergecells', //合并多个单元格
            'deletetable', //删除表格
            'cleardoc', //清空文档
            'insertparagraphbeforetable', //"表格前插入行"
            //'insertcode', //代码语言
            'fontfamily', //字体
            'fontsize', //字号
            'paragraph', //段落格式
            'simpleupload', //单图上传
            'insertimage', //多图上传
            'edittable', //表格属性
            'edittd', //单元格属性
            'link', //超链接
            'emotion', //表情
            'spechars', //特殊字符
            'searchreplace', //查询替换
            'map', //Baidu地图
            //'gmap', //Google地图
            //'insertvideo', //视频
            'help', //帮助
            'justifyleft', //居左对齐
            'justifyright', //居右对齐
            'justifycenter', //居中对齐
            'justifyjustify', //两端对齐
            'forecolor', //字体颜色
            'backcolor', //背景色
            'insertorderedlist', //有序列表
            'insertunorderedlist', //无序列表
            'fullscreen', //全屏
            'directionalityltr', //从左向右输入
            'directionalityrtl', //从右向左输入
            'rowspacingtop', //段前距
            'rowspacingbottom', //段后距
            'pagebreak', //分页
            //'insertframe', //插入Iframe
            'imagenone', //默认
            'imageleft', //左浮动
            'imageright', //右浮动
            'attachment', //附件
            'imagecenter', //居中
            'wordimage', //图片转存
            'lineheight', //行间距
            'edittip ', //编辑提示
            'customstyle', //自定义标题
            'autotypeset', //自动排版
            //'webapp', //百度应用
            'touppercase', //字母大写
            'tolowercase', //字母小写
            'background', //背景
            'template', //模板
            //'scrawl', //涂鸦
            //'music', //音乐
            'inserttable', //插入表格
            //'drafts', // 从草稿箱加载
            'charts', // 图表
        ]
    ];
    var ue = UE.getEditor('UContainer', {
        toolbars: toolbarsItems,
        autoHeightEnabled: true,
        autoFloatEnabled: true
    });


</script>
</body>

</html>

2、common server

  @RequestMapping(value = "ueditor/upload", method = RequestMethod.POST)
    @ResponseBody
    public Map<String, Object> upload(HttpServletRequest request, HttpServletResponse response) {
        try {
//            String uploadDomain = "http://127.0.0.1:8083";//本地测试
            

            Map<String, Object> result = new HashMap<>();
            MultipartHttpServletRequest multipartHttpServletRequest = (MultipartHttpServletRequest) request;
            MultipartFile multipartFile = multipartHttpServletRequest.getFile("upfile");

            Long startTime = System.currentTimeMillis();
            String url = uploadDomain + "/hessian/hessianFileUploadImpl";
            HessianFileUpload service = (HessianFileUpload) factory.create(HessianFileUpload.class, url);
//            Map<String, Object> map = service.uploadForStream(multipartHttpServletRequest.getInputStream(),multipartFile.getOriginalFilename(), multipartFile.getSize());
//            Map<String, Object> map = service.uploadForSpring(multipartFile);
            byte[] data = multipartFile.getBytes();

            if (data != null && data.length > 5242880 || data == null) {//上限5M 5242880
                result.put("state", "文件过大,上传失败,上文大小上限5MB");
                return result;
            }
            System.err.println("文件大小=" + (data.length));
            Map<String, Object> map = service.uploadByBytes(data, multipartFile.getOriginalFilename(), multipartFile.getSize());
            System.err.println("duration=" + (System.currentTimeMillis() - startTime));
            return map;
        } catch (Exception e) {
            e.printStackTrace();
        }


        return null;
    }

3、Hessian接口

public interface HessianFileUpload {



    /**
     * 按字节上传文件
     * @return
     */
    Map<String, Object> uploadByBytes(byte[] bytes,String filename, Long available);
}

3、hessian实现

 /**
     * 按字节上传,
     *
     * @param bytes
     * @return
     */
    @Override
    public Map<String, Object> uploadByBytes(byte[] bytes, String oldFilename, Long available) {
//test***********************windows本地测试
        //download
        String domain = "http://127.0.0.1:8083/";
        String realPathDown = "upload/";
        //upload
        String realPathUpload = "D:\\Program Files (x86)\\JetBrains\\IDEA_WORKSPACE\\QyImage\\src\\main\\webapp\\upload";
//test*******************END


        

//        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;
        Map<String, Object> jsonObject = new HashMap<>();
        try {
            //获取客户端传递的InputStream
//            bis = new BufferedInputStream(inputStream);


            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMdd");
            String dateDir = simpleDateFormat.format(new Date());
            //上传的路径名*****************************
            String uploadPath = realPathUpload + File.separator + dateDir;
            logger.info("uploadPath=" + uploadPath);
            File filey = new File(uploadPath);
            if (!filey.exists()) {
                filey.mkdirs();
            }

            //获取后缀,仅限于图片格式
            //[".png", ".jpg", ".jpeg", ".gif", ".bmp"]
            List<String> limitsuffixList = Arrays.asList(".png", ".jpg", ".jpeg", ".gif", ".bmp");
            String suffixName = oldFilename.substring(oldFilename.lastIndexOf("."), oldFilename.length());
            if (!limitsuffixList.contains(suffixName)) {
                jsonObject.put("state", "文件格式不合法,支持的文件类型[\".png\", \".jpg\", \".jpeg\", \".gif\", \".bmp\"]");
                return jsonObject;//文件后缀名不合法,上传失败
            }
            //上传的文件名
            String filename = UUID.randomUUID() + new SimpleDateFormat("yyyyMMddHHmmssSSS").format(new Date()) + suffixName;
            logger.info("filename=" + filename);
            //文件名不能大于5M
            if (available > 5242880) {
                jsonObject.put("state", "文件过大,上传失败");
                return jsonObject;//返回上传失败
            }
            String saveFilename = uploadPath + File.separator + filename;


            //创建文件输出流
            bos = new BufferedOutputStream(new FileOutputStream(new File(saveFilename)));
//            byte[] buffer = new byte[8192];
//            int r = bis.read(buffer, 0, buffer.length);
//            while (r > 0) {
//                bos.write(buffer, 0, r);
//                r = bis.read(buffer, 0, buffer.length);
//            }
            bos.write(bytes);
            String imgAccessUrl = domain + realPathDown + File.separator + dateDir + "/" + filename;
            jsonObject.put("state", "SUCCESS");
            jsonObject.put("url", imgAccessUrl);//图片的展示路径
            jsonObject.put("title", oldFilename);//图片的名称
            jsonObject.put("original", oldFilename);

//            response.getWriter().write(jsonObject.toString());
//            response.setHeader("referer","http://127.0.0.1/");
            logger.info(jsonObject.toString());
            logger.info("-------upload success!-------------");
            return jsonObject;
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            if (bos != null) {
                try {
                    bos.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
//            if (bis != null) {
//                try {
//                    bis.close();
//                } catch (IOException e) {
//                    throw new RuntimeException(e);
//                }
//            }
        }

    }

4、hessian配置

服务端配置:

web.xml

<!-- hessian 配置  默认会加载hessian-servlet.xml-->
    <servlet>
        <servlet-name>hessian</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>hessian</servlet-name>
        <url-pattern>/hessian/*</url-pattern>
    </servlet-mapping>
    <!-- hessian 配置 -->

hessian-servlet.xml

  <!--  Hessian访问路径 含权限认证 -->
    <bean name="/hessianFileUploadImpl" class="com.*.HessianServerProxyExporter">
        <property name="service" ref="hessianFileUploadImpl"/>
        <property name="serviceInterface">
            <value>
                com.yizhilu.os.image.framework.hessian.service.HessianFileUpload
            </value>
        </property>
    </bean>

 hessian客户端配置

<!--Ueditor上传图片-->
    <bean id="hessianFileUpload"
          class="org.springframework.remoting.caucho.HessianProxyFactoryBean">
        <property name="serviceInterface"
                  value="com.*.framework.hessian.service.HessianFileUpload"></property>
        <property name="serviceUrl">
            <value>${fileUploadPath}/hessian/hessianFileUploadImpl</value>
        </property>
        <property name="readTimeout">
            <value>100000</value>
        </property>
        <property name="proxyFactory">
            <bean
                    class="com.*.hessian.client.HessianClientProxyFactory" />
        </property>
        <property name="chunkedPost" value="false" />
    </bean>

 

posted @ 2017-04-24 14:06  构建巨人肩膀  阅读(6937)  评论(0编辑  收藏  举报