zoukankan      html  css  js  c++  java
  • 关于百度Editor富文本编辑器 自定义上传位置

    因为要在网站上编辑富文本数据,所以直接采用百度的富文本编辑器,但是这个编辑器有个缺点,默认情况下,文件只能上传到网站的根目录,不能自定义路径。

    而且json配置文件只能和controller.jsp在同一个目录下,不好管理。所以小淘气儿修改了部分源码以及配置了一个拦截器,实现了以上功能。

    首先,将下载,并解压的文件夹复制到webapp目录下,如图:

                                  

    并将ueditor/jsp/下的config.json移动到resources目录下,

    config.json是配置图片,文件,视频信息的json格式的文件。以下我就用图片讲解:

    /* 前后端通信相关的配置,注释只允许使用多行方式 */
    {
    
    
        "uploadRoot": "F://javaWeb//UEditor/target/ueditor-1.0-SNAPSHOT/", /*文件上传根目录  */
        /* 上传图片配置项 */
        "imageActionName": "uploadimage", /* 执行上传图片的action名称 */
        "imageFieldName": "upfile", /* 提交的图片表单名称 */
        "imageMaxSize": 2048000, /* 上传大小限制,单位B */
        "imageAllowFiles": [".png", ".jpg", ".jpeg", ".gif", ".bmp"], /* 上传图片格式显示 */
        "imageCompressEnable": true, /* 是否压缩图片,默认是true */
        "imageCompressBorder": 1600, /* 图片压缩最长边限制 */
        "imageInsertAlign": "none", /* 插入的图片浮动方式 */
        "imageUrlPrefix": "http://localhost:8088/ueditor", /* 图片访问路径前缀 */
        "imagePathFormat": "/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */
                                    /* {filename} 会替换成原文件名,配置这项需要注意中文乱码问题 */
                                    /* {rand:6} 会替换成随机数,后面的数字是随机数的位数 */
                                    /* {time} 会替换成时间戳 */
                                    /* {yyyy} 会替换成四位年份 */
                                    /* {yy} 会替换成两位年份 */
                                    /* {mm} 会替换成两位月份 */
                                    /* {dd} 会替换成两位日期 */
                                    /* {hh} 会替换成两位小时 */
                                    /* {ii} 会替换成两位分钟 */
                                    /* {ss} 会替换成两位秒 */
                                    /* 非法字符  : * ? " < > | */
                                    /* 具请体看线上文档: fex.baidu.com/ueditor/#use-format_upload_filename */
    
        /* 涂鸦图片上传配置项 */
        "scrawlActionName": "uploadscrawl", /* 执行上传涂鸦的action名称 */
        "scrawlFieldName": "upfile", /* 提交的图片表单名称 */
        "scrawlPathFormat": "/ueditor/jsp/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */
        "scrawlMaxSize": 2048000, /* 上传大小限制,单位B */
        "scrawlUrlPrefix": "", /* 图片访问路径前缀 */
        "scrawlInsertAlign": "none",
    
        /* 截图工具上传 */
        "snapscreenActionName": "uploadimage", /* 执行上传截图的action名称 */
        "snapscreenPathFormat": "/ueditor/jsp/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */
        "snapscreenUrlPrefix": "", /* 图片访问路径前缀 */
        "snapscreenInsertAlign": "none", /* 插入的图片浮动方式 */
    
        /* 抓取远程图片配置 */
        "catcherLocalDomain": ["127.0.0.1", "localhost", "img.baidu.com"],
        "catcherActionName": "catchimage", /* 执行抓取远程图片的action名称 */
        "catcherFieldName": "source", /* 提交的图片列表表单名称 */
        "catcherPathFormat": "/ueditor/jsp/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */
        "catcherUrlPrefix": "", /* 图片访问路径前缀 */
        "catcherMaxSize": 2048000, /* 上传大小限制,单位B */
        "catcherAllowFiles": [".png", ".jpg", ".jpeg", ".gif", ".bmp"], /* 抓取图片格式显示 */
    
        /* 上传视频配置 */
        "videoActionName": "uploadvideo", /* 执行上传视频的action名称 */
        "videoFieldName": "upfile", /* 提交的视频表单名称 */
        "videoPathFormat": "/ueditor/jsp/upload/video/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */
        "videoUrlPrefix": "", /* 视频访问路径前缀 */
        "videoMaxSize": 102400000, /* 上传大小限制,单位B,默认100MB */
        "videoAllowFiles": [
            ".flv", ".swf", ".mkv", ".avi", ".rm", ".rmvb", ".mpeg", ".mpg",
            ".ogg", ".ogv", ".mov", ".wmv", ".mp4", ".webm", ".mp3", ".wav", ".mid"], /* 上传视频格式显示 */
    
        /* 上传文件配置 */
        "fileActionName": "uploadfile", /* controller里,执行上传视频的action名称 */
        "fileFieldName": "upfile", /* 提交的文件表单名称 */
        "filePathFormat": "/ueditor/jsp/upload/file/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */
        "fileUrlPrefix": "", /* 文件访问路径前缀 */
        "fileMaxSize": 51200000, /* 上传大小限制,单位B,默认50MB */
        "fileAllowFiles": [
            ".png", ".jpg", ".jpeg", ".gif", ".bmp",
            ".flv", ".swf", ".mkv", ".avi", ".rm", ".rmvb", ".mpeg", ".mpg",
            ".ogg", ".ogv", ".mov", ".wmv", ".mp4", ".webm", ".mp3", ".wav", ".mid",
            ".rar", ".zip", ".tar", ".gz", ".7z", ".bz2", ".cab", ".iso",
            ".doc", ".docx", ".xls", ".xlsx", ".ppt", ".pptx", ".pdf", ".txt", ".md", ".xml"
        ], /* 上传文件格式显示 */
    
        /* 列出指定目录下的图片 */
        "imageManagerActionName": "listimage", /* 执行图片管理的action名称 */
        "imageManagerListPath": "/ueditor/jsp/upload/image/", /* 指定要列出图片的目录 */
        "imageManagerListSize": 20, /* 每次列出文件数量 */
        "imageManagerUrlPrefix": "", /* 图片访问路径前缀 */
        "imageManagerInsertAlign": "none", /* 插入的图片浮动方式 */
        "imageManagerAllowFiles": [".png", ".jpg", ".jpeg", ".gif", ".bmp"], /* 列出的文件类型 */
    
        /* 列出指定目录下的文件 */
        "fileManagerActionName": "listfile", /* 执行文件管理的action名称 */
        "fileManagerListPath": "/ueditor/jsp/upload/file/", /* 指定要列出文件的目录 */
        "fileManagerUrlPrefix": "", /* 文件访问路径前缀 */
        "fileManagerListSize": 20, /* 每次列出文件数量 */
        "fileManagerAllowFiles": [
            ".png", ".jpg", ".jpeg", ".gif", ".bmp",
            ".flv", ".swf", ".mkv", ".avi", ".rm", ".rmvb", ".mpeg", ".mpg",
            ".ogg", ".ogv", ".mov", ".wmv", ".mp4", ".webm", ".mp3", ".wav", ".mid",
            ".rar", ".zip", ".tar", ".gz", ".7z", ".bz2", ".cab", ".iso",
            ".doc", ".docx", ".xls", ".xlsx", ".ppt", ".pptx", ".pdf", ".txt", ".md", ".xml"
        ] /* 列出的文件类型 */
    
    }

    imageUrlPrefix+imagePathFormat是图片的访问路径,也是图片显示的关键。

    uploadRoot是我新增加的键,对应的value是图片上传绝对路径。

    正常情况下,在加载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() );

      在这里解析的config.json,

      在创建ActionEnter实例的时候,初始化ConfigManager类,其中ConfigManager类是关键。

     百度源代码:

      1 //
      2 // Source code recreated from a .class file by IntelliJ IDEA
      3 // (powered by Fernflower decompiler)
      4 //
      5 
      6 package com.baidu.ueditor;
      7 
      8 import java.io.BufferedReader;
      9 import java.io.File;
     10 import java.io.FileInputStream;
     11 import java.io.FileNotFoundException;
     12 import java.io.IOException;
     13 import java.io.InputStreamReader;
     14 import java.io.UnsupportedEncodingException;
     15 import java.util.HashMap;
     16 import java.util.Map;
     17 import org.json.JSONArray;
     18 import org.json.JSONObject;
     19 
     20 public final class ConfigManager {
     21     private final String rootPath;//绝对根路径
     22     private final String originalPath;
     23     private final String contextPath;
     24     private static final String configFileName = "config.json";
     25     private String parentPath = null;//controller.jsp的上级目录路径
     26     private JSONObject jsonConfig = null;//解析config.json后的json对象
     27     private static final String SCRAWL_FILE_NAME = "scrawl";
     28     private static final String REMOTE_FILE_NAME = "remote";
     29 
     30     private ConfigManager(String rootPath, String contextPath, String uri) throws FileNotFoundException, IOException {
     31         rootPath = rootPath.replace("\", "/");
     32         this.rootPath = rootPath;
     33         this.contextPath = contextPath;
     34         if(contextPath.length() > 0) {
     35             this.originalPath = this.rootPath + uri.substring(contextPath.length());
     36         } else {
     37             this.originalPath = this.rootPath + uri;
     38         }
     39 
     40         this.initEnv();
     41     }
     42 
     43     public static ConfigManager getInstance(String rootPath, String contextPath, String uri) {
     44         try {
     45             return new ConfigManager(rootPath, contextPath, uri);
     46         } catch (Exception var4) {
     47             return null;
     48         }
     49     }
     50 
     51     public boolean valid() {
     52         return this.jsonConfig != null;
     53     }
     54 
     55     public JSONObject getAllConfig() {
     56         return this.jsonConfig;
     57     }
     58 
     59     public Map<String, Object> getConfig(int type) {
     60         HashMap conf = new HashMap();
     61         String savePath = null;
     62         switch(type) {
     63         case 1:
     64             conf.put("isBase64", "false");
     65             conf.put("maxSize", Long.valueOf(this.jsonConfig.getLong("imageMaxSize")));
     66             conf.put("allowFiles", this.getArray("imageAllowFiles"));
     67             conf.put("fieldName", this.jsonConfig.getString("imageFieldName"));
     68             savePath = this.jsonConfig.getString("imagePathFormat");
     69             break;
     70         case 2:
     71             conf.put("filename", "scrawl");
     72             conf.put("maxSize", Long.valueOf(this.jsonConfig.getLong("scrawlMaxSize")));
     73             conf.put("fieldName", this.jsonConfig.getString("scrawlFieldName"));
     74             conf.put("isBase64", "true");
     75             savePath = this.jsonConfig.getString("scrawlPathFormat");
     76             break;
     77         case 3:
     78             conf.put("maxSize", Long.valueOf(this.jsonConfig.getLong("videoMaxSize")));
     79             conf.put("allowFiles", this.getArray("videoAllowFiles"));
     80             conf.put("fieldName", this.jsonConfig.getString("videoFieldName"));
     81             savePath = this.jsonConfig.getString("videoPathFormat");
     82             break;
     83         case 4:
     84             conf.put("isBase64", "false");
     85             conf.put("maxSize", Long.valueOf(this.jsonConfig.getLong("fileMaxSize")));
     86             conf.put("allowFiles", this.getArray("fileAllowFiles"));
     87             conf.put("fieldName", this.jsonConfig.getString("fileFieldName"));
     88             savePath = this.jsonConfig.getString("filePathFormat");
     89             break;
     90         case 5:
     91             conf.put("filename", "remote");
     92             conf.put("filter", this.getArray("catcherLocalDomain"));
     93             conf.put("maxSize", Long.valueOf(this.jsonConfig.getLong("catcherMaxSize")));
     94             conf.put("allowFiles", this.getArray("catcherAllowFiles"));
     95             conf.put("fieldName", this.jsonConfig.getString("catcherFieldName") + "[]");
     96             savePath = this.jsonConfig.getString("catcherPathFormat");
     97             break;
     98         case 6:
     99             conf.put("allowFiles", this.getArray("fileManagerAllowFiles"));
    100             conf.put("dir", this.jsonConfig.getString("fileManagerListPath"));
    101             conf.put("count", Integer.valueOf(this.jsonConfig.getInt("fileManagerListSize")));
    102             break;
    103         case 7:
    104             conf.put("allowFiles", this.getArray("imageManagerAllowFiles"));
    105             conf.put("dir", this.jsonConfig.getString("imageManagerListPath"));
    106             conf.put("count", Integer.valueOf(this.jsonConfig.getInt("imageManagerListSize")));
    107         }
    108 
    109         conf.put("savePath", savePath);
    110         conf.put("rootPath", this.rootPath);
    111         return conf;
    112     }
    113 
    114     private void initEnv() throws FileNotFoundException, IOException {
    115         File file = new File(this.originalPath);
    116         if(!file.isAbsolute()) {
    117             file = new File(file.getAbsolutePath());
    118         }
    119 
    120         this.parentPath = file.getParent();
    121         String configContent = this.readFile(this.getConfigPath());
    122 
    123         try {
    124             JSONObject e = new JSONObject(configContent);
    125             this.jsonConfig = e;
    126         } catch (Exception var4) {
    127             this.jsonConfig = null;
    128         }
    129 
    130     }
    131     
    132     private String getConfigPath() {
    133         return this.parentPath + File.separator + "config.json";
    134     }
    135 
    136     private String[] getArray(String key) {
    137         JSONArray jsonArray = this.jsonConfig.getJSONArray(key);
    138         String[] result = new String[jsonArray.length()];
    139         int i = 0;
    140 
    141         for(int len = jsonArray.length(); i < len; ++i) {
    142             result[i] = jsonArray.getString(i);
    143         }
    144 
    145         return result;
    146     }
    147 
    148     private String readFile(String path) throws IOException {
    149         StringBuilder builder = new StringBuilder();
    150 
    151         try {
    152             InputStreamReader reader = new InputStreamReader(new FileInputStream(path), "UTF-8");
    153             BufferedReader bfReader = new BufferedReader(reader);
    154             String tmpContent = null;
    155 
    156             while((tmpContent = bfReader.readLine()) != null) {
    157                 builder.append(tmpContent);
    158             }
    159 
    160             bfReader.close();
    161         } catch (UnsupportedEncodingException var6) {
    162             ;
    163         }
    164 
    165         return this.filter(builder.toString());
    166     }
    167 
    168     private String filter(String input) {
    169         return input.replaceAll("/\*[\s\S]*?\*/", "");
    170     }
    171 }

    其中   

        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,

     1 //
     2 // Source code recreated from a .class file by IntelliJ IDEA
     3 // (powered by Fernflower decompiler)
     4 //
     5 
     6 package com.baidu.ueditor.upload;
     7 
     8 import com.baidu.ueditor.PathFormat;
     9 import com.baidu.ueditor.define.BaseState;
    10 import com.baidu.ueditor.define.FileType;
    11 import com.baidu.ueditor.define.State;
    12 import org.apache.commons.fileupload.FileItemIterator;
    13 import org.apache.commons.fileupload.FileItemStream;
    14 import org.apache.commons.fileupload.FileUploadException;
    15 import org.apache.commons.fileupload.disk.DiskFileItemFactory;
    16 import org.apache.commons.fileupload.servlet.ServletFileUpload;
    17 
    18 import javax.servlet.http.HttpServletRequest;
    19 import java.io.IOException;
    20 import java.io.InputStream;
    21 import java.util.Arrays;
    22 import java.util.List;
    23 import java.util.Map;
    24 
    25 public class BinaryUploader {
    26     public BinaryUploader() {
    27     }
    28 
    29     public static final State save(HttpServletRequest request, Map<String, Object> conf) {
    30         FileItemStream fileStream = null;
    31         boolean isAjaxUpload = request.getHeader("X_Requested_With") != null;
    32         if(!ServletFileUpload.isMultipartContent(request)) {
    33             return new BaseState(false, 5);
    34         } else {
    35             ServletFileUpload upload = new ServletFileUpload(new DiskFileItemFactory());
    36             if(isAjaxUpload) {
    37                 upload.setHeaderEncoding("UTF-8");
    38             }
    39 
    40             try {
    41                 for(FileItemIterator e = upload.getItemIterator(request); e.hasNext(); fileStream = null) {
    42                     fileStream = e.next();
    43                     if(!fileStream.isFormField()) {
    44                         break;
    45                     }
    46                 }
    47 
    48                 if(fileStream == null) {
    49                     return new BaseState(false, 7);
    50                 } else {
    51                     String savePath = (String)conf.get("savePath");
    52                     String originFileName = fileStream.getName();
    53                     String suffix = FileType.getSuffixByFilename(originFileName);
    54                     originFileName = originFileName.substring(0, originFileName.length() - suffix.length());
    55                     savePath = savePath + suffix;
    56                     long maxSize = ((Long)conf.get("maxSize")).longValue();
    57                     if(!validType(suffix, (String[])conf.get("allowFiles"))) {
    58 
    59                         return new BaseState(false, 8);
    60 
    61                     } else {
    62 
    63                         savePath = PathFormat.parse(savePath, originFileName);
    64                         String physicalPath = (String)conf.get("rootPath") + savePath;
    65                         InputStream is = fileStream.openStream();
    66                         State storageState = StorageManager.saveFileByInputStream(is, physicalPath, maxSize);
    67                         is.close();
    68                         if(storageState.isSuccess()) {
    69                             storageState.putInfo("url", PathFormat.format(savePath));
    70                             storageState.putInfo("type", suffix);
    71                             storageState.putInfo("original", originFileName + suffix);
    72                         }
    73                         return storageState;
    74                     }
    75                 }
    76             } catch (FileUploadException var14) {
    77                 return new BaseState(false, 6);
    78             } catch (IOException var15) {
    79                 return new BaseState(false, 4);
    80             }
    81         }
    82     }
    83 
    84     private static boolean validType(String type, String[] allowTypes) {
    85         List list = Arrays.asList(allowTypes);
    86         return list.contains(type);
    87     }
    88 }

    在第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的替代方法:

    利用拦截器:

     1 package com.imp.filter;
     2 
     3 import com.baidu.ueditor.ActionEnter;
     4 
     5 import javax.servlet.*;
     6 import javax.servlet.annotation.WebFilter;
     7 import javax.servlet.http.HttpServletRequest;
     8 import javax.servlet.http.HttpServletResponse;
     9 import java.io.IOException;
    10 import java.util.logging.Logger;
    11 
    12 /**
    13  * Created by (IMP)郑和明
    14  * Date is 2016/12/26
    15  *
    16  * UEditor controller.jsp 拦截器
    17  *
    18  * 初始化 config,json
    19  *
    20  */
    21 @WebFilter(filterName = "UEditorFilter",urlPatterns = "/ueditor/jsp/controller.jsp")
    22 public class UEditorFilter implements Filter {
    23     private FilterConfig config;
    24 
    25     public void destroy() {
    26 
    27     }
    28 
    29     public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
    30 
    31         HttpServletRequest request= (HttpServletRequest) req;
    32         HttpServletResponse response= (HttpServletResponse) resp;
    33         request.setCharacterEncoding("utf-8");
    34         response.setHeader("Content-Type", "text/html");
    35         String rootPath= config.getServletContext().getRealPath("/");
    36         Logger.getLogger("imp").info(rootPath);
    37         String res=new ActionEnter(request, rootPath).exec();
    38         response.getWriter().write(res);
    39 
    40     }
    41     public void init(FilterConfig config) throws ServletException {
    42         this.config=config;
    43     }
    44 
    45 }

    或者

    String mvc也可以(前提拦截所有jsp请求,然后自定义controller)(代码(略))

    代码 github 地址  https://github.com/zhenghe1993/UEditor

  • 相关阅读:
    【mybatis】IF判断的坑
    QCheckBox控件
    对话框——文件对话框
    对话框——颜色对话框
    对话框——输入对话框
    事件和信号
    布局管理——复习示例
    布局管理——网格布局
    布局管理——盒式布局
    1.4 控制流
  • 原文地址:https://www.cnblogs.com/xiaotaoqi/p/6436362.html
Copyright © 2011-2022 走看看