最近公司里需要做一个项目,需要使用编辑器上传图片功能。以前没有弄个,就找了百度的Ueditor(毕竟国产的,文档都是中文)。虽然有文档说明,但是在使用图片上传功能时还是一脸懵逼.....后来在网上找了很多的博客神马的,大部分都是爬虫爬来的文章,写的乱七八糟的,也没有具体的例子。只能慢慢摸索了。经过1天努力,终于通过各个文章的整合说明弄出来了图片上传的功能,特此记录一下,方便自己以后使用,也希望能帮到一些跟我同样需求的童鞋。
已经上传了我的整合项目在GitHub上,地址:https://github.com/wcfeng9527/SpringMVCUeditor
推荐文章:http://blog.csdn.net/huangwenyi1010/article/details/51637427
一共3篇,写的很好,我就是参考了他的文章来修改的。
首先,我的项目是使用的SpringMVC的框架实现的,所以百度自带的ueditor-1.1.2.jar包中内容需要修改,所以要下载源码包,我下载的是1.4.3.3 版本,当前最新版。
使用的maven管理的包依赖,使用的jboss7 作为服务器,也可以使用其他的服务器,但是需要对配置文件的位置进行修改。
项目结构:
其中百度的包是使用的源码,因为需要修改图片保存的代码。直接将百度下载的源码中jsp中src内容copy到自己的项目中。
然后就是插件放在了static文件夹下,把jsp中的config.json文件提出来,放到ueditor下,即与ueditor.config.js在同一个文件夹下。
编写自己的controller作为编辑器的总入口,不使用controller.jsp,把controller.jsp的内容复制过来即可。然后修改ueditor.config.js中的serverUrl,改成action的地址即可。
我的controller类:
package com.shijie99.ueditor.controller;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import com.baidu.ueditor.ActionEnter;
@Controller
public class InitController {
private Logger logger = Logger.getLogger(InitController.class);
/**
* 初始化百度编辑器,可传入其他参数生成不同的编辑器,总入口
*
* @param response
* @param request
*/
@RequestMapping("/ueditor/init")
public void initUeditor(HttpServletResponse response,HttpServletRequest request) {
response.setContentType("application/json");
// 配置路径,首先获取static根目录绝对路径
String rootPath = request.getSession().getServletContext().getRealPath("/static");
// 将config.json放到与ueditor.config.js同一级的目录下。将ueditor所有文件放入到wapapp-static-ueditor下
// 设置获取服务端配置文件地址修正路径,此路径同时作用于文件上传
PrintWriter writer = null;
try {
String exec = new ActionEnter(request, rootPath).exec();
writer = response.getWriter();
writer.write(exec);
writer.flush();
} catch (IOException e) {
logger.error("百度编辑器初始化错误!", e);
} finally {
if (writer != null) {
writer.close();
}
}
}
}
我的ueditor.config.js 配置:
/**
* 配置项主体。注意,此处所有涉及到路径的配置别遗漏URL变量。
*/
window.UEDITOR_CONFIG = {
//为编辑器实例添加一个路径,这个不能被注释
UEDITOR_HOME_URL: URL
// 服务器统一请求接口路径
// , serverUrl: URL + "jsp/controller.jsp"
,serverUrl: "ueditor/init"
这样以后应该启动应用就应该可以正确的显示编辑器和打开图片上传的功能了。但是上传会失败。因为是使用的SpringMVC,封装了conmmons-fileupload,所以需要修改她的源码。
百度提供源码中的BinaryUploader类修改后:
package com.baidu.ueditor.upload;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
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.support.DefaultMultipartHttpServletRequest;
import com.baidu.ueditor.PathFormat;
import com.baidu.ueditor.define.AppInfo;
import com.baidu.ueditor.define.BaseState;
import com.baidu.ueditor.define.FileType;
import com.baidu.ueditor.define.State;
import com.shijie99.ueditor.Config.ConfigTool;
import com.shijie99.ueditor.util.Constant;
public class BinaryUploader {
public static final State save(HttpServletRequest request,
Map<String, Object> conf) {
InputStream fileStream = null;
boolean isAjaxUpload = request.getHeader( "X_Requested_With" ) != null;
if (!ServletFileUpload.isMultipartContent(request)) {
return new BaseState(false, AppInfo.NOT_MULTIPART_CONTENT);
}
ServletFileUpload upload = new ServletFileUpload(new DiskFileItemFactory());
if ( isAjaxUpload ) {
upload.setHeaderEncoding( "UTF-8" );
}
try {
//修改了百度使用原生的commons上传方式
DefaultMultipartHttpServletRequest multipartRequest=(DefaultMultipartHttpServletRequest)request;
Iterator<String> fileNames=multipartRequest.getFileNames();
MultipartFile file=null;
while (fileNames.hasNext()){
file=multipartRequest.getFiles(fileNames.next()).get(0);
fileStream=file.getInputStream();
}
if (fileStream == null) {
return new BaseState(false, AppInfo.NOTFOUND_UPLOAD_DATA);
}
String savePath = (String) conf.get("savePath");
String originFileName = file.getOriginalFilename();
String suffix = FileType.getSuffixByFilename(originFileName);
originFileName = originFileName.substring(0,
originFileName.length() - suffix.length());
savePath = savePath + suffix;
long maxSize = ((Long) conf.get("maxSize")).longValue();
if (!validType(suffix, (String[]) conf.get("allowFiles"))) {
return new BaseState(false, AppInfo.NOT_ALLOW_FILE_TYPE);
}
savePath = PathFormat.parse(savePath, originFileName);
String physicalPath = (String) conf.get("rootPath") + savePath;
//修改成自己的保存图片路径
if(conf.containsKey("myImageSavePath")){
physicalPath = (String) conf.get("myImageSavePath") + savePath;
}
State storageState = StorageManager.saveFileByInputStream(fileStream,
physicalPath, maxSize);
fileStream.close();
if (storageState.isSuccess()) {
//原始url
//String utl = PathFormat.format(savePath);
//url改为请求地址,获取 日期/图片名/action名 为请求地址 --by wangcf
String[] ss = PathFormat.format(savePath).substring(0,PathFormat.format(savePath).lastIndexOf(".")).split("/");
//拼写请求的action地址
String url = ss[ss.length-2]+Constant.separator+ss[ss.length-1]+Constant.separator+suffix.substring(suffix.lastIndexOf(".")+1)+Constant.separator+ConfigTool.imageAction;
storageState.putInfo("url", url);
storageState.putInfo("type", suffix);
storageState.putInfo("original", originFileName + suffix);
if(conf.containsKey("myImageSavePath")){
storageState.putInfo("myImageSavePath", conf.get("myImageSavePath").toString());
}
}
return storageState;
} catch (ClassCastException e) {
return new BaseState(false, AppInfo.PARSE_REQUEST_ERROR);
} catch (IOException e) {
}
return new BaseState(false, AppInfo.IO_ERROR);
}
private static boolean validType(String type, String[] allowTypes) {
List<String> list = Arrays.asList(allowTypes);
return list.contains(type);
}
}
修改后就可以正确的上传并保存图片了。
但是会有一个问题,就是图片会保存到项目的包中,重新部署包图片就会丢失。所以需要将图片保存到磁盘指定位置。我这里做了一个配置,来设置保存图片的地址。上面代码中也已经包含了修改保存地址的内容。
在页面上,获取图片则不是直接获取图片地址,而是通过向服务器发送请求,服务器去找到磁盘中指定地址的图片在加载进来。
获取图片信息controller:
package com.shijie99.ueditor.controller;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import com.shijie99.ueditor.pojo.SysAttachment;
import com.shijie99.ueditor.service.SysAttachmentService;
/**
* 获取保存在磁盘上的图片信息
* @author wangcf
* @date 2016-9-21 上午11:14:41
*/
@Controller
public class ImageController {
@Autowired
private SysAttachmentService sysAttachmentService;
/**
* 从磁盘获取图片
* @author wangcf
* @date 2016-9-21 下午3:12:06
*/
@RequestMapping(value = "/{date}/{id}/{type}/image", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
public void image(@PathVariable("date") String date,@PathVariable("id") String id,@PathVariable("type") String type,HttpServletRequest request, HttpServletResponse response)
throws IOException {
SysAttachment sysAttachment = sysAttachmentService.findById(date,id,type);
response.setContentType("image/x-png");
response.setCharacterEncoding("UTF-8");
File file = new File(sysAttachment.getPath());
BufferedImage image = ImageIO.read(file);
ImageIO.write(image, sysAttachment.getType(), response.getOutputStream());
}
}
这样,就完全实现了SpringMVC+Ueditor的图片上传的功能。
注意:
1、在类ConfigManager 中需要将自己的保存图片地址配置进去,在public Map<String, Object> getConfig ( int type ) 方法最后中需要增加以下代码:
//增加自己的保存图片地址,从配置文件中读取
if(StringUtils.isNotBlank(ConfigTool.getImageSavePath())){
conf.put( "myImageSavePath", ConfigTool.getImageSavePath());
}
2、config,json 中的配置项imagePathFormat 不要写除了替换类以外的文件夹名,需要的话在配置自己的保存地址时设置。imageUrlPrefix不要设置。
目前就这么多吧,以后有其他的新的需求再研究吧......
有问题欢迎留言讨论,谢谢