1. 程式人生 > >UMEditor(UEditor縮減版)與Struts2整合實現富文字框貼上圖片

UMEditor(UEditor縮減版)與Struts2整合實現富文字框貼上圖片

所謂圖片貼上功能實際上就是通過控制元件將貼上的圖片上傳後讀取到本地顯示,UMEditor非常方便的幫我們實現了這一系列功能,現在說說如何使用UMEditor+Struts2整合實現編輯.
本示例通過官方模版進行修改,為了方便看得懂,部分變數採用的全域性變數.不喜勿噴.

前端JSP程式碼(示例程式碼主方法:寫入檔案按鈕):

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%
	String contextPath = request.getContextPath();
%>
<!DOCTYPE html>
<html>
<head>
<title>NO TITLE</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link
	href="../../jslib/umeditor1_2_2/themes/default/css/umeditor.min.css"
	type="text/css" rel="stylesheet">
<style type="text/css">
.disabled {
	opacity: 0.5;
	cursor: default;
	*filter: alpha(opacity = 50);
}

.links a {
	color: #ff5400;
	margin-right: 5px;
}

.links a.green {
	color: green;
}
</style>
<!-- 匯入jquery -->
<jsp:include page="../../inc.jsp"></jsp:include>
<!-- 匯入umeditor -->
<script type="text/javascript" charset="utf-8"
	src="../../jslib/umeditor1_2_2/umeditor.config.js"></script>
<script type="text/javascript" charset="utf-8"
	src="../../jslib/umeditor1_2_2/umeditor.min.js"></script>
<script type="text/javascript"
	src="../../jslib/umeditor1_2_2/lang/zh-cn/zh-cn.js"></script>
<script type="text/javascript">
	var um;
	$(function() {
		var serverPath = '<%=contextPath%>/bd/';
		um = UM.getEditor('editor', {
			imageUrl : serverPath + "um-editor!upload.cz",//請求位置
			imagePath : serverPath,//檔案儲存url
			lang : /^zh/.test(navigator.language || navigator.browserLanguage
					|| navigator.userLanguage) ? 'zh-cn' : 'en',
			langPath : UMEDITOR_CONFIG.UMEDITOR_HOME_URL + "lang/",
			focus : true
		});
	})
	/**
	 * 解碼
	 */
	function HtmlDecode(str) { 
		var t = document.createElement("div"); 
		t.innerHTML = str; 
		return t.innerText || t.textContent 
	}
	/**
	 * [writeContent 寫入檔案]
	 * @param  {Function} callback [成功後回撥函式]
	 */
	function writeContent(callback) {
		var arr = [];
		var url = "<%=contextPath%>/bd/um-editor!write.cz";
		var data = {
			dataJson : UM.getEditor('editor').getContent()
		}
		function success(json){
			if(json.success){
				var no = json.obj;
				//儲存成功後嘗試讀取檔案並追加到編輯器中
				readContent(no, true);
			}else{
				$.messager.alert("提示",obj.msg)
			}
			callback(json);
		}
		callAjax(url,data,success);
	}
	/**
	 * [readContent 讀取檔案]
	 * @param  {String} fn         [檔名]
	 * @param  {Boolean}  isAppendTo [是否追加]
	 */
	function readContent(fn,isAppendTo) {
		var u  = "<%=contextPath%>/bd/um-editor!read.cz";
		var d = {no:fn};
		function suc(json){
			if(json.success){
				um.setContent(HtmlDecode(json.obj), true);
			}
		}
		callAjax(u,d,suc);
	}
	function setDisabled() {
		UM.getEditor('editor').setDisabled('fullscreen');
		disableBtn("enable");
	}

	function setEnabled() {
		UM.getEditor('editor').setEnabled();
		enableBtn();
	}
	function hasContent() {
		return um.hasContents();
	}
	function setFocus() {
		UM.getEditor('editor').focus();
	}
	
	window.onkeydown = function(e) {
		if (!um.isFocus()) {
			var keyCode = e.keyCode || e.which;
			if (keyCode == 8) {
				e.preventDefault();
			}
		}
	};
