【完整靠谱版】结合公司项目,仔细总结自己使用百度编辑器实现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);  //上传的图片大小可以放到配置中读取,这里设置10M
12         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/MM
28                     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 可自定义配置参数 imageFieldName
22         // 移除不符合条件的
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 ThinkGem
20  * @version 2013-01-15
21  */
22 @Service
23 @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      * @return
38      */
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     @Override
58     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、设置水印文字Font
139             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 file
173      * @return
174      * @author guogf
175      */
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),如发现错误,欢迎批评指正。

时间: 2024-08-18 16:05:49

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

js仿百度文库文档上传页面的分类选择器_第二版

仿百度文库文档上传页面的多级联动分类选择器第二版,支持在一个页面同时使用多个分类选择器: 此版本把HTML,CSS,以及图片都封装到"category.js"中,解决因文件路径找不到样式及图片的问题: 源码下载地址:http://download.csdn.net/detail/testcs_dn/7290577 初始状态,一个页面使用两个,可以初始化之前选中的分类: 选择状态: 当选中一个分类后,会触发"onChange"事件,如上图中的"您选择的分类编

ecshop 后台批量上传商品 完整上传

ecshop 后台批量上传商品,之所以无法上传,是因为后台上传php文件方法中没有导入商品原图路径 将ecshop根目录中的admin/goods_batch.php文件全部修改为 <?php /** * ECSHOP 商品批量上传.修改 * ============================================================================ * * 版权所有 2005-2012 上海商派网络科技有限公司,并保留所有权利. * 网站地址: ht

推荐ajaxfilemanager for tiny_mce 比较完善的tiny_mce编辑器的图片上传及图片管理插件PHP版 支持中文

tiny_mce编辑器,我觉得挺简洁.好用的,但就是图片上传的插件是收费的,而且网上找了半天也没有找到开源好用的上传插件. 不过功夫不负有心人,终于还就被我找到一款相当满意的插件. 这个插件的名字叫ajaxfilemanager 官方网址是http://www.phpletter.com/DOWNLOAD/ Tinymce Ajax File and Image Manager Tinymce Ajax File and Image Manager Version 1.0 Final Proje

如何让vue项目跑起来(示例:阿里短视频上传项目vue版demo)

在cmd操作如下:node -vnpm -v 由于有些npm有些资源被屏蔽或者是国外资源的原因,经常会导致用npm安装依赖包的时候失败,所有我还需要npm的国内镜像---cnpmcnpm -v 报错,cnpm不是内部指令.解决办法如下:安装cnpmhttps://jingyan.baidu.com/article/9080802239521cfd90c80f55.html 完成之后,我们就可以用cnpm代替npm来安装依赖包了. 安装vue-cli脚手架构建工具 cnpm install -g

一步步开发自己的博客 .NET版(4、文章发布功能)百度编辑器

前言 这次开发的博客主要功能或特点:    第一:可以兼容各终端,特别是手机端.    第二:到时会用到大量html5,炫啊.    第三:导入博客园的精华文章,并做分类.(不要封我)    第四:做个插件,任何网站上的技术文章都可以转发收藏 到本博客. 所以打算写个系类:<一步步搭建自己的博客> 一.一步步开发自己的博客  .NET版(1.页面布局.blog迁移.数据加载) 二.一步步开发自己的博客  .NET版(2.评论功能) 三.一步步开发自己的博客  .NET版(3.注册登录功能) 四

项目开发笔记-传单下发 名片替换 文件复制上传/html静态内容替换/json解析/html解析

//////////////////////////// 注意: 此博客是个人工作笔记 非独立demo////////////////////////////////// ....................................................................................................................................................................

配置Spring项目输出JSON到LogStash或者使用FileBeat收集上传到ELK

一.使用LogStash 在项目中添加Gradle依赖,然后Sync项目: "net.logstash.logback:logstash-logback-encoder:4.11", 或者使用Maven: <!-- https://mvnrepository.com/artifact/net.logstash.logback/logstash-logback-encoder --> <dependency> <groupId>net.logstash

IIS创建ftp服务器和ftp上传发布项目的步骤

Java中实现FTP上传下载文件的功能,完整代码

一个JAVA 实现FTP功能的代码,包括了服务器的设置模块,并包括有上传文件至FTP的通用方法.下载文件的通用方法以及删除文件.在ftp服务器上穿件文件夹.检测文件夹是否存在等,里面的有些代码对编写JAVA文件上传或许有参考价值,Java FTP主文件代码: package ftpDemo;         import java.io.DataOutputStream;         import java.io.InputStream;         import java.io.Out