有没有人可以不用第三方组件处理文件上传(纯Servlet)

sunbo624 2013-09-16 03:54:57
最近要写一个东西,不依赖于其它第三方组件,处理文件上传,而且是多文件上传。
只能用Servlet API,不能用apache或者其它的那些组件,哪位高手做过类似的功能并且成功过,求助!
我想一定有办法,不然在没有那些组件的时候遇到文件上传需求怎么办。
...全文
229 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
sunbo624 2013-09-18
  • 打赏
  • 举报
回复
引用 1 楼 etnet 的回复:
我在这里解答过。 http://bbs.csdn.net/topics/390154611
我自己实现了,虽然你的代码虽然没用上,但是就是看了那篇帖子的request信息才实现的,分全给你!
无聊找乐 2013-09-17
  • 打赏
  • 举报
回复
网上例子很多好吧
shpery 2013-09-17
  • 打赏
  • 举报
回复
留个邮箱 发个项目给你
sunbo624 2013-09-17
  • 打赏
  • 举报
回复
引用 5 楼 etnet 的回复:
[quote=引用 2 楼 sunbo624 的回复:] [quote=引用 1 楼 etnet 的回复:] 我在这里解答过。 http://bbs.csdn.net/topics/390154611
UploadBytes这个是什么类[/quote] 是一个工具类,如下. [/quote] 你以前做过同样的功能吗,我按照你那个帖子里的request信息,对字符串进行分析,结果能出来,但是中文乱码,你遇到过吗
sunbo624 2013-09-17
  • 打赏
  • 举报
回复
引用 6 楼 wenjie4892543 的回复:
搜索servlet批量上传 N多吧!!
能搜到还用在这求助?
wenjie4892543 2013-09-17
  • 打赏
  • 举报
回复
搜索servlet批量上传 N多吧!!
etnet 2013-09-17
  • 打赏
  • 举报
回复
引用 2 楼 sunbo624 的回复:
[quote=引用 1 楼 etnet 的回复:] 我在这里解答过。 http://bbs.csdn.net/topics/390154611
UploadBytes这个是什么类[/quote] 是一个工具类,如下.

public class UploadBytes {

    //文件名的标志位
    public static final String SIGN_FILENAME = "filename=\"";
    //表单域名称的标志位
    public static final String FORM_NAME = "name=\"";
    //以引号结束的标志位(文件名和表单域名称后的内容)
    public static final String QUOTE_FLAG = "\"";
    //含文件名的表单域的上传文件类型 Content-type
    private final static String CONTENT_TYPE = "Content-Type:";
    //自动换行符(上传文件类型名称后面的内容 实际上传文件内容之前的换行符)
    private final static String AUTO_LINE = "\r\n\r\n";
    private static final String SIGN_MULTIDATA = "multipart/form-data";
    //默认编码
    private final static String DEFAULT_ENCODING = "iso8859_1";

    /**
     * buff为当前已经读取的上传流字节
     * boundary为HTTP头信息中的Content-Type指定的当前域的分隔符的字节数组
     * 处理思想即找到一组成对的boundary,那么其中的字节即为表单域的数据.
     * @param boundary 分隔符
     * @param buff 输出流
     * @return 各分隔符之间的字节列表
     * @throws Exception
     */
    public static List<byte[]> findFiled(byte[] boundary,
            ByteArrayOutputStream buff)
            throws Exception {

        //当前的数据连成对的boundary长度都不够,直接返回。
        if (buff.size() < boundary.length * 2) {
            return Collections.emptyList();
        } else {
            byte[] data = buff.toByteArray();//当前数据

            List<byte[]> fileds = new ArrayList<byte[]>();
            int point = 0;//当前指针位置
            int alertStart = 0;//最近一次警戒区的位置
            boolean alert = false;//是否处于警戒区
            int treated = 0;//已经处理的字节长度

            while (true) {
                if (!alert && data.length - point < boundary.length * 2) {
                    break;
                } else if (alert && data.length - point < boundary.length) { 
                    break;
                }

                if (isBytes(data, boundary, point)) {
                    if (!alert) { //start line
                        alert = true;
                        alertStart = point + boundary.length;
                        point = alertStart;
                    } else { //end line
                        byte[] filed;
                        filed = Arrays.copyOfRange(data, alertStart, point);
                        treated += (point - alertStart + boundary.length);

                        fileds.add(filed);
                        alert = false;
                    }
                } else {
                    point++;
                }
            }

            if (fileds.size() > 0) {
                buff.reset();
                buff.write(data, treated, data.length - treated);
                return fileds;
            }

            return Collections.emptyList();
        }

    }

