wangEditor富文字編輯器
富文字編輯器,Rich Text Editor, 簡稱 RTE, 是一種可內嵌於瀏覽器,所見即所得的文字編輯器.
CSDN的markdown編輯器便是一種富文字編輯器.
藍莓商城商品詳情這一部分的編輯需要使用富文字編輯器.本來想使用百度的ueditor的,但是弄了好久依然還是有問題.所以就放棄了.ueditor配置確實比較複雜,官方的文件也沒有很好的說清楚,錯誤提示不夠明瞭,出錯時未提示具體的原因.
最後找到這個wangEditor.相比ueditor,配置更加簡單,使用更加方便.其功能雖不及ueditor多,但是應付一般的需求足夠了.
流程說明
由於對於圖片上傳整個流程比較複雜,所以本文僅對其進行說明.
圖片上傳的流程是,當頁面選擇圖片後,將會建立XMLHttpRequest請求,將圖片資料傳送給服務端,服務端接收後將圖片儲存到本地,再將圖片路徑返回給客戶端,客戶端接收到圖片路徑後,建立元素,並將圖片路徑賦給src,最後再把該元素插入到編輯器中.
// 定義 xhr 傳送請求給服務端
var xhr = new XMLHttpRequest();
xhr.open('POST', uploadImgServer);
客戶端配置說明
下載
直接下載:https://github.com/wangfupeng1988/wangEditor/releases
使用npm下載:npm install wangeditor (注意 wangeditor 全部是小寫字母)
使用bower下載:bower install wangEditor (前提保證電腦已安裝了bower)
使用CDN://unpkg.com/wangeditor/release/wangEditor.min.js
除錯階段推薦使用方式1中的未壓縮版本,因為如果出現問題也好除錯和查詢.
下載後將目錄裡的wangEditor.js放入工程目錄中.只需要這個檔案,其他的不需要.
我放在webapp下的wangEditor路徑下.
前端配置
引入js檔案
contextPathOfStatic這裡是我的專案路徑下的static資料夾:http://localhost:8080/lanmei-os/static
<script type="text/javascript" src="${contextPathOfStatic}/wangEditor/wangEditor.js"></script>
1
jsp頁面新增
<div id="editor">
<!-- 預設顯示 -->
<p>歡迎使用 <b>wangEditor</b> 富文字編輯器</p>
</div>
這裡我建立3個按鈕進行測試
<button id="editorSetBtn">設定內容</button>
<button id="editorGetBtn1">獲取內容1</button>
<button id="editorGetBtn2">獲取內容2</button>
js檔案編寫
$(function(){
var E = window.wangEditor;
//這裡的id為<div id="editor"中的id.
var editor = new E('#editor');
// 配置伺服器端地址,也就是controller的請求路徑,不帶專案路徑,前面沒有/
editor.customConfig.uploadImgServer = 'commodity/upload/editor/img';
//配置屬性名稱,繫結請求的圖片資料
//controller會用到,可以隨便設定,但是一定要與controller一致
editor.customConfig.uploadFileName = 'img';
//建立編輯器
editor.create();
$("#editorSetBtn").click(function(){
//這是設定編輯器內容
editor.txt.html("dsafdfadsfdafdsfds");
})
$("#editorGetBtn1").click(function(){
//獲取編輯器的內容,帶樣式
//一般使用這個獲取資料,通過ajax傳送給服務端 ,然後服務端以String接收,儲存到資料庫.
alert(editor.txt.html());
})
$("#editorGetBtn2").click(function(){
//獲取編輯器的內容,不帶樣式,純文字
alert(editor.txt.text());
})
})
程式載入完之後頁面就會出現編輯器.
客戶端設定完成
服務端配置
WEB層建立Controller
@Controller
@RequestMapping(path="/commodity")
public class CommodityController {
@Autowired
AddCommodityService addCommodityService;
@Autowired
private static final Logger logger = LoggerFactory.getLogger("CommodityController.class");
@ResponseBody
@RequestMapping(path="/upload/editor/img")
//RequestParam中的屬性名稱要和前端定義的一致,上面說明了.所以寫"img"
//使用List<MultipartFile>進行接收
//返回的是一個Dto類,後面會說明,使用@ResponseBody會將其轉換為Json格式資料
public ImgResultDto uploadEditorImg(@RequestParam("img") List<MultipartFile> list) {
//這裡是我在web中定義的兩個初始化屬性,儲存目錄的絕對路徑和相對路徑,你們可以自定義
String imgUploadAbsolutePath = request.getServletContext().getInitParameter("imgUploadAbsolutePath");
String imgUploadRelativePath = request.getServletContext().getInitParameter("imgUploadRelativePath");
//服務曾處理資料,返回Dto
ImgResultDto imgResult
= addCommodityService.upLoadEditorImg(list, imgUploadAbsolutePath,
imgUploadRelativePath,1);
return imgResult;
}
}
服務層建立Service類
服務層建立Service介面類
public interface AddCommodityService {
/**
* 上傳商品圖片
* @param files
*/
ImgResultDto upLoadEditorImg(List<MultipartFile> list,
String UploadAbsolutePath,
String UploadRelativePath,
int commodityId);
}
服務層建立Service介面實現類
這裡需要注意的是儲存地址,我是儲存在專案路徑下,有的會儲存在檔案系統根目錄下,比如windows可能是D://xxx/xx,linux是/xx/xx,那麼返回給客戶端的地址就會不一樣.需要根據實際情況設定
public class AddCommodityServiceImpl extends BaseService implements AddCommodityService{
@Autowired
private CommodityMapper commodityMapper;
@Autowired
CommodityImageMapper commodityImageMapper;
@Autowired
private DruidDataSource dataSource;
@Autowired
private SqlSessionFactoryBean sqlSessionFactory;
/**
* 圖片上傳處理
*/
@Override
public ImgResultDto upLoadEditorImg(List<MultipartFile> list,
String UploadAbsolutePath,
String UploadRelativePath,
int commodityId) {
//獲取當前登入的管理員
//CmsAdmin admin = (CmsAdmin) SessionUtils.getSession("currenLogintAdmin");
CmsAdmin admin = new CmsAdmin("測試使用者");
//工程絕對路徑
String imgUploadAbsolutePath = UploadAbsolutePath;
//工程相對路徑
String imgUploadRelativePath = UploadRelativePath;
logger.debug("files.length = " + list.size() );
ImgResultDto imgResultDto = new ImgResultDto();
//這裡定
String[] urlData = new String[5];
int index = 0;
try {
for(MultipartFile img : list) {
//獲取原始檔名,比如你上傳的是 圖片.jpg,則fileName=圖片.jpg
String fileName = img.getOriginalFilename();
if(fileName == "") {
continue;
}
logger.debug("file name = " + fileName);
String finalPath = imgUploadAbsolutePath + imgUploadRelativePath; //絕對路徑 + 相對路徑
//為了保證檔名不一致,因此檔名稱使用當前的時間戳和4位的隨機數,還有原始檔名組成
//覺得實際的企業開發不應當使用原始檔名,否則上傳者使用一些不好的名字,對於下載者就不好了.
//這裡為了除錯方便,可以加上.
String finalFileName = (new Date().getTime()) + Math.round(Math.random() * 1000) //檔名動態部分
+ fileName; //檔名 原始檔名
File newfile = new File( finalPath + finalFileName);
logger.debug("建立資料夾 = " + newfile.mkdirs() + " path = " + newfile.getPath());
logger.debug("" + newfile.getAbsolutePath());
//儲存檔案到本地
img.transferTo(newfile);
logger.debug("上傳圖片成功");
//持久化到資料庫
CommodityImage commodityImage = new CommodityImage(commodityId, imgUploadRelativePath,
finalFileName,(byte)(0),admin.getLoginJobnum(), new Date());
commodityImageMapper.insert(commodityImage);
logger.debug("資料庫寫入圖片成功");
//這裡的路徑是專案路徑+檔案路徑+檔名稱
//這麼寫不是規範的做法,專案路徑應是放在前端處理,只需要傳送相對路徑和檔名稱即可,專案路徑由前端加上.
urlData[index++] = "http://localhost:8080/lanmei-cms/"+imgUploadRelativePath + finalFileName;
logger.debug("index = " + index
+ " url = " + urlData[0]);
//設定異常代號
imgResultDto.setErrno(0);
}
imgResultDto.setData(urlData);
//返回Dto
return imgResultDto;
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
return imgResultDto;
}
}
}
Dto編寫
Dto 只是一個普通的pojo類,沒有業務方法,只有屬性和構造器,getter and setter.主要用於層間傳輸資料,更詳細的說明自行百度.
public class ImgResultDto<T> {
private int errno;//錯誤程式碼
private String[] data;//存放資料
//構造器
//getter and setter
前端接收處理
新增 customInsert: function (insertImg, result, editor)這段程式
result是返回的json資料
因為上面只是上傳了一張圖片,儲存在陣列索引0裡
因此通過下面獲取圖片地址.
var url = result.data[0];
// 上傳圖片 hook
uploadImgHooks: {
before: function before(xhr, editor, files) {
// 圖片上傳之前觸發
// 如果返回的結果是 {prevent: true, msg: 'xxxx'} 則表示使用者放棄上傳
// return {
// prevent: true,
// msg: '放棄上傳'
// }
},
success: function success(xhr, editor, result) {
// 圖片上傳並返回結果,圖片插入成功之後觸發
console.log("插入圖片成功 success result = " + result.errno + " path = " + result.data[0] );
},
fail: function fail(xhr, editor, result) {
console.log(" fail result = " + result.errno + " path = " + result.data[0] );
// 圖片上傳並返回結果,但圖片插入錯誤時觸發
},
error: function error(xhr, editor) {
// 圖片上傳出錯時觸發
console.log("error result = " + result.errno + " path = " + result.data[0] );
},
timeout: function timeout(xhr, editor) {
// 圖片上傳超時時觸發
console.log("timeout result = " + result.errno + " path = " + result.data );
},
// 如果伺服器端返回的不是 {errno:0, data: [...]} 這種格式,可使用該配置
//--------------新增這段程式------------------
customInsert: function (insertImg, result, editor) {
// 圖片上傳並返回結果,自定義插入圖片的事件(而不是編輯器自動插入圖片!!!)
// insertImg 是插入圖片的函式,editor 是編輯器物件,result 是伺服器端返回的結果
// 舉例:假如上傳圖片成功後,伺服器端返回的是 {url:'....'} 這種格式,即可這樣插入圖片:
//-----------修改這裡------------------
//獲取返回的圖片地址
var url = result.data[0];
insertImg(url);
console.log("插入圖片 url = " + url );
// result 必須是一個 JSON 格式字串!!!否則報錯
}
},
// 是否上傳七牛雲,預設為 false
qiniu: false
};
總結
本文說明了如何在Java WEB專案中使用富文字編輯器wangEditor,包括前端配置和後端處理.僅說明其簡單的用法,業務也未考慮的很周詳.更多功能擴充套件請看官方的說明.
專案的完整程式請看藍莓商城專案,後面我會陸續完善.
參考:https://blog.csdn.net/u011676300/article/details/80345152