191210P4 Java富文本編輯之圖片鏈接本地化

Java富文本編輯之圖片鏈接本地化

作者:邵發
官網:http://afanihao.cn/java

本文介紹在圖文混編項目中(博客、新聞等),如何將富文本中的圖片外鏈轉爲本地鏈接的問題。本文是Java學習指南系列教程的官方配套文檔,項目源碼在本文末尾說明。

所謂富文本Rich Text,就是以HTML形式表示的文本。在前端通常由富文本編輯器得到,比如UEditor,KindEditor,wangEditor等富文本編輯器。在富文本中可能存在外鏈的圖片鏈接,那麼後臺如何將外鏈圖片轉爲本站鏈接,是本文要討論的話題。

 

1.  富文本編輯器

在需要實現圖文混排功能時,可以使用前端的富文本編輯器。常見的富文本編輯器有 UEditor, KindEditor, wangEditor等,使用起來大同小異。比如,下圖以KindEditor來演示。

在提交給後臺時,可以調用編輯器提供的API來獲取編輯器裏面的HTML文本,裏面包含了CSS樣式和圖片鏈接。關於富文本編輯器的使用,不在本文中詳述。

 

2.  富文本中的圖片外鏈

當富文本中包含了圖片外鏈接,一般要求將外鏈轉換爲本站鏈接。

例如以下文本:

<p>  根據外媒報道,12月6日,美國海軍最新的兩棲攻擊艦“美國”號抵達了日本佐世保,加入了美國海軍第七艦隊。</p>
<p style='text-align:center'>
  <img src='https://sinaimg.cn/mil/crawl/116/w550h366/20191210/b48a-ikn7476.jpg'>
</p>

後臺應該處理這一段HTML,找到<img>元素的src屬性,將其外鏈的圖片轉爲本站鏈接。在HTML中可能包含了多個圖片<img>,因而這裏需要使用正則表達式,找到所有的<img>進行處理。

2.1  正則替換

使用正則表達式來尋找 src 屬性並不難,例如定義一個正則表達式來匹配src屬性。

   String regex = "src=['\"](.*?)['\"]";

關於Java中的正則表達式的用法,可以參考Java學習指南系列教程中的《項目應用篇》中的講解。

現在,需要用此正則表達式,將HTML中的所有src屬性找出來。將外鏈轉換爲本站鏈接,再替換回去。在LocalImgSrc.process()中,演示了正則替換的基本寫法:

String regex = "src=['\"](.*?)['\"]";
Pattern pattern = Pattern.compile(regex);
Matcher m = pattern.matcher(html);
StringBuffer sb = new StringBuffer();
while( m.find())       
{     
	String url = m.group(1);  // 外鏈URL 
	String newUrl = localize(url);  // 本地化
	String newSrc = String.format(" src='%s' ", newUrl); // 新的src屬性
	m.appendReplacement(sb, escapeDollar(newSrc)); // 替換回去
}
m.appendTail(sb);
String result = sb.toString();

需要注意的是,在調用appendReplacement(sb, str)時要求對str中的$字符進行轉義,因爲$在正則語境下有特殊語義。這裏使用escapeDollar()方法對其轉義,將$轉義爲\$。

2.2  外鏈圖片的本地化

所謂的本地化,將是將外鏈圖片下載到本站服務器上,並生成一個本站URL。比如。

外鏈圖片:

<img src='https://sinaimg.cn/mil/crawl/116/w550h366/20191210/b48a-ikn7476.jpg' >

本地化:

<img src="/demo/tmp/test/1576029683983001.jpg" >

在演示項目中,在服務器上指定一個目錄用於存儲圖片,稱爲Store目錄。爲演示方便,直接使用WebRoot下的tmp目錄作爲Store目錄。在執行本地化時,只需要將圖片下載到Store目錄,然後拼湊出相應的URL即可。

例如,

1 將圖片下載到WebRoot\tmp\test\ 目錄下,命名爲1576029683983001.jpg

2 生成該圖片對應的本站鏈接 /demo/tmp/test/1576029683983001.jpg

詳見 LocalImgSrc.localize()方法,代碼如下。

private String localize(String imageUrl) throws Exception
{
	...... 略 ......
	// 外鏈圖片本地化處理
	String newName = guid.gen() + suffix;
	String filePath = storePath + newName;
	File storeDir = store.fileOfPath(storePath);
	String localUrl = store.urlOfPath(filePath);
	System.out.println("圖片本地化:" + imageUrl + " -> " + localUrl);
	try {
		http.download(imageUrl, storeDir, newName, 2*1000000);
	}catch(Exception e) {
		System.out.println("無法下載圖片URL:" + imageUrl + "," + e.getMessage());
		return imageUrl;
	}
	return localUrl;
}

其中,FileStore是一個工具類,提供URL地址與存儲路徑之間的轉換功能。

 

3.  項目源碼

3.1  演示頁面

演示頁面仍然是 http://127.0.0.1:8080/demo/test ,以Spring MVC實現。

後臺:TestController.test()

前端:/WebRoot/template/test.html

其中,在前端頁面 test.html裏包含了KindEditor富文本編輯的支持。

 

3.2  富文本處理

當用戶在頁面裏點‘保存’按鈕時,將富文本傳到後臺,後臺在TestController. update()中處理這個請求,將外鏈圖片本地化。代碼如下。

@PostMapping("/blog/update.do")
public Object update(@RequestBody JSONObject jreq
		, HttpSession session) throws Exception
{
	// 取得用戶的輸入
	String title = jreq.getString("title");
	String content = jreq.getString("content");

	// 將HTML中的圖片鏈接本地化
	LocalImgSrc lm = new LocalImgSrc(tmpStore, "/test/");
	try{
		content = lm.process( content);
	}finally {
		lm.destroy();
	}

	// 模擬更新到數據庫
	BlogDB.update(title, content);
	// 返回OK
	return new AfRestData("");
}

其中,lm.process()爲核心方法。直接調用LocalImgSrc工具類,將HTML中的圖片外鏈本地化,然後將轉換後的HTML存儲到服務器系統中。在真正的項目中可能需要存到數據庫裏,這裏的數據庫類BlogDB僅僅是演示模擬。

在轉換之後,富文本HTML中的<img>元素就統一爲本站鏈接。本站的演示項目源碼可以在此處獲取。更多技術請參考Java學習指南系列的其他課程。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章