1.application.properties文件配置
#FTP文件上传
#ftp config
ftp.enabled=true
ftp.host=127.0.0.1
ftp.port=21
ftp.username=zz
ftp.password=123456
ftp_img_path=/home/zz/img/
ftp_file_path=/home/zz/file/
ftp_img_show_path=/img/
ftp_file_show_path=/file/
2.ftp配置类
package com.config;
import javax.annotation.PreDestroy;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.pool2.ObjectPool;
import org.apache.commons.pool2.PooledObject;
import org.apache.commons.pool2.PooledObjectFactory;
import org.apache.commons.pool2.impl.DefaultPooledObject;
import org.apache.commons.pool2.impl.GenericObjectPool;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import com.cwh.springbootMybatis.utils.FtpUtil;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
/**
* FTP配置类
*
*
*/
@Slf4j
@Configuration
@ConditionalOnClass({GenericObjectPool.class, FTPClient.class})
@ConditionalOnProperty(value = "ftp.enabled", havingValue = "true")
@EnableConfigurationProperties(FTPConfiguration.FtpConfigProperties.class)
public class FTPConfiguration {
private ObjectPool pool;
public FTPConfiguration(FtpConfigProperties props) {
// 默认最大连接数与最大空闲连接数都为8,最小空闲连接数为0
// 其他未设置属性使用默认值,可根据需要添加相关配置
GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();
poolConfig.setTestOnBorrow(true);
poolConfig.setTestOnReturn(true);
poolConfig.setTestWhileIdle(true);
//poolConfig.setMaxWaitMillis(-1);//永不超时
//连接空闲的最小时间,达到此值后空闲连接将可能会被移除。默认为1000L 60L 30L
poolConfig.setMinEvictableIdleTimeMillis(1000*60*30);//1000L 60L 30L 60000
//连接空闲的最小时间,达到此值后空闲链接将会被移除,且保留minIdle个空闲连接数。默认为-1.
poolConfig.setSoftMinEvictableIdleTimeMillis(-1);//-1 50000
//空闲链接检测线程检测的周期,毫秒数。如果为负值,表示不运行检测线程。默认为-1.
poolConfig.setTimeBetweenEvictionRunsMillis(-1);//30000
pool = new GenericObjectPool<>(new FtpClientPooledObjectFactory(props), poolConfig);
preLoadingFtpClient(props.getInitialSize(), poolConfig.getMaxIdle());
// 初始化ftp工具类中的ftpClientPool
FtpUtil.init(pool);
}
/**
* 预先加载FTPClient连接到对象池中
* @param initialSize 初始化连接数
* @param maxIdle 最大空闲连接数
*/
private void preLoadingFtpClient(Integer initialSize, int maxIdle) {
if (initialSize == null || initialSize <= 0) {
return;
}
int size = Math.min(initialSize.intValue(), maxIdle);
for (int i = 0; i < size; i++) {
try {
pool.addObject();
} catch (Exception e) {
log.error("preLoadingFtpClient error...", e);
}
}
}
@PreDestroy
public void destroy() {
if (pool != null) {
pool.close();
log.info("销毁ftpClientPool...");
}
}
/**
* Ftp配置属性类,建立ftpClient时使用
*/
@Data
@ConfigurationProperties(prefix = "ftp")
static class FtpConfigProperties {
private String host = "localhost";
private int port = FTPClient.DEFAULT_PORT;
private String username;
private String password;
private int bufferSize = 8096;
private String encoding="UTF-8";
/**
* 初始化连接数
*/
private Integer initialSize = 0;
}
/**
* FtpClient对象工厂类
*/
static class FtpClientPooledObjectFactory implements PooledObjectFactory {
private FtpConfigProperties props;
public FtpClientPooledObjectFactory(FtpConfigProperties props) {
this.props = props;
}
@Override
public PooledObject makeObject() throws Exception {
FTPClient ftpClient = new FTPClient();
try {
long time=System.currentTimeMillis();
ftpClient.connect(props.getHost(), props.getPort());
ftpClient.login(props.getUsername(), props.getPassword());
log.info("连接FTP服务器返回码{}", ftpClient.getReplyCode());
ftpClient.setBufferSize(props.getBufferSize());
ftpClient.setControlEncoding(props.getEncoding());
ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
ftpClient.enterLocalPassiveMode();
log.info("登录耗时 "+(System.currentTimeMillis()-time)+" ms!");
return new DefaultPooledObject<>(ftpClient);
} catch (Exception e) {
log.error("建立FTP连接失败", e);
if (ftpClient.isAvailable()) {
ftpClient.disconnect();
}
ftpClient = null;
throw new Exception("建立FTP连接失败", e);
}
}
@Override
public void destroyObject(PooledObject p) throws Exception {
FTPClient ftpClient = getObject(p);
if (ftpClient != null && ftpClient.isConnected()) {
ftpClient.disconnect();
}
}
@Override
public boolean validateObject(PooledObject p) {
FTPClient ftpClient = getObject(p);
if (ftpClient == null || !ftpClient.isConnected()) {
return false;
}
try {
ftpClient.changeWorkingDirectory("/");
return true;
} catch (Exception e) {
log.error("验证FTP连接失败::{}", ExceptionUtils.getStackTrace(e));
return false;
}
}
@Override
public void activateObject(PooledObject p) throws Exception {
}
@Override
public void passivateObject(PooledObject p) throws Exception {
}
private FTPClient getObject(PooledObject p) {
if (p == null || p.getObject() == null) {
return null;
}
return p.getObject();
}
}
}
3.ftp工具类
package com.utils;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.SocketException;
import java.util.UUID;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;
import org.apache.commons.pool2.ObjectPool;
import org.apache.shiro.util.Assert;
import org.springframework.stereotype.Component;
import lombok.extern.slf4j.Slf4j;
/***
* ftp上传下载工具类
*
* @author
*
*/
@Component
@Slf4j
public class FtpUtil {
/**
* ftpClient连接池初始化标志
*/
private static volatile boolean hasInit = false;
/**
* ftpClient连接池
*/
private static ObjectPool ftpClientPool;
/**
* Description: 向FTP服务器上传文件
* @param ftpHost FTP服务器hostname
* @param ftpUserName 账号
* @param ftpPassword 密码
* @param ftpPort 端口
* @param ftpPath FTP服务器中文件所在路径 格式: ftptest/aa
* @param fileName ftp文件名称
* @param input 文件流
* @return 成功返回true,否则返回false
*/
public String uploadFile(String ftpPath,String fileName,InputStream input) {
FTPClient ftpClient = null;
String newName=null;
try {
int reply;
ftpClient = getFtpClient();
reply = ftpClient.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
ftpClient.disconnect();
log.debug("上传失败,连接断开了!");
}
//ftpClient.setControlEncoding("UTF-8"); // 中文支持
//ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
//ftpClient.enterLocalPassiveMode();
ftpClient.changeWorkingDirectory(ftpPath);
newName=getCurrentDay()+ "__"+UUID.randomUUID().toString()+fileName.substring(fileName.lastIndexOf(".",
fileName.length()));
//ftpClient.storeFile(fileName, input);
boolean f=ftpClient.storeFile(new String(newName.getBytes("UTF-8"),"iso-8859-1"),input);
if(f) {
log.debug("上传成功!");
}else {
log.debug("上传失败!");
}
input.close();
//ftpClient.logout();
} catch (IOException e) {
e.printStackTrace();
} finally {
releaseFtpClient(ftpClient);
}
return newName;
}
/*
* 从FTP服务器下载文件
*
* @param ftpHost FTP IP地址
* @param ftpUserName FTP 用户名
* @param ftpPassword FTP用户名密码
* @param ftpPort FTP端口
* @param ftpPath FTP服务器中文件所在路径 格式: ftptest/aa
* @param localPath 下载到本地的位置 格式:H:/download
* @param fileName 文件名称
*/
public void downloadFtpFile(String ftpPath, String localPath,
String fileName) {
FTPClient ftpClient = null;
try {
ftpClient = getFtpClient();
ftpClient.setControlEncoding("UTF-8"); // 中文支持
ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
ftpClient.enterLocalPassiveMode();
ftpClient.changeWorkingDirectory(ftpPath);
File localFile = new File(localPath + File.separatorChar + fileName);
OutputStream os = new FileOutputStream(localFile);
//ftpClient.retrieveFile(fileName, os);
boolean f=ftpClient.retrieveFile(new String(localFile.getName().getBytes("utf-8"),"iso-8859-1"), os);
System.out.println("download "+f);
os.close();
//ftpClient.logout();
} catch (FileNotFoundException e) {
System.out.println("没有找到" + ftpPath + "文件");
e.printStackTrace();
} catch (SocketException e) {
System.out.println("连接FTP失败.");
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
System.out.println("文件读取错误。");
e.printStackTrace();
}
}
private static String getCurrentDay() {
java.text.SimpleDateFormat format = new java.text.SimpleDateFormat(
"yyyy-MM-dd-HH-mm-ss");
return format.format(new java.util.Date());
}
/**
* 初始化ftpClientPool
*
* @param ftpClientPool
*/
public static void init(ObjectPool ftpClientPool) {
if (!hasInit) {
synchronized (FtpUtil.class) {
if (!hasInit) {
FtpUtil.ftpClientPool = ftpClientPool;
hasInit = true;
}
}
}
}
/**
* 获取ftpClient
*
* @return
*/
private static FTPClient getFtpClient() {
checkFtpClientPoolAvailable();
FTPClient ftpClient = null;
Exception ex = null;
// 获取连接最多尝试3次
for (int i = 0; i < 3; i++) {
try {
ftpClient = ftpClientPool.borrowObject();
ftpClient.changeWorkingDirectory("/");
break;
} catch (Exception e) {
ex = e;
}
}
if (ftpClient == null) {
throw new RuntimeException("Could not get a ftpClient from the pool", ex);
}
return ftpClient;
}
/**
* 释放ftpClient
*/
private static void releaseFtpClient(FTPClient ftpClient) {
if (ftpClient == null) {
return;
}
try {
ftpClientPool.returnObject(ftpClient);
} catch (Exception e) {
log.error("Could not return the ftpClient to the pool", e);
// destoryFtpClient
if (ftpClient.isAvailable()) {
try {
ftpClient.disconnect();
} catch (IOException io) {
}
}
}
}
/**
* 检查ftpClientPool是否可用
*/
private static void checkFtpClientPoolAvailable() {
Assert.state(hasInit, "FTP未启用或连接失败!");
}
}
4.ftp controller类
package com.cwh.springbootMybatis.controller.system;
import java.util.HashMap;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import com.cwh.springbootMybatis.utils.FtpUtil;
import com.cwh.springbootMybatis.utils.UUIDUtil;
import lombok.extern.slf4j.Slf4j;
import net.sf.json.JSONObject;
/**
*
*/
@Controller
@Slf4j
public class UploadController {
@Autowired
FtpUtil ftpUtil;
@Value("${ftp_img_path}")
private String ftp_img_path;
@RequestMapping(value = "/uploadFTP", method = RequestMethod.POST)
@ResponseBody
public String uploadFTP(@RequestParam("upfile") MultipartFile file,String id) throws Exception {
JSONObject json = new JSONObject();
if(file == null) {
log.debug("文件为空,上传失败!");
return null;
}
String name=ftpUtil.uploadFile(ftp_img_path, file.getOriginalFilename(), file.getInputStream());
json.put("state", "SUCCESS");
json.put("url", name);
json.put("title", file.getOriginalFilename());
json.put("original", file.getOriginalFilename());
return json.toString();
}
}
5.页面部分代码注意百度编辑器插件的位置src/main/resources/static/lib
6.如何获取百度编辑器的内容呢?
var content=UE.getEditor('content').getContent();
7.百度编辑器配置代码
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
@Controller
@RequestMapping("/lib/ueditor")
public class ConfigController {
// 图片上传 跳转到配置文件
@RequestMapping(value = "/config")
public void ueditor(@RequestParam("action") String action,
HttpServletRequest request, HttpServletResponse response) {
org.springframework.core.io.Resource res = new ClassPathResource("config/config.json");
InputStream is = null;
response.setHeader("Content-Type", "text/html");
try {
is = res.getInputStream();
StringBuffer sb = new StringBuffer();
byte[] b = new byte[1024];
int length = 0;
while (-1 != (length = is.read(b))) {
sb.append(new String(b, 0, length, "utf-8"));
}
String result = sb.toString().replaceAll("/\\*(.|[\\r\\n])*?\\*/", "");
net.sf.json.JSONObject json = net.sf.json.JSONObject.fromObject(result);
PrintWriter out = response.getWriter();
out.print(json.toString());
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
8.百度编辑器配置json文件,注意json文件的位置 src/main/resources/config/config.json
/* 前后端通信相关的配置,注释只允许使用多行方式 */
{
/* 上传图片配置项 */
"imageActionName": "uploadimage", /* 执行上传图片的action名称 */
"imageFieldName": "upfile", /* 提交的图片表单名称 */
"imageMaxSize": 2048000, /* 上传大小限制,单位B */
"imageAllowFiles": [".png", ".jpg", ".jpeg", ".gif", ".bmp"], /* 上传图片格式显示 */
"imageCompressEnable": true, /* 是否压缩图片,默认是true */
"imageCompressBorder": 1600, /* 图片压缩最长边限制 */
"imageInsertAlign": "none", /* 插入的图片浮动方式 */
"imageUrlPrefix": "http://x.x.x.x/img/", /* 图片访问路径前缀 */
"imagePathFormat": "", /* 上传保存路径,可以自定义保存路径和文件名格式 */
/* {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": "", /* 上传保存路径,可以自定义保存路径和文件名格式 */
"scrawlMaxSize": 2048000, /* 上传大小限制,单位B */
"scrawlUrlPrefix": "http://x.x.x.x/img/", /* 图片访问路径前缀 */
"scrawlInsertAlign": "none",
/* 截图工具上传 */
"snapscreenActionName": "uploadimage", /* 执行上传截图的action名称 */
"snapscreenPathFormat": "", /* 上传保存路径,可以自定义保存路径和文件名格式 */
"snapscreenUrlPrefix": "http://x.x.x.x/img/", /* 图片访问路径前缀 */
"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": "", /* 上传保存路径,可以自定义保存路径和文件名格式 */
"fileUrlPrefix": "http://x.x.x.x/img/", /* 文件访问路径前缀 */
"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"
] /* 列出的文件类型 */
}
最后注意百度编辑器文件的路径src\main\resources\static\lib\ueditor,其中ueditor就是百度编辑器的插件,下载地址
https://ueditor.baidu.com/website/