UEditor 是由百度开发的开源富文本编辑器,它的后端集成需要我们提供一个专门的服务来处理其发起的各种请求,其中就包括图片、附件的上传。

整个过程可以分为以下几个步骤:
- 获取 UEditor 源码
- 配置后端控制器
- 实现文件上传逻辑
- 集成到你的 Web 项目中
- 在前端页面配置和初始化 UEditor
第 1 步:获取 UEditor 源码
你需要从 UEditor 的官方 GitHub 仓库下载最新版本的源码。
GitHub 地址: https://github.com/fex-team/ueditor
下载后,你会看到一个包含 jsp、php、net、asp 等多个文件夹的压缩包,因为我们用的是 Java,所以我们需要 jsp 目录下的内容。

将 jsp 目录下的所有文件和文件夹复制到你的 Java Web 项目的 webapp 目录下,并重命名,ueditor,这样你的项目结构中就有了一个类似 webapp/ueditor/ 的路径。
ueditor 目录下最重要的文件是:
config.json: UEditor 的核心配置文件,你需要在这里配置上传路径等。controller.jsp: UEditor 的后端请求入口点,所有的上传、配置获取请求都会发到这里。lib/: 包含了 UEditor 运行所需的一些 JAR 包(如json.jar)。jsp/: 包含了处理各种请求的具体 JSP 文件(如imageUp.jsp,fileUp.jsp)。
第 2 步:配置 UEditor (config.json)
这是最关键的一步,你需要编辑 webapp/ueditor/config.json 文件,告诉 UEditor 你的文件应该上传到哪里。
打开 config.json,找到 imageFieldName、scrawlFieldName 等配置项,并重点关注 imageUrlPrefix、imagePathFormat 和 filePathFormat。

