文件上传

文件上传技术

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;
    }
}
原文地址:https://www.cnblogs.com/boomoom/p/10134349.html