Ueditor是百度富文本编辑器,一款非常优秀的轻量级编辑器。工作中经常会用到Ueditor,如何整合Ueditor是个问题,尤其是上传图片更是令人头痛不已。所以将工作中整合Ueditor的方法写出来,仅供大家参考。 此次案例是将图片上传至图片服务器(已有上传文件接口),采用前后端分离的方式,未将图片保存至本地。
下载版本:dev-2.0.0 Ueditor下载地址:https://github.com/fex-team/ueditor#ueditor
Ueditor官方文档:http://fex.baidu.com/ueditor/
需要重新写一个controller,用于识别config的配置代码。 注意事项: ActionEnter类的使用,此处是上传图片保存成功的关键之处; "uploadimage"比对成功后执行上传图片操作,其他操作默认架在你配置项。
代码示例如下:
package com.cn.controller; import cn.hutool.core.text.UnicodeUtil; import com.cn.service.FileService; import com.alibaba.fastjson.JSONObject; import com.baidu.ueditor.ActionEnter; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.HashMap; import java.util.Map; /** * @Author 奈何繁华如云烟 * @Description TODO * @Date 2020/9/10 18:16 */ @Slf4j @RestController public class UeditorController { @Autowired private FileService fileService; @RequestMapping("/ueditorConfig") public void ueditorConfig(HttpServletRequest request, HttpServletResponse response, MultipartFile upfile) { response.setContentType("application/json"); //配置config.json的位置 String rootPath = Thread.currentThread().getContextClassLoader().getResource("").getPath(); log.info("rootPath: {}", rootPath); try { String exec = ""; String actionType = request.getParameter("action"); if("uploadimage".equalsIgnoreCase(actionType) && !upfile.isEmpty()){ // 做图片上传操作 exec = uploadImage(upfile); }else{ request.setCharacterEncoding( "utf-8" ); exec = new ActionEnter(request, rootPath).exec(); } log.info("exec: {}", UnicodeUtil.toString(exec)); response.getWriter().write(exec); } catch (IOException e) { log.error("UeditorController#config exception:",e); } } private String uploadImage(MultipartFile file) { JSONObject jsonResult = null; try { Map map = fileService.uploadFile(file); if (map == null) { jsonResult = new JSONObject(resultMap("文件上传失败","","","")); } else { String url = map.get("fileUrl").toString(); String fileName = map.get("originalFilename").toString(); String extraName = fileName.substring(fileName.lastIndexOf(".")); jsonResult = new JSONObject(resultMap("SUCCESS",url,fileName,fileName)); } } catch (Exception e) { log.error("UeditorController#uploadImage exception:",e); jsonResult = new JSONObject(resultMap("文件上传失败","","","")); } log.info("jsonResult: {}", jsonResult); return jsonResult.toString(); } //返回结果集 //{"state": "SUCCESS","original": "111.jpg","title": "1535961757878095151.jpg","url": "/1535961757878095151.jpg"} private Map<String,Object> resultMap(String state, String url, String title, String original){ Map<String ,Object> result = new HashMap<>(); result.put("state",state); result.put("url", url); result.put("title",title); result.put("original",original); return result; } }从下载的Ueditor项目中找到config.json文件,并在resource目录下加入此文件。
直接更改Ueditor.config.js文件中的服务器端统一请求路径
var URL = window.UEDITOR_HOME_URL || getUEBasePath(); //添加 // var server_url = window.location.protocol + "//"+window.location.hostname+":"+window.location.port; //可以改成远程服务器域名或IP var server_url = "http://127.0.0.1:8099" /** * * 配置项主体。注意,此处所有涉及到路径的配置别遗漏URL变量。 */ window.UEDITOR_CONFIG = { //为编辑器实例添加一个路径,这个不能被注释 UEDITOR_HOME_URL: URL // 服务器统一请求接口路径 , serverUrl: server_url + "/ueditorConfig"因为单图上传,是为了兼容 低版本,使用了 表单提交到 iframe 的方式,不支持跨域,只能修改源码
更改ueditor.all.js 第24568行,注释form提交的相关代码,并加入以下代码:
// domUtils.on(iframe, 'load', callback); // form.action = utils.formatUrl(imageActionUrl + (imageActionUrl.indexOf('?') == -1 ? '?':'&') + params); // form.submit(); var formdata = new FormData(form); var arr,reg=new RegExp("(^| )_token=([^;]*)(;|$)"); var myForm = document.getElementById("myForm"); var xhr= new XMLHttpRequest(); xhr.open("POST", me.getOpt('serverUrl')+'?action=uploadimage', true); xhr.onreadystatechange = function() { if (xhr.readyState === 4) if ((xhr.status >=200 && xhr.status < 300) || xhr.status == 304) alert(xhr.responseText); } xhr.send(formdata); xhr.onreadystatechange = function () { if(xhr.readyState == 4) { var response = JSON.parse(xhr.responseText); if(response.state=='SUCCESS' ){ loader = me.document.getElementById(loadingId); loader.setAttribute('src', response.url); loader.setAttribute('_src', response.url); loader.setAttribute('title', response.title || ''); loader.setAttribute('alt', response.original || ''); loader.removeAttribute('id'); domUtils.removeClasses(loader, 'loadingclass'); } } }引用的ueditor.all.min.js 改为ueditor.all.js
有可能是跨域问题,需要后台加入全局过滤器,支持跨域访问。代码如下:
/** * @Author 奈何繁华如云烟 * @Description TODO 全局过滤器,支持跨域 * @Date 2020/9/11 15:24 */ @Component public class ServletFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { HttpServletResponse response = (HttpServletResponse) servletResponse; response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE"); response.setHeader("Access-Control-Allow-Origin", "*"); response.setHeader("Access-Control-Allow-Headers", "*"); filterChain.doFilter(servletRequest, servletResponse); } @Override public void destroy() { } }因为ConfigManager中读取config.json文件,是使用的File流,发布到线上后由于本地和服务器的路径配置不同会出现无法读取的现象。所以需要更改ConfigManager中的initEnv()方法,以适配线上应用。修改读取文件的方式为:
//原读取方式 private void initEnv () throws FileNotFoundException, IOException { File file = new File( this.originalPath ); if ( !file.isAbsolute() ) { file = new File( file.getAbsolutePath() ); } this.parentPath = file.getParent(); String configContent = this.readFile( this.getConfigPath() ); try{ JSONObject jsonConfig = new JSONObject( configContent ); this.jsonConfig = jsonConfig; } catch ( Exception e ) { this.jsonConfig = null; } } //修改后读取方式 private void initEnv() throws FileNotFoundException, IOException { File file = new File(this.originalPath); if (!file.isAbsolute()) { file = new File(file.getAbsolutePath()); } this.parentPath = file.getParent(); String configContent = this.filter(IOUtils.toString(this.getClass().getClassLoader().getResourceAsStream("config.json"))); try { JSONObject jsonConfig = JSON.parseObject(configContent); this.jsonConfig = jsonConfig; } catch (Exception var4) { this.jsonConfig = null; } }以上内容仅是一次经验总结,并未深入研究其中的原因,希望可以对阅读到此文章的同学有所帮助。