Servlet实现文件上传

      本次的JSP实验的内容是采用Servlet来实现文件上传,本次实验的原理就是对post产生的数据进行分析,得出所需要的部分。我们需要的信息有两个部分,第一就是所上传的文件名,第二就是上传过来的文件信息。通过对post信息的分析,第一行信息是分隔符信息,第二行信息是文件名信息,第三行和第四行是我们不需要的信息,第五行开始是传的文件信息。如果同时上传多个文件,就会有多个分隔符,信息的最后一行比第一行(就是分隔符)多"--",当出现这个的时候说明信息已经结束了。本次实验的重点和难点也就是如何正确提取出所需要的信息,文件名和文件内容,对于文件名的处理时,把读进来的信息变成字符串,然后进行处理,这样使在后面的字符串比较变得简单。
      本次实验的关键代码:
public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        String filepath = "d:\\ex\\"; // 上传之后的文件保存在这个文件夹下
        String filename = "";
        ServletInputStream in = request.getInputStream();
        byte[] buf = new byte[4048];
        int len = in.readLine(buf, 0, buf.length); // 取出第一行
        String f = new String(buf, 0, len - 1); // 把第一行变成字符串,方便下面的匹配
        while ((len = in.readLine(buf, 0, buf.length)) != -1) {
            filename = new String(buf, 0, len);
            int i = filename.lastIndexOf("\\"); // 文件名以"\"开始,这个处理方式在Linux下就不行了,如果在Linux下运行,这个地方要修改一下。
            int j = filename.lastIndexOf("\""); // 文件名是以"""结尾的。
            // 处理多个框时,处理没有选择文件的框
            if (i == -1 || j == -1) {
                for (int k = 0; k < 4; k++)
                    in.readLine(buf, 0, buf.length);
                continue;
            }
            filename = filename.substring(i + 1, j);
            DataOutputStream fileStream = new DataOutputStream(
                    new BufferedOutputStream(new FileOutputStream(filepath
                            + filename)));
            len = in.readLine(buf, 0, buf.length); // 在处理信息时,这行信息不要
            len = in.readLine(buf, 0, buf.length); // 这行信息也不要
            while ((len = in.readLine(buf, 0, buf.length)) != -1) {
                String tempf = new String(buf, 0, len - 1);
                if (tempf.equals(f) || tempf.equals(f + "--")) { // 如果匹配,就说明信息结束了
                    break;    //注意此行
                }
                else
                    fileStream.write(buf, 0, len); // 写入
            }
            fileStream.close();
        }
        in.close();
    }
      在有多个文件上传框的时候,如果中间有某个没有上传文件的时候,会出现" filename="" "的情况,所以要进行处理。
      本次实验有一个漏洞,我还没有解决。就是当最后一个文件是文本的时候,会在文本的最后加上分隔符,当最后一个文件是图像或者其他的东西的时候,图像传上去可以正常显示,不会出现问题,那说明传图像的时候不会写入分隔符。在上面代码里面有注意此行,老师说跳出多层循环,可是跳出去还是不可以,不过这个代码能够实现基本的文件传输,也对文件传输中遇到的问题能够进行处理,也能够传大文件。

1 Comment

  1. 感谢曙光做的工作。

    我发现,楼主所说的漏洞其实不是一个漏洞,因为取得boundary(分隔符)的时候,后面多了一个空格,所以要先trim一下,就可以了。但是还是要解决末尾分隔符之前的一个空行也不要写入文件。