所谓图片粘贴功能实际上就是通过控件将粘贴的图片上传后读取到本地显示,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 οnclick="writeContent()">写入文件</button>
</td>
</tr>
<tr>
<td>
<button οnclick="UM.getEditor('editor').setHide()">隐藏编辑器</button>
<button οnclick="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;
}
}
* 本示例通过官方模版进行修改,为了方便看得懂,部分变量采用的全局变量