用户注册



邮箱:

密码:

用户登录


邮箱:

密码:
记住登录一个月忘记密码?

发表随想


还能输入:200字
云代码 - java代码库

CKEditor上传图片 服务端

2013-04-24 作者: 神马举报

[java]代码库

package com.normandy.position.web;

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.time.DateUtils;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

/**
 * 上传图片
 * <p>
 * 	为CKEDITOR定制的图片上传功能,后续可以扩展上传其他格式的文件
 *  上传的文件的基础路径为: ${apache.home}/${project.name}/${project.name}/freemarker/upload/img/${'yyyyMMdd'}/
 *  每个文件夹下最多500个文件
 * </p>
 * @author mikko
 *
 */
@Controller
@RequestMapping ("/upload.do")
public class FileUploadController {
    protected final Logger logger = Logger
                                    .getLogger (FileUploadController.class);

    /** ~~~ 上传文件的保存路径 */
    private static final String FILE_UPLOAD_DIR = "/upload";
    /** ~~~ 上传文件的保存的下一级路径,标示存储类型 */
    private static final String FILE_UPLOAD_SUB_IMG_DIR = "/img";
    /** ~~~ 为了能让CKEDITOR加载到上传的图片,此处将位置限制在了freemarker下*/
    private static final String FOR_FREEMARKER_LOAD_DIR = "/freemarker";
    /** ~~~ 每个上传子目录保存的文件的最大数目 */
    private static final int MAX_NUM_PER_UPLOAD_SUB_DIR = 500;
    /** ~~~ 上传文件的最大文件大小 */
    private static final long MAX_FILE_SIZE = 1024 * 1024 * 2;
    /** ~~~ 系统默认建立和使用的以时间字符串作为文件名称的时间格式*/
    private static final String DEFAULT_SUB_FOLDER_FORMAT_AUTO = "yyyyMMdd";
    /** ~~~ 这里扩充一下格式,防止手动建立的不统一*/
    private static final String DEFAULT_SUB_FOLDER_FORMAT_NO_AUTO = "yyyy-MM-dd";

    @RequestMapping (method = RequestMethod.GET)
    public void processUpload (ModelMap modelMap, HttpServletRequest request,
                               HttpServletResponse response) {
        processUploadPost (modelMap, request, response);
        return;
    }

