之前写过一版本的ueditor的使用方式,感觉后来ueditor升级很快,转眼间又升级了,今天有一个人问这块相关的问题,正好又熟悉下。
首先最基本的用法我就不讲了,只讲文件上传的这块。
首先,文件上传这块和之前的变化很大,先慢慢的讲讲用法。
1. java版本的在jsp目录的文件结构如下:
从这地方可以看出来,有一个controller.jsp, 一个config.json,一堆jar文件, 这个和之前版本是不一致的。
2. maven工程的jar包的引用
如果没有使用jar包,很容易,直接copy文件就可以,但是maven的方式,这个jar又在网上没有,索幸maven提供了system方式的依赖方式:
- < dependency>
- < groupId> com.baidu.ueditor </groupId >
- < artifactId> ueditor </artifactId >
- < version> 1.1.1 </version >
- < scope> system </scope >
- < systemPath> ${basedir}/ src/main/webapp /WEB-INF/lib/ ueditor-1.1.1.jar </systemPath >
- </ dependency>
其他的jar我就不多讲了,都很容易找。
3. controller.jsp文件阅读
- <%@ page language="java" contentType="text/html; charset=UTF-8"
- import="com.baidu.ueditor.ActionEnter"
- pageEncoding="UTF-8"%>
- <%@ page trimDirectiveWhitespaces="true" %>
- <%
- request.setCharacterEncoding( "utf-8" );
- response.setHeader("Content-Type" , "text/html");
- String rootPath = application.getRealPath( "/" );
- out.write( new ActionEnter( request, rootPath ).exec() );
- %>
从代码来看,rootPath其实就是项目的根路径,构建了ActionEnter,并调用了exec函数。
我们来看下ActionEnter的代码:
- package com.baidu.ueditor;
- import com.baidu.ueditor.define.ActionMap;
- import com.baidu.ueditor.define.BaseState;
- import com.baidu.ueditor.define.State;
- import com.baidu.ueditor.hunter.FileManager;
- import com.baidu.ueditor.hunter.ImageHunter;
- import com.baidu.ueditor.upload.Uploader;
- import java.util.Map;
- import javax.servlet.http.HttpServletRequest;
- import org.json.JSONObject;
- public class ActionEnter
- {
- private HttpServletRequest request = null;
- private String rootPath = null;
- private String contextPath = null;
- private String actionType = null;
- private ConfigManager configManager = null;
- public ActionEnter(HttpServletRequest request, String rootPath)
- {
- this.request = request;
- this.rootPath = rootPath;
- // 对action进行赋值。
- this.actionType = request.getParameter("action");
- this.contextPath = request.getContextPath();
- // 构建configManager类
- this.configManager = ConfigManager.getInstance(this.rootPath, this.contextPath, request.getRequestURI());
- }
- public String exec()
- {
- // 这个是处理jsonp的形式,一般都是不跨域的。
- String callbackName = this.request.getParameter("callback");
- if (callbackName != null)
- {
- if (!validCallbackName(callbackName)) {
- return new BaseState(false, 401).toJSONString();
- }
- return callbackName + "(" + invoke() + ");";
- }
- return invoke();
- }
- public String invoke()
- {
- // 判断action是否合法,如果不合法返回一个非法状态
- if ((this.actionType == null) || (!ActionMap.mapping.containsKey(this.actionType))) {
- return new BaseState(false, 101).toJSONString();
- }
- // 如果找不到configManager也报错
- if ((this.configManager == null) || (!this.configManager.valid())) {
- return new BaseState(false, 102).toJSONString();
- }
- State state = null;
- // 取得actionCode
- int actionCode = ActionMap.getType(this.actionType);
- Map conf = null;
- switch (actionCode)
- {
- case 0:
- return this.configManager.getAllConfig().toString();
- case 1:
- case 2:
- case 3:
- case 4:
- // 处理上传文件
- conf = this.configManager.getConfig(actionCode);
- state = new Uploader(this.request, conf).doExec();
- break;
- case 5:
- conf = this.configManager.getConfig(actionCode);
- String[] list = this.request.getParameterValues((String)conf.get("fieldName"));
- // 处理在线编辑
- state = new ImageHunter(conf).capture(list);
- break;
- case 6:
- case 7:
- conf = this.configManager.getConfig(actionCode);
- int start = getStartIndex();
- // 处理文件list
- state = new FileManager(conf).listFile(start);
- }
- return state.toJSONString();
- }
- public int getStartIndex()
- {
- String start = this.request.getParameter("start");
- try
- {
- return Integer.parseInt(start); } catch (Exception e) {
- }
- return 0;
- }
- public boolean validCallbackName(String name)
- {
- if (name.matches("^[a-zA-Z_]+[\\w0-9_]*$")) {
- return true;
- }
- return false;
- }
- }
假设我们的项目的contextPath为:test,那么下面两个函数的返回值则如下:
request.getContextPath /test
request.getRequestURI /test/resources/ueditor/jsp/controller.jsp
我们还是先来看下ConfigManager类吧。
- package com.baidu.ueditor;
- import java.io.BufferedReader;
- import java.io.File;
- import java.io.FileInputStream;
- import java.io.FileNotFoundException;
- import java.io.IOException;
- import java.io.InputStreamReader;
- import java.io.UnsupportedEncodingException;
- import java.util.HashMap;
- import java.util.Map;
- import org.json.JSONArray;
- import org.json.JSONObject;
- public final class ConfigManager
- {
- private final String rootPath;
- private final String originalPath;
- private final String contextPath;
- private static final String configFileName = "config.json";
- private String parentPath = null;
- private JSONObject jsonConfig = null;
- private static final String SCRAWL_FILE_NAME = "scrawl";
- private static final String REMOTE_FILE_NAME = "remote";
- private ConfigManager(String rootPath, String contextPath, String uri)
- throws FileNotFoundException, IOException
- {
- rootPath = rootPath.replace("\\", "/");
- this.rootPath = rootPath;
- this.contextPath = contextPath;
- // 这个地方要特别注意,originalPath其实就是controller.jsp所在的路径
- if (contextPath.length() > 0)
- this.originalPath = (this.rootPath + uri.substring(contextPath.length()));
- else {
- this.originalPath = (this.rootPath + uri);
- }
- initEnv();
- }
- public static ConfigManager getInstance(String rootPath, String contextPath, String uri)
- {
- try
- {
- return new ConfigManager(rootPath, contextPath, uri); } catch (Exception e) {
- }
- return null;
- }
- public boolean valid()
- {
- return this.jsonConfig != null;
- }
- public JSONObject getAllConfig()
- {
- return this.jsonConfig;
- }
- public Map<String, Object> getConfig(int type)
- {
- Map conf = new HashMap();
- String savePath = null;
- // 根据不同的code来解析config.json的配置文件
- switch (type)
- {
- case 4:
- conf.put("isBase64", "false");
- conf.put("maxSize", Long.valueOf(this.jsonConfig.getLong("fileMaxSize")));
- conf.put("allowFiles", getArray("fileAllowFiles"));
- conf.put("fieldName", this.jsonConfig.getString("fileFieldName"));
- savePath = this.jsonConfig.getString("filePathFormat");
- break;
- case 1:
- conf.put("isBase64", "false");
- conf.put("maxSize", Long.valueOf(this.jsonConfig.getLong("imageMaxSize")));
- conf.put("allowFiles", getArray("imageAllowFiles"));
- conf.put("fieldName", this.jsonConfig.getString("imageFieldName"));
- savePath = this.jsonConfig.getString("imagePathFormat");
- break;
- case 3:
- conf.put("maxSize", Long.valueOf(this.jsonConfig.getLong("videoMaxSize")));
- conf.put("allowFiles", getArray("videoAllowFiles"));
- conf.put("fieldName", this.jsonConfig.getString("videoFieldName"));
- savePath = this.jsonConfig.getString("videoPathFormat");
- break;
- case 2:
- conf.put("filename", "scrawl");
- conf.put("maxSize", Long.valueOf(this.jsonConfig.getLong("scrawlMaxSize")));
- conf.put("fieldName", this.jsonConfig.getString("scrawlFieldName"));
- conf.put("isBase64", "true");
- savePath = this.jsonConfig.getString("scrawlPathFormat");
- break;
- case 5:
- conf.put("filename", "remote");
- conf.put("filter", getArray("catcherLocalDomain"));
- conf.put("maxSize", Long.valueOf(this.jsonConfig.getLong("catcherMaxSize")));
- conf.put("allowFiles", getArray("catcherAllowFiles"));
- conf.put("fieldName", this.jsonConfig.getString("catcherFieldName") + "[]");
- savePath = this.jsonConfig.getString("catcherPathFormat");
- break;
- case 7:
- conf.put("allowFiles", getArray("imageManagerAllowFiles"));
- conf.put("dir", this.jsonConfig.getString("imageManagerListPath"));
- conf.put("count", Integer.valueOf(this.jsonConfig.getInt("imageManagerListSize")));
- break;
- case 6:
- conf.put("allowFiles", getArray("fileManagerAllowFiles"));
- conf.put("dir", this.jsonConfig.getString("fileManagerListPath"));
- conf.put("count", Integer.valueOf(this.jsonConfig.getInt("fileManagerListSize")));
- }
- conf.put("savePath", savePath);
- conf.put("rootPath", this.rootPath);
- return conf;
- }
- // 加载config.json配置文件
- 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 = readFile(getConfigPath());
- try
- {
- JSONObject jsonConfig = new JSONObject(configContent);
- this.jsonConfig = jsonConfig;
- } catch (Exception e) {
- this.jsonConfig = null;
- }
- }
- private String getConfigPath()
- {
- return this.parentPath + File.separator + "config.json";
- }
- private String[] getArray(String key)
- {
- JSONArray jsonArray = this.jsonConfig.getJSONArray(key);
- String[] result = new String[jsonArray.length()];
- int i = 0; for (int len = jsonArray.length(); i < len; i++) {
- result[i] = jsonArray.getString(i);
- }
- return result;
- }
- // 读取config.json里面的内容
- private String readFile(String path)
- throws IOException
- {
- StringBuilder builder = new StringBuilder();
- try
- {
- InputStreamReader reader = new InputStreamReader(new FileInputStream(path), "UTF-8");
- BufferedReader bfReader = new BufferedReader(reader);
- String tmpContent = null;
- while ((tmpContent = bfReader.readLine()) != null) {
- builder.append(tmpContent);
- }
- bfReader.close();
- }
- catch (UnsupportedEncodingException localUnsupportedEncodingException)
- {
- }
- return filter(builder.toString());
- }
- private String filter(String input)
- {
- return input.replaceAll("/\\*[\\s\\S]*?\\*/", "");
- }
- }
我们再来看Uploader函数,其实很简单:
- package com.baidu.ueditor.upload;
- import com.baidu.ueditor.define.State;
- import java.util.Map;
- import javax.servlet.http.HttpServletRequest;
- public class Uploader
- {
- private HttpServletRequest request = null;
- private Map<String, Object> conf = null;
- public Uploader(HttpServletRequest request, Map<String, Object> conf) {
- this.request = request;
- this.conf = conf;
- }
- public final State doExec() {
- String filedName = (String)this.conf.get("fieldName");
- State state = null;
- if ("true".equals(this.conf.get("isBase64")))
- state = Base64Uploader.save(this.request.getParameter(filedName),
- this.conf);
- else {
- state = BinaryUploader.save(this.request, this.conf);
- }
- return state;
- }
- }
这个很好理解,我们接着来看BinaryUploader类:
- package com.baidu.ueditor.upload;
- import com.baidu.ueditor.PathFormat;
- import com.baidu.ueditor.define.BaseState;
- import com.baidu.ueditor.define.FileType;
- import com.baidu.ueditor.define.State;
- import java.io.IOException;
- import java.io.InputStream;
- import java.util.Arrays;
- import java.util.List;
- import java.util.Map;
- import javax.servlet.http.HttpServletRequest;
- import org.apache.commons.fileupload.FileItemIterator;
- import org.apache.commons.fileupload.FileItemStream;
- import org.apache.commons.fileupload.FileUploadException;
- import org.apache.commons.fileupload.disk.DiskFileItemFactory;
- import org.apache.commons.fileupload.servlet.ServletFileUpload;
- public class BinaryUploader
- {
- // 使用fileupload来处理文件上传
- 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, 5);
- }
- ServletFileUpload upload = new ServletFileUpload(
- new DiskFileItemFactory());
- if (isAjaxUpload) {
- upload.setHeaderEncoding("UTF-8");
- }
- try
- {
- FileItemIterator iterator = upload.getItemIterator(request);
- while (iterator.hasNext()) {
- fileStream = iterator.next();
- if (!fileStream.isFormField())
- break;
- fileStream = null;
- }
- if (fileStream == null) {
- return new BaseState(false, 7);
- }
- String savePath = (String)conf.get("savePath");
- String originFileName = fileStream.getName();
- 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);
- String physicalPath = (String)conf.get("rootPath") + savePath;
- // 调用存储类来处理文件存储
- InputStream is = fileStream.openStream();
- 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 (FileUploadException e) {
- return new BaseState(false, 6);
- } catch (IOException localIOException) {
- }
- return new BaseState(false, 4);
- }
- private static boolean validType(String type, String[] allowTypes) {
- List list = Arrays.asList(allowTypes);
- return list.contains(type);
- }
- }
StorageManager我们就不看了,无非就是做一些文件存储的一些事情,下面我们来分析下这种实现方式的问题。
最后我稍微总结下看这个代码得收获和对作者的建议:
- 从这个地方来看,无法将图片放置在外部路径,因为这种实现就决定了只能放到项目路径下,这个最大的问题就是,有可能不小心,重新上下线,内容全部丢了。
- 从实现来看,大量的使用静态调用,基本上无法二次开发,不能灵活的继承它来处理个性化的东西,比如如果存储到fastDFS里面,这个就需要改里面的代码,不能通过扩展的方式来进行
- config.json里面的配置项转换的时候,进行了重命名,这个地方就要求读者要记两个变量名,比如:imagePathFormat变成了savePath, 感觉好像挺好理解,但是这种明显不是好的方式,如果里面存在一个这个逻辑,最好显式的说明,而不是硬编码
- 源代码不开放,无法进行扩展和修改,建议作者开发这个jar到github里面,社区一块维护
相关推荐
【标题】"ueditor上传图片配置"涉及到的是在SpringBoot框架下集成并配置ueditor,以便实现用户在编辑器中上传图片的功能。ueditor是一款流行的富文本编辑器,它提供了丰富的在线编辑功能,包括文字编辑、图片上传、...
5. **图片展示**:ueditor上传的图片需要能在编辑器中正常显示,这可能需要服务器提供一个图片访问的URL,ueditor通过这个URL显示图片。 6. **错误处理**:在开发过程中,可能出现网络问题、文件读写异常、权限问题...
作者通过自己的研究和实践,创建了一个能够工作的图片上传功能,并愿意分享给其他开发者,帮助他们节省时间和精力。 【标签】"ueditor"是富文本编辑器的名字,它提供了丰富的文本格式化选项,如插入图片、链接、...
仔细研究这两个文件,结合UEditor的官方文档,开发者可以找到解决问题的具体步骤。 总之,面对UEditor的这些问题,我们需要从多个角度进行排查和调试,包括前端的UEditor配置、后端的接口逻辑以及浏览器和服务器...
UEditor是一款由百度开发的富文本编辑器,广泛应用于网页内容编辑,支持多种语言,...通过深入研究这个demo,开发者能够熟练掌握UEditor的用法,将其无缝地融入到自己的JSP项目中,提升用户编辑内容的便捷性和效率。
【Ueditor研究代码】 Ueditor是一款由百度公司开发的开源富文本编辑器,它具有功能丰富、性能稳定、易用性好等特点,广泛应用于各类网站的内容编辑与发布。Ueditor的源码研究对于理解富文本编辑器的工作原理、定制...
在本文中,我们将深入探讨如何在Java Web项目中使用JSP技术来...当然,Ueditor还有许多高级特性,如视频上传、公式编辑等,可以根据实际需求进一步研究和配置。记得在实际应用中,始终关注安全性,防止潜在的安全风险。
2. **图片上传与管理**:UEditor 内置了图片上传功能,允许用户直接在编辑器中上传本地图片,并提供了图片预览、裁剪、排序等管理功能。此外,还支持图片的远程抓取和网络URL插入。 3. **视频插入**:UEditor 允许...
在深入研究ueditor源码时,开发者可以学习到以下知识: - JavaScript编程,包括DOM操作、事件处理、Ajax异步通信等。 - JSP和Servlet的基础,理解服务器端如何与ueditor交互。 - JSON格式的使用,ueditor与服务器...
3. 兼容性处理:ueditor虽然有较好的浏览器兼容性,但在某些老旧浏览器上可能存在问题,源码研究有助于解决这些问题。 通过深入学习ueditor源码,开发者不仅可以提升前端开发技能,也能更好地理解和应对实际项目中...
ueditor是由百度开发的一款开源的Web在线文本编辑器,它提供了丰富的API接口,支持图片上传、视频插入、表格操作、表情插入等功能,使得网页内容编辑变得更加直观和便捷。ueditor还支持自定义皮肤和插件,可以满足...
- **服务器配置**:需要在服务器端设置一个处理UEditor上传请求的接口,例如PHP、Java或.NET,处理图片或文件的上传、保存路径和权限控制。 - **自定义功能**:可以通过修改或扩展UEditor的源代码,实现特定的功能...
通过研究源码,开发者可以学习到如何将MathQuill与UEditor结合,以及如何处理公式编辑器的事件监听、数据交互和样式渲染等问题。 6. **Integration and Customization**:UEditor公式编辑器的集成与自定义是关键。...
【UEditor全部源码】是基于JavaScript开发的一款强大的富文本编辑器,...通过研究`ueditor-dev-1.5.0`这个版本,我们可以学习到如何利用其API进行二次开发,以及如何利用插件系统扩展功能,更好地服务于实际的Web应用。
3. **服务器端处理**:由于UEditor的文件上传等功能需要后端支持,因此开发者需要编写Java处理程序来接收并处理UEditor上传的文件,包括验证、存储和返回结果。 4. **安全考虑**:在使用UEditor时,需要防范XSS(跨...
通过研究这些示例,你可以快速理解和实施ueditor与阿里云OSS的集成。 总结来说,将ueditor(jsp版)与阿里云OSS结合,能帮助开发者构建出高效、稳定的文件上传功能。这需要对ueditor的配置、阿里云OSS的使用以及...
总之,ueditor-1.4.3.3 JSP版本源码为Java开发者提供了一套完整的富文本编辑解决方案,通过深入研究源码,不仅可以了解编辑器的工作原理,还能提升在Web开发中的实践能力。无论你是初学者还是经验丰富的开发者,都能...
其次,UEditor Plus的源码开放,意味着开发者可以深入研究其内部机制,根据自身需求进行定制化开发。这对于软件工具的爱好者和学习者来说,是一个宝贵的资源,特别是对于那些正在进行毕业设计论文或计算机案例研究的...
富文本编辑器是网页开发中常见的一种工具,用于提供用户在网页上进行格式化文本输入的界面。...通过深入研究和利用ueditor-1.4.3.3提供的资源,开发者可以构建出满足特定需求的高效、个性化的富文本编辑解决方案。
开发者可以深入研究源码,了解其工作原理,根据项目需求进行二次开发,例如增加新的插件、优化性能或修复特定问题。此外,Ueditor社区提供了大量的插件和示例,方便开发者快速实现特定功能。 **5. 注意事项** - ...