web文件上传与下载

文件上传与下载

项目包 (不喜勿喷)

链接:https://pan.baidu.com/s/1sCSFE3kcLFNin04rZTl46Q 
提取码:0000 
复制这段内容后打开百度网盘手机App,操作更方便哦

上传

  • 概念:
    • 当用户在前端页面点击文件上传后,文件数据提交给服务器端,实现保存
  • 步骤:
    • 编写文件上传表单
    • 编写服务器程序接收文件
  • 注意:
    • 文件上传表单提交方式:post
    • 表单提交类型:multipart/form-data
页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/upload" method="post" enctype="multipart/form-data">
    <input type="text" name="username" placeholder="请输入用户名"/><br/>
    <input type="file" name="photo1"><br/>
    <input type="file" name="photo1"><br/>
    <input type="submit" value="提交">
</form>
</body>
</html>
核心服务器程序
  • 核心步骤
    • 编写Servlet
    • 使用@MultipartConfig进行注解
    • 使用javax.servlet.http.Part接口接收文件类型
Part file = request.getPart("file");
文件上传细节
  • 安全问题
    • 上传文件应该放在外界无法直接访问的目录下,比如放于WEB-INF目录下
  • 文件覆盖
  • 散列存储
    • 防止一个目录下面出现太多文件
  • 文件类型限制
    • 在收到上传文件名时,判断后缀名是否合法
实践代码
servlet
//Servlet
@WebServlet(name = "UploadServlet",value = "/upload")
@MultipartConfig(maxFileSize = 1024*1024*5,maxRequestSize = 1024*1024*20)
public class UploadServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=utf-8");
        //接收数据
        //getParts() 获取所有的分部数据
        Collection<Part> parts = request.getParts();
        String basePath = this.getServletContext().getRealPath("WEB-INF/upload");
        File dir = new File(basePath);
        if (!dir.exists()){
            dir.mkdirs();
        }

        PrintWriter out = response.getWriter();
        //允许的文件类型
        List<String> allowExts = new ArrayList<>();
        allowExts.add("jpg");
        allowExts.add("png");
        allowExts.add("bmp");

        //遍历集合
        if (parts!=null){
            for (Part part : parts) {
                //判断表单的类型,
                String submittedFileName = part.getSubmittedFileName();
                if (submittedFileName==null){    //说明是输入框
                    String name = part.getName();
                    String value = request.getParameter(name);
                    System.out.println(name+"....."+value);
                }else{
                    //IE获取文件名命题
                    String dis = part.getHeader("Content-Disposition");
                    String filename = dis.substring(dis.lastIndexOf("filename=") + 10, dis.length() - 1);
                    filename = filename.substring(filename.lastIndexOf("\\") + 1);
                    //读取后缀
                    if(filename.equals("")){
                        out.write("没有选择文件<br/>");
                        continue;
                    }
                    String ext = filename.substring(filename.lastIndexOf(".") + 1);   //文件后缀
                    if (!allowExts.contains(ext)){
                        out.write("文件格式不匹配<br/>");
                        continue;
                    }
                    //生成新的文件名
                    String newFileName = UploadUtils.newFileName(filename);
                    //打撒存储
                    String newPath = UploadUtils.makePath(basePath, filename);
                    //保存文件
                    part.write(newPath+File.separator+"/"+newFileName);
                    //删除缓存
                    part.delete();
                    //响应
                    out.write(filename+"上传成功<br/>");
                }

            }
        }
    }
