• 文件上传


    文件上传技术

    Servlet3.0:注解开发,文件上传,异步请求。
    JSPSmartUpload:嵌入到JSP中完成文件上传.主要用于Model1年代的。
    FileUpload:Apache的文件上传组件。
    Struts2:底层是FileUpload。

    Servlet3.0

    Servlet3.0与Servlet2.5提供了三个新特性:
    注解开发:方便
    文件上传:有些API不是特别全.
    异步请求:

    /**
     * 异步请求的Servlet
     */
    @WebServlet(urlPatterns="/AsyncServlet",asyncSupported=true)
    public class AsyncServlet extends HttpServlet {
        private static final long serialVersionUID = 1L;
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            AsyncContext context = request.startAsync(request, response);
            context.start(new MyRunnable(context));
            
            for(int i = 1;i<=10;i++){
                System.out.println(i);
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            doGet(request, response);
        }
    }
    
    class MyRunnable implements Runnable{
        private AsyncContext context;
        public MyRunnable(AsyncContext context) {
            this.context = context;
        }
        @Override
        public void run() {
            for(char i='a';i<='z';i++){
                try {
                    context.getResponse().getWriter().println(i);
                    Thread.sleep(100);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }
    Servlet3.0异步请求

    Servlet3.0的注解开发

    @WebServlet
    @WebListener
    @WebFilter

    文件上传的要素

    表单的提交的方式必须是POST。
    表单中需要有文件上传的表单元素:这个元素这个元素必须有name属性和值:<input type=”file” name=”upload”>。
    表单的enctype属性的值必须是multipart/form-data。

    文件上传问题解决

    文件重名

    使用UUID作为随机的文件名。
    真实文件名和UUID存入数据表。

    文件上传的目录分离

    按时间分;
    按数量分;
    按用户分;
    按目录分离算法分:
      使用唯一文件名.hashCode(); -- 得到一个代表当前这个文件的int类型值。
      int类型占4个字节32位.可以让hashCode值&0xf; 得到一个int值,用这个int值作为一级目录。
      让hashCode右移4位 &0xf ;得到一个int值,用这个int值作为二级目录.依次类推。

    代码实现

    1:设置一个文件上传页面.
    2:点击提交,提交到Servlet中.
      没有设置enctype属性的时候:只能获得文件的名称,而没有文件内容.
      设置enctype属性为multipart/form-data:获得到文件名及文件内容.
    3:在Servlet中接收参数.
    4:获得服务器的文件上传的路径.
    5:通过流写到该路径下就OK了.

    package com.boomoom.upload;
    
    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    
    import javax.servlet.ServletException;
    import javax.servlet.annotation.MultipartConfig;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.Part;
    
    import com.boomoom.utils.UUIDUtils;
    import com.boomoom.utils.UploadUtils;
    
    /**
     * 文件上传的Servlet
     */
    @WebServlet("/UploadServlet")
    @MultipartConfig
    public class UploadServlet extends HttpServlet {
        private static final long serialVersionUID = 1L;
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            // 接收普通数据:
            request.setCharacterEncoding("UTF-8");
            String filedesc = request.getParameter("filedesc");
            System.out.println("文件描述"+filedesc);
            // 接收文件:
            Part part = request.getPart("upload");
            
            long size = part.getSize();// 获得文件大小:
            System.out.println("文件大小:"+size);
            String name = part.getName();
            System.out.println("文件表单中的name属性的名称"+name);
            // 获得文件名:
            String header = part.getHeader("Content-Disposition");
            int idx = header.lastIndexOf("filename="");
            String fileName = header.substring(idx+10, header.length()-1);
            System.out.println("文件名:"+fileName);
            // 获得文件内容:
            InputStream is = part.getInputStream();
            // 获得upload的路径:
            String path = this.getServletContext().getRealPath("/upload");
            // 获得文件的唯一文件名:
            String uuidFileName = UUIDUtils.getUUIDFileName(fileName);
            String realPath = path+UploadUtils.getPath(uuidFileName);
            File file = new File(realPath);
            if(!file.exists()){
                file.mkdirs();
            }
            OutputStream os = new FileOutputStream(realPath+"/"+uuidFileName);
            byte[] b = new byte[1024];
            int len = 0;
            while((len = is.read(b))!=-1){
                os.write(b, 0, len);
            }
            is.close();
            os.close();
        }
    
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            doGet(request, response);
        }
    
    }
    package com.boomoom.utils;
    
    import java.util.UUID;
    
    public class UUIDUtils {
    
        public static String getUUID(){
            return UUID.randomUUID().toString().replace("-", "");
        }
        
        public static String getUUIDFileName(String fileName){
            return UUID.randomUUID().toString().replace("-", "")+"_"+fileName;
        }
    }
    UUIDUtils
    package com.boomoom.utils;
    
    public class UploadUtils {
    
        public static String getPath(String uuidFileName){
            // 使用唯一文件名.hashCode();
            int code1 = uuidFileName.hashCode();
            int d1 = code1 & 0xf; // 获得到1级目录.
            int code2 = code1 >>> 4;
            int d2 = code2 & 0xf; // 获得到2级目录.
            return "/"+d1+"/"+d2;
        }
    }
  • 相关阅读:
    上传图片并压缩
    一张图教会你es6
    字符串生成二维码
    city-picker城市选择,三级联动
    jquery本地文件
    前端颜色选择器
    某音乐api
    js正则那些事
    Android判断网络是否打开,并打开设置网络界面
    execute、executeQuery和executeUpdate之间的区别 转
  • 原文地址:https://www.cnblogs.com/boomoom/p/10134349.html
Copyright © 2020-2023  润新知