百度Editor富文本编辑器 自定义上传位置(imagePathFormat)动态化
1.前言
在网站上编辑富文本数据,直接采用百度的富文本编辑器,但是这个编辑器有个缺点,后端部分配置只能通过/jsp/config.json
文件配置,为了解决动态化存储问题只能修改编辑器源码
2.参考资料
https://www.cnblogs.com/xiaotaoqi/p/6436362.html
感谢优秀博主提供的参考资料,原博文更详细,请支持原博文
3.具体操作
imageUrlPrefix
+ imagePathFormat
是图片的访问路径
正常情况下,在加载ueditor
编辑器时,会访问ueditor/jsp/controller.jsp
controller.jsp
request.setCharacterEncoding( "utf-8" );
response.setHeader("Content-Type" , "text/html");
String rootPath = application.getRealPath( "/" );
System.out.println(rootPath);
out.write( new ActionEnter( request, rootPath ).exec() );
在创建ActionEnter
实例的时候,初始化ConfigManager
类
源代码(查看源码可是使用jsp
返编译工具):
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
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;//controller.jsp的上级目录路径
private JSONObject jsonConfig = null;//解析config.json后的json对象
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;
if(contextPath.length() > 0) {
this.originalPath = this.rootPath + uri.substring(contextPath.length());
} else {
this.originalPath = this.rootPath + uri;
}
this.initEnv();
}
public static ConfigManager getInstance(String rootPath, String contextPath, String uri) {
try {
return new ConfigManager(rootPath, contextPath, uri);
} catch (Exception var4) {
return null;
}
}
public boolean valid() {
return this.jsonConfig != null;
}
public JSONObject getAllConfig() {
return this.jsonConfig;
}
public Map<String, Object> getConfig(int type) {
HashMap conf = new HashMap();
String savePath = null;
switch(type) {
case 1:
conf.put("isBase64", "false");
conf.put("maxSize", Long.valueOf(this.jsonConfig.getLong("imageMaxSize")));
conf.put("allowFiles", this.getArray("imageAllowFiles"));
conf.put("fieldName", this.jsonConfig.getString("imageFieldName"));
savePath = this.jsonConfig.getString("imagePathFormat");
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 3:
conf.put("maxSize", Long.valueOf(this.jsonConfig.getLong("videoMaxSize")));
conf.put("allowFiles", this.getArray("videoAllowFiles"));
conf.put("fieldName", this.jsonConfig.getString("videoFieldName"));
savePath = this.jsonConfig.getString("videoPathFormat");
break;
case 4:
conf.put("isBase64", "false");
conf.put("maxSize", Long.valueOf(this.jsonConfig.getLong("fileMaxSize")));
conf.put("allowFiles", this.getArray("fileAllowFiles"));
conf.put("fieldName", this.jsonConfig.getString("fileFieldName"));
savePath = this.jsonConfig.getString("filePathFormat");
break;
case 5:
conf.put("filename", "remote");
conf.put("filter", this.getArray("catcherLocalDomain"));
conf.put("maxSize", Long.valueOf(this.jsonConfig.getLong("catcherMaxSize")));
conf.put("allowFiles", this.getArray("catcherAllowFiles"));
conf.put("fieldName", this.jsonConfig.getString("catcherFieldName") + "[]");
savePath = this.jsonConfig.getString("catcherPathFormat");
break;
case 6:
conf.put("allowFiles", this.getArray("fileManagerAllowFiles"));
conf.put("dir", this.jsonConfig.getString("fileManagerListPath"));
conf.put("count", Integer.valueOf(this.jsonConfig.getInt("fileManagerListSize")));
break;
case 7:
conf.put("allowFiles", this.getArray("imageManagerAllowFiles"));
conf.put("dir", this.jsonConfig.getString("imageManagerListPath"));
conf.put("count", Integer.valueOf(this.jsonConfig.getInt("imageManagerListSize")));
}
conf.put("savePath", savePath);
conf.put("rootPath", this.rootPath);
return conf;
}
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 e = new JSONObject(configContent);
this.jsonConfig = e;
} catch (Exception var4) {
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;
}
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 var6) {
;
}
return this.filter(builder.toString());
}
private String filter(String input) {
return input.replaceAll("/\\*[\\s\\S]*?\\*/", "");
}
}
private String getConfigPath() {
return this.parentPath + File.separator + "config.json";
}
这方法是拼全config.json
的绝对路径,但是parentPath
是controller.jsp
的目录路径,所以限制config.json
必须和controller.jsp
在同一个目录下。当用spring
或者其他代替controller.jsp
时,就会找不到这个json文件。
所以这个地方直接改为
//修改
private String getConfigPath() {
return this.rootPath + File.separator + "WEB-INF" + File.separator + "classes"+File.separator + "config.json";
}
关于上传文件路径配置问题,在源码中下载图片的类是BinaryUploader
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
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 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;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
public class BinaryUploader {
public BinaryUploader() {
}
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);
} else {
ServletFileUpload upload = new ServletFileUpload(new DiskFileItemFactory());
if(isAjaxUpload) {
upload.setHeaderEncoding("UTF-8");
}
try {
for(FileItemIterator e = upload.getItemIterator(request); e.hasNext(); fileStream = null) {
fileStream = e.next();
if(!fileStream.isFormField()) {
break;
}
}
if(fileStream == null) {
return new BaseState(false, 7);
} else {
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);
} else {
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 var14) {
return new BaseState(false, 6);
} catch (IOException var15) {
return new BaseState(false, 4);
}
}
}
private static boolean validType(String type, String[] allowTypes) {
List list = Arrays.asList(allowTypes);
return list.contains(type);
}
}
在第64行中,String physicalPath = (String)conf.get("rootPath") + savePath;
就是上传图片最后的路径。
其中rootPath
是根路径,savePath
是自定义的图片保存路径(即imagePathFormat对应的值
)
在源码中rootPath
已被限制为网站根目录,所以在这里需要改变为自定义的路径。
其中ConfigManager
类中第109,110这里传入的路径字符串,只需将这改为
conf.put("savePath", savePath);
conf.put("rootPath", this.jsonConfig.getString("uploadRoot"));
最后,controller.jsp的替代方法:
package com.imp.filter;
import com.baidu.ueditor.ActionEnter;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.logging.Logger;
/**
* Created by (IMP)郑和明
* Date is 2016/12/26
*
* UEditor controller.jsp 拦截器
*
* 初始化 config,json
*
*/
@WebFilter(filterName = "UEditorFilter",urlPatterns = "/ueditor/jsp/controller.jsp")
public class UEditorFilter implements Filter {
private FilterConfig config;
public void destroy() {
}
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
HttpServletRequest request= (HttpServletRequest) req;
HttpServletResponse response= (HttpServletResponse) resp;
request.setCharacterEncoding("utf-8");
response.setHeader("Content-Type", "text/html");
String rootPath= config.getServletContext().getRealPath("/");
Logger.getLogger("imp").info(rootPath);
String res=new ActionEnter(request, rootPath).exec();
response.getWriter().write(res);
}
public void init(FilterConfig config) throws ServletException {
this.config=config;
}
}
结束。