UEditor很好用,但是它的图片默认是上传到项目中,重新部署项目后之前的图片全会被删掉(坑爹),为了实现把图片传到其他地方,如阿里云的OSS(不是打广告),可以进行以下改造实现。
后端配置
- 在下载的包里面
./jsp/lib
有5个jar包,其中commons-*.jar
与json.jar
可通过maven下载,ueditor-*.jar
Maven上有但是不是官方上传的,所以我手动导入到项目 - 把整个包复制到项目资源目录,如放到
WEB-INF
目录下还要通过一下特殊配置,如直接放到webapp
目录下可参考官方文档 - 假设插件放置位置为
WEB-INF/assets/plugins/ueditor
,因为WEB-INF
目录下内容不能直接访问,ueditor/jsp/controller.jsp
是无法配置的,所以需要通过Spring Mvc中的Controller转发访问 - 项目新建一个Controller并配置RequestMapping
Controller
@Controller
@RequestMapping("/ueditor")
public class UEditorController {
/**
* UEditor 入口
*
* @return
*/
@RequestMapping("/controller")
public String controller() {
return "common/_ueditor";
}
}
common/_ueditor.jsp
- 在要调用ueditor的页面配置ueditor
- 到此ueditor的后端配置完成,调用方法可参考官方文档
改造
1.重写ActionEnter类
import com.baidu.ueditor.ConfigManager;
import com.baidu.ueditor.define.ActionMap;
import com.baidu.ueditor.define.BaseState;
import com.baidu.ueditor.define.State;
import com.baidu.ueditor.hunter.FileManager;
import com.baidu.ueditor.hunter.ImageHunter;
import javax.servlet.http.HttpServletRequest;
import java.util.Map;
/**
* Created by GustinLau on 2017-05-11.
*/
public class ActionEnter extends com.baidu.ueditor.ActionEnter {
private HttpServletRequest request = null;
private String rootPath = null;
private String contextPath = null;
private String actionType = null;
private ConfigManager configManager = null;
public ActionEnter(HttpServletRequest request, String rootPath) {
super(request, rootPath);
this.request = request;
this.rootPath = rootPath;
this.actionType = request.getParameter("action");
this.contextPath = request.getContextPath();
this.configManager = ConfigManager.getInstance(this.rootPath, this.contextPath, request.getRequestURI());
}
@Override
public String invoke() {
if(this.actionType != null && ActionMap.mapping.containsKey(this.actionType)) {
if(this.configManager != null && this.configManager.valid()) {
State state = null;
int actionCode = ActionMap.getType(this.actionType);
Map conf = null;
switch(actionCode) {
case 0:
return this.configManager.getAllConfig().toString();
case 1:
case 2:
case 3:
case 4:
conf = this.configManager.getConfig(actionCode);
state = (new Uploader(this.request, conf)).doExec();
break;
case 5:
conf = this.configManager.getConfig(actionCode);
String[] list = this.request.getParameterValues((String)conf.get("fieldName"));
state = (new ImageHunter(conf)).capture(list);
break;
case 6:
case 7:
conf = this.configManager.getConfig(actionCode);
int start = this.getStartIndex();
state = (new FileManager(conf)).listFile(start);
}
return state.toJSONString();
} else {
return (new BaseState(false, 102)).toJSONString();
}
} else {
return (new BaseState(false, 101)).toJSONString();
}
}
}
其中case 4
中的Uploader
需要重写
2.重写Uploader
import com.baidu.ueditor.define.State;
import javax.servlet.http.HttpServletRequest;
import java.util.Map;
/**
* Created by GustinLau on 2017-05-11.
*/
public class Uploader {
private HttpServletRequest request = null;
private Map conf = null;
public Uploader(HttpServletRequest request, Map conf) {
this.request = request;
this.conf = conf;
}
public final State doExec() {
String filedName = (String) this.conf.get("fieldName");
State state;
if ("true".equals(this.conf.get("isBase64"))) {
state = Base64Uploader.save(this.request.getParameter(filedName), this.conf);
} else {
state = BinaryUploader.save(this.request, this.conf);
}
return state;
}
}
其中Base64Uploader
和BinaryUploader
需要重写
3.重写Base64Uploader,主要用于涂鸦功能
import com.baidu.ueditor.PathFormat;
import com.baidu.ueditor.define.BaseState;
import com.baidu.ueditor.define.FileType;
import com.baidu.ueditor.define.State;
import com.xiaosuokeji.feelschool.admin.util.OssUtils;
import org.apache.commons.codec.binary.Base64;
import java.io.ByteArrayInputStream;
import java.util.Map;
/**
* Created by GustinLau on 2017-05-11.
*/
public class Base64Uploader {
public static State save(String content, Map conf) {
byte[] data = decode(content);
long maxSize = ((Long) conf.get("maxSize")).longValue();
if (!validSize(data, maxSize)) {
return new BaseState(false, 1);
} else {
String suffix = FileType.getSuffix("JPG");
String savePath = PathFormat.parse((String) conf.get("savePath"), (String) conf.get("filename"));
savePath = savePath + suffix;
//自定义处理部分
//将byte[]转换成输入流
ByteArrayInputStream is = new ByteArrayInputStream(data);
//图片上传到阿里云OSS服务器,自己写的工具类
Map result = OssUtils.ueditorUpload(is, savePath);
//构造对应的Stage让UEditor读取
State storageState = new BaseState((boolean) result.get("status"));
if (storageState.isSuccess()) {
storageState.putInfo("url", (String) result.get("url"));
storageState.putInfo("type", suffix);
storageState.putInfo("original", "");
}
return storageState;
}
}
private static byte[] decode(String content) {
return Base64.decodeBase64(content);
}
private static boolean validSize(byte[] data, long length) {
return (long) data.length <= length;
}
}
4.重写BinaryUploader主要用于上传图片
import com.baidu.ueditor.PathFormat;
import com.baidu.ueditor.define.BaseState;
import com.baidu.ueditor.define.FileType;
import com.baidu.ueditor.define.State;
import com.xiaosuokeji.feelschool.admin.util.OssUtils;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
/**
* Created by GustinLau on 2017-05-11.
*/
public class BinaryUploader {
public static final State save(HttpServletRequest request, Map conf) {
MultipartFile multipartFile = null;
boolean isAjaxUpload = request.getHeader("X_Requested_With") != null;
if (!ServletFileUpload.isMultipartContent(request)) {
return new BaseState(false, 5);
} else {
ServletFileUpload upload = new ServletFileUpload(new DiskFileItemFactory());
if (isAjaxUpload) {
upload.setHeaderEncoding("UTF-8");
}
//自定义处理部分
try {
//request获取MultipartFile对象
MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
multipartFile = multipartRequest.getFile(conf.get("fieldName").toString());
if (multipartFile == null) {
return new BaseState(false, 7);
} else {
//重命名
String savePath = (String) conf.get("savePath");
String originFileName = multipartFile.getOriginalFilename();
String suffix = FileType.getSuffixByFilename(originFileName);
originFileName = originFileName.substring(0, originFileName.length() - suffix.length());
savePath = savePath + suffix;
if (!validType(suffix, (String[]) conf.get("allowFiles"))) {
return new BaseState(false, 8);
} else {
savePath = PathFormat.parse(savePath, originFileName);
//获取输入流
InputStream is = multipartFile.getInputStream();
//上传到阿里云OSS
Map result = OssUtils.ueditorUpload(is, savePath);
//构造State
State storageState = new BaseState((boolean) result.get("status"));
is.close();
if (storageState.isSuccess()) {
storageState.putInfo("url", (String) result.get("url"));
storageState.putInfo("type", suffix);
storageState.putInfo("original", originFileName + suffix);
}
return storageState;
}
}
} catch (IOException e) {
return new BaseState(false, 4);
}
}
}
private static boolean validType(String type, String[] allowTypes) {
List list = Arrays.asList(allowTypes);
return list.contains(type);
}
}
5.将在WEB-INF/assets/plugins/ueditor/jsp/controller.jsp
中的ActionEnter
换自己重写的ActionEnter
依赖
com.baidu
ueditor
1.1.2
system
${project.basedir}/lib/ueditor-1.1.2.jar
org.json
json
20160212
commons-codec
commons-codec
1.10
commons-io
commons-io
2.4
commons-fileupload
commons-fileupload
1.3.1
备注
记得在spring.xml中配置MultipartResolver