用户注册



邮箱:

密码:

用户登录


邮箱:

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

发表随想


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

struts 上传处理类

2013-05-03 作者: 神马举报

[jsp]代码库

import com.bruce.util.BeanHelper;
import com.bruce.util.Logger;
import com.bruce.util.http.FileUploader;
import com.bruce.util.http.FileUploader.FileInfo;
import static com.bruce.util.http.FileUploader.*;
@SuppressWarnings ("unused")
public class CheckUpload extends ActionSupport
{
    // 上传路径
    private static final String UPLOAD_PATH        = "upload";
    // 可接受的文件类型
    private static final String[] ACCEPT_TYPES    = {"txt", "pdf", "doc", ".Jpg", "*.zip", "*.RAR"};
    // 总上传文件大小限制
    private static final long MAX_SIZE            = 1024 * 1024 * 100;
    // 单个传文件大小限制
    private static final long MAX_FILE_SIZE        = 1024 * 1024 * 10;

    @Override
    public String execute()
    {
        // 创建 FileUploader 对象
        FileUploader fu = new FileUploader (UPLOAD_PATH, ACCEPT_TYPES, MAX_SIZE, MAX_FILE_SIZE);

        // 根据实际情况设置对象属性(可选)
        /*
        fu.setFileNameGenerator(new FileNameGenerator()
        {

            @Override
            public String generate(FileItem item, String suffix)
            {
                return String.format("%d_%d", item.hashCode(), item.get().hashCode());
            }
        });

        fu.setServletProgressListener(new ProgressListener()
        {

            @Override
            public void update(long pBytesRead, long pContentLength, int pItems)
            {
                System.out.printf("%d: length -> %d, read -> %d.\n", pItems, pContentLength, pBytesRead);
            }
        });
        */

        // 执行上传并获取操作结果
        Result result = fu.upload (getRequest(), getResponse() );

        // 检查操作结果
        if (result != FileUploader.Result.SUCCESS)
        {
            // 设置 request attribute
            setRequestAttribute ("error", fu.getCause() );
            // 记录日志
            Logger.exception (fu.getCause(), "upload file fail", Level.ERROR, false);

            return ERROR;
        }

        // 通过非文件表单域创建 Form Bean
        Persion persion = BeanHelper.createBean (Persion.class, fu.getParamFields() );
        // 图片保存路径的列表
        List<String> photos    = new ArrayList<String>();

        /* 轮询文件表单域,填充 photos */
        Set<String> keys = fu.getFileFields().keySet();
for (String key : keys)
        {
            FileInfo[] ffs = fu.getFileFields().get (key);
for (FileInfo ff : ffs)
            {
                photos.add (String.format ("(%s) %s%s%s", key, fu.getSavePath(), File.separator, ff.getSaveFile().getName() ) );
            }
        }

        // 设置 Form Bean 的 photos 属性
        persion.setPhotos (photos);
        // 设置 request attribute
        setRequestAttribute ("persion", persion);

        return SUCCESS;
    }
}
class Persion
{
    private String firstName;
    private String lastName;
    private Date birthday;
    private boolean gender;
    private int workingAge;
    private int[] interest;
    private List<String> photos;
}
static class FileInfo
{
    private String uploadFileName;
    private File saveFile;
}


/** 文件上传器 */
class FileUploader
{
    /** 不限制文件上传总大小的 Size Max 常量 */
    public static final long NO_LIMIT_SIZE_MAX        = -1;
    /** 不限制文件上传单个文件大小的 File Size Max 常量 */
    public static final long NO_LIMIT_FILE_SIZE_MAX    = -1;
    /** 默认的写文件阀值 */
    public static final int DEFAULT_SIZE_THRESHOLD    = DiskFileItemFactory.DEFAULT_SIZE_THRESHOLD;
    /** 默认的文件名生成器 */
    public static final FileNameGenerator DEFAULT_FILE_NAME_GENERATOR = new CommonFileNameGenerator();

