你的位置:首页 > Java教程

[Java教程]【完整靠谱版】结合公司项目,仔细总结自己使用百度编辑器实现FTP上传的完整过程


说在前面

    工作中会遇到很多需要使用富文本编辑器的地方,比如我现在发布这篇文章离不开这个神器,而且现在网上编辑器太多了。记得之前,由于工作需要自己封装过一个编辑器的公共插件,是用ckeditor改版的,目的是要兼容公司所有项目,使用方便。废话不多说,今天写这篇文章,一是总结自己学习复习,二是关于FTP上传官方资料太少,也便于他人少趟坑,我在这里会说的很细很明白,希望亲们以后不要中枪了!

关于编辑器的简单部署

     去官网下载后,我们需要把下载的编辑器文件夹,摘一部分放到项目中,下载之后的目录,如下图(我这里用的是jsp简化版 1.2.2)

 

        我在外面新建了个插件目录umeditor,如下图:

 

 

 

       除了jsp文件夹,其余拷到项目静态资源的目录中,然后 我们来分析jsp文件夹都有哪些东东?

 

       这里,我把那两个jar包带入到项目中,这里我改了名字,方便导入,fileupload那个jar包项目之前就有。如下图:

    

 

      接下来,就是页面调用了,很简单,首先将编辑器所需要的样式和脚本文件引入:

/**以上省略,这里引入到页面头部**/<link href="${ctx}/static/umeditor/themes/default/css/umeditor.css" type="text/css" rel="stylesheet">  <script type="text/javascript" charset="utf-8" src="${ctx}/static/umeditor/umeditor.config.js"></script>  <script type="text/javascript" charset="utf-8" src="${ctx}/static/umeditor/umeditor.min.js"></script>  <script type="text/javascript" src="${ctx}/static/umeditor/lang/zh-cn/zh-cn.js"></script></head>

      接下来,需要在页面调用编辑器对象,官方用的是script标签,我这里用textarea来构造

<div class="controls">      <form:textarea id="content" htmlEscape="true" path="articleData.content" rows="4" maxlength="200" class="input-xxlarge"/>              <script type="text/javascript">        //实例化编辑器        var um = UM.getEditor('content'); //注意ID的一致        um.setWidth(700); //设置编辑器宽度      </script></div>

 

    至此基本的工作已做完,上述相信大部分搞开发的同胞们,都没问题吧!效果图如下:

 

 

