springboot +Thymeleaf+UEditor整合记录
1,ueditor官网下载:https://ueditor.baidu.com/website/download.html 下载相应的工具包和源码,ps:源码放到工程中
2,解压放到放到项目中,springboot工程创建不再描述过程,resources:下放config.json文件;resources/static/ueditor 放ueditor其他相关内容
3,整理pom.xml文件
<!--thymeleaf 模板 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <!-- thymeleaf网页解析 --> <dependency> <groupId>net.sourceforge.nekohtml</groupId> <artifactId>nekohtml</artifactId> </dependency> <!-- 引入ueditor 需要的工具包 --> <dependency> <groupId>org.json</groupId> <artifactId>json</artifactId> <version>20180130</version> </dependency> <dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.4</version> </dependency> <dependency> <groupId>commons-codec</groupId> <artifactId>commons-codec</artifactId> </dependency>
4,添加UEditorController,跳转到 index页面
import java.io.IOException; import java.io.PrintWriter; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import com.baidu.ueditor.ActionEnter; import com.taogou.controller.base.BaseController; /** * 百度编辑富文本 * * @author Administrator * */ @Controller public class UEditorController extends BaseController { private String prefix = "/ueditor"; @RequestMapping("/") private String showPage() { return prefix + "/index"; } @RequestMapping(value = "/config") public void config(HttpServletRequest request, HttpServletResponse response) { response.setContentType("application/json;charset=utf-8"); String rootPath = request.getSession().getServletContext().getRealPath("/"); try { String exec = new ActionEnter(request, rootPath).exec(); PrintWriter writer = response.getWriter(); writer.write(exec); writer.flush(); writer.close(); } catch (IOException e) { e.printStackTrace(); } } }
index 页面:修改静态资源路径,其他保持一致
<!DOCTYPE> <html xmlns:th="http://www.thymeleaf.org"> <head> <title>完整demo</title> <meta http-equiv="Content-Type" content="text/html;charset=utf-8"/> <script type="text/javascript" charset="utf-8" th:src="@{/static/ueditor/ueditor.config.js}"></script> <script type="text/javascript" charset="utf-8" th:src="@{/static/ueditor/ueditor.all.min.js}"> </script> <!--建议手动加在语言,避免在ie下有时因为加载语言失败导致编辑器加载失败--> <!--这里加载的语言文件会覆盖你在配置项目里添加的语言类型,比如你在配置项目里配置的是英文,这里加载的中文,那最后就是中文--> <script type="text/javascript" charset="utf-8" th:src="@{/static/ueditor/lang/zh-cn/zh-cn.js}"></script> <style type="text/css"> div{ width:100%; } </style> </head> <body>
网页输入:http://localhost:8081/ 查看效果
5,上传图片部分整合 :controller 里面的 /config 放到 ueditor.config.js 中
window.UEDITOR_CONFIG = { //为编辑器实例添加一个路径,这个不能被注释 UEDITOR_HOME_URL: URL // 服务器统一请求接口路径 , serverUrl: "/config" //, serverUrl: URL + "/config" //工具栏上的所有的功能按钮和下拉框,可以在new编辑器的实例时选择自己需要的重新定义 , toolbars: [[
此时会发现无法加载 config.json文件,修改源码ConfigManage 下的getConfigPath()方法
private String getConfigPath() { // return this.parentPath + File.separator + ConfigManager.configFileName; try { // 获取classpath下的config.json路径 // this.getClass().getClassLoader().getResource("config.json").getPath() String classPath = this.getClass().getClassLoader().getResource("config.json").toURI().getPath(); return classPath; } catch (URISyntaxException e) { return null; } }
网页输出看看是否正确:http://localhost:8081/config?action=config
6,此时点击上传图片显示 如下
7,在源码: BinaryUploader 类中 把原有的文件上传request请求替换成spring的上传控件
static Logger logger = LoggerFactory.getLogger(BinaryUploader.class); public static final State save(HttpServletRequest request, Map<String, Object> conf) { FileItemStream fileStream = null; boolean isAjaxUpload = request.getHeader("X_Requested_With") != null; if (!ServletFileUpload.isMultipartContent(request)) { return new BaseState(false, AppInfo.NOT_MULTIPART_CONTENT); } ServletFileUpload upload = new ServletFileUpload(new DiskFileItemFactory()); if (isAjaxUpload) { upload.setHeaderEncoding("UTF-8"); } try { // 把原有的文件上传request请求替换成spring的上传控件 MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request; MultipartFile multipartFile = multipartRequest.getFile(conf.get("fieldName").toString()); if (multipartFile == null) { return new BaseState(false, 7); } /* * FileItemIterator iterator = upload.getItemIterator(request); while * (iterator.hasNext()) { fileStream = iterator.next(); * * if (!fileStream.isFormField()) break; fileStream = null; } if (fileStream == * null) { return new BaseState(false, AppInfo.NOTFOUND_UPLOAD_DATA); } */ String savePath = (String) conf.get("savePath"); String localSavePathPrefix = (String) conf.get("localSavePathPrefix"); // spring String originFileName = multipartFile.getOriginalFilename(); String suffix = FileType.getSuffixByFilename(originFileName); originFileName = originFileName.substring(0, originFileName.length() - suffix.length()); savePath = savePath + suffix; long maxSize = ((Long) conf.get("maxSize")).longValue(); if (!validType(suffix, (String[]) conf.get("allowFiles"))) { return new BaseState(false, 8); } savePath = PathFormat.parse(savePath, originFileName); localSavePathPrefix = localSavePathPrefix + savePath; String physicalPath = localSavePathPrefix; logger.info("BinaryUploader physicalPath:{},savePath:{}", localSavePathPrefix, savePath); // spring InputStream is = multipartFile.getInputStream(); State storageState = StorageManager.saveFileByInputStream(is, physicalPath, maxSize); is.close(); if (storageState.isSuccess()) { storageState.putInfo("url", PathFormat.format(savePath)); storageState.putInfo("type", suffix); storageState.putInfo("original", originFileName + suffix); } return storageState; } catch (IOException e) { } return new BaseState(false, AppInfo.IO_ERROR); }
8,解决图片上传路径问题
在config.json 增加 localSavePathPrefix 地址保存图片
{ /* 上传图片配置项 */ "localSavePathPrefix":"D:/ueditor/images", /* 上传图片配置项 */ "imageActionName": "uploadimage", /* 执行上传图片的action名称 */ "imageFieldName": "upfile", /* 提交的图片表单名称 */ "imageMaxSize": 2048000, /* 上传大小限制,单位B */ "imageAllowFiles": [".png", ".jpg", ".jpeg", ".gif", ".bmp"], /* 上传图片格式显示 */ "imageCompressEnable": true, /* 是否压缩图片,默认是true */ "imageCompressBorder": 1600, /* 图片压缩最长边限制 */ "imageInsertAlign": "none", /* 插入的图片浮动方式 */ "imageUrlPrefix": "", /* 图片访问路径前缀 */ "imagePathFormat": "/image/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */
修改源码:ConfigManager 方法 getConfig
public Map<String, Object> getConfig(int type) { Map<String, Object> conf = new HashMap<String, Object>(); String savePath = null; // 增加接收要保存图片的物理路径 String localSavePathPrefix = null; switch (type) { case ActionMap.UPLOAD_FILE: conf.put("isBase64", "false"); conf.put("maxSize", this.jsonConfig.getLong("fileMaxSize")); conf.put("allowFiles", this.getArray("fileAllowFiles")); conf.put("fieldName", this.jsonConfig.getString("fileFieldName")); savePath = this.jsonConfig.getString("filePathFormat"); localSavePathPrefix = this.jsonConfig.getString("localSavePathPrefix"); break; case ActionMap.UPLOAD_IMAGE: conf.put("isBase64", "false"); conf.put("maxSize", this.jsonConfig.getLong("imageMaxSize")); conf.put("allowFiles", this.getArray("imageAllowFiles")); conf.put("fieldName", this.jsonConfig.getString("imageFieldName")); savePath = this.jsonConfig.getString("imagePathFormat"); localSavePathPrefix = this.jsonConfig.getString("localSavePathPrefix"); break; case ActionMap.UPLOAD_VIDEO: conf.put("maxSize", this.jsonConfig.getLong("videoMaxSize")); conf.put("allowFiles", this.getArray("videoAllowFiles")); conf.put("fieldName", this.jsonConfig.getString("videoFieldName")); savePath = this.jsonConfig.getString("videoPathFormat"); localSavePathPrefix = this.jsonConfig.getString("localSavePathPrefix"); break; case ActionMap.UPLOAD_SCRAWL: conf.put("filename", ConfigManager.SCRAWL_FILE_NAME); conf.put("maxSize", this.jsonConfig.getLong("scrawlMaxSize")); conf.put("fieldName", this.jsonConfig.getString("scrawlFieldName")); conf.put("isBase64", "true"); savePath = this.jsonConfig.getString("scrawlPathFormat"); localSavePathPrefix = this.jsonConfig.getString("localSavePathPrefix"); break; case ActionMap.CATCH_IMAGE: conf.put("filename", ConfigManager.REMOTE_FILE_NAME); conf.put("filter", this.getArray("catcherLocalDomain")); conf.put("maxSize", this.jsonConfig.getLong("catcherMaxSize")); conf.put("allowFiles", this.getArray("catcherAllowFiles")); conf.put("fieldName", this.jsonConfig.getString("catcherFieldName") + "[]"); savePath = this.jsonConfig.getString("catcherPathFormat"); localSavePathPrefix = this.jsonConfig.getString("localSavePathPrefix"); break; case ActionMap.LIST_IMAGE: conf.put("allowFiles", this.getArray("imageManagerAllowFiles")); conf.put("dir", this.jsonConfig.getString("imageManagerListPath")); conf.put("count", this.jsonConfig.getInt("imageManagerListSize")); localSavePathPrefix = this.jsonConfig.getString("localSavePathPrefix"); break; case ActionMap.LIST_FILE: conf.put("allowFiles", this.getArray("fileManagerAllowFiles")); conf.put("dir", this.jsonConfig.getString("fileManagerListPath")); conf.put("count", this.jsonConfig.getInt("fileManagerListSize")); localSavePathPrefix = this.jsonConfig.getString("localSavePathPrefix"); break; } conf.put("savePath", savePath); conf.put("rootPath", this.rootPath); // 接收要保存图片的物理路径 conf.put("localSavePathPrefix", localSavePathPrefix); return conf; }
然后修改 BinaryUploader 中新增的 localSavePathPrefix
String savePath = (String) conf.get("savePath"); String localSavePathPrefix = (String) conf.get("localSavePathPrefix");
此时点击上传 图片会上传到指定的目录中
图片显示问题 在application.properties 中指定映射地址
#upload img set path taogou.imagesPath=D:/fileUpload/ spring.mvc.static-path-pattern=/** spring.resources.static-locations=classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/,classpath:/public/,file:${taogou.imagesPath}
至此 整合完成,
具体情况具体配置,有什么错误请留言指正