{
// ... 其他配置 ...
"imageActionName": "uploadimage", // 执行上传图片的action名称
"imageFieldName": "upfile", // 提交的图片表单名称
"imageMaxSize": 2048000, // 上传大小限制,单位B
"imageAllowFiles": [".png", ".jpg", ".jpeg", ".gif", ".bmp"], // 上传图片格式显示
"imageCompressEnable": true, // 是否压缩图片,默认是true
"imageCompressBorder": 1600, // 图片压缩最长边限制
"imageInsertAlign": "none", // 插入的图片浮动方式
"imageUrlPrefix": "", // 图片访问路径前缀
"imagePathFormat": "/ueditor/jsp/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}", // 上传保存路径,可以自定义保存路径和文件名格式
// ... 其他配置,如视频、附件等,配置方式类似 ...
"fileActionName": "uploadfile",
"fileFieldName": "upfile",
"fileMaxSize": 51200000,
"fileAllowFiles": [
".png", ".jpg", ".jpeg", ".gif", ".bmp",
".flv", ".swf", ".mkv", ".avi", ".rm", ".rmvb", ".mpeg", ".mpg",
".ogg", ".ogv", ".mov", ".wmv", ".mp4", ".webm", ".mp3", ".wav", ".mid",
".rar", ".zip", ".tar", ".gz", ".7z", ".bz2", ".cab", ".iso",
".doc", ".docx", ".xls", ".xlsx", ".ppt", ".pptx", ".pdf", ".txt", ".md", ".xml"
],
"fileUrlPrefix": "",
"filePathFormat": "/ueditor/jsp/upload/file/{yyyy}{mm}{dd}/{time}{rand:6}"
}
关键配置解释:
-
imageUrlPrefix/fileUrlPrefix:- 这个配置非常重要,它决定了前端访问上传后的文件时使用的 URL 前缀。
- 如果你的项目部署在根目录下,可以留空 。
- 如果你的项目部署在某个子路径下,
http://yourserver.com/myapp/,那么这里就应该填写/myapp。 - 绝对路径:也可以填写完整的域名,如
http://yourserver.com。
-
imagePathFormat/filePathFormat:- 这是文件在服务器上的存储路径格式。
{yyyy}: 年{mm}: 月{dd}: 日{time}: 时间戳{rand:6}: 6位随机数/ueditor/jsp/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}最终会生成一个类似/ueditor/jsp/upload/image/20251027/1698345678123_aBcDeF.png的路径。- 注意: 这个路径是相对于你的项目根目录(
webapp)的。
第 3 步:实现文件上传逻辑 (Java 方式)
UEditor 自带的 JSP 上传逻辑比较简单,直接操作 HttpServletRequest,与 Servlet API 耦合度高,在更现代的 Java Web 项目(如 Spring Boot, Spring MVC)中,我们更推荐使用 Java 代码来处理上传,这样更符合项目架构。
方案 A:使用 UEditor 自带的 JSP (简单直接)
如果你不想用 Java 代码处理,可以直接使用 UEditor 自带的 JSP 逻辑,你只需要确保你的项目支持运行 JSP,并且第 2 步的 config.json 配置正确即可。
优点:
- 开箱即用,无需额外编码。
缺点:
- 架构耦合,不易于集成到 Spring Boot 等现代框架中。
- 功能扩展性差。
方案 B:使用 Java 代码处理上传 (推荐)
这是更专业、更灵活的做法,我们将创建一个 Spring MVC 的 Controller 来接收 UEditor 的上传请求。
添加依赖
确保你的项目有处理文件上传的依赖,如果你使用 Spring Boot,spring-boot-starter-web 通常已经包含了,如果没有,请添加:
<!-- Maven -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.11.0</version>
</dependency>
配置上传路径
在 application.properties 或 application.yml 中配置文件上传的物理路径。
# application.properties # 上传文件保存的物理路径 file.upload.path=/path/to/your/project/uploads
注意: /path/to/your/project/uploads 是你服务器上一个真实存在的、有读写权限的目录。
创建上传 Controller
创建一个 Controller 来处理 UEditor 的上传请求,UEditor 会根据 action 参数来区分是上传图片、文件还是获取配置。
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;
import java.util.UUID;
@RestController
@RequestMapping("/ueditor")
public class UEditorController {
// 从配置文件中读取上传路径
@Value("${file.upload.path}")
private String uploadPath;
// 获取配置信息
@GetMapping("config")
public void getConfig(HttpServletRequest request, HttpServletResponse response) {
response.setContentType("application/json");
String rootPath = request.getSession().getServletContext().getRealPath("/");
try {
// 读取config.json文件内容
String config = new org.apache.commons.io.FileUtils.readFileToString(
new File(rootPath, "ueditor/config.json"), "UTF-8");
PrintWriter writer = response.getWriter();
writer.write(config);
writer.flush();
writer.close();
} catch (Exception e) {
e.printStackTrace();
}
}
// 统一处理上传请求
@PostMapping("upload")
public void upload(HttpServletRequest request, HttpServletResponse response,
@RequestParam(value = "upfile", required = false) MultipartFile file) {
String action = request.getParameter("action");
String callback = request.getParameter("callback");
JSONObject jsonResult = new JSONObject();
try {
if ("uploadimage".equals(action)) {
// 处理图片上传
handleUpload(file, "image", jsonResult);
} else if ("uploadfile".equals(action)) {
// 处理文件上传
handleUpload(file, "file", jsonResult);
}
// ... 可以继续添加其他 action 的处理,如上传视频等 ...
} catch (Exception e) {
e.printStackTrace();
jsonResult.put("state", e.getMessage());
}
// 返回JSONP或JSON响应
response.setContentType("text/html");
try {
PrintWriter writer = response.getWriter();
if (callback != null && !callback.isEmpty()) {
writer.write(callback + "(" + jsonResult.toString() + ")");
} else {
writer.write(jsonResult.toString());
}
writer.flush();
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
private void handleUpload(MultipartFile file, String type, JSONObject jsonResult) throws IOException {
if (file == null || file.isEmpty()) {
jsonResult.put("state", "文件不能为空");
return;
}
// 原始文件名
String originalFilename = file.getOriginalFilename();
// 文件扩展名
String fileExtension = originalFilename.substring(originalFilename.lastIndexOf("."));
// 新文件名 (UUID + 随机数)
String newFileName = UUID.randomUUID().toString().replace("-", "") +
"_" + new Random().nextInt(10000) + fileExtension;
// 按日期创建目录
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
String datePath = sdf.format(new Date());
// 物理存储路径
String physicalDir = uploadPath + File.separator + type + File.separator + datePath;
File destDir = new File(physicalDir);
if (!destDir.exists()) {
destDir.mkdirs();
}
// 物理文件
File destFile = new File(destDir, newFileName);
// 保存文件
file.transferTo(destFile);
// 构造返回的URL
// 注意:这里的URL前缀需要根据你的项目实际情况配置
String urlPrefix = "/uploads"; // 假设你配置了一个静态资源映射指向 uploadPath
String fileUrl = urlPrefix + "/" + type + "/" + datePath + "/" + newFileName;
// 返回UEditor需要的格式
jsonResult.put("state", "SUCCESS");
jsonResult.put("url", fileUrl);
jsonResult.put("title", newFileName);
jsonResult.put("original", originalFilename);
jsonResult.put("type", fileExtension);
jsonResult.put("size", file.getSize());
}
}
配置静态资源访问
为了让前端能够访问到上传的文件,你需要配置一个静态资源映射,这个映射的路径应该与你 Controller 中返回的 urlPrefix 一致。
如果你使用 Spring Boot,可以在配置类中添加:
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Value("${file.upload.path}")
private String uploadPath;
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
// 将 "/uploads" 路径下的所有请求映射到文件系统的 uploadPath 目录
registry.addResourceHandler("/uploads/**")
.addResourceLocations("file:" + uploadPath + File.separator);
}
}
第 4 步:集成到你的 Web 项目中
前端页面需要知道如何与你的后端 Controller 通信。
-
引入 UEditor 的 JS 文件: 在你的 JSP 或 HTML 页面中,引入 UEditor 的核心 JS 文件。
<script type="text/javascript" charset="utf-8" src="/ueditor/ueditor.config.js"></script> <script type="text/javascript" charset="utf-8" src="/ueditor/ueditor.all.min.js"></script> <!-- 如果你需要使用 Vue、React 等框架,还需要引入对应的 integration 文件 -->
-
创建编辑器实例: 在页面中放置一个
<textarea>作为编辑器的容器,并用 JS 初始化它。<textarea id="editor" name="content" style="width:1024px;height:500px;"></textarea> <script type="text/javascript"> // 实例化编辑器 // 注意:这里的 serverUrl 指向你 Java 后端提供的配置接口 var ue = UE.getEditor('editor', { // serverUrl: "/ueditor/config" // 如果你用方案B,这个URL用来获取配置 // 但更推荐使用 UEditor 的默认方式,它会自动请求 /ueditor/controller.jsp // 所以我们只需要确保 controller.jsp 或我们自己的 Controller 能正确处理请求即可 }); </script>
第 5 步:处理请求路由 (Spring MVC 与 JSP 的冲突)
这里有一个常见的陷阱,如果你使用了 Spring MVC,它会拦截所有以 .jsp 结尾的请求,导致 UEditor 默认的 controller.jsp 无法被访问。
解决方案:
-
修改 UEditor 入口 (推荐): 修改
ueditor.config.js文件,将serverUrl指向你自己的 Java Controller。// ueditor.config.js window.UEDITOR_CONFIG = { // ... 其他配置 ... serverUrl: "/ueditor/upload" // 指向你上面创建的 Java Controller };这样,UEditor 的所有请求(包括获取配置和上传文件)都会直接发到
/ueditor/upload这个 URL,由你的 Java Controller 统一分发处理。 -
禁用 Spring 对 JSP 的拦截: 在 Spring MVC 的配置文件中,排除对 UEditor 相关 JSP 的拦截。
<!-- Spring MVC 配置文件 --> <mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/**"/> <!-- 排除对 ueditor 目录下所有资源的拦截 --> <mvc:exclude-mapping path="/ueditor/**"/> </mvc:interceptor> </mvc:interceptors>这种方法保留了 UEditor 的原始结构,但不如第一种方法彻底。
总结与最佳实践
| 步骤 | 关键点 | 备注 |
|---|---|---|
| 获取源码 | 将 jsp 目录内容放入 webapp,并重命名。 |
这是基础。 |
配置 config.json |
重点配置 imageUrlPrefix 和 imagePathFormat。 |
imageUrlPrefix 是前端访问URL,imagePathFormat 是服务器存储路径。 |
| 实现后端 | 强烈推荐使用 Java Controller。 | 创建一个 Controller 处理 /ueditor/upload 请求,根据 action 参数分发逻辑。 |
| 静态资源映射 | 配置 Spring Boot/Spring MVC 将 /uploads/** 映射到文件系统。 |
确保前端能通过 URL 访问上传的文件。 |
| 前端集成 | 在 ueditor.config.js 中设置 serverUrl 为你的 Java Controller 路径。 |
这是打通前后端的关键一步。 |
遵循以上步骤,你就可以成功地在 Java 项目中集成 UEditor 并实现健壮的文件上传功能。