关于编辑器的后台实现

        官方下载给的后台处理文件除了必要的jar外有三个文件:

       (1) Uploader.java 文件

       该文件主封装了一个文件上传对象,包括上传后需要返回的参数、状态、URL,除此还有一个上传的处理函数,当然只是普通的文件存储,不符合我们的需求,但是我们可以知道前端需要的一些返回值。

       (2) imageUp.jsp 文件

       上传图片默认配置后台处理文件,主要调用Upload上传类,完成上传 并把上传结果 以json字符串发往前台,其中包括重要的state、url等参数

       (3) getContent.jsp 文件 (和上传没关系,略过)

         以上分析过官方给的简单后台处理逻辑,我们不难知道实际上就是需要我们提供一个上传处理函数并返回包含必要参数的JSON串

        那好,接下来我们开始写自己的后台上传处理函数了。

        第一步 后台控制器处理函数(重要程度:☆☆☆☆☆)  

 1 /** 2    * 编辑器上传图片  3   */ 4   @RequiresPermissions("cms:article:view") 5   @RequestMapping(value={"/upload"}) 6   @ResponseBody() 7   public String upload(HttpServletRequest request,HttpServletResponse response){ 8      9     //request.getParameter("path");10     String[] allowExtName = {".jpg",".png",".gif",".bmp",".jpeg"};//图片格式限制11     List<MultipartFile> multipartFiles = getFileSet(request, 1024 * 1024 * 10, allowExtName); //上传的图片大小可以放到配置中读取,这里设置10M12     Map<String,Object> map = new HashMap<String,Object>();13     try {14       if(multipartFiles.size() > 0){15         MultipartFile file = multipartFiles.get(0);16         InputStream is = file.getInputStream();17         String tempFileName = file.getOriginalFilename();18         if(is != null&&StringUtils.isNotBlank(tempFileName)){19           20           //生成文件名21           String uuid = IdGen.uuid(); //生成的一个随机字符串,用于图片名22           String fileName = uuid+tempFileName.substring(tempFileName.indexOf("."));23           //生成文件路徑24           boolean ftpWaterRs=true;25           FTPUtils ftpUtils = FTPUtils.getInstance();26           SimpleDateFormat sf = new SimpleDateFormat("yyyy/MM/");27           String ss = sf.format(new Date()); //以当前时间,生成存放目录,格式/yyyy/MM28           String storePath = ftpUtils.getSaveFilePath() + ss; //读取配置的存储目录 比如 /upload/image/29           //图片加水印 getResourceRootRealPath ; 若图片大小小于logo大小则不加水印30           if(file.getSize()>1200){ //这里给图片增加水印功能31             String waterName= uuid + "_water"+tempFileName.substring(tempFileName.indexOf("."));32             //缓存文件类型转换33             CommonsMultipartFile cf= (CommonsMultipartFile)file; 34             DiskFileItem fi = (DiskFileItem)cf.getFileItem(); 35             File tempFile = fi.getStoreLocation();36             String waterTempPath = SpringContextHolder.getRootRealPath()+"/"+waterName;37             String logoPath=SpringContextHolder.getRootRealPath()+"/static/images/shuiyin.png";  //水印图片路径       38              ImageUtils.markImageByIcon(logoPath, tempFile, waterTempPath, 45); //添加水印39             File waterFile = new File(waterTempPath);40             //上传水印图片41             ftpWaterRs = ftpUtils.storeFile(storePath,waterName,new FileInputStream(waterFile));42             if(ftpWaterRs){43               FileUtils.deleteFile(waterTempPath);44               is.close();45               map.clear();46               map.put("state","SUCCESS"); //注意:返回的参数state 成功必须是 SUCCESS,否则需要到image.js中改,失败可以自定义47               //map.put("url",ftpUtils.getSiteName().trim()+storePath.trim() + waterName);48               map.put("url",storePath.trim() + waterName);
//url 这里有个坑,绝对完整地址图片不会显示
//我现在返回的是不包含域名的路径 如 /upload/images/2016/08/03/a23ssds6s6d56ds656a6a5652636.jpg
//域名部分路径也就是http://static.xx.com/ 需要到前端配置,具体是 在umeditor.config.js 配置参数 imagePath 所谓的图片修正地址喽 49 return JsonMapper.toJsonString(map);50 } 51 }52 53 //上传源文件54 boolean ftpFileRs = ftpUtils.storeFile(storePath, fileName, is);55 is.close();56 if(ftpFileRs){ //这里水印图片上传失败 会采用原图57 map.clear();58 map.put("state","SUCCESS");59 map.put("url",storePath.trim() + fileName);60 return JsonMapper.toJsonString(map);61 }62 }63 }64 else{65 map.clear();66 map.put("state","请检查图片格式或尺寸,图片必须小于10M");67 return JsonMapper.toJsonString(map);68 }69 } catch (Exception e) {70 e.printStackTrace();71 }72 map.clear();73 map.put("state","上传请求异常");74 return JsonMapper.toJsonString(map);75 }

           

          第二步 处理函数用到上传图片验证函数包含大小和格式(重要程度:☆☆☆)  

 1 /**  2    * @descrption 根据HttpServletRequest对象获取MultipartFile集合  3    * @author zp  4    * @param request  5    * @param maxLength  6    *      文件最大限制  7    * @param allowExtName  8    *      不允许上传的文件扩展名  9    * @return MultipartFile集合 10   */ 11   public static List<MultipartFile> getFileSet(HttpServletRequest request, 12       long maxLength, String[] allowExtName) { 13     MultipartHttpServletRequest multipartRequest = null; 14     try { 15       multipartRequest = (MultipartHttpServletRequest) request; 16     } catch (Exception e) { 17       return new LinkedList<MultipartFile>(); 18     } 19  20     List<MultipartFile> files = new LinkedList<MultipartFile>(); 21     files = multipartRequest.getFiles("upfile"); //upfile 是编辑器默认的上传图片表单name,在文件umeditor.config.js 可自定义配置参数 imageFieldName22     // 移除不符合条件的 23     for (int i = 0; i < files.size(); i++) { 24       if (!validateFile(files.get(i), maxLength, allowExtName)) { 25         files.remove(files.get(i)); 26         if (files.size() == 0) { 27           return files; 28         } 29       } 30     } 31     return files; 32   } 33   34   /** 35    * @descrption 验证文件格式,这里主要验证后缀名 36    * @author zp 37    * @param file 38    *      MultipartFile对象 39    * @param maxLength 40    *      文件最大限制 41    * @param allowExtName 42    *      不允许上传的文件扩展名 43    * @return 文件格式是否合法 44   */ 45   private static boolean validateFile(MultipartFile file, long maxLength, 46       String[] allowExtName) { 47     if (file.getSize() < 0 || file.getSize() > maxLength) 48       return false; 49     String filename = file.getOriginalFilename(); 50  51     // 处理不选择文件点击上传时,也会有MultipartFile对象,在此进行过滤 52     if (filename == "") { 53       return false; 54     } 55     String extName = filename.substring(filename.lastIndexOf(".")) 56         .toLowerCase(); 57     if (allowExtName == null || allowExtName.length == 0 58         || Arrays.binarySearch(allowExtName, extName) != -1) { 59       return true; 60     } else { 61       return false; 62     } 63   } 

 

           第三步 FTP上传处理类,绝对福利..好多人想要哦 0.0(重要程度:☆☆☆

 1 package com.xx.utils; 2  3 import java.io.File; 4 import java.io.FileInputStream; 5 import java.io.IOException; 6 import java.io.InputStream; 7  8 import org.apache.commons.net.ftp.FTPClient; 9 import org.apache.commons.net.ftp.FTPFile; 10 import org.apache.commons.net.ftp.FTPReply; 11  12 import com.xx.Global; 13   14 /**  15  * FTP服务器工具类  16 */  17 public class FTPUtils {  18     19   private static FTPUtils ftpUtils;  20   private FTPClient ftpClient;  21   //private FTPFile ftpFile; 22   private String port; // 服务器端口  23   private String username; // 用户登录名  24   private String password; // 用户登录密码  25   private String serverName; // 服务名  26   private int localPasv;//开启本地被动模式 27   private String siteName; // 站点域名 28   private String saveFilePath;//存储路径 29    30     31   private InputStream is; // 文件下载输入流  32     33   /**  34    * 私有构造方法  35   */  36   private FTPUtils() {  37     initConfig();  38     if (null == ftpClient) {  39       ftpClient = new FTPClient();  40     }  41   }   42  43   /**  44    * 获取FTPUtils对象实例  45    * @return  46    *   FTPUtils对象实例  47   */  48   public synchronized static FTPUtils getInstance () {  49     if (null == ftpUtils) {  50       ftpUtils = new FTPUtils();  51     }  52     return ftpUtils;  53   }  54     55   /**  56    * 初始化FTP服务器连接属性  57   */  58 //  public void initConfig () {  59 //    // 构造Properties对象  60 //    Properties properties = new Properties();  61 //      62 //    // 定义配置文件输入流  63 //    InputStream is = null;  64 //    try {  65 //      // 获取配置文件输入流  66 //      is = FTPUtils.class.getResourceAsStream("/ftp.properties");  67 //      // 加载配置文件  68 //      properties.load(is);  69 //      // 读取配置文件  70 //      port = (String) properties.get("port"); // 设置端口  71 //      username = (String) properties.get("username1"); // 设置用户名  72 //      password = (String) properties.get("password1"); // 设置密码  73 //      serverName = (String) properties.get("serverName"); // 服务名  74 //      localPasv = Integer.valueOf(String.valueOf(properties.get("localPasv"))); 75 //    } catch (IOException e) {  76 //      e.printStackTrace();  77 //    } finally {  78 //      // 判断输入流是否为空  79 //      if (null != is) {  80 //        try {  81 //          // 关闭输入流  82 //          is.close();  83 //        } catch (IOException e) {  84 //          e.printStackTrace();  85 //        }  86 //      }  87 //    }  88 //  }  89     90   public void initConfig () {  91     serverName = Global.getConfig("ftp.serverName"); 92 //        SystemConfig.getInstance().getApplication().get("ftp.serverName");  93     port = Global.getConfig("ftp.port"); 94 //        SystemConfig.getInstance().getApplication().get("ftp.port"); 95     username = Global.getConfig("ftp.username1"); 96 //        SystemConfig.getInstance().getApplication().get("ftp.username1"); 97     password =Global.getConfig("ftp.password1"); 98 //        portSystemConfig.getInstance().getApplication().get("ftp.password1");  99     localPasv = Integer.valueOf(Global.getConfig("ftp.localPasv"));100 //        Integer.valueOf(SystemConfig.getInstance().getApplication().get("ftp.localPasv")); 101     siteName = Global.getConfig("ftp.readPath"); //读取配置 访问路径102     saveFilePath = Global.getConfig("ftp.upLoadPath"); //读取配置 上传路径103     104   }  105   /** 106    * 连接(配置通用连接属性)至服务器 107    * 108    * @param serverName 109    *   服务器名称 110    * @param remotePath 111    *   当前访问目录 112    * @return 113    *   <b>true</b>:连接成功 114    *   <br/> 115    *   <b>false</b>:连接失败 116   */ 117   public boolean connectToTheServer (String remotePath) { 118     // 定义返回值 119     boolean result = false; 120     try { 121       // 连接至服务器,端口默认为21时,可直接通过URL连接 122       ftpClient.connect(serverName, Integer.parseInt(port)); 123       // 登录服务器 124       ftpClient.login(username, password); 125       // 判断返回码是否合法 126       if (!FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) { 127         // 不合法时断开连接 128         ftpClient.disconnect(); 129         // 结束程序 130         return result; 131       }132       if(localPasv==1)133       ftpClient.enterLocalPassiveMode();134       // 设置文件操作目录 135       result = createDirAndToDir(remotePath);136       System.out.println("result===="+result);137       // 设置文件类型,二进制 138       result = ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE); 139       // 设置缓冲区大小 140       ftpClient.setBufferSize(3072); 141       // 设置字符编码 142       ftpClient.setControlEncoding("UTF-8"); 143     } catch (IOException e) { 144       e.printStackTrace(); 145     } 146     return result; 147   } 148    149   /** 150    * 上传文件至FTP服务器 151    * 152    * @param serverName 153    *   服务器名称 154    * @param storePath 155    *   上传文件存储路径 156    * @param fileName 157    *   上传文件存储名称 158    * @param is 159    *   上传文件输入流 160    * @return 161    *   <b>true</b>:上传成功 162    *   <br/> 163    *   <b>false</b>:上传失败 164   */ 165   public boolean storeFile (String storePath, String fileName, InputStream is) { 166     boolean result = false; 167     try { 168       // 连接至服务器 169       result = connectToTheServer(storePath); 170       // 判断服务器是否连接成功 171       if (result) { 172         // 上传文件 173         result = ftpClient.storeFile(fileName, is); 174       } 175       // 关闭输入流 176       is.close(); 177     } catch (IOException e) { 178       e.printStackTrace(); 179     } finally { 180       // 判断输入流是否存在 181       if (null != is) { 182         try { 183           // 关闭输入流 184           is.close(); 185         } catch (IOException e) { 186           e.printStackTrace(); 187         } 188       } 189       // 登出服务器并断开连接 190       ftpUtils.logout(); 191     } 192     return result; 193   } 194    195   /** 196    * 下载FTP服务器文件至本地<br/> 197    * 操作完成后需调用logout方法与服务器断开连接 198    *   服务器名称 199    * @param remotePath 200    *   下载文件存储路径 201    * @param fileName 202    *   下载文件存储名称 203    * @return 204    *   <b>InputStream</b>:文件输入流 205   */ 206   public InputStream retrieveFile (String remotePath, String fileName) { 207     try { 208       boolean result = false; 209       // 连接至服务器 210       result = connectToTheServer(remotePath); 211       // 判断服务器是否连接成功 212       if (result) { 213         // 获取文件输入流 214         is = ftpClient.retrieveFileStream(fileName); 215       } 216     } catch (IOException e) { 217       e.printStackTrace(); 218     } 219     return is; 220   } 221    222   /** 223    * 删除FTP服务器文件 224    * 225    * @param serverName 226    *   服务器名称 227    * @param remotePath 228    *   当前访问目录 229    * @param fileName 230    *   文件存储名称 231    * @return 232    *   <b>true</b>:删除成功 233    *   <br/> 234    *   <b>false</b>:删除失败 235   */ 236   public boolean deleteFile (String serverName, String remotePath, String fileName) { 237     boolean result = false; 238     // 连接至服务器 239     result = connectToTheServer(remotePath); 240     // 判断服务器是否连接成功 241     if (result) { 242       try { 243         // 删除文件 244         result = ftpClient.deleteFile(fileName); 245       } catch (IOException e) { 246         e.printStackTrace(); 247       } finally { 248         // 登出服务器并断开连接 249         ftpUtils.logout(); 250       } 251     } 252     return result; 253   } 254   255   /** 256    * 创建目录 257    * 258    * @param remotePath 259    *   目录储路径 260    * @return 261    *   <b>true</b>:创建成功262    *   <br/> 263    *   <b>false</b>:创建失败 264   */ 265   public boolean createDirAndToDir (String remotePath) {266     boolean result = false; 267     try { 268       // 连接至服务器 269       //result = ftpClient.changeWorkingDirectory(remotePath);270       String [] dirs = remotePath.split("/");271       if(dirs!=null){272         String tempDir = "";273         for(String dir : dirs){274           tempDir += dir +"/";275           result = ftpClient.changeWorkingDirectory(tempDir);276           if(!result){277             result = ftpClient.makeDirectory(dir);278             ftpClient.changeWorkingDirectory(dir);279           }280         }281       }282     } catch (IOException e) { 283       e.printStackTrace(); 284       return false;285     }  286     return true; 287   }288   /** 289    * 检测FTP服务器文件是否存在 290    * 服务器名称 291    * @param remotePath 292    *   检测文件存储路径 293    * @param fileName 294    *   检测文件存储名称 295    * @return 296    *   <b>true</b>:文件存在 297    *   <br/> 298    *   <b>false</b>:文件不存在 299   */ 300   public boolean checkFile (String remotePath, String fileName) {301     boolean result = false; 302     try { 303       // 连接至服务器 304       result = connectToTheServer(remotePath); 305       // 判断服务器是否连接成功 306       if (result) {307         // 默认文件不存在 308         result = false; 309         // 获取文件操作目录下所有文件名称 310         String[] remoteNames = ftpClient.listNames(); 311         // 循环比对文件名称,判断是否含有当前要下载的文件名 312         for (String remoteName: remoteNames) { 313           if (fileName.equals(remoteName)) { 314             result = true; 315           } 316         } 317       } 318     } catch (IOException e) { 319       e.printStackTrace(); 320     } finally { 321       // 登出服务器并断开连接 322       ftpUtils.logout(); 323     } 324     return result; 325   }326  327   /** 328    * 登出服务器并断开连接 329    * 330    * @param ftp 331    *   FTPClient对象实例 332    * @return 333    *   <b>true</b>:操作成功 334    *   <br/> 335    *   <b>false</b>:操作失败 336   */ 337   public boolean logout () { 338     boolean result = false; 339     if (null != is) { 340       try { 341         // 关闭输入流 342         is.close(); 343       } catch (IOException e) { 344         e.printStackTrace(); 345       } 346     } 347     if (null != ftpClient) { 348       try { 349         // 登出服务器 350         result = ftpClient.logout(); 351       } catch (IOException e) { 352         e.printStackTrace(); 353       } finally { 354         // 判断连接是否存在 355         if (ftpClient.isConnected()) { 356           try { 357             // 断开连接 358             ftpClient.disconnect(); 359           } catch (IOException e) { 360             e.printStackTrace(); 361           } 362         } 363       } 364     } 365     return result; 366   } 367   368   public String getSiteName() {369     return siteName;370   }371 372   public String getSaveFilePath() {373     return saveFilePath;374   }    375 } 

  

           第四步 用到的副类,真正做到任君品尝 !!(重要程度:☆☆

         (1)IDGen工具类

 1 /** 2  * 随机ID工具类 3 */ 4 package com.xx.utils; 5  6 import java.io.Serializable; 7 import java.security.SecureRandom; 8 import java.text.DecimalFormat; 9 import java.util.Date;10 import java.util.UUID;11 12 import org.apache.shiro.session.Session;13 import org.apache.shiro.session.mgt.eis.SessionIdGenerator;14 import org.springframework.context.annotation.Lazy;15 import org.springframework.stereotype.Service;16 17 /**18  * 封装各种生成唯一性ID算法的工具类.19  * @author ThinkGem20  * @version 2013-01-1521 */22 @Service23 @Lazy(false)24 public class IdGen implements SessionIdGenerator {25 26   private static SecureRandom random = new SecureRandom();27   private static int num;28   29   /**30    * 封装JDK自带的UUID, 通过Random数字生成, 中间无-分割.31   */32   public static String uuid() {33     return UUID.randomUUID().toString().replaceAll("-", "");34   }35   /**36    * 生成投资编号37    * @return38   */39   public static String investNo(){40     String date = DateUtils.formatDateToStr("yyyyMMddHHmmss",new Date());41     if(num>999999){42       num = 0;43     }44     String numStr = new DecimalFormat("000000").format(num++);45     return date.substring(2)+ numStr;46   }47   48   /**49    * 使用SecureRandom随机生成Long. 50   */51   public static long randomLong() {52     return Math.abs(random.nextLong());53   }54 55 56 57   @Override58   public Serializable generateId(Session session) {59     return IdGen.uuid();60   }61   62   public static String getRandomName(int k){63     String chars = "abcdefghijklmnopqrstuvwxyz0123456789";64     StringBuilder sb = new StringBuilder();65     for (int i = 0; i < k; i++) {66       sb.append(chars.charAt((int)(Math.random() * 36)));67     }68     return sb.toString();69   }70 71 72 }

         (2)ImageUtil工具类

 1 package com.xx.utils; 2  3 import java.awt.AlphaComposite; 4 import java.awt.Color; 5 import java.awt.Font; 6 import java.awt.Graphics2D; 7 import java.awt.Image; 8 import java.awt.RenderingHints; 9 import java.awt.image.BufferedImage; 10 import java.io.File; 11 import java.io.FileOutputStream; 12 import java.io.InputStream; 13 import java.io.OutputStream; 14  15 import javax.imageio.ImageIO; 16 import javax.swing.ImageIcon; 17  18 import org.slf4j.Logger; 19 import org.slf4j.LoggerFactory; 20  21 /** 22  * 图片处理类 23  * @author xx 24 */ 25 public class ImageUtils { 26   private final static Logger logger = LoggerFactory.getLogger(ImageUtils.class); 27   // 水印透明度  28   private static float alpha = 0.5f; 29   // 水印横向位置 30   private static int positionWidth = 150; 31   // 水印纵向位置 32   private static int positionHeight = 300; 33   // 水印文字字体 34   private static Font font = new Font("宋体", Font.BOLD, 30); 35   // 水印文字颜色 36   private static Color color = Color.red; 37  38   /**  39    * 给图片添加图片水印 40    * @param iconPath 水印图片路径  41    * @param file 源文件  42    * @param targerPath 目标图片路径  43    * @param degree 水印图片旋转角度  44   */  45   public static void markImageByIcon(String iconPath, File file,   46       String targerPath, Integer degree) {   47     OutputStream os = null;   48     try {  49       logger.info("水印图片路径:{}", iconPath); 50       logger.info("源文件:{}", file.getAbsolutePath()); 51       logger.info("目标图片路径:{}", targerPath); 52       Image srcImg = ImageIO.read(file);  53   54       BufferedImage buffImg = new BufferedImage(srcImg.getWidth(null),   55           srcImg.getHeight(null), BufferedImage.TYPE_INT_RGB);   56   57       // 得到画笔对象   58       Graphics2D g = buffImg.createGraphics();   59   60       // 设置对线段的锯齿状边缘处理   61       g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,   62           RenderingHints.VALUE_INTERPOLATION_BILINEAR);   63   64       g.drawImage(srcImg.getScaledInstance(srcImg.getWidth(null), srcImg   65           .getHeight(null), Image.SCALE_SMOOTH), 0, 0, null);   66   67       if (null != degree) {   68         // 设置水印旋转   69         g.rotate(Math.toRadians(degree),   70             (double) buffImg.getWidth() / 2, (double) buffImg   71                 .getHeight() / 2);   72       }   73   74       // 水印图象的路径 水印一般为gif或者png的,这样可设置透明度   75       ImageIcon imgIcon = new ImageIcon(iconPath);   76   77       // 得到Image对象。   78       Image img = imgIcon.getImage();   79   80       float alpha = 0.5f; // 透明度   81       g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP,   82           alpha));   83   84       // 表示水印图片的位置  相对于中心店的宽高以及水印图片宽高(img,x,y,width,height,obnull) 85       g.drawImage(img, buffImg.getWidth() / 6,buffImg.getHeight() / 3, buffImg.getWidth() / 2,buffImg.getHeight() / 4, null);   86   87       g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER));   88   89       g.dispose();   90   91       os = new FileOutputStream(targerPath);   92   93       // 生成图片   94       ImageIO.write(buffImg, "JPG", os);   95   96       logger.info("图片完成添加水印");   97     } catch (Exception e) {   98       e.printStackTrace();  99       logger.error("图片完成添加水印error:{}", e.getMessage());100     } finally {  101       try {  102         if (null != os)  103           os.close();  104       } catch (Exception e) {  105         e.printStackTrace();  106       }  107     }  108   }  109   110   /**111    * 给图片添加水印文字112    * @param logoText 水印文字113    * @param srcImgPath 原图片路径114    * @param targerPath 目标图片路径115    * @param degree 旋转角度116   */117   public static void markImageByText(String logoText, String srcImgPath,118       String targerPath, Integer degree) {119     120     InputStream is = null;121     OutputStream os = null;122     try {123       // 1、源图片124       Image srcImg = ImageIO.read(new File(srcImgPath));125       BufferedImage buffImg = new BufferedImage(srcImg.getWidth(null),srcImg.getHeight(null), BufferedImage.TYPE_INT_RGB);126 127       // 2、得到画笔对象128       Graphics2D g = buffImg.createGraphics();129       // 3、设置对线段的锯齿状边缘处理130       g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,RenderingHints.VALUE_INTERPOLATION_BILINEAR);131       g.drawImage(srcImg.getScaledInstance(srcImg.getWidth(null), srcImg.getHeight(null), Image.SCALE_SMOOTH), 0, 0, null);132       // 4、设置水印旋转133       if (null != degree) {134         g.rotate(Math.toRadians(degree),(double) buffImg.getWidth() / 2, (double) buffImg.getHeight() / 2);135       }136       // 5、设置水印文字颜色137       g.setColor(color);138       // 6、设置水印文字Font139       g.setFont(font);140       // 7、设置水印文字透明度141       g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP,alpha));142       // 8、第一参数->设置的内容,后面两个参数->文字在图片上的坐标位置(x,y)143       g.drawString(logoText, positionWidth, positionHeight);144       // 9、释放资源145       g.dispose();146       // 10、生成图片147       os = new FileOutputStream(targerPath);148       ImageIO.write(buffImg, "JPG", os);149 150       logger.info("图片完成添加水印文字");151       152     } catch (Exception e) {153       e.printStackTrace();154     } finally {155       try {156         if (null != is)157           is.close();158       } catch (Exception e) {159         e.printStackTrace();160       }161       try {162         if (null != os)163           os.close();164       } catch (Exception e) {165         e.printStackTrace();166       }167     }168   }169   170   /**171    * 判断文件是不是图片172    * @param file173    * @return174    * @author guogf175   */176   public static boolean isImage(File file) 177     { 178       boolean flag = false;  179       try 180       { 181         Image is = ImageIO.read(file); 182         if(null != is) 183         { 184           flag = true;185         }186       } catch (Exception e) 187       { 188         e.printStackTrace(); 189       } 190       return flag; 191     }192    193 }

 

关于编辑器的前台配置

        到此后台处理函数已完整实现,现在需要将后台返回的json串回调到前端编辑器来处理,写入上传容器框以及编辑器文章当中。

       首先去找到umeditor.config.js 找到如下并修改: 

1 //图片上传配置区2     ,imageUrl:ctx+"/cms/article/upload"       //图片上传提交地址 很重要!上传提交地址,这里配置成我刚才写的那个控制器函数 路径很重要 ctx获取的是当前域名3     ,imagePath:"http://static.xx.com/"           //图片修正地址,对应刚才我提到的域名配置的地方 必须配置!!4     ,imageFieldName:"upfile"          //图片数据的key,若此处修改,需要在后台对应文件修改对应参数 对应刚才提到的上传图片的表单name 默认即可

       配置好之后,后来调试发现 返回的json 串包含在pre标签里,编辑器脚本解析不了,报错,所以,这里还需要修改编辑器目录 dialogs\image\image.js文件  

 1 uploadComplete: function(r){ 2       debugger; 3       var me = this; 4       try{ 5         var json = eval('('+$(r).html()+')'); //这里需要把返回的字符串转化成对象 pre对象,然后获取里面json串 6         Base.callback(me.editor, me.dialog, json.url, json.state); 7       }catch (e){ 8         var lang = me.editor.getLang('image'); 9         Base.callback(me.editor, me.dialog, '', (lang && lang.uploadError) || 'Error!');10       }11     },

 

    好了,到这里基本完事了,我们看下最终效果吧!

 

    开始上传效果图:

 

 

      拖曳或者上传效果图:

    

 

       编辑器效果图:

                                  

       文章预览效果图:

 

 

 

说在后面

      这篇博文写了挺长时间,手都酸了...之前有部分分享总是被移除首页,所以,在格式排版上花很长时间..

如果,您认为阅读这篇博客让您有些收获,不妨点击一下右下角的【推荐】按钮。
如果,您希望更容易地发现我的新博客,不妨点击一下绿色通道的【关注我】。

如果,想给予我更多的鼓励,求打赏

  
欢迎资助我持续写作,金额随意,欢迎来赏!

因为,我的写作热情也离不开您的肯定支持。

感谢您的阅读,如果您对我的博客所讲述的内容有兴趣,请继续关注我的后续博客 。

另外,需要声明:原创博客请在转载时保留原文链接或者在文章开头加上本人博客地址(http://www.cnblogs.com/sybboy),如发现错误,欢迎批评指正。