    /**
     * 根据解析上传文件的所有分隔符之间的字节数组列表
     * 来获取各个文件上传的文件名所在表单域的字节数组列表
     * 即含“filename=”的表单域字节数组
     * @param filesByte 所有分隔符之间的字节数组列表
     * @param charset 上传文件的字符集
     * @return 各个文件上传的文件名所在表单域的字节数组列表
     */
    public static List<byte[]> getFilesByteList(
            List<byte[]> filesByte, String charset)
            throws UnsupportedEncodingException {
        List<byte[]> fieldFilesByte = new ArrayList<byte[]>();

        byte[] fileName = SIGN_FILENAME.getBytes(charset);
        for (int i = 0; i < filesByte.size(); i++) {
            byte[] bs = filesByte.get(i);
            int point = 0;
            while (true) {
                if (bs.length - point < fileName.length) {
                    break;
                }
                if (isBytes(bs, fileName, point)) {
                    fieldFilesByte.add(bs);
                    break;
                } else {
                    point++;
                }
            }
        }

        return fieldFilesByte;
    }

    /**
     * 根据获取上传文件实际域的数据的字节 获取实际域数据
     * @param fieldByte 实际域的数据的字节
     * @param charset 上传文件的编码
     * @return 实际域的数据
     */
    public static Field getField(byte[] fieldByte, String charset)
            throws UnsupportedEncodingException, IOException {
        Field field = new Field();

        String fileNameStr = getFieldStr(fieldByte, charset, SIGN_FILENAME,
                QUOTE_FLAG);

        field.setFieldName(fileNameStr);
        String fileName = "";
        if (fileNameStr != null && !fileNameStr.isEmpty()) {
            fileName = getExtensionName(fileNameStr);
        }
        field.setFileName(fileName);

        String fileType = getFieldStr(fieldByte, charset, CONTENT_TYPE,
                AUTO_LINE);
        field.setContentType(fileType);

        byte[] realFileBytes = getRealFileByte(fieldByte, charset);
        field.setFieldData(realFileBytes);

        return field;
    }

    /**
     * 根据域数据获取域中标志的名称
     * @param fieldByte 域数据
     * @param charset 编码
     * @param nameFlag 名称的标志
     * @param endFlag 以该标志位结束的内容
     * @return 名称
     */
    private static String getFieldStr(byte[] fieldByte, String charset,
            String nameFlag, String endFlag)
            throws UnsupportedEncodingException {

        byte[] fileNameByte = nameFlag.getBytes(charset);
        int point = 0;
        while (true) {
            if (fieldByte.length - point < fileNameByte.length) {
                break;
            }
            if (isBytes(fieldByte, fileNameByte, point)) {
                break;
            } else {
                point++;
            }
        }

        int pos = point + fileNameByte.length;

        //截取从名称开始到内容结束的部分的字节数组
        byte[] fileStart = Arrays.copyOfRange(fieldByte, pos, fieldByte.length);

        //从文件名开始 第一个引号 " 出现的位置 (即为文件名后面的第一个引号)
        byte[] quoteBytes = endFlag.getBytes(charset);
        int point1 = 0;
        while (true) {
            if (fileStart.length - point1 < quoteBytes.length) {
                break;
            }
            if (isBytes(fileStart, quoteBytes, point1)) {
                break;
            } else {
                point1++;
            }
        }

        //名称开始到名称结束的字节数组
        byte[] nameBytes = Arrays.copyOfRange(fieldByte, pos, pos + point1);
        if (nameBytes == null || nameBytes.length == 0) {
            return null;
        }
        String result = new String(nameBytes, charset);
        //若结果前后含有空格,则去掉前后的空格
        result = result.trim();
        return result;
    }

