# 前后端分离 ueditor 富文本编辑器的使用-Java 版本

在前后端分离的情况下把 ueditor 集成到系统中。项目页面如图:

picture

说明:由于 ueditor 的上传文件的功能默认是上传在项目工程目录下的,而我这里是把文件上传到另外一个 Tomcat 服务器下的,所以我自己单独写了一个上传接口,并且还要修改 config.json 文件。

  • 1、下载 ueditor 打开http://ueditor.baidu.com/website/download.html#ueditor 需要下载两个压缩包

    • 1、下载完整源码,并解压
    • 2、下载 jsp 版本【UTF-8】,并解压 源码版本是为了使用里面的 java 文件,而后来发现在源码版本中没有 ueditor.all.min.js 文件,而在前端是需要引入这个 js 文件的,所以需要再把 jsp 版本下载下来,该版本中有该 js 文件。

picture

picture

# 2、java 后台部分

# 2.1、config.json 文件

在 java 项目的 src/main/webapp 目录下新建一个 conf 目录,然后在解压后的源码版本中的 jsp 目录下找到 config.json 文件,把它复制到新建的 conf 目录下,并做修改。 该文件是用来配置 ueditor 编辑器的上传文件的功能的各种参数的。

picture

picture

其中,imageActionName 属性的取值“uploadimage”要记住,后续上传接口中要用到

# 2.2、把源码版本中的 jsp/src/com 目录下的 baidu 这个文件夹拷贝到项目 com.lin 包下

拷贝后,里面 java 文件肯定会报错,只需修改各个 java 文件的 package 包路径和引用其他文件的路径即可。

picture

另外由于在上一步中,把 config.json 文件放置到了 src/main/webapp/conf 目录下,而在 ConfigManager 类中需要读取该 json 文件的内容,所以需要在 ConfigManager.java 文件中修改少量代码,大于在 170 多行,修改如下:

picture

# 2.3、项目常量配置-config.properties

#host地址
host=http://172.16.4.160:8081/ssm_project
#文件上传服务器地址(ip+端口)
uploadHost=http://172.16.4.160:8090/
#普通图片上传保存目录
imagePath = file/image/
#系统用户头像上传保存目录
headImgPath = file/image/headImg/
#系统用户默认头像
sysUserDefImg = sysUser-default.jpg
#文本文件上传保存目录
documentPath = file/document/
#音频文件上传保存目录
soundPath = file/sound/
#视频文件上传保存目录
videoPath = file/video/
#ueditor编辑器上传文件保存目录(包括图片、视频、音频、文本等文件)
ueditor = file/ueditor/
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# 2.4、新建上传工具类-Upload.java

前后端分离跨服务器文件上传

package com.lin.utils;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.io.FilenameUtils;
import org.springframework.web.multipart.MultipartFile;
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.WebResource;

/**
 * 上传文件工具类
 * @author libo
 */
public class Upload {

    /**
     * 上传文件
     * @param request
     * @param response
     * @param serverPath    服务器地址:(http://172.16.5.102:8090/)
     * @param path             文件路径(不包含服务器地址:upload/)
     * @return
     */
    public static String upload(Client client, MultipartFile file, HttpServletRequest request,HttpServletResponse response, String serverPath, String path){
        // 文件名称生成策略(日期时间+uuid )
        UUID uuid = UUID.randomUUID();
        Date d = new Date();
        SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss");
        String formatDate = format.format(d);
        // 获取文件的扩展名
        String extension = FilenameUtils.getExtension(file.getOriginalFilename());
        // 文件名
        String fileName = formatDate + "-" + uuid + "." + extension;
        //相对路径
        String relaPath = path + fileName;

        String a = serverPath + path.substring(0, path.lastIndexOf("/"));
        File file2 = new File(a);
        if(!file2.exists()){
            boolean mkdirs = file2.mkdirs();
            System.out.println(mkdirs);
        }

        // 另一台tomcat的URL(真实路径)
        String realPath = serverPath + relaPath;
        // 设置请求路径
        WebResource resource = client.resource(realPath);

        // 发送开始post get put(基于put提交)
        try {
            resource.put(String.class, file.getBytes());
            return fileName+";"+relaPath+";"+realPath;
        } catch (IOException e) {
            e.printStackTrace();
            return "";
        }
    }

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64

# 2.5、新建 UEditorController.java 文件,编写上传接口

package com.lin.controller;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.io.FilenameUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.MultipartResolver;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
import com.lin.baidu.ueditor.ActionEnter;
import com.lin.utils.ResponseUtils;
import com.lin.utils.Upload;
import com.sun.jersey.api.client.Client;
import net.sf.json.JSONObject;
/**
 * baidu-ueditor
 * @author libo
 */
@Controller
@RequestMapping("/ueditor")
public class UEditorController {
    @Value(value="${ueditor}")    //后台图片保存地址
    private String ueditor;