</script>
</head>
<body>
	<div id="content" class="w900 border-style1 bg">
		<div style="width: 800px; margin: 20px auto 40px;">
			<script type="text/plain" id="editor"
				style="width: 100%; height: 360px;"></script>
		</div>
		<div id="btnContainer" style="width: 800px; margin: 20px auto 40px;">
			<table>
				<tr>
					<td>
						<button onclick="writeContent()">寫入檔案</button> 
					</td>
				</tr>
				<tr>
					<td>
						<button onclick="UM.getEditor('editor').setHide()">隱藏編輯器</button> 
						<button onclick="UM.getEditor('editor').setShow()">顯示編輯器</button> 
					</td>
				</tr>

			</table>
		</div>
	</div>

	<div style="display: none">
		<script type="text/javascript">
			var _bdhmProtocol = (("https:" == document.location.protocol) ? " https://"
					: " http://");
			document
					.write(unescape("%3Cscript src='"
							+ _bdhmProtocol
							+ "hm.baidu.com/h.js%3F3dee3eb2a97e7b6c323e44f08568ed8b' type='text/javascript'%3E%3C/script%3E"));
		</script>
		<script type="text/javascript"
			src="http://img.baidu.com/hunter/ueditor.js"></script>
	</div>
</body>
</html>


後臺Action程式碼:

package com.change.pub.action;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.Iterator;
import java.util.Random;

import org.apache.commons.fileupload.util.Streams;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Namespace;
import org.apache.struts2.dispatcher.multipart.MultiPartRequestWrapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import com.alibaba.fastjson.JSONObject;
import com.change.func.model.bd.BdImage;
import com.change.func.service.bd.BdImageServiceI;
import com.change.pub.model.easyui.Json;

/**
 * UMEditor富文字編輯器功能Action
 * 將編輯文字內容儲存到檔案中,再從檔案中讀取內容資訊
 * @author Ray
 */
@Namespace("/bd")
@Action
public class UmEditorAction extends BaseAction<BdImage> {
	/**
	 * 
	 */
	private static final long serialVersionUID = -5598549183251094596L;

	/**
	 * Logger for this class
	 */
	private static final Logger logger = LoggerFactory.getLogger(UmEditorAction.class);

	// 輸出檔案地址
	private String url = "";
	// 上傳檔名
	private String fileName = "";
	// 狀態
	private String state = "";
	// 檔案型別
	private String type = "";
	// 原始檔名
	private String originalName = "";
	// 檔案大小
	private long size = 0;
	// 儲存路徑
	private String savePath = "upload";
	// 檔案允許格式,僅做圖片上傳只用到了png格式
	private String[] allowFiles = { ".rar", ".doc", ".docx", ".zip", ".pdf", ".txt", ".swf", ".wmv", ".gif", ".png",
			".jpg", ".jpeg", ".bmp" };
	// 檔案大小限制,單位KB,備用,暫未使用
	private int maxSize = 10000;

