在博客中看到了一位大侠的ckeidtor的图片上传的servlet实现,写的很好,也给了我思路,但是图片上传后,是自动保存在了tomcat的服务器上的,对于图片的管理有些不方便,现对代码进行一些改进,支持将图片放在指定的目录下。
首先在ckeidtor的配置文件config.js中将上传配置打开:脚本如下:
config.filebrowserImageUploadUrl = '../CKEditorImageServlet?Type=Image';
然后就是web.xml文件的配置了:
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"> <servlet> <servlet-name>CKEditorImageServlet</servlet-name> <servlet-class>com.jabberchina.poms.servlet.CKEditorImageServlet</servlet-class> <init-param> <param-name>allowedImageExtensions</param-name> <param-value>jpg|gif|jpeg|png|bmp</param-value> </init-param> <load-on-startup>0</load-on-startup> </servlet> <servlet-mapping> <servlet-name>CKEditorImageServlet</servlet-name> <url-pattern>/CKEditorImageServlet</url-pattern> </servlet-mapping> <session-config> <session-timeout>30</session-timeout> </session-config> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app>
主要是Servlet文件上传的扩展名规则,就是允许上传的类型和阻止上传的类型。与要拦截的URL。
下面就是Servlet的实现了:
package com.servlet; import java.awt.image.BufferedImage; import java.io.IOException; import java.io.PrintWriter; import javax.imageio.ImageIO; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.io.FilenameUtils; import org.springframework.context.ApplicationContext; import org.springframework.web.context.support.WebApplicationContextUtils; import com.dao.CkeditorImageDAO; public class CKEditorImageServlet extends HttpServlet { /** * */ private static final long serialVersionUID = -735481391001655214L; private CkeditorImageDAO ckeditorImageDAO; /** * Servlet初始化方法 */ public void init() throws ServletException { ApplicationContext ac = WebApplicationContextUtils .getRequiredWebApplicationContext(getServletContext()); ckeditorImageDAO = (CkeditorImageDAO) ac.getBean("ckeditorImageDAO"); } public void destroy() { ckeditorImageDAO = null; } public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String fileName = request.getParameter("fileName"); String extensionName = FilenameUtils.getExtension(fileName); response.setContentType("image/" + extensionName); BufferedImage bufferImage = ckeditorImageDAO.getFromDisk(fileName); ImageIO.write(bufferImage, extensionName, response.getOutputStream()); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html; charset=UTF-8"); response.setHeader("Cache-Control", "no-cache"); PrintWriter out = response.getWriter(); String imageURL = ""; try { imageURL = ckeditorImageDAO.saveTODisk(request); } catch (Exception e) { e.printStackTrace(); } // CKEditorFuncNum是回调时显示的位置,这个参数必须有 String callback = request.getParameter("CKEditorFuncNum"); out.println("<script type=\"text/javascript\">"); out.println("window.parent.CKEDITOR.tools.callFunction(" + callback + ",'" + imageURL + "',''" + ");"); out.println("</script>"); out.flush(); out.close(); } } package com.dao.impl; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.util.Date; import java.util.List; import javax.imageio.ImageIO; import javax.servlet.http.HttpServletRequest; import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.apache.commons.fileupload.servlet.ServletFileUpload; import org.apache.commons.io.FilenameUtils; import com.dao.CkeditorImageDAO; public class CkeditorImageDAOImpl implements CkeditorImageDAO{ private String dataFilePath; private String ckeditorImageServletPath; public String getCkeditorImageServletPath() { return ckeditorImageServletPath; } public void setCkeditorImageServletPath(String ckeditorImageServletPath) { this.ckeditorImageServletPath = ckeditorImageServletPath; } public String getDataFilePath() { return dataFilePath; } public void setDataFilePath(String dataFilePath) { this.dataFilePath = dataFilePath; } @SuppressWarnings("unchecked") public String saveTODisk(HttpServletRequest request) throws Exception { String imageURL = ""; // 判断文件夹是否存在,不存在则创建 File dirTest = new File(dataFilePath); if (!dirTest.exists()) { dirTest.mkdirs(); } ServletFileUpload upload = new ServletFileUpload( new DiskFileItemFactory()); try { List<FileItem> items = upload.parseRequest(request); if (items != null && !items.isEmpty()) { FileItem fileItem = items.get(0);//目前ckeditor编辑器只允许同时上传一个图片文件,所以只处理第一个即可 String fileName = new Date().getTime() + "." + FilenameUtils.getExtension(fileItem.getName());//获取文件扩展名 File pathToSave = new File(dataFilePath, fileName); fileItem.write(pathToSave); imageURL = this.ckeditorImageServletPath + fileName; } } catch (Exception ex) { throw ex; } return imageURL; } public BufferedImage getFromDisk(String fileName) throws IOException { File file = new File(dataFilePath + fileName); BufferedImage bufferImage = ImageIO.read(file); return bufferImage; } }
dataFilePath为图片要上传到磁盘路径:如为:D:/poms_workspace/upload/
ckeditorImageDAO与ckeditorImageServletPath 需要在spring的配置文件中进行配置:
<bean id="ckeditorImageDAO" name="ckeditorImageDAO" class="com.jabberchina.poms.dao.impl.CkeditorImageDAOImpl" scope="prototype"> <property name="dataFilePath" value="${dataFilePath}"></property> <property name="ckeditorImageServletPath" value="../CKEditorImageServlet?fileName="></property> </bean>
package com.dao;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
public interface CkeditorImageDAO {
public String saveTODisk(HttpServletRequest request) throws Exception;
public BufferedImage getFromDisk(String fileName) throws IOException;
}
此servlet实现写在了一个servlet中,可以分别写两个servlet,一个是上传图片,一个是读取图片。在此取了个巧,因为上传文件时,是以表单的方式post上去的,所以写在doPost方法中,而对于图片的读取我们用的是"URL?fileName="的get形式发送的请求,所以写在了doGet方法中实现。