首页 > 学院 > 开发设计 > 正文

UEditor FTP上传

2019-11-15 01:02:02
字体:
来源:转载
供稿:网友
UEditor FTP上传

最近在项目中遇到了使用文本编辑器的情况,但是根据项目要求,文本编辑器的图片不能保存在本地服务器上,必须上传到远程文件服务器上,找了众多资料,没有找到答案,最后终于自己反编译了百度的JAR包,完完整整的研究了一次逻辑,终于实现了该功能,这里分享一下.以免后来者枉费时间.

步骤1.在自己的工程中实现一个ActionEnter类

package com.xxxx.ueditor;import com.baidu.ueditor.ConfigManager;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.xxxx.ueditor.upload.Uploader;import java.util.Map;import javax.servlet.http.HttpServletRequest;import org.apache.log4j.Logger;public class ActionEnter{  //日志器  PRotected Logger log = Logger.getLogger(ActionEnter.class);                  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;    this.actionType = request.getParameter("action");    this.contextPath = request.getContextPath();    this.configManager = ConfigManager.getInstance(this.rootPath, this.contextPath, request.getRequestURI());  }  public String exec()  {    String callbackName = this.request.getParameter("callback");    if (callbackName != null)    {      if (!validCallbackName(callbackName)) {        return new BaseState(false, 401).toJSONString();      }      return callbackName + "(" + invoke() + ");";    }    String response = invoke();    log.debug(response);    return response;  }  @SuppressWarnings({ "unchecked", "rawtypes" })public String invoke()  {    if ((this.actionType == null) || (!ActionMap.mapping.containsKey(this.actionType))) {      return new BaseState(false, 101).toJSONString();    }    if ((this.configManager == null) || (!this.configManager.valid())) {      return new BaseState(false, 102).toJSONString();    }    State state = null;    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);      conf.put("useFtpUpload",this.configManager.getAllConfig().getString("useFtpUpload"));      conf.put("keepLocalFile",this.configManager.getAllConfig().getString("keepLocalFile"));      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();      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;  }}

这个类是反编译的原有百度的代码,只加入了两行读取配置文件的内容:

conf.put("useFtpUpload",this.configManager.getAllConfig().getString("useFtpUpload"));   //是否使用FTP上传conf.put("keepLocalFile",this.configManager.getAllConfig().getString("keepLocalFile")); //是否上传后保留本地服务器文件步骤2.在ueditor目录下的jsp目录下,找到controller.jsp,修改ActionEnter的实现
<%@ page language="java" contentType="text/html; charset=UTF-8" import="com.xxxx.ueditor.ActionEnter"    pageEncoding="UTF-8"%><%    request.setCharacterEncoding( "utf-8" );    response.setHeader("Content-Type" , "text/html");        String rootPath = application.getRealPath( "/" );        out.write( new ActionEnter( request, rootPath ).exec() );    %>

只修改一处import改为刚才创建的ActionEnter即可

步骤3.修改controller.jsp同级目录下的config.json,加入之前新增的两个配置项,并且修改prefix为文件服务器的域名
/* 前后端通信相关的配置,注释只允许使用多行方式 */{    "useFtpUpload": "true", /* 是否使用FTP上传 */    "keepLocalFile": "true", /* 使用FTP上传后本地服务器是否保存 */        /* 上传图片配置项 */    "imageActionName": "uploadimage", /* 执行上传图片的action名称 */    "imageFieldName": "upfile", /* 提交的图片表单名称 */    "imageMaxSize": 3145728, /* 上传大小限制,单位B */    "imageAllowFiles": [".png", ".jpg", ".jpeg", ".gif", ".bmp"], /* 上传图片格式显示 */    "imageCompressEnable": true, /* 是否压缩图片,默认是true */    "imageCompressBorder": 1600, /* 图片压缩最长边限制 */    "imageInsertAlign": "none", /* 插入的图片浮动方式 */    "imageUrlPrefix": "http://localhost:8081/", /* 图片访问路径前缀 */    "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": "/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */    "scrawlMaxSize": 2048000, /* 上传大小限制,单位B */    "scrawlUrlPrefix": "", /* 图片访问路径前缀 */    "scrawlInsertAlign": "none",    /* 截图工具上传 */    "snapscreenActionName": "uploadimage", /* 执行上传截图的action名称 */    "snapscreenPathFormat": "/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": "/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */    "catcherUrlPrefix": "", /* 图片访问路径前缀 */    "catcherMaxSize": 2048000, /* 上传大小限制,单位B */    "catcherAllowFiles": [".png", ".jpg", ".jpeg", ".gif", ".bmp"], /* 抓取图片格式显示 */    /* 上传视频配置 */    "videoActionName": "uploadvideo", /* 执行上传视频的action名称 */    "videoFieldName": "upfile", /* 提交的视频表单名称 */    "videoPathFormat": "/upload/video/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */    "videoUrlPrefix": "http://localhost:8081/", /* 视频访问路径前缀 */    "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": "/upload/file/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */    "fileUrlPrefix": "http://localhost:8081/", /* 文件访问路径前缀 */    "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": "/upload/image/", /* 指定要列出图片的目录 */    "imageManagerListSize": 20, /* 每次列出文件数量 */    "imageManagerUrlPrefix": "http://localhost:8081/", /* 图片访问路径前缀 */    "imageManagerInsertAlign": "none", /* 插入的图片浮动方式 */    "imageManagerAllowFiles": [".png", ".jpg", ".jpeg", ".gif", ".bmp"], /* 列出的文件类型 */    /* 列出指定目录下的文件 */    "fileManagerActionName": "listfile", /* 执行文件管理的action名称 */    "fileManagerListPath": "/upload/file/", /* 指定要列出文件的目录 */    "fileManagerUrlPrefix": "http://localhost:8081/", /* 文件访问路径前缀 */    "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"    ] /* 列出的文件类型 */}

步骤4.创建一个Uploader类,其他代码反编译百度,加入红色内容,通过配置文件配置是上传本地服务器还是远程FTP服务器

package com.xxxx.ueditor.upload;import com.baidu.ueditor.define.State;import com.baidu.ueditor.upload.Base64Uploader;import com.baidu.ueditor.upload.BinaryUploader;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;        //保留原有逻辑,在json.config中加入是否使用FTP上传配置项        if ("true".equals(this.conf.get("isBase64")))          state = Base64Uploader.save(this.request.getParameter(filedName),             this.conf);        else {          if("true".equals(this.conf.get("useFtpUpload")))              state = FtpUploader.save(request, conf);          else            state = BinaryUploader.save(this.request, this.conf);        }        return state;      }}

步骤5.创建一个FtpUploader类,内容是反编译的BinaryUploader,稍作修改,保证在远程服务器上创建路径和本地服务器的一致

package com.xxxx.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 FtpUploader{      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 remoteDir = "";            int pos = savePath.lastIndexOf("/");      if(pos > -1){          remoteDir = savePath.substring(0,pos + 1);      }      String physicalPath = (String)conf.get("rootPath") + savePath;      boolean keepLocalFile = "false".equals(conf.get("keepLocalFile")) ? false : true;      InputStream is = fileStream.openStream();      State storageState = StorageManager.saveFtpFileByInputStream(is, remoteDir,        physicalPath, maxSize, keepLocalFile);      is.close();      if (storageState.isSuccess()) {        storageState.putInfo("url", 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);  }  @SuppressWarnings("rawtypes")private static boolean validType(String type, String[] allowTypes) {    List list = Arrays.asList(allowTypes);    return list.contains(type);  }}

步骤6.创建一个StorageManager类,内容反编译百度原有内容,加入几个FTP相关函数

package com.xxxx.ueditor.upload;import com.baidu.ueditor.define.BaseState;import com.baidu.ueditor.define.State;import com.xxxx.common.util.FileToFTP;import java.io.BufferedInputStream;import java.io.BufferedOutputStream;import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import org.apache.commons.io.FileUtils;public class StorageManager{      public static final int BUFFER_SIZE = 8192;  public static State saveBinaryFile(byte[] data, String path)  {    File file = new File(path);    State state = valid(file);    if (!state.isSuccess()) {      return state;    }    try    {      BufferedOutputStream bos = new BufferedOutputStream(        new FileOutputStream(file));      bos.write(data);      bos.flush();      bos.close();    } catch (IOException ioe) {      return new BaseState(false, 4);    }    state = new BaseState(true, file.getAbsolutePath());    state.putInfo("size", data.length);    state.putInfo("title", file.getName());    return state;  }  public static State saveFileByInputStream(InputStream is, String path, long maxSize)  {    State state = null;    File tmpFile = getTmpFile();    byte[] dataBuf = new byte[2048];    BufferedInputStream bis = new BufferedInputStream(is, 8192);    try    {      BufferedOutputStream bos = new BufferedOutputStream(        new FileOutputStream(tmpFile), 8192);      int count = 0;      while ((count = bis.read(dataBuf)) != -1) {        bos.write(dataBuf, 0, count);      }      bos.flush();      bos.close();      if (tmpFile.length() > maxSize) {        tmpFile.delete();        return new BaseState(false, 1);      }      state = saveTmpFile(tmpFile, path);      if (!state.isSuccess()) {        tmpFile.delete();      }      return state;    }    catch (IOException localIOException) {    }    return new BaseState(false, 4);  }  public static State saveFileByInputStream(InputStream is, String path) {    State state = null;    File tmpFile = getTmpFile();    byte[] dataBuf = new byte[2048];    BufferedInputStream bis = new BufferedInputStream(is, 8192);    try    {      BufferedOutputStream bos = new BufferedOutputStream(        new FileOutputStream(tmpFile), 8192);      int count = 0;      while ((count = bis.read(dataBuf)) != -1) {        bos.write(dataBuf, 0, count);      }      bos.flush();      bos.close();      state = saveTmpFile(tmpFile, path);      if (!state.isSuccess()) {        tmpFile.delete();      }      return state;    } catch (IOException localIOException) {    }    return new BaseState(false, 4);  }  private static File getTmpFile() {    File tmpDir = FileUtils.getTempDirectory();    double d = Math.random() * 10000.0D;    String tmpFileName = String.valueOf(d).replace(".", "");    return new File(tmpDir, tmpFileName);  }  private static State saveTmpFile(File tmpFile, String path) {    State state = null;    File targetFile = new File(path);    if (targetFile.canWrite())      return new BaseState(false, 2);    try    {      FileUtils.moveFile(tmpFile, targetFile);    } catch (IOException e) {      return new BaseState(false, 4);    }    state = new BaseState(true);    state.putInfo("size", targetFile.length());    state.putInfo("title", targetFile.getName());    return state;  }  private static State valid(File file) {    File parentPath = file.getParentFile();    if ((!parentPath.exists()) && (!parentPath.mkdirs())) {      return new BaseState(false, 3);    }    if (!parentPath.canWrite()) {      return new BaseState(false, 2);    }    return new BaseState(true);  }    /**   * 上传FTP文件   * @param is   * @param path   * @param maxSize   * @return   */  public static State saveFtpFileByInputStream(InputStream is, String remoteDir, String path, long maxSize,boolean keepLocalFile)  {    State state = null;    File tmpFile = getTmpFile();    byte[] dataBuf = new byte[2048];    BufferedInputStream bis = new BufferedInputStream(is, 8192);    try    {      BufferedOutputStream bos = new BufferedOutputStream(        new FileOutputStream(tmpFile), 8192);      int count = 0;      while ((count = bis.read(dataBuf)) != -1) {        bos.write(dataBuf, 0, count);      }      bos.flush();      bos.close();      if (tmpFile.length() > maxSize) {        tmpFile.delete();        return new BaseState(false, 1);      }      state = saveFtpTmpFile(tmpFile, remoteDir, path, keepLocalFile);      if (!state.isSuccess()) {        tmpFile.delete();      }      return state;    }    catch (IOException localIOException) {    }    return new BaseState(false, 4);  }    private static State saveFtpTmpFile(File tmpFile, String remoteDir, String path,boolean keepLocalFile) {        State state = null;        File targetFile = new File(path);        if (targetFile.canWrite())          return new BaseState(false, 2);        try        {          FileUtils.moveFile(tmpFile, targetFile);        } catch (IOException e) {          return new BaseState(false, 4);        }                try        {            FileToFTP t = new FileToFTP();            t.connect("");            if(! t.uploadWithRemoteDir(remoteDir,targetFile)){                return new BaseState(false, 4);            }        }catch (Exception e) {            return new BaseState(false, 4);        }                try        {            if(! keepLocalFile)                targetFile.delete();        }catch(Exception e){                    }        state = new BaseState(true);        state.putInfo("size", targetFile.length());        state.putInfo("title", targetFile.getName());        return state;  }}

到此就完成了UEditor上传FTP服务器的工作了.


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表