    @Value(value="${uploadHost}")
    private String uploadHost;    //项目host路径

    /**
     * ueditor文件上传(上传到外部服务器)
     * @param request
     * @param response
     * @param action
     */
    @ResponseBody
    @RequestMapping(value="/ueditorUpload.do", method={RequestMethod.GET, RequestMethod.POST})
    public void editorUpload(HttpServletRequest request, HttpServletResponse response, String action) {
        response.setContentType("application/json");
        String rootPath = request.getSession().getServletContext().getRealPath("/");

        try {
            if("config".equals(action)){    //如果是初始化
                String exec = new ActionEnter(request, rootPath).exec();
                PrintWriter writer = response.getWriter();
                writer.write(exec);
                writer.flush();
                writer.close();
            }else if("uploadimage".equals(action) || "uploadvideo".equals(action) || "uploadfile".equals(action)){    //如果是上传图片、视频、和其他文件
                try {
                    MultipartResolver resolver = new CommonsMultipartResolver(request.getSession().getServletContext());
                    MultipartHttpServletRequest Murequest = resolver.resolveMultipart(request);
                    Map<String, MultipartFile> files = Murequest.getFileMap();//得到文件map对象
                    // 实例化一个jersey
                    Client client = new Client();

                    for(MultipartFile pic: files.values()){
                        JSONObject jo = new JSONObject();
                        long size = pic.getSize();    //文件大小
                        String originalFilename = pic.getOriginalFilename();  //原来的文件名
                        String uploadInfo = Upload.upload(client, pic, request, response, uploadHost, ueditor);
                        if(!"".equals(uploadInfo)){    //如果上传成功
                            String[] infoList = uploadInfo.split(";");
                            jo.put("state", "SUCCESS");
                            jo.put("original", originalFilename);//原来的文件名
                            jo.put("size", size);  //文件大小
                            jo.put("title", infoList[1]);  //随意,代表的是鼠标经过图片时显示的文字
                            jo.put("type", FilenameUtils.getExtension(pic.getOriginalFilename()));  //文件后缀名
                            jo.put("url", infoList[2]);//这里的url字段表示的是上传后的图片在图片服务器的完整地址(http://ip:端口/***/***/***.jpg)
                        }else{    //如果上传失败
                        }
                        ResponseUtils.renderJson(response, jo.toString());
                    }
                }catch (Exception e) {
                    e.printStackTrace();
                }
            }
        } catch (Exception e) {
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87

其中: if("config".equals(action)){

这段代码是用来判断是否是初始化上传的,因为在点击多图上传弹出上传窗口的时候,是会请求这个接口,经测试,如果没有该段判断,前端的上传是无法使用的。 else if("uploadimage".equals(action) || "uploadvideo".equals(action) || "uploadfile".equals(action)){

这一部分代码判断中, uploadimage,uploadvideo,uploadfile 这三个值,都是来自于 conf.json 文件中的配置,因此这一个接口既可以上传图片,也可以上传其他类型文件。 另外接口返回的 json 字段,也是固定的。

# 3、前端部分

# 3.1、demo 目录结构

picture

在 ueditor-demo 目录下新建 lib 目录,然后从之前解压的 jsp 版本中,把 dialogs、lang、themes、third-party 四个文件夹和 ueditor.all.min.js、ueditor.config.js、ueditor.parse.js、ueditor.parse.min.js 四个 js 文件复制到 lib 目录下,并添加 jQuery(用来执行 ajax 提交数据)

# 3.2、文件修改

  • 1、修改 ueditor.config.js 修改服务器统一请求接口路径 - serverUrl 属性的值修改为后台上传文件的接口地址

picture

  • 2、修改 dialogs/image/image.js、dialogs/video/video.js、dialogs/attachment/attachment.js 三个文件 这三个文件分别对应图片上传、视频上传、附件上传,主要是要去掉默认设置的请求头(可以直接在这三个 js 文件中删掉该段代码),否则无法上传文件

    2.1、dialogs/image/image.js 大概在 706 行

picture

2.2、dialogs/video/video.js 大概在 719 行

picture

2.3、dialogs/attachment/attachment.js 大概在 488 行

picture

# 3.3、index.html

在页面中需要引入 ueditor.config.jsueditor.all.min.jszh-cn.js

在 body 元素中写一个 script 元素,给一个 id,这里为 editor,并设置 type="text/plain" ,这个 id 主要是通过它来初始化 ueditor 实例的。 初始化的方式是在通过 UE.getEditor('script 标签 id', {})

这里有两个参数,第一个参数是 script 标签的 id 值,第二个参数是一个对象,可以用来设置 ueditor 编辑框的宽高等属性,这里只设置了宽高。

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <title>ueditor-demo</title>
  <script src="/lib/jquery.min.js"></script>
  <script src="/lib/ueditor/ueditor.config.js"></script>
  <script src="/lib/ueditor/ueditor.all.min.js"></script>
  <script src="/lib/ueditor/lang/zh-cn/zh-cn.js"></script>
  <style>
    #submit {
      width: 100px;
      height: 30px;
      line-height: 30px;
      font-size: 16px;
    }
  </style>
</head>

<body>
  <h2>ueditor测试使用</h2>
  <script id="editor" type="text/plain"></script>
  <div style="margin-top: 20px; text-align: center;">
    <input type="button" class="btn btn-blue w-100" value="提 交" id="submit" />
  </div>

  <script>
    $(function() {
      //实例化编辑器
      var ue = UE.getEditor("editor", {
        initialFrameWidth: "100%", //初始化宽度
        initialFrameHeight: 400, //初始化高度
      });

      $("#submit").click(function() {
        //获取ueditor编辑框中的html文本内容
        var content = UE.getEditor("editor").getContent();
        $.ajax({
          url: "http://172.16.4.160:8081/ssm_project/news/addNews.do",
          type: "POST",
          data: {
            content: content,
          },
          dataType: "json",
          success: function(res) {
            console.log(res);
          },
          error: function() {
            console.log(res);
          },
        });
      });
    });
  </script>
</body>

</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58

UE.getEditor('editor').getContent()方法就可以获取到编辑框中的 html 文本,然后调用添加接口,就可以把 html 格式的文本保存到数据库中了。 此时就可以在服务环境下访问该 index.html 页面,即可看到 ueditor 富文本编辑框,并进行上传文件并保存到数据库中。

# 4、效果

picture

picture

上传接口返回的 json 格式如下:

picture

存放到数据库的为 html 结构的文本,如图:

picture

注意:在测试之前,需要先启动文件服务器——另外一个 Tomcat 服务器 ,至于关于这一块的介绍,请参考 11 月 2 号的一篇博客:前后端分离跨服务器文件上传-Java SpringMVC 版