    /** 设置上传文件的保存路径(不包含文件名)
     *
     * 文件路径,可能是绝对路径或相对路径<br>
     *     1) 绝对路径:以根目录符开始(如:'/'、'D:\'),是服务器文件系统的路径<br>
     *     2) 相对路径:不以根目录符开始,是相对于 WEB 应用程序 Context 的路径,(如:mydir 是指
     *         '${WEB-APP-DIR}/mydir')<br>
     *     3) 规则:上传文件前会检查该路径是否存在,如果不存在则会尝试生成该路径,如果生成失败则
     *         上传失败并返回 {@link Result#INVALID_SAVE_PATH}
     *
     */
    private String savePath;
    /** 文件上传的总文件大小限制 */
    private long sizeMax                        = NO_LIMIT_SIZE_MAX;
    /** 文件上传的单个文件大小限制 */
    private long fileSizeMax                    = NO_LIMIT_FILE_SIZE_MAX;
    /** 可接受的上传文件类型集合,默认:不限制 */
    private Set<String> acceptTypes                = new LStrSet();
    /** 非文件表单域的映射 */
    private Map<String, String[]> paramFields    = new HashMap<String, String[]>();
    /** 文件表单域的映射 */
    private Map<String, FileInfo[]> fileFields    = new HashMap<String, FileInfo[]>();
    /** 文件名生成器 */
    private FileNameGenerator fileNameGenerator    = DEFAULT_FILE_NAME_GENERATOR;

    // commons file upload 相关属性
    private int factorySizeThreshold            = DEFAULT_SIZE_THRESHOLD;
    private String factoryRepository;
    private FileCleaningTracker factoryCleaningTracker;
    private String servletHeaderencoding;
    private ProgressListener servletProgressListener;

    /** 文件上传失败的原因(文件上传失败时使用) */
    private Throwable cause;

    /** 执行上传
     *
     * @param request    : {@link HttpServletRequest} 对象
     * @param response    : {@link HttpServletResponse} 对象
     *
     * @return            : 成功:返回 {@link Result#SUCCESS} ,失败:返回其他结果,
     *                       失败原因通过 {@link FileUploader#getCause()} 获取
     *
     */
    @SuppressWarnings ("unchecked")
    public Result upload (HttpServletRequest request, HttpServletResponse response)
    {
        reset();

        // 获取上传目录绝对路径
        String absolutePath     = getAbsoluteSavePath (request);
        if (absolutePath == null)
        {
            cause = new FileNotFoundException (String.format ("path '%s' not found or is not directory", savePath) );
            return Result.INVALID_SAVE_PATH;
        }

        ServletFileUpload sfu    = getFileUploadComponent();
        List<FileItemInfo> fiis    = new ArrayList<FileItemInfo>();

        List<FileItem> items    = null;
        Result result            = Result.SUCCESS;

        // 获取文件名生成器
        String encoding                    = servletHeaderencoding != null ? servletHeaderencoding : request.getCharacterEncoding();
        FileNameGenerator fnGenerator    = fileNameGenerator != null ? fileNameGenerator : DEFAULT_FILE_NAME_GENERATOR;

        try
        {
            // 执行上传操作
            items = (List<FileItem>) sfu.parseRequest (request);
        }
        catch (FileUploadException e)
        {
            cause = e;

            if (e instanceof FileSizeLimitExceededException)
            {
                result = Result.FILE_SIZE_EXCEEDED;
            }
            else if (e instanceof SizeLimitExceededException)
            {
                result = Result.SIZE_EXCEEDED;
            }
            else if (e instanceof InvalidContentTypeException)
            {
                result = Result.INVALID_CONTENT_TYPE;
            }
            else if (e instanceof IOFileUploadException)
            {
                result = Result.FILE_UPLOAD_IO_EXCEPTION;
            }
            else
            {
                result = Result.OTHER_PARSE_REQUEST_EXCEPTION;
            }
        }

        if (result == Result.SUCCESS)
        {
            // 解析所有表单域
            result = parseFileItems (items, fnGenerator, absolutePath, encoding, fiis);
            if (result == Result.SUCCESS)
                // 保存文件
            {
                result = writeFiles (fiis);
            }
        }

        return result;
    }

    // 解析所有表单域
    private Result parseFileItems (List<FileItem> items, FileNameGenerator fnGenerator, String absolutePath, String encoding, List<FileItemInfo> fiis)
    {
for (FileItem item : items)
        {
            if (item.isFormField() )
                // 解析非文件表单域
            {
                parseFormField (item, encoding);
            }
            else
            {
                if (item.getSize() == 0)
                {
                    continue;
                }

                // 解析文件表单域
                Result result = parseFileField (item, absolutePath, fnGenerator, fiis);
                if (result != Result.SUCCESS)
                {
                    reset();

                    cause = new InvalidParameterException (String.format ("file '%s' not accepted", item.getName() ) );
                    return result;
                }
            }
        }

        return Result.SUCCESS;
    }