	/**
	 * 支援直接粘帖圖片
	 */
	public void upload() {
		if (logger.isDebugEnabled()) {
			logger.debug("upload() - start"); //$NON-NLS-1$
		}

		JSONObject json = new JSONObject();
		// Struts2 請求 包裝過濾器
		MultiPartRequestWrapper wrapper = (MultiPartRequestWrapper) getRequest();
		// 獲得檔案過濾器
		File[] files = wrapper.getFiles("upfile");
		String savePath = null;
		// file轉is
		try {
			savePath = this.getFolder(this.savePath);
		} catch (Exception e) {
			logger.error("upload()", e); //$NON-NLS-1$

			json.put("state", "目錄不存在");
		}
		try {
			if (files == null || files.length == 0) {
				json.put("state", "未包含檔案上傳域");
			} else {
				// 獲得上傳的檔名
				File file = files[0];
				String srcFileName = wrapper.getFileNames("upfile")[0];
				InputStream is = new FileInputStream(file);
				this.fileName = this.getName(srcFileName);
				this.type = this.getFileExt(srcFileName);
				this.url = savePath + "/" + this.fileName;
				if (!this.checkFileType(this.fileName)) {
					json.put("state", "不允許的檔案格式");
				} else {
					BufferedInputStream in = new BufferedInputStream(is);
					File outFile = new File(this.getPhysicalPath(this.url));
					FileOutputStream out = new FileOutputStream(outFile);
					BufferedOutputStream output = new BufferedOutputStream(out);
					Streams.copy(in, output, true);
					json.put("state", "SUCCESS");
					json.put("name", fileName);
					json.put("originalName", srcFileName);
					json.put("type", type);
					json.put("url", url);
					json.put("size", outFile.length());
				}
			}
		} catch (FileNotFoundException e2) {
			logger.error("upload()", e2); //$NON-NLS-1$
			json.put("state", "檔案上傳異常");
		} catch (IOException e) {
			logger.error("upload()", e); //$NON-NLS-1$
			json.put("state", "伺服器內部異常.");
		}
		writeJson(json);
		if (logger.isDebugEnabled()) {
			logger.debug("upload() - end"); //$NON-NLS-1$
		}
	}

	/**
	 * 用於儲存內容
	 */
	public void write() {
		Json json = new Json();
		if (dataJson == null || dataJson.length() == 0) {
			json.setMsg("沒有需要儲存的內容");
		} else {
			String savePath = null;
			// file轉is
			try {
				savePath = this.getFolder(this.savePath);
			} catch (Exception e) {
				json.setMsg("目錄不存在");
			}
			try {
				// 獲得上傳的檔名
				this.fileName = this.getName("");
				this.url = savePath + "/" + this.fileName;
				BufferedInputStream in = new BufferedInputStream(new ByteArrayInputStream(dataJson.getBytes()));
				File outFile = new File(this.getPhysicalPath(this.url));
				FileOutputStream out = new FileOutputStream(outFile);
				BufferedOutputStream output = new BufferedOutputStream(out);
				Streams.copy(in, output, true);
				json.setSuccess(true);
				json.setObj(url);
			} catch (FileNotFoundException e2) {
				json.setMsg("檔案上傳異常");
			} catch (IOException e) {
				json.setMsg("伺服器內部異常.");
			}
		}
		writeJson(json);
	}

	/**
	 * 用於讀取內容
	 */
	public void read() {
		Json json = new Json();
		if (no == null || no.length() == 0) {
			json.setMsg("沒有需要讀取的內容");
		} else {
			try {
				// 獲得上傳的檔名
				File inFile = new File(this.getPhysicalPath(no));
				if (!inFile.isFile()) {
					json.setMsg("檔案不存在");
				} else {
					String content = FileUtils.readFileToString(inFile);
					json.setSuccess(true);
					json.setObj(content);
				}
			} catch (FileNotFoundException e2) {
				json.setMsg("檔案讀取異常");
			} catch (IOException e) {
				json.setMsg("伺服器內部異常.");
			}
		}
		writeJson(json);
	}

	/**
	 * 檔案型別判斷
	 * 
	 * @param fileName
	 * @return
	 */
	private boolean checkFileType(String fileName) {
		if (logger.isDebugEnabled()) {
			logger.debug("checkFileType(String) - start"); //$NON-NLS-1$
		}

		Iterator<String> type = Arrays.asList(this.allowFiles).iterator();
		while (type.hasNext()) {
			String ext = type.next();
			if (fileName.toLowerCase().endsWith(ext)) {
				if (logger.isDebugEnabled()) {
					logger.debug("checkFileType(String) - end"); //$NON-NLS-1$
				}
				return true;
			}
		}

		if (logger.isDebugEnabled()) {
			logger.debug("checkFileType(String) - end"); //$NON-NLS-1$
		}
		return false;
	}