    /**
     * 根据带文件名的文件表单域字节获取实际要上传的字节内容
     * @param fieldByte 带文件名的文件表单域字节
     * @param charset 文件的字符集
     * @return 实际要上传的字节内容
     */
    public static byte[] getRealFileByte(byte[] fieldByte, String charset)
            throws UnsupportedEncodingException, FileNotFoundException,
            IOException {

        //自动换行开始的位置
        byte[] autoLineByte = AUTO_LINE.getBytes(charset);
        int point = 0;
        while (true) {
            if (fieldByte.length - point < autoLineByte.length) {
                break;
            }
            if (isBytes(fieldByte, autoLineByte, point)) {
                break;
            } else {
                point++;
            }
        }

        //上传文件的实际内容(自动换行结束的位置开始,内容的结束有一个换行符)
        byte[] realFileByte = Arrays.copyOfRange(fieldByte,
                point + autoLineByte.length, fieldByte.length - 2);

        return realFileByte;
    }

    /**
     * 比较源数据中是否有与给定的字节数组匹配的数据
     * @param data 源数据
     * @param byteGiven 要比较的数据
     * @param point 当前指针所在的位置
     * @return
     */
    public static boolean isBytes(byte[] data, byte[] byteGiven, int point) {
        for (int i = 0; i < byteGiven.length; i++) {
            if (data[point + i] != byteGiven[i]) {
                return false;
            }
        }
        return true;
    }

    /**
     * 获取上传文件的字符集
     * @param request 请求
     * @return 如果设置字符集的话 则返回字符集,否则 返回默认的字符集
     */
    public static String getCharset(HttpServletRequest request) {
        CharsetParser charsetParser = new CharsetParser();
        String contentType = request.getContentType();
        String charset = charsetParser.getCharset(contentType, ';');
        if (charset == null || charset.isEmpty()) {
            charset = DEFAULT_ENCODING;
        }
        return charset;
    }

    /**
     * 获取请求的信息
     * @param request 请求
     * @return 请求信息byte数组
     * @throws IOException
     */
    public static byte[] getContentBytes(HttpServletRequest request) throws
            IOException {

        InputStream sis = request.getInputStream();

        int dataLength = request.getContentLength();
        //保存上传图片的数据
        byte[] dataBytes = new byte[dataLength];
        int byteRead = 0;
        int totalBytes = 0;
        //上传的数据保存在byte数组
        while (totalBytes < dataLength) {
            byteRead = sis.read(dataBytes, totalBytes, dataLength);
            totalBytes += byteRead;
        }

        sis.close();

        return dataBytes;
    }

    /**
     * 取得数据的分隔字符串
     * @param request 请求
     * @return 数据的分隔字符串
     */
    public static String getBoundaryStr(HttpServletRequest request) {
        String contentType = request.getContentType();
        int lastIndex = contentType.lastIndexOf("=");

        //取得数据的分隔字符串
        String boundaryStr = "--" + contentType.substring(lastIndex + 1,
                contentType.length());


        return boundaryStr;
    }

    /**
     * 获取上传文件的扩展名
     * @param fileName 文件名
     * @return 文件名的扩展名
     */
    public static String getExtensionName(String fileName) {
        int format = fileName.lastIndexOf(".");
        String extensionName = "";

        if (format >= 0) {
            extensionName = fileName.substring(format);
        }
        return extensionName;
    }

    /**
     * 判断上传文件类型,如果是multipart/form-data,则返回true,否则返回fase
     * @param request 请求
     * @return boolean
     */
    public static boolean getContentTypeFlag(HttpServletRequest request) {
        String contentType = request.getContentType();
        if (contentType != null && !contentType.isEmpty()) {
            if (contentType.indexOf(SIGN_MULTIDATA) >= 0) {
                return true;
            }
        }
        return false;
    }
}
sunbo624 2013-09-17
  • 打赏
  • 举报
回复
还真少 基本上都用的第三方
sunbo624 2013-09-16
  • 打赏
  • 举报
回复
引用 1 楼 etnet 的回复:
我在这里解答过。 http://bbs.csdn.net/topics/390154611
UploadBytes这个是什么类
etnet 2013-09-16
  • 打赏
  • 举报
回复
我在这里解答过。 http://bbs.csdn.net/topics/390154611

67,515

社区成员

发帖
与我相关
我的任务
社区描述
J2EE只是Java企业应用。我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本。
社区管理员
  • Java EE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