百度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的绝对路径,但是parentPathcontroller.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;
    }
}

结束。

posted @ 2023-03-15 00:06  轻风细雨_林木木  阅读(110)  评论(0编辑  收藏  举报  来源