	/**
	 * 獲取副檔名
	 * 
	 * @return string
	 */
	private String getFileExt(String fileName) {
		if (logger.isDebugEnabled()) {
			logger.debug("getFileExt(String) - start"); //$NON-NLS-1$
		}

		if (StringUtils.isNotBlank(fileName)) {
			return fileName.substring(fileName.lastIndexOf("."));
		}
		if (logger.isDebugEnabled()) {
			logger.debug("getFileExt(String) - end"); //$NON-NLS-1$
		}
		return fileName;
	}

	/**
	 * 依據原始檔名生成新檔名
	 * 
	 * @return
	 */
	private String getName(String fileName) {
		if (logger.isDebugEnabled()) {
			logger.debug("getName(String) - start"); //$NON-NLS-1$
		}

		Random random = new Random();
		String returnString = "" + random.nextInt(10000) + System.currentTimeMillis() + this.getFileExt(fileName);
		if (logger.isDebugEnabled()) {
			logger.debug("getName(String) - end"); //$NON-NLS-1$
		}
		return returnString;
	}

	/**
	 * 根據字串建立本地目錄 並按照日期建立子目錄返回
	 * 
	 * @param path
	 * @return
	 */
	private String getFolder(String path) throws Exception {
		if (logger.isDebugEnabled()) {
			logger.debug("getFolder(String) - start"); //$NON-NLS-1$
		}

		SimpleDateFormat formater = new SimpleDateFormat("yyyyMMdd");
		path += "/" + formater.format(new Date());
		File dir = new File(this.getPhysicalPath(path));
		if (!dir.exists()) {
			dir.mkdirs();
		}

		if (logger.isDebugEnabled()) {
			logger.debug("getFolder(String) - end"); //$NON-NLS-1$
		}
		return path;
	}

	/**
	 * 根據傳入的虛擬路徑獲取物理路徑
	 * 
	 * @param path
	 * @return
	 */
	private String getPhysicalPath(String path) {
		if (logger.isDebugEnabled()) {
			logger.debug("getPhysicalPath(String) - start"); //$NON-NLS-1$
		}

		String servletPath = getRequest().getServletPath();
		String realPath = getRequest().getSession().getServletContext().getRealPath(servletPath);
		String returnString = new File(realPath).getParent() + "/" + path;
		if (logger.isDebugEnabled()) {
			logger.debug("getPhysicalPath(String) - end"); //$NON-NLS-1$
		}
		return returnString;
	}

	/**
	 * <p>
	 * 注入業務邏輯,使當前action呼叫service.xxx的時候,直接是呼叫基礎業務邏輯
	 * </p>
	 * <p>
	 * 如果想呼叫自己特有的服務方法時,請使用((TServiceI) service).methodName()這種形式強轉型別呼叫
	 * </p>
	 * 
	 * @param service
	 */
	@Autowired
	public void setService(BdImageServiceI service) {
		this.service = service;
	}

	public String getUrl() {
		return url;
	}

	public void setUrl(String url) {
		this.url = url;
	}

	public String getFileName() {
		return fileName;
	}

	public void setFileName(String fileName) {
		this.fileName = fileName;
	}

	public String getState() {
		return state;
	}

	public void setState(String state) {
		this.state = state;
	}

	public String getType() {
		return type;
	}

	public void setType(String type) {
		this.type = type;
	}

	public String getOriginalName() {
		return originalName;
	}

	public void setOriginalName(String originalName) {
		this.originalName = originalName;
	}

	public long getSize() {
		return size;
	}

	public void setSize(long size) {
		this.size = size;
	}

	public String getSavePath() {
		return savePath;
	}

	public void setSavePath(String savePath) {
		this.savePath = savePath;
	}

	public String[] getAllowFiles() {
		return allowFiles;
	}

	public void setAllowFiles(String[] allowFiles) {
		this.allowFiles = allowFiles;
	}

	public int getMaxSize() {
		return maxSize;
	}

	public void setMaxSize(int maxSize) {
		this.maxSize = maxSize;
	}

}


 * 本示例通過官方模版進行修改,為了方便看得懂,部分變數採用的全域性變數