这里使用的是[1.4.3.2 Jsp 版本],UTF-8版
下载之后,将多余的demo文件去除后,基本的目录如下
页面中使用,第一步:引入js,第二步:添加script元素,第三部:初始化编辑器。其中元素script中id为初始化时使用,name为后台接收参数的命名,跟input的name一样一样的
<script type="text/javascript" charset="utf-8" src="${jsPath}/ueditor/ueditor.config.js"></script>
<script type="text/javascript" charset="utf-8" src="${jsPath}/ueditor/ueditor.all.min.js"> </script>
<script type="text/javascript" charset="utf-8" src="${jsPath}/ueditor/lang/zh-cn/zh-cn.js"></script>
<tr>
<td class="xtsz_common">内容</td>
<td class="xtsz_common2">
<script id="container" name="body" type="text/plain">
</script>
</td>
</tr>
<script>
var ue = UE.getEditor('container');
</script>
如上面步骤,如果引用都ok,那页面应该已经显示出了编辑器,但是由于编辑器需要上传图片的相关功能,所以需要配合后台使用。
ueditor在第一次加载初始化时会访问后台获取配置内容,以此保证前后台对文件的相关过滤校验等保证一致。当然,前台的校验只需在初始化时后台返给ueditor即可,它自己会根据配置进行校验。
涉及到的js有ueditor.config.js,文件中:
// 服务器统一请求接口路径
, serverUrl: URL + "jsp/controller.jsp"
这个是关键,需要自行更改成项目的后台接口地址
以我自己本地为例,tomcat中ROOT根目录地址,我使用:serverUrl:"/admin/uploadConfig"
web.xml
<!-- 上传相关 -->
<servlet>
<servlet-name>uploadConfig</servlet-name>
<servlet-class>com.mcp.core.servlet.UploadConfigServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>uploadConfig</servlet-name>
<url-pattern>/admin/uploadConfig</url-pattern>
</servlet-mapping>
package com.mcp.core.servlet;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.mcp.cons.UploadCons;
import com.mcp.util.Uploader;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class UploadConfigServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doPost(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
String action = request.getParameter("action");
if (action.equals("config")) {
response.getWriter().write(UploadCons.jsonObject.toString());
} else if (action.equals("uploadImage")) {
Uploader up = null;
try {
up = new Uploader(request);
up.upload();
} catch (Exception e) {
e.printStackTrace();
response.getWriter().print("出错了!");
}
JSONObject res= new JSONObject();
res.put("original",up.getOriginalName());
res.put("url",up.getViewUrl());
res.put("title",up.getOriginalName());
res.put("state",up.getState());
response.getWriter().write(res.toString());
}
}
}
Uploader.java
package com.mcp.util;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Random;
import javax.servlet.http.HttpServletRequest;
import com.alibaba.fastjson.JSONArray;
import com.mcp.cons.UploadCons;
import org.apache.commons.fileupload.FileItemIterator;
import org.apache.commons.fileupload.FileItemStream;
import org.apache.commons.fileupload.FileUploadBase;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.fileupload.util.Streams;
public class Uploader {
// 文件保存地址
private String url;
// 文件浏览地址
private String viewUrl;
private String imagePathFormat = UploadCons.jsonObject.getString("imagePathFormat");
// 当天时间
private String yyyyMMdd;
// 上传文件名
private String fileName;
// 状态
private String state;
// 文件类型
private String type;
// 原始文件名
private String originalName;
private HttpServletRequest request = null;
private String title;
// 保存路径
private String savePath = UploadCons.jsonObject.getString("imageSavePath");
// 文件允许格式
private JSONArray allowFiles = UploadCons.jsonObject.getJSONArray("imageAllowFiles");
// 文件大小限制,单位KB
private int maxSize = UploadCons.jsonObject.getInteger("imageMaxSize");
private HashMap<String, String> errorInfo = new HashMap<String, String>();
public Uploader(HttpServletRequest request) {
this.request = request;
HashMap<String, String> tmp = this.errorInfo;
tmp.put("SUCCESS", "SUCCESS"); // 默认成功
tmp.put("NOFILE", "未包含文件上传域");
tmp.put("TYPE", "不允许的文件格式");
tmp.put("SIZE", "文件大小超出限制");
tmp.put("ENTYPE", "请求类型ENTYPE错误");
tmp.put("REQUEST", "上传请求异常");
tmp.put("IO", "IO异常");
tmp.put("DIR", "目录创建失败");
tmp.put("UNKNOWN", "未知错误");
}
public void upload() throws Exception {
boolean isMultipart = ServletFileUpload
.isMultipartContent(this.request);
if (!isMultipart) {
this.state = this.errorInfo.get("NOFILE");
return;
}
DiskFileItemFactory dff = new DiskFileItemFactory();
//创建保存目录
String savePath = this.getFolder(this.savePath);
dff.setRepository(new File(savePath));
try {
ServletFileUpload sfu = new ServletFileUpload(dff);
sfu.setSizeMax(this.maxSize);
sfu.setHeaderEncoding("UTF-8");
FileItemIterator fii = sfu.getItemIterator(this.request);
while (fii.hasNext()) {
FileItemStream fis = fii.next();
if (!fis.isFormField()) {
this.originalName = fis.getName();
if (!this.checkFileType(this.originalName)) {
this.state = this.errorInfo.get("TYPE");
continue;
}
this.fileName = this.getName(this.originalName);
this.type = this.getFileExt(this.fileName);
this.url = savePath + "/" + this.fileName;
this.setViewUrl(this.imagePathFormat+this.yyyyMMdd + "/" + this.fileName);
BufferedInputStream in = new BufferedInputStream(
fis.openStream());
FileOutputStream out = new FileOutputStream(new File(this.url));
BufferedOutputStream output = new BufferedOutputStream(
out);
Streams.copy(in, output, true);
this.state = this.errorInfo.get("SUCCESS");
// UE中只会处理单张上传,完成后即退出
break;
} else {
String fname = fis.getFieldName();
// 只处理title,其余表单请自行处理
if (!fname.equals("pictitle")) {
continue;
}
BufferedInputStream in = new BufferedInputStream(
fis.openStream());
BufferedReader reader = new BufferedReader(
new InputStreamReader(in));
StringBuffer result = new StringBuffer();
while (reader.ready()) {
result.append((char) reader.read());
}
this.title = new String(result.toString().getBytes(),
"utf-8");
reader.close();
}
}
} catch (FileUploadBase.SizeLimitExceededException e) {
this.state = this.errorInfo.get("SIZE");
} catch (FileUploadBase.InvalidContentTypeException e) {
this.state = this.errorInfo.get("ENTYPE");
} catch (FileUploadException e) {
this.state = this.errorInfo.get("REQUEST");
} catch (Exception e) {
e.printStackTrace();
this.state = this.errorInfo.get("UNKNOWN");
}
// log.debug("上传后的文件名为:"+this.title);
}
/**
* 文件类型判断
*
* @param fileName
* @return
*/
private boolean checkFileType(String fileName) {
int size = this.allowFiles.size();
String type = this.getFileExt(fileName);
for (int i = 0; i < size; i++) {
String typeTemp = allowFiles.getString(i);
if (typeTemp.toLowerCase().equals(type)) {
return true;
}
}
return false;
}
/**
* 获取文件扩展名
*
* @return string
*/
private String getFileExt(String fileName) {
return fileName.substring(fileName.lastIndexOf("."));
}
/**
* 依据原始文件名生成新文件名
*
* @return
*/
private String getName(String fileName) {
Random random = new Random();
return this.fileName = "" + random.nextInt(10000)
+ System.currentTimeMillis() + this.getFileExt(fileName);
}
/**
* 根据字符串创建本地目录 并按照日期建立子目录返回
*
* @param path
* @return
*/
private String getFolder(String path) {
SimpleDateFormat formater = new SimpleDateFormat("yyyyMMdd");
this.setYyyyMMdd(formater.format(new Date()));
path += "/" + this.yyyyMMdd;
;
File dir = new File(path);
if (!dir.exists()) {
try {
dir.mkdirs();
} catch (Exception e) {
this.state = this.errorInfo.get("DIR");
return "";
}
}
return path;
}
public void setSavePath(String savePath) {
this.savePath = savePath;
}
public void setMaxSize(int size) {
this.maxSize = size;
}
public String getUrl() {
return this.url;
}
public String getState() {
return this.state;
}
public String getTitle() {
return this.title;
}
public String getType() {
return this.type;
}
public String getOriginalName() {
return this.originalName;
}
public String getViewUrl() {
return viewUrl;
}
public void setViewUrl(String viewUrl) {
this.viewUrl = viewUrl;
}
public void setYyyyMMdd(String yyyyMMdd) {
this.yyyyMMdd = yyyyMMdd;
}
}
package com.mcp.cons;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import java.io.*;
public class UploadCons {
public static JSONObject jsonObject;
static {
load("upload.json");
}
private static void load(String name) {
InputStream in = Thread.currentThread().getContextClassLoader()
.getResourceAsStream(name);
BufferedReader br = null;
try {
br = new BufferedReader(new InputStreamReader(in,"utf-8"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
String line = null;
StringBuffer strObj = new StringBuffer();
try {
while ((line = br.readLine()) != null) {
strObj.append(line);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
jsonObject = JSON.parseObject(strObj.toString());
}
}
下载的ueditor里边会有一个config.json文件,里边有相关的配置,页面对编辑的操作,都会触发后台的访问,每次访问都带入action参数,action参数名称在配置文件中会有体现,你看下文件就明白,我这里只做上传,所以只对uploadimage进行处理,如果有相关其它需求,只需要在servlet里的switch里添加相关action处理即可。
其实ueditor第一次初始化action参数值是config,后台需要返回给他配置文件的json格式的字符串,即config.json的内容。我这里做了更改,放到资源目录下,如下:
upload.json
{
"imageActionName": "uploadImage",
"imageFieldName": "upfile",
"imageMaxSize": 2048000,
"imageAllowFiles": [".png", ".jpg", ".jpeg", ".gif", ".bmp"],
"imageCompressEnable": true,
"imageCompressBorder": 1600,
"imageInsertAlign": "none",
"imageUrlPrefix": "",
"imagePathFormat": "/upload/",
"imageSavePath": "/data/upload",
"imageManagerActionName": "listimage",
"imageManagerListPath": "/ueditor/jsp/upload/image/",
"imageManagerListSize": 20,
"imageManagerUrlPrefix": "",
"imageManagerInsertAlign": "none",
"imageManagerAllowFiles": [".png", ".jpg", ".jpeg", ".gif", ".bmp"]
}
其中imageSavePath是保存图片的绝对路径,imagePathFormat是前台展示时所带的前缀,因为我这里nginx对静态文件进行管理,对upload过滤,所以如此。如果你是单tomcat或者其它容器,只要在webapps下新建upload文件夹,并把sevePath路径存过去就行了。(因为我是用阿里的JSONObject封装的,所以去掉了文字,保证转JSON对象不报错)
整体部署的时候需要注意:
1 前台的ueditor是否能访问到接口地址,根据例如chroom浏览器,F12查看下控制台是否报错,如果有错误,一般是接口地址的问题,更改ueditor.config.js文件即可。
2 后台接口是否正确接收到了action=config的参数,并且返回了upload.json的里字符串,如果都ok,就没问题了。
3 后台上传成功后,返回到前台的结果也是json格式字符串,代码中有体现,格式是固定的,返回后由ueditor自己去解析。
其实这个servlet可以作为项目统一上传接口,如何设计,就看自己的项目情况了,当让也可以直接下载ueditor官方的后台代码,反正我是不喜欢。。