    @RequestMapping (method = RequestMethod.POST)
    public void processUploadPost (ModelMap modelMap,
                                   HttpServletRequest request, HttpServletResponse response) {

        // 判断提交的请求是否包含文件
        boolean isMultipart = ServletFileUpload.isMultipartContent (request);

        if (!isMultipart) {
            return;
        }

        // 获取目录
        File floder = buildFolder (request);
        if (null == floder) {
            return;
        }

        try {
            response.setContentType ("text/html; charset=UTF-8");
            response.setHeader ("Cache-Control", "no-cache");
            PrintWriter out = response.getWriter();
            // 上传文件的返回地址
            String fileUrl = "";

            FileItemFactory factory = new DiskFileItemFactory();

            ServletFileUpload servletFileUpload = new ServletFileUpload (factory);
            servletFileUpload.setFileSizeMax (MAX_FILE_SIZE);

            @SuppressWarnings ("unchecked")
            List<FileItem> fileitem = servletFileUpload.parseRequest (request);

            if (null == fileitem || 0 == fileitem.size() ) {
                return;
            }

            Iterator<FileItem> fileitemIndex = fileitem.iterator();
            if (fileitemIndex.hasNext() ) {
                FileItem file = fileitemIndex.next();

                if (file.isFormField() ) {
                    logger.error ("上传文件非法!isFormField=true");
                }

                String fileClientName = getFileName (file.getName() );
                String fileFix = StringUtils.substring (fileClientName,
                                                        fileClientName.lastIndexOf (".") + 1);
                if (!StringUtils.equalsIgnoreCase (fileFix, "jpg")
                        && !StringUtils.equalsIgnoreCase (fileFix, "jpeg")
                        && !StringUtils.equalsIgnoreCase (fileFix, "bmp")
                        && !StringUtils.equalsIgnoreCase (fileFix, "gif")
                        && !StringUtils.equalsIgnoreCase (fileFix, "png") ) {
                    logger.error ("上传文件的格式错误=" + fileFix);
                    return;
                }

                if (logger.isInfoEnabled() ) {
                    logger.info ("开始上传文件:" + file.getName() );
                }

                // 为了客户端已经设置好了图片名称在服务器继续能够明确识别,这里不改名称
                File newfile = new File (floder, fileClientName);
                file.write (newfile);

                if (logger.isInfoEnabled() ) {
                    logger.info ("上传文件结束,新名称:" + fileClientName + ".floder:"
                                 + newfile.getPath() );
                }

                // 组装返回url,以便于ckeditor定位图片
                fileUrl = FOR_FREEMARKER_LOAD_DIR + FILE_UPLOAD_DIR + FILE_UPLOAD_SUB_IMG_DIR + File.separator + floder.getName() + File.separator + newfile.getName();
                fileUrl = fileUrl.substring (1); // 去掉/freemarker的第一个/,否则ckeditor不识别
                fileUrl = StringUtils.replace (fileUrl, "//", "/");

                // 将上传的图片的url返回给ckeditor
                String callback = request.getParameter ("CKEditorFuncNum");
                out.println ("<mce:script type=/"text / javascript / "><!--
                             ");
                out.println ("window.parent.CKEDITOR.tools.callFunction("
                             + callback + ",'" + fileUrl + "',''" + ")");
                out.println ("
                             // --></mce:script>");
            }

            out.flush();
            out.close();

        } catch (IOException e) {
            logger.error ("上传文件发生异常!", e);
        } catch (FileUploadException e) {
            logger.error ("上传文件发生异常!", e);
        } catch (Exception e) {
            logger.error ("上传文件发生异常!", e);
        }

        return;
    }

    /**
     * 获取文件名称
     * @param str
     * @return
     */
    private String getFileName (String str) {
        int index = str.lastIndexOf ("//");
        if (-1 != index) {
            return str.substring (index);
        } else {
            return str;
        }
    }

    /**
     * 创建目录
     *
     * @return
     */
    private File buildFolder (HttpServletRequest request) {
        // 这里照顾一下CKEDITOR,由于ftl放置位置的原因,这里必须要在freemarker目录下才能被加载到图片,否则虽然可以正常上传和使用,但是
        // 在控件中无法正常操作
        String realPath = request.getSession().getServletContext()
                          .getRealPath (FOR_FREEMARKER_LOAD_DIR);

        logger.error (realPath);

        // 一级目录,如果不存在,创建
        File firstFolder = new File (realPath + FILE_UPLOAD_DIR);
        if (!firstFolder.exists() ) {
            if (!firstFolder.mkdir() ) {
                return null;
            }
        }

        // 二级目录,如果不存在,创建
        String folderdir = realPath + FILE_UPLOAD_DIR + FILE_UPLOAD_SUB_IMG_DIR;
        if (logger.isDebugEnabled() ) {
            logger.debug ("folderdir" + folderdir);
        }

        if (StringUtils.isBlank (folderdir) ) {
            logger.error ("路径错误:" + folderdir);
            return null;
        }

        File floder = new File (folderdir);
        if (!floder.exists() ) {
            if (!floder.mkdir() ) {
                logger.error ("创建文件夹出错!path=" + folderdir);
                return null;
            }

        }
        // 再往下的文件夹都是以时间字符串来命名的,所以获取最新时间的文件夹即可
        String[] files = floder.list();
        if (null != files && 0 < files.length) {
            // 含有子文件夹,则获取最新的一个
            Date oldDate = null;
            int index = -1;
            for (int i = 0; i < files.length; i++) {
                String fileName = files[i];

                try {
                    Date thisDate = DateUtils.parseDate (fileName, new String[] {
                        DEFAULT_SUB_FOLDER_FORMAT_AUTO, DEFAULT_SUB_FOLDER_FORMAT_NO_AUTO
                    });
                    if (oldDate == null) {
                        oldDate = thisDate;
                        index = i;
                    } else {
                        if (thisDate.after (oldDate) ) {
                            // 保存最新的时间和数组中的下标
                            oldDate = thisDate;
                            index = i;
                        }
                    }
                } catch (ParseException e) {
                    // 这里异常吃掉,不用做什么,如果解析失败,会建立新的文件夹,防止人为的建立文件夹导致的异常。
                }
            }// for

            // 判断当前最新的文件夹下是否已经存在了最大数目的图片
            if (null != oldDate && -1 != index) {
                File pointfloder = new File (folderdir + File.separator
                                             + files[index]);
                if (!pointfloder.exists() ) {
                    if (!pointfloder.mkdir() ) {
                        logger.error ("创建文件夹出错!path=" + folderdir);
                        return null;
                    }
                }

                // 如果文件夹下的文件超过了最大值,那么也需要新建一个文件夹
                String[] pointfloderFiles = pointfloder.list();
                if (null != pointfloderFiles
                        && MAX_NUM_PER_UPLOAD_SUB_DIR < pointfloderFiles.length) {
                    return buildNewFile (folderdir);
                }

                return pointfloder;
            }

            // 查找当前子文件夹失败,新建一个
            return buildNewFile (folderdir);
        } else {
            // 不含有子文件夹,新建一个,通常系统首次上传会有这个情况
            return buildNewFile (folderdir);
        }

    }

    /**
     * 创建一个新文件
     * @param path
     * @return
     */
    private File buildNewFile (String path) {
        // 不含有子文件夹,新建一个,通常系统首次上传会有这个情况
        File newFile = buildFileBySysTime (path);
        if (null == newFile) {
            logger.error ("创建文件夹失败!newFile=" + newFile);
        }

        return newFile;
    }

    /**
     * 根据当前的时间建立文件夹,时间格式yyyyMMdd
     *
     * @param path
     * @return
     */
    private File buildFileBySysTime (String path) {
        DateFormat df = new SimpleDateFormat (DEFAULT_SUB_FOLDER_FORMAT_AUTO);
        String fileName = df.format (new Date() );
        File file = new File (path + File.separator + fileName);
        if (!file.mkdir() ) {
            return null;
        }
        return file;
    }
}


网友评论    (发表评论)


发表评论:

评论须知:

  • 1、评论每次加2分,每天上限为30;
  • 2、请文明用语,共同创建干净的技术交流环境;
  • 3、若被发现提交非法信息,评论将会被删除,并且给予扣分处理,严重者给予封号处理;
  • 4、请勿发布广告信息或其他无关评论,否则将会删除评论并扣分,严重者给予封号处理。


扫码下载

加载中,请稍后...

输入口令后可复制整站源码

加载中,请稍后...