    // 解析文件表单域
    private Result parseFileField (FileItem item, String absolutePath, FileNameGenerator fnGenerator, List<FileItemInfo> fiis)
    {
        String suffix            = null;
        String uploadFileName    = item.getName();
        boolean isAcceptType    = acceptTypes.isEmpty();

        if (!isAcceptType)
        {
            suffix = null;
            int stuffPos = uploadFileName.lastIndexOf (".");
            if (stuffPos != -1)
            {
                suffix = uploadFileName.substring (stuffPos, uploadFileName.length() ).toLowerCase();
                isAcceptType = acceptTypes.contains (suffix);
            }
        }

        if (!isAcceptType)
        {
            return Result.INVALID_FILE_TYPE;
        }

        // 通过文件名生成器获取文件名
        String saveFileName = fnGenerator.generate (item, suffix);
        if (!saveFileName.endsWith (suffix) )
        {
            saveFileName += suffix;
        }

        String fullFileName    = absolutePath + File.separator + saveFileName;
        File saveFile        = new File (fullFileName);
        FileInfo info        = new FileInfo (uploadFileName, saveFile);

        // 添加表单域文件信息
        fiis.add (new FileItemInfo (item, saveFile) );
        addFileField (item.getFieldName(), info);

        return Result.SUCCESS;
    }

    private void parseFormField (FileItem item, String encoding)
    {
        String name = item.getFieldName();
        String value = item.getString();

        // 字符串编码转换
        if (!GeneralHelper.isStrEmpty (value) && encoding != null)
        {
            try
            {
                value = new String (value.getBytes ("ISO-8859-1"), encoding);
            }
            catch (UnsupportedEncodingException e)
            {

            }
        }

        // 添加表单域名/值映射
        addParamField (name, value);
    }

    /** 文件名生成器接口
     *
     * 每次保存一个上传文件前都需要调用该接口的 {@link FileNameGenerator#generate} 方法生成要保存的文件名
     *
     */
    public static interface FileNameGenerator
    {
        /** 文件名生成方法
         *
         * @param item        : 上传文件对应的 {@link FileItem} 对象
         * @param suffix    : 上传文件的后缀名
         *
         */
        String generate (FileItem item, String suffix);
    }

    /** 默认通用文件名生成器
     *
     * 实现 {@link FileNameGenerator} 接口,根据序列值和时间生成唯一文件名
     *
     */
    public static class CommonFileNameGenerator implements FileNameGenerator
    {
        private static final int MAX_SERIAL            = 999999;
        private static final AtomicInteger atomic = new AtomicInteger();

        private static int getNextInteger()
        {
            int value = atomic.incrementAndGet();
            if (value >= MAX_SERIAL)
            {
                atomic.set (0);
            }

            return value;
        }

        /** 根据序列值和时间生成 'XXXXXX_YYYYYYYYYYYYY' 格式的唯一文件名 */
        @Override
        public String generate (FileItem item, String suffix)
        {
            int serial        = getNextInteger();
            long millsec    = System.currentTimeMillis();

            return String.format ("%06d_%013d", serial, millsec);
        }
    }

    /** 上传文件信息结构体 */
    public static class FileInfo
    {
        private String uploadFileName;
        private File saveFile;

        // getters and setters ...
    }

    private class FileItemInfo
    {
        FileItem item;
        File file;

        // getters and setters ...
    }

    /** 文件上传结果枚举值 */
    public static enum Result
    {
        /** 成功 */
        SUCCESS,
        /** 失败:文件总大小超过限制 */
        SIZE_EXCEEDED,
        /** 失败:单个文件大小超过限制 */
        FILE_SIZE_EXCEEDED,
        /** 失败:请求表单类型不正确 */
        INVALID_CONTENT_TYPE,
        /** 失败:文件上传 IO 错误 */
        FILE_UPLOAD_IO_EXCEPTION,
        /** 失败:解析上传请求其他异常 */
        OTHER_PARSE_REQUEST_EXCEPTION,
        /** 失败:文件类型不正确 */
        INVALID_FILE_TYPE,
        /** 失败:文件写入失败 */
        WRITE_FILE_FAIL,
        /** 失败:文件的保存路径不正确 */
        INVALID_SAVE_PATH;
    }
}


网友评论    (发表评论)


发表评论:

评论须知:

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


扫码下载

加载中,请稍后...

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

加载中,请稍后...