java web的文件上传

来源:互联网 发布:数据透视表的高级用法 编辑:程序博客网 时间:2024/05/17 08:04

今天学习了javaWeb的文件上传功能。


首先要导入两个相关的jar包,一个是Apache的commons-fileupload包,一个Apache的commons-io包,在网上或者在Apache都能找到,并导到工程文件内。
这里写图片描述


jsp端通过form表单进行对服务器的提交:

 <!-- 以流的形式提交表单 -->    <form action="${pageContext.request.contextPath}/servlet/Download" enctype="multipart/form-data" method="post">        上传用户:<input type="text" name="name"><br/>        上传文件1:<input type="file" name="file1"><br/>        上传文件2:<input type="file" name="file2"><br/>        <input type="submit" value="提交">    </form>
enctype="multipart/form-data"       //以流的形式提交表单,支持任何文件上传

package com.lk;import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.util.List;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.apache.commons.fileupload.FileItem;import org.apache.commons.fileupload.FileUploadException;import org.apache.commons.fileupload.disk.DiskFileItemFactory;import org.apache.commons.fileupload.servlet.ServletFileUpload;public class Download extends HttpServlet {    public void doGet(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {        // 得到上传文件的保存目录,将上传的文件存放于WEB-INF目录下,不允许外界直接访问,保证上传文件的安全        String savePath = this.getServletContext().getRealPath(                "/WEB-INF/upload");        File file = new File(savePath);        // 判断上传文件的保存目录是否存在        if (!file.exists() && !file.isDirectory()) {            System.out.println(savePath + "目录不存在,需要创建");            // 创建目录            file.mkdirs();        }        try {            // 创建一个DiskFileItemFactory工厂            DiskFileItemFactory factory = new DiskFileItemFactory();            ServletFileUpload upload = new ServletFileUpload(factory);            upload.setHeaderEncoding("UTF-8");            // 查看是否以流的形式把表单传进            if (!upload.isMultipartContent(request)) {                // 不是就按正常的方式执行                return;            }            // 使用ServletFileUpload解析器解析上传数据,解析结果返回的是一个List<FileItem>集合,每一个FileItem对应一个Form表单的输入项            List<FileItem> fileItems = upload.parseRequest(request);            for (FileItem item : fileItems) {                // 判断FileItem的数据类型                if (item.isFormField()) {                    String name = item.getFieldName();                    String value = item.getString("UTF-8");                    System.out.println("name" + name + "   " + "value" + value);                } else {                    // 上传的为文件                    String filename = item.getName();                    filename = filename                            .substring(filename.lastIndexOf("\\") + 1);                    // 读取文件,io流操作                    InputStream in = item.getInputStream();                    File file2 = new File(savePath + "\\" + filename);                    FileOutputStream out = new FileOutputStream(file2);                    byte buf[] = new byte[1024];                    int len = 0;                    while ((len = in.read(buf)) > 0) {                        out.write(buf, 0, len);                    }                    in.close();                    out.close();                }            }        } catch (Exception e) {            request.setAttribute("message", "上传失败");            e.printStackTrace();        }    }    public void doPost(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {        doGet(request, response);    }}

注意事项:
1.乱码问题,上传的文件名乱码,普通表单乱码问题(在上面的代码中已经解决)

//文件名乱码的解决方式upload.setHeaderEncoding("UTF-8");//普通表单乱码问题的解决方式String value = item.getString("UTF-8");

2.上传的文件应该受到保护,外界无法直接访问
3.为防止文件覆盖的现象发生,要为上传文件产生一个唯一的文件名。
4.为防止一个目录下面出现太多文件,要使用hash算法打散存储。
5.要限制上传文件的最大值。
6.要限制上传文件的类型,在收到上传文件名时,判断后缀名是否合法。
7.删除零时文件。在关闭流前用 item.delete;

package com.lk;import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.util.List;import java.util.UUID;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.apache.commons.fileupload.FileItem;import org.apache.commons.fileupload.FileUploadBase;import org.apache.commons.fileupload.FileUploadException;import org.apache.commons.fileupload.disk.DiskFileItemFactory;import org.apache.commons.fileupload.servlet.ServletFileUpload;import org.apache.taglibs.standard.tag.el.sql.UpdateTag;public class Download extends HttpServlet {    public void doGet(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {        // 得到上传文件的保存目录,将上传的文件存放于WEB-INF目录下,不允许外界直接访问,保证上传文件的安全        String savePath = this.getServletContext().getRealPath(                "/WEB-INF/upload");        try {            // 创建一个DiskFileItemFactory工厂            DiskFileItemFactory factory = new DiskFileItemFactory();            factory.setRepository(new File(this.getServletContext().getRealPath("/WEB-INF/temp")));            ServletFileUpload upload = new ServletFileUpload(factory);            upload.setHeaderEncoding("UTF-8");            // 查看是否以流的形式把表单传进            if (!upload.isMultipartContent(request)) {                return;            }            //限制单个文件的大小            //upload.setFileSizeMax(1024);            // 使用ServletFileUpload解析器解析上传数据,解析结果返回的是一个List<FileItem>集合,每一个FileItem对应一个Form表单的输入项            List<FileItem> fileItems = upload.parseRequest(request);            for (FileItem item : fileItems) {                // 判断FileItem的数据类型                if (item.isFormField()) {                    String name = item.getFieldName();                    String value = item.getString("UTF-8");                    System.out.println("name" + name + "   " + "value" + value);                } else {                    // 得到上传的文件名称,不同电脑的名字不同判断下是否为空                    String filename = item.getName();                    if(filename==null||filename.equals("")){                        continue;                    }                    filename = filename                            .substring(filename.lastIndexOf("\\") + 1);                    filename = getUnqieName(filename);                    String dirName = getSavePath(savePath, filename);                    // 读取文件                    InputStream in = item.getInputStream();                    File file2 = new File(dirName + "\\" + filename);                    FileOutputStream out = new FileOutputStream(file2);                    byte buf[] = new byte[1024];                    int len = 0;                    while ((len = in.read(buf)) > 0) {                        out.write(buf, 0, len);                    }                    item.delete();                    in.close();                    out.close();                }            }        }catch(FileUploadBase.FileSizeLimitExceededException e){            e.printStackTrace();            request.setAttribute("message", "文件太大");            request.getRequestDispatcher("/message.jsp").forward(request, response);            return ;        }        catch (Exception e) {            request.setAttribute("message", "上传失败");            e.printStackTrace();        }    }    // 相同名的文件得到不同的名字    public String getUnqieName(String fileName) {        return UUID.randomUUID() + "_" + fileName;    }    // 产生多个文件夹保存,用hash打散储存    public String getSavePath(String savePath, String fileName) {        int fileHash = fileName.hashCode();        // 分别通过位运算,得出12级目录的目录名        int file1 = fileHash & 0Xf; // 取fileHash最后四位数字        int file2 = fileHash & 0Xf0>>4; // 取fileHash最后四~八位数字        String dir = savePath + "\\" + file1 + "\\" + file2;        File file = new File(dir);        // 创建文件        if (!file.exists()) {            file.mkdirs();        }        return dir;    }    public void doPost(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {        doGet(request, response);    }}
0 0
原创粉丝点击