百度ueditor富文本编辑器实现上传文件、图片、视频到ftp服务器并在页面端回显
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
百度ueditor富⽂本编辑器实现上传⽂件、图⽚、视频到ftp服务
器并在页⾯端回显
之前⼀直⽤ueditor作为富⽂本编辑器,想要实现图⽚上传到ftp的功能,⽹上搜索了⼀圈,发现都感觉讲的不是很明⽩,⽽且有不少要引⼊其他的java代码,最近⾃⼰试了⼀下,终于调通了,希望能帮到各位。
废话不多说,查看步骤。
(注意,这个是springboot版本,其实springmvc的也差不多,有⼀点点不同,最后我会说明)
1.将utf8-jsp的整个⽂件夹复制到resources的static⽬录下,打开之后⽬录如下。
项⽬⽬录如下(我多加了⼀层ueditor⽬录,不过也⼀样)
2.写两个controller,代码如下(请忽略楼主潦草的代码,⾃⼰拿回去调整⼀下,修改⼀下UploadController中ftp的地址,密码即可,总共有三个地⽅)
1.UploadController
package com.wang.controller;
import lombok.extern.slf4j.Slf4j;
import mons.fileupload.FileItem;
import mons.fileupload.disk.DiskFileItemFactory;
import mons.fileupload.servlet.ServletFileUpload;
import .ftp.FTP;
import .ftp.FTPClient;
import .ftp.FTPConnectionClosedException;
import .ftp.FTPReply;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.*;
import .URLEncoder;
import java.text.SimpleDateFormat;
import java.util.*;
@RequestMapping("/ueditor/file")
@Controller
@Slf4j
public class UploadController {
private FTPClient ftpClient = new FTPClient();
private Logger logger = LoggerFactory.getLogger(UploadController.class);
//上传图⽚并回显
@RequestMapping("/uploadImg")
@ResponseBody
public Map<String,Object> upload(HttpServletRequest request) throws Exception {
Map<String ,Object> map = new HashMap<>();
// 判断enctype属性是否为multipart/form-data
boolean isMultipart = ServletFileUpload.isMultipartContent(request);
if (!isMultipart)
throw new IllegalArgumentException(
"上传内容不是有效的multipart/form-data类型.");
// Create a factory for disk-based file items
DiskFileItemFactory factory = new DiskFileItemFactory();
// Create a new file upload handler
ServletFileUpload upload = new ServletFileUpload(factory);
FileItem item = (FileItem) iter.next();
// 如果是⽂件字段
String fieldName = item.getFieldName();
String orginFileName = item.getName();
String imgSunffix = orginFileName.substring(stIndexOf(".")); String uuid = UUID.randomUUID().toString().replaceAll("-", "");
String fileName = uuid+imgSunffix;
// String contentType = item.getContentType();
// boolean isInMemory = item.isInMemory();
// long sizeInBytes = item.getSize();
// String filePath = STORE_FILE_DIR + fileName;
//写⼊⽂件到当前服务器磁盘
// File uploadedFile = new File(filePath);
SimpleDateFormat formatPath = new SimpleDateFormat("yyMMdd");
SimpleDateFormat fromahhPath = new SimpleDateFormat("HH");
String yyMMdd = formatPath.format(new Date());
String hours = fromahhPath.format(new Date());
String ftpfilePath = yyMMdd + "/" + hours;
// FileInputStream fileInputStream = (FileInputStream) item.getInputStream(); InputStream inputStream = item.getInputStream();
BufferedInputStream bufferedInputStream = null;
bufferedInputStream = new BufferedInputStream(inputStream);
FTPClient ftp = new FTPClient();
try {
int reply;
ftp.connect("11111", 21);// 连接FTP服务器
// 如果采⽤默认端⼝,可以使⽤ftp.connect(url)的⽅式直接连接FTP服务器 ftp.login("11111", "11111");// 登录
ftp.setFileType(FTP.BINARY_FILE_TYPE);
ftp.setFileTransferMode(FTP.STREAM_TRANSFER_MODE);
reply = ftp.getReplyCode();
if(!FTPReply.isPositiveCompletion(reply)){
ftp.disconnect();
throw new IOException("ftp登录失败");
}
for (String str:ftpfilePath.split("/")){
ftp.makeDirectory(str);
ftp.changeWorkingDirectory(str);
}
boolean tag = ftp.appendFile(fileName,bufferedInputStream);
if(!tag){
throw new Exception("保存到FTP失败");
}
}catch (Exception e){
e.printStackTrace();
}finally {
try {
inputStream.close();
ftp.logout();
} catch (IOException e) {
e.printStackTrace();
}
if(ftp.isConnected()){
try {
ftp.disconnect();
}catch (IOException e){
e.printStackTrace();
}
}
}
String path = "/"+ftpfilePath+"/"+fileName;
// item.write(uploadedFile);
map.put("state","SUCCESS");
map.put("url",path);
map.put("title",orginFileName);
map.put("original",orginFileName);
}
// response.setCharacterEncoding("UTF-8");
// response.getWriter().println("上传成功");
return map;
}
//回显图⽚
// imgPath = "ftpfile\\upload\\11.png";
OutputStream os = null;
ftp = new FTPClient();
ftp.setConnectTimeout(1000 * 30);//设置连接超时时间
ftp.setControlEncoding("utf-8");//设置ftp字符集
ftp.enterLocalPassiveMode();//设置被动模式,⽂件传输端⼝设置
try {
int reply;
ftp.connect("11111", 21);// 连接FTP服务器
// 如果采⽤默认端⼝,可以使⽤ftp.connect(url)的⽅式直接连接FTP服务器
ftp.login("11111", "11111");// 登录
ftp.setFileType(FTP.BINARY_FILE_TYPE);
ftp.setFileTransferMode(FTP.STREAM_TRANSFER_MODE);
reply = ftp.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
ftp.disconnect();
throw new IOException("FTP登录失败");
}
//下载⽂件 FTP协议⾥⾯,规定⽂件名编码为iso-8859-1,所以读取时要将⽂件名转码为iso-8859-1
//如果没有设置按照UTF-8读,获取的流是空值null
in = ftp.retrieveFileStream(new String(imgPath.getBytes("UTF-8"), "iso-8859-1"));
String picType = imgPath.split("\\.")[1];
BufferedImage bufImg = null;
bufImg = ImageIO.read(in);
os = response.getOutputStream();
ImageIO.write(bufImg, picType, os);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
in.close();// 在这⾥关闭,保证⼀定要关闭
ftp.logout();// 在这⾥登出,保证⼀定要登出
} catch (IOException e) {
e.printStackTrace();
}
if (ftp.isConnected()) {
try {
ftp.disconnect();
} catch (IOException ioe) {
}
}
}
response.setContentType("image/jpg");
}
/**
* 下载⽂件到浏览器
* @param response
* @throws IOException
*/
@RequestMapping("/downloadFile.do")
@ResponseBody
public void downFile(@RequestParam("path")String path, HttpServletResponse response) throws IOException {
// 获取ftp信息
// 获取⽂件名称
String[] strs = path.split("/");
String downloadFile = strs[strs.length - 1];
try {
// 设置⽂件ContentType类型,这样设置,会⾃动判断下载⽂件类型
response.setContentType("application/x-msdownload");
// 设置⽂件头:最后⼀个参数是设置下载的⽂件名并编码为UTF-8
response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(downloadFile, "UTF-8")); // 建⽴连接
connectToServer();
ftpClient.enterLocalPassiveMode();
// 设置传输⼆进制⽂件
int reply = ftpClient.getReplyCode();
// ftpClient.changeWorkingDirectory("./home/ftp");
if(!FTPReply.isPositiveCompletion(reply)) {
ftpClient.disconnect();
throw new IOException("failed to connect to the FTP Server:"+21);
}
// 此句代码适⽤Linux的FTP服务器
String newPath = new String(path.getBytes("GBK"),"ISO-8859-1");
bis = new BufferedInputStream(is);
OutputStream out = response.getOutputStream();
byte[] buf = new byte[1024];
int len = 0;
while ((len = bis.read(buf)) > 0) {
out.write(buf, 0, len);
}
out.flush();
} catch (Exception e) {
e.printStackTrace();
} finally {
closeConnect();
if (bis != null) {
try {
bis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (is != null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
} catch (FTPConnectionClosedException e) {
logger.error("ftp连接被关闭!", e);
throw e;
} catch (Exception e) {
logger.error("ERR : upload file "+ downloadFile+ " from ftp : failed!", e);
}
}
/**
* 连接到ftp服务器
*/
private void connectToServer() throws Exception {
// ftpClient.connect(server,21);
if (!ftpClient.isConnected()) {
int reply;
try {
ftpClient=new FTPClient();
ftpClient.connect("111111", 21);// 连接FTP服务器
// 如果采⽤默认端⼝,可以使⽤ftp.connect(url)的⽅式直接连接FTP服务器
ftpClient.login("111111", "111111");// 登录
reply = ftpClient.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
ftpClient.disconnect();
("connectToServer FTP server refused connection.");
}
}catch(FTPConnectionClosedException ex){
logger.error("服务器:IP:"+21+"没有连接数!there are too many connected users,please try later", ex); throw ex;
}catch (Exception e) {
logger.error("登录ftp服务器【"+21+"】失败", e);
throw e;
}
}
}
/**
*
* 功能:关闭连接
*/
public void closeConnect() {
try {
if (ftpClient != null) {
ftpClient.logout();
ftpClient.disconnect();
}
} catch (Exception e) {
logger.error("ftp连接关闭失败!", e);
}
2.ServerController
package com.wang.controller;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baidu.ueditor.ActionEnter;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Controller;
import org.springframework.util.ClassUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
//ueditor单独上传的controller
@Controller
public class ServerController {
@RequestMapping("/configNew")
public void config(HttpServletRequest request, HttpServletResponse response){
response.setContentType("application/json");
// String res = ClassUtils.getDefaultClassLoader().getResource("km").getPath();
// System.out.println("res:"+res);
System.out.println("路径:"+ClassUtils.getDefaultClassLoader().getResource("").getPath());
// String rootPath = ClassUtils.getDefaultClassLoader().getResource("../../").getPath() + "static/ueditor/jsp"; String rootPath = ClassUtils.getDefaultClassLoader().getResource("").getPath() + "static/ueditor/jsp";
System.out.println("root路径:"+rootPath);
try {
response.setCharacterEncoding("UTF-8");
String exec = new ActionEnter(request, rootPath).exec();
System.out.println(exec);
PrintWriter writer = response.getWriter();
writer.write(new ActionEnter(request, rootPath).exec());
writer.flush();
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
// public void getUEConfig(HttpServletRequest request, HttpServletResponse response){
// org.springframework.core.io.Resource res = new ClassPathResource("config.json");
// InputStream is = null;
// response.setHeader("Content-Type" , "text/html");
// try {
// is = new FileInputStream(res.getFile());
// 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])*?\\*/","");
// JSONObject json = JSON.parseObject(result);
// PrintWriter out = response.getWriter();
// out.print(json.toString());
// } catch (IOException e) {
// e.printStackTrace();
// }finally {
// try {
// is.close();
// } catch (IOException e) {
// e.printStackTrace();
// }
// }
// }
}
3.修改ueditor.config.js
var URL = window.UEDITOR_HOME_URL || getUEBasePath();
var server_url = window.location.protocol+"//"+window.location.hostname+":"+window.location.port;
/**
* 配置项主体。
注意,此处所有涉及到路径的配置别遗漏URL变量。
*/
window.UEDITOR_CONFIG = {
//为编辑器实例添加⼀个路径,这个不能被注释
UEDITOR_HOME_URL: URL
// 服务器统⼀请求接⼝路径
// , serverUrl: URL + "jsp/controller.jsp"
, serverUrl: server_url+"/configNew"
4.修改ueditor的jsp⽬录下的config.json⽂件⽬录图⽚如下
打开这个⽂件之后修改⼤概7.8个地⽅的参数,都是xxxUrlPrefix,反正只要是图⽚注释就换成Ueditortxtcontroller中的getIMg路径,⽂件就换成downloadFile路径
图⽚
⽂件路径
5.关键⼀步,记得在你的启动类application中排除掉有关⽂件上传的⾃动配置。
如果是springmvc,那就是在xml⽂件中注释掉multipartfile这个bean了
6.然后是改造的你的编辑器的访问页⾯index.html。
这是楼主的html页⾯,如果要⽤的话,记得把那个juqery-3.5.1.min.js和⼀个保存saveContent的⽅法排除掉就可以了<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"/TR/html4/loose.dtd">
<html>
<head>
<title>完整demo</title>
<link REL="shortcut icon" href="/favicon.ico" type="image/ico"/>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
<script type="text/javascript" charset="utf-8" src="/ueditor/ueditor.config.js"></script>
<script type="text/javascript" charset="utf-8" src="/ueditor/ueditor.all.min.js"> </script>
<script type="text/javascript" charset="utf-8" src="/js/jquery-3.5.1.min.js"> </script>
<!--建议⼿动加在语⾔,避免在ie下有时因为加载语⾔失败导致编辑器加载失败-->
<!--这⾥加载的语⾔⽂件会覆盖你在配置项⽬⾥添加的语⾔类型,⽐如你在配置项⽬⾥配置的是英⽂,这⾥加载的中⽂,那最后就是中⽂--> <script type="text/javascript" charset="utf-8" src="/ueditor/lang/zh-cn/zh-cn.js"></script>
<style type="text/css">
div{
width:100%;
}
</style>
</head>
<body>
<div>
<h1>完整demo</h1>
<script id="editor" type="text/plain" style="width:1024px;height:500px;"></script>
</div>
<div id="btns">
<div>
<button onclick="saveContent()">保存</button>
<button onclick="getAllHtml()">获得整个html的内容</button>
<button onclick="getContent()">获得内容</button>
<button onclick="setContent()">写⼊内容</button>
<button onclick="setContent(true)">追加内容</button>
<button onclick="getContentTxt()">获得纯⽂本</button>
<button onclick="getPlainTxt()">获得带格式的纯⽂本</button>
<button onclick="hasContent()">判断是否有内容</button>
<button onclick="setFocus()">使编辑器获得焦点</button>
<button onmousedown="isFocus(event)">编辑器是否获得焦点</button>
<button onmousedown="setblur(event)" >编辑器失去焦点</button>
</div>
<div>
<button onclick="getText()">获得当前选中的⽂本</button>
<button onclick="insertHtml()">插⼊给定的内容</button>
<button id="enable" onclick="setEnabled()">可以编辑</button>
<button onclick="setDisabled()">不可编辑</button>
<button onclick=" UE.getEditor('editor').setHide()">隐藏编辑器</button>
<button onclick=" UE.getEditor('editor').setShow()">显⽰编辑器</button>
<button onclick=" UE.getEditor('editor').setHeight(300)">设置⾼度为300默认关闭了⾃动长⾼</button>
</div>
<div>
<button onclick="getLocalData()" >获取草稿箱内容</button>
<button onclick="clearLocalData()" >清空草稿箱</button>
</div>
</div>
<div>
<button onclick="createEditor()">
创建编辑器</button>
<button onclick="deleteEditor()">
删除编辑器</button>
</div>
<script type="text/javascript">
//实例化编辑器
//建议使⽤⼯⼚⽅法getEditor创建和引⽤编辑器实例,如果在某个闭包下引⽤该编辑器,直接调⽤UE.getEditor('editor')就能拿到相关的实例 var ue = UE.getEditor('editor');
ue.ready(function () {
UE.Editor.prototype._bkGetActionUrl=UE.Editor.prototype.getActionUrl;
UE.Editor.prototype.getActionUrl=function(action){
if (action == 'uploadimage' ||action== 'uploadscrawl' || action == 'uploadimage') {
return "/ueditor/file/uploadImg";
return "/ueditor/file/uploadImg";
} else{
return this._bkGetActionUrl.call(this, action);
}
}
});
function isFocus(e){
alert(UE.getEditor('editor').isFocus());
UE.dom.domUtils.preventDefault(e)
}
function setblur(e){
UE.getEditor('editor').blur();
UE.dom.domUtils.preventDefault(e)
}
function insertHtml() {
var value = prompt('插⼊html代码', '');
UE.getEditor('editor').execCommand('insertHtml', value)
}
function createEditor() {
enableBtn();
UE.getEditor('editor');
}
function getAllHtml() {
alert(UE.getEditor('editor').getAllHtml())
}
function saveContent() {
var arr = [];
arr.push(UE.getEditor('editor').getContent());
$.ajax({
type : 'post',
dataType : 'json',
url : '/ueditortxt/save',
data:{
content: arr.join("\n")
},
success:function(datas){
alert("添加成功");
},
error:function(a,b,c){
alert("添加失败");
}
});
}
function getContent() {
var arr = [];
arr.push("使⽤editor.getContent()⽅法可以获得编辑器的内容");
arr.push("内容为:");
arr.push(UE.getEditor('editor').getContent());
alert(arr.join("\n"));
}
function getPlainTxt() {
var arr = [];
arr.push("使⽤editor.getPlainTxt()⽅法可以获得编辑器的带格式的纯⽂本内容");
arr.push("内容为:");
arr.push(UE.getEditor('editor').getPlainTxt());
alert(arr.join('\n'))
}
function setContent(isAppendTo) {
var arr = [];
arr.push("使⽤editor.setContent('欢迎使⽤ueditor')⽅法可以设置编辑器的内容");
UE.getEditor('editor').setContent('欢迎使⽤ueditor', isAppendTo);
alert(arr.join("\n"));
}
function setDisabled() {
UE.getEditor('editor').setDisabled('fullscreen');
disableBtn("enable");
}
function setEnabled() {
UE.getEditor('editor').setEnabled();
enableBtn();
}
function getText() {
//当你点击按钮时编辑区域已经失去了焦点,如果直接⽤getText将不会得到内容,所以要在选回来,然后取得内容 var range = UE.getEditor('editor').selection.getRange();
range.select();
var txt = UE.getEditor('editor').selection.getText();
alert(txt)
arr.push("编辑器的纯⽂本内容为:");
arr.push(UE.getEditor('editor').getContentTxt());
alert(arr.join("\n"));
}
function hasContent() {
var arr = [];
arr.push("使⽤editor.hasContents()⽅法判断编辑器⾥是否有内容");
arr.push("判断结果为:");
arr.push(UE.getEditor('editor').hasContents());
alert(arr.join("\n"));
}
function setFocus() {
UE.getEditor('editor').focus();
}
function deleteEditor() {
disableBtn();
UE.getEditor('editor').destroy();
}
function disableBtn(str) {
var div = document.getElementById('btns');
var btns = UE.dom.domUtils.getElementsByTagName(div, "button");
for (var i = 0, btn; btn = btns[i++];) {
if (btn.id == str) {
UE.dom.domUtils.removeAttributes(btn, ["disabled"]);
} else {
btn.setAttribute("disabled", "true");
}
}
}
function enableBtn() {
var div = document.getElementById('btns');
var btns = UE.dom.domUtils.getElementsByTagName(div, "button");
for (var i = 0, btn; btn = btns[i++];) {
UE.dom.domUtils.removeAttributes(btn, ["disabled"]);
}
}
function getLocalData () {
alert(UE.getEditor('editor').execCommand( "getlocaldata" ));
}
function clearLocalData () {
UE.getEditor('editor').execCommand( "clearlocaldata" );
alert("已清空草稿箱")
}
</script>
</body>
</html>
7.现在就可以访问这个页⾯然后上传⽂件、图⽚、视频并且回显了 ⽂件
效果
图⽚
效果:
视频:
效果:
这⾥有个问题,就是如果连续点击这个按钮,页⾯会回显不了视频,我发现可以把那个Ueditor的XSS过滤关掉就可以(注意,这个操作我也不知道会导致什么问题,慎重操作)
关掉XSS过滤,修改ueditor.config.js中的三个参数为false即可
⾄此就完成了,如果是springmvc的话怎么办呢?
三步不同
1.将serverController中上半部分代码注释掉,放开下半部分中注释掉的代码
2.将改造过后的config.json⽂件放到resource下⾯
3.pom⽂件中放开对json⽂件的限制,以便target中能够找到该⽂件。