工具类

 //产生新的文件名
    public static String newFileName(String oldFileName){
        UUID uuid = UUID.randomUUID();
        return uuid.toString().replace("-", "")+"_"+oldFileName;
    }

    //产生新的目录
    public static String makePath(String basePath,String oldFileName){
        int hashCode = oldFileName.hashCode();
        int dir1 = hashCode&0xf;
        int dir2 = (hashCode>>4)&0xf;
        String path = basePath+ File.separator+dir1+File.separator+dir2;
        File dir = new File(path);
        if (!dir.exists()){
            dir.mkdirs();
        }
        return path;
    }

    //读取文件列表
    public static void listDir(File dir, HashMap<String,String> hashMap){
        File[] files = dir.listFiles();
        if (files!=null){
            for (File file : files) {
                if (file.isDirectory()){
                    listDir(file, hashMap);
                }else {
                    //key 保存uuid文件名, value 没有uuid的文件名
                    String uuidFileName = file.getName();
                    String fileName = uuidFileName.substring(uuidFileName.indexOf("_") + 1);
                    hashMap.put(uuidFileName, fileName);
                }
            }
        }
    }

下载

文件下载
  • 概念:
    • 首先我们要有一个页面列出上传文目录下的无所有文件
    • 当用户点击文件下载超链接时,就进行下载操作
  • 步骤
    • 获取文件列表
    • 下载处理
获取文件列表
  • 编写servlet 查询的代码
@WebServlet(name = "DownListServlet",value = "/downlist")
public class DownListServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //读取上传的文件列表
        String basePath = this.getServletContext().getRealPath("WEB-INF/upload");
        HashMap<String, String> hashMap = new HashMap<>();
        UploadUtils.listDir(new File(basePath), hashMap);
        //放入域
        request.setAttribute("hashmap", hashMap);
        //转发
        request.getRequestDispatcher("/download.jsp").forward(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request,response);
    }
下载文件列表
  • 编写jsp代码显示页面列表
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>下载页面</title>
</head>
<body>
<%--    <form action="${pageContext.request.contextPath}/download" method="post" enctype="multipart/form-data">--%>
        <h3>下载链接</h3>
        <ul>
            <c:forEach items="${hashmap}" var="entry">
            <li>
<%--                这样写  servlet 要进行解码   URLEncoder.encode(filename, "utf-8");--%>
<%--                <a href="${pageContext.request.contextPath}/download?filename=${entry.key}">${entry.value}</a>--%>
<%--                <c:out value="${entry.value}"></c:out>--%>

<%--            将<c:url>标签将URL格式化为一个字符串,然后存储在一个变量中。
                   这个标签在需要的时候会自动重写URL。    可以免去解码--%>
            <c:url var="myurl" value="/download">
                <c:param name="filename" value="${entry.key}"></c:param>
            </c:url>
                <a href="${myurl}">${entry.value}</a>
            </li>
            </c:forEach>
        </ul>

<%--    </form>--%>
</body>
</html>
下载处理
  • 获取客户端需要下载的文件名,使用流读取后,并返回给浏览器
  • 注意
    • 添加响应头:content-disposition,浏览器保存文件 (不加的话,只是在浏览器显示,不会下载到本地硬盘)
    • 中文文件名需要编码
@WebServlet(name = "DownloadServlet",value = "/download")
public class DownloadServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("utf-8");
        String uuidFileName = request.getParameter("filename");
        System.out.println(uuidFileName);         //测试
        String filename = uuidFileName.substring(uuidFileName.indexOf("_") + 1);
        String basePath = this.getServletContext().getRealPath("WEB-INF/upload");
        String path = UploadUtils.makePath(basePath, filename);       //下载源文件的地址
        //读文件
        FileInputStream fis = new FileInputStream(path+ File.separator+uuidFileName);
        //写文件
        ServletOutputStream os = response.getOutputStream();
        //读取
        byte[] buffer = new byte[1024*4];
        int len;
     //   URLEncoder.encode(filename, "utf-8");   //  url 对中文字符进行编码和解码
        // 下载头 不加不能下载 只是在浏览器端打开
        response.setHeader("Content-Disposition", "attachment;filename="+ URLEncoder.encode(filename, "utf-8"));
        while ((len=fis.read(buffer))!=-1){
                os.write(buffer, 0, len);
        }
    }

项目实践部分代码(添加书籍)

