kindeditor官网:http://kindeditor.net/doc.php
我做的springMVC架构企业博客项目中的写博客中的编辑器是kindeditor,为了进一步熟悉kindeditor,我重新编写了它的上传文件功能。
首先要修改kindeditor的初始化参数中的uploadJson,让前台把上传图片的请求发到自己写的controller中
<script type="text/javascript">
KindEditor.ready(function(K){
window.editor = K.create("#editor_id" , {
allowFileManager: true,
uploadJson: '../KindEditor/uploadImage',
fileManagerJson: '../kindeditor/jsp/file_manager_json.jsp'
});
});
</script>
在网上,servlet获取前台的文件是用ServletFileUpload类,而且kindeditor的演示文件也是用的它。用法如下
//创建工厂
FileItemFactory factory = new DiskFileItemFactory()
//解析request中的内容
ServletFileUpload upload = new ServletFileUpload(factory);
List<FileItem> items = upload.parseRequest(request);
我按照上面的步骤写好后发现获取不到文件,items.size()为空
这是因为我用的spring框架,我在spring的配置文件中添加了spring自带的解析request请求的类。
<!-- 文件上传的配置 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="defaultEncoding" value="utf-8"></property>
<property name="maxUploadSize" value="1048576000"></property>
<property name="maxInMemorySize" value="4096"></property>
</bean>
参考:https://blog.csdn.net/lwphk/article/details/43015829
如果在配置文件中添加了这个类,当request中的数据是multipart/form-data时,会自动调用该类的方法解析,并把解析的数据封装到MultipartHttpServletRequest中,spring已经帮你解析了一次,你在手动解析一次解释两次。解析两次会获取不到值。
所以解决办法解释要么自己解析,要么然spring帮你解析。
上传文件的controller,是仿照官方给的演示文件写的
package com.yc.springblog.controller;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Random;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.json.simple.JSONObject;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import com.yc.springblog.entity.Admin;
@RestController
@RequestMapping("/KindEditor")
public class KindEditorController {
@RequestMapping("/uploadImage")
public void uploadImage(HttpServletRequest request, HttpServletResponse response, HttpSession session) {
MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;
//文件保存路径
String savePath = request.getServletContext().getRealPath("/");
savePath = new File(savePath).getParent();
//E:\software\apache-tomcat-8.5.40\apache-tomcat-8.5.40\webapps\
//文件保存目录URL
String saveUrl = "";
//定义允许上传的文件扩展名
HashMap<String, String> extMap = new HashMap<String, String>();
extMap.put("image", "gif,jpg,jpeg,png,bmp");
//最大文件大小
long maxSize = 1000000;
response.setContentType("text/html; charset=UTF-8");
PrintWriter out = null;
try {
out = response.getWriter();
} catch (IOException e1) {
e1.printStackTrace();
}
if(!ServletFileUpload.isMultipartContent(multiRequest)){
out.println(getError("请选择文件。"));
return;
}
//检查目录
File uploadDir = new File(savePath);
if(!uploadDir.isDirectory()){
out.println(getError("上传目录不存在。"));
return;
}
//检查目录写权限
if(!uploadDir.canWrite()){
out.println(getError("上传目录没有写权限。"));
return;
}
//创建文件夹
savePath += "/attached/";
saveUrl += "/attached/";
File saveDirFile = new File(savePath);
if (!saveDirFile.exists()) {
saveDirFile.mkdirs();
}
Admin admin = (Admin) session.getAttribute("admin");
String department = admin.getDepartment();
savePath += department + "/";
saveUrl += department + "/";
File dirFile = new File(savePath);
if (!dirFile.exists()) {
dirFile.mkdirs();
}
String fileType = request.getParameter("dir");
Map<String, MultipartFile> fileMap = multiRequest.getFileMap();
// 循环遍历,取出单个文件
for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {
// 获取单个文件
MultipartFile mf = entity.getValue();
String fileName = mf.getOriginalFilename();
//检查文件大小
if(mf.getSize() > maxSize){
out.println(getError("上传文件大小超过限制。"));
return;
}
//检查扩展名
String fileExt = fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase();
if(!Arrays.<String>asList(extMap.get(fileType).split(",")).contains(fileExt)){
out.println(getError("上传文件扩展名是不允许的扩展名。\n只允许" + extMap.get(fileType) + "格式。"));
return;
}
SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");
String newFileName = df.format(new Date()) + "_" + new Random().nextInt(1000) + "." + fileExt;
try{
File uploadedFile = new File(savePath, newFileName);
mf.transferTo(uploadedFile);
}catch(Exception e){
out.println(getError("上传文件失败。"));
return;
}
JSONObject obj = new JSONObject();
obj.put("error", 0);
obj.put("url", saveUrl + newFileName);
out.println(obj.toJSONString());
}
}
@RequestMapping("/managerImage")
public int managerImage(HttpServletRequest request) {
return 0;
}
private String getError(String message) {
JSONObject obj = new JSONObject();
obj.put("error", 1);
obj.put("message", message);
return obj.toJSONString();
}
}
后来我发现我不需要重新编写上传文件功能,我之前想的是图片存到webapps下面,以免重新部署图片消失,我可以先用官方的模板上传到项目路径下的attach文件下,然后点提交博客的时候再从attach中移到webapps下的指定文件夹。重新部署项目可能会间隔很久,为了避免attach中的图片不断增加还可以为每一个用户创建attach下的一个专有文件夹,每次用户提交博客就清空文件夹。而且img标签中有相对路径,即使多个图片也不怕找不到,只是重新部署的时候可能会有人再写博客但是没有写完提交导致缓存在attach中的图片消失,但是我这个毕业设计的小项目就不考虑那么多了。