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中的圖片消失,但是我這個畢業設計的小項目就不考慮那麼多了。