servlet
@WebServlet(name = "AddBookServlet",value = "/addBook")
@MultipartConfig(maxFileSize = 1024*1024*4,maxRequestSize = 1024*1024*20)   //上传书籍图片用
public class AddBookServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("utf-8");

        if (request.getSession().getAttribute("username")==null){
            request.setAttribute("msg", "请先登录");
            request.getRequestDispatcher("/login.html").forward(request, response);
            return;
        }

        BookService bookService = new BookServiceImpl();

        String title = request.getParameter("title");
        String author = request.getParameter("author");
        String publicDate = request.getParameter("publicDate");
        String publisher = request.getParameter("publisher");
        String isbn = request.getParameter("isbn");
        String price = request.getParameter("price");
        String cid = request.getParameter("cid");
        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd");

        Part picture = request.getPart("picture");
        String basePath = this.getServletContext().getRealPath("WEB-INF/bookCovers");
        File dir = new File(basePath);
        if (!dir.exists()){
            dir.mkdirs();
        }
        String newFileName = null;
        if (!picture.equals("")){
            String dis = picture.getHeader("Content-Disposition");
            String filename = dis.substring(dis.lastIndexOf("filename=") + 10, dis.length() - 1);
            filename = filename.substring(filename.lastIndexOf("\\") + 1);
            //获取文件后缀名   没有不包含 .
            String ext = filename.substring(filename.lastIndexOf(".") + 1);
            //产生新的文件名
            UUID uuid = UUID.randomUUID();
            String uu = uuid.toString().replace("-", "");
            newFileName = uu+"."+ext;
            //上传
            picture.write(basePath+File.separator+newFileName);
            //清除缓存
            picture.delete();
        }
        try {
            Book book = new Book(0, title, author, sf.parse(publicDate), publisher, isbn, new BigDecimal(price), newFileName, Integer.parseInt(cid));
            boolean flag = bookService.addBook(book);
            if (!flag){
                request.setAttribute("msg", "添加失败");
                request.getRequestDispatcher("/message.jsp").forward(request, response);
                return;
              }
//            response.sendRedirect(request.getContextPath()+"/query");
            response.sendRedirect(request.getContextPath()+"/pagequery");
        }catch (Exception e){
            request.setAttribute("msg", e);
            request.getRequestDispatcher("/message.jsp").forward(request, response);
        }
    }
jsp

<form action="${pageContext.request.contextPath}/addBook" method="post" enctype="multipart/form-data">
    <h3>添加书籍</h3>
    <table>
        <tr>
            <td>书名</td>
            <td>
                <input type="text" name="title">
            </td>
        </tr>
        <tr>
            <td>作者</td>
            <td>
                <input type="text" name="author">
            </td>
        </tr>
        <tr>
            <td>出版日期</td>
            <td>
                <input type="date" name="publicDate">
            </td>
        </tr>
        <tr>
            <td>出版社</td>
            <td>
                <input type="text" name="publisher">
            </td>
        </tr>

        <tr>
            <td>isbn</td>
            <td>
                <input type="text" name="isbn">
            </td>
        </tr>
        <tr>
            <td>价格</td>
            <td>
                <input type="text" name="price">
            </td>
        </tr>
 <%--       <tr>
            <td>图片</td>
            <td>
                <input type="text" name="picture">
            </td>
        </tr>--%>
        <tr>
            <td>图片</td>
            <td>
                <input type="file" name="picture">
            </td>
        </tr>
        <tr>
            <td>类别</td>
            <td>
                <input type="text" name="cid">
            </td>
        </tr>

        <tr>
            <td><input type="submit" value="提交"></td>
            <td><input type="reset"  value="重置"></td>
        </tr>
    </table>
</form>
        <td>
            <input type="file" name="picture">
        </td>
    </tr>
    <tr>
        <td>类别</td>
        <td>
            <input type="text" name="cid">
        </td>
    </tr>

    <tr>
        <td><input type="submit" value="提交"></td>
        <td><input type="reset"  value="重置"></td>
    </tr>
</table>
```
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值