JavaWeb实现上传下载

上传

基本实现思路

  1. 表单设计

    enctype="multipart/form-data"
    
  2. Servlet设计

     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
         	//设置编码
            request.setCharacterEncoding(StandardCharsets.UTF_8.toString());
            response.setContentType("text/html;charset=utf-8");
         	//获取解析器工厂,其中的两个参数分别为内存的缓存大小和缓存的临时存放路径
            DiskFileItemFactory dif=new DiskFileItemFactory(1024*20,new File("C:/temp"));
            //获取解析器
         	ServletFileUpload sfi=new ServletFileUpload(dif);
            try {
                //通过解析器获取List,List中存放的是FileItem
                List<FileItem> items = sfi.parseRequest(request);
                for (FileItem item : items) {
                    //该方法用来判断是否为普通表单
                    if (item.isFormField()){
                        System.out.println(item.getFieldName()+" "+item.getString(StandardCharsets.UTF_8.toString()));
                    }else{
                        //因为个别浏览器的文件名会包含磁盘路径,因此需要先通过判断来截取实际文件名
                        String name=item.getName();
                        int index=name.lastIndexOf("\");
                        if (index!=-1){
                            name=name.substring(index+1);
                        }
                        //为了避免重名,所以为文件重新命名
                        String saveName= CommonsUtils.getUUID()+"_"+name;
                        //获取文件名对象的hashcode
                        int hashCode = name.hashCode();
                        //获取hashcode的16进制表示的字符串
                        String hexString = Integer.toHexString(hashCode);
                        //获取web项目的实际路径信息
                        String root=this.getServletContext().getRealPath("/WEB-INF/files");
                        //设置保存路径:规则为截取字符串的第一个和第二个字符作为路径
                        File file=new File(root,hexString.charAt(0)+"/"+hexString.charAt(1));
                        //该方法可以判断路径是否存在,若路径存在啥也不干,若不存在则创建路径
                        file.mkdirs();
                        //文件的保存路径
                        File saveFile=new File(file,saveName);
                        //保存文件
                        item.write(saveFile);
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
  3. Servlet3.0对上传的支持

    req.setCharacterEncoding("utf-8");
    //可以直接获取参数
    System.out.println(req.getParameter("username"));
    //获取Part对象,以便于对文件的操作
    Part part = req.getPart("pic");
    String header = part.getHeader("Content-Disposition");
    int indexOf = header.lastIndexOf("filename=");
    int start=indexOf+10;
    int end=header.length()-1;
    String filename=header.substring(start,end);        					                //写入文件
    part.write("C:/Users/wu2we/Desktop/java/bookstore/out/artifacts/bookstore_war_exploded/book_img/"+filename);
    

下载

基本实现思路

总结起来就是两头一流:

两头:

  1. Content-Type :用来设置文件的类型,文件类型可以通过this.getServletContext().getMimeType(String s)方法获取到,参数是文件名。
  2. Content-Disposition:用来设置下载方式(弹出下载框),以及文件名,格式固定:attachment;filename=?

一流:即输出流

File file=new File("C:/Users/wu2we/Desktop/jdk-9_汉化版.CHM");
FileInputStream inputStream=new FileInputStream(file);
String mimeType = this.getServletContext().getMimeType("C:/Users/wu2we/Desktop/jdk-9_汉化版.CHM");
//解决编码问题
String newDisposition= DownUtils.filenameEncoding("jdk-9_汉化版.CHM",request);
String disposition="attachment;filename="+newDisposition;
response.setHeader("Content-Type",mimeType);
response.setHeader("Content-Disposition",disposition);
ServletOutputStream stream = response.getOutputStream();
IOUtils.copy(inputStream,stream);
inputStream.close();

文件名的编码问题

解决方案见上方

原文地址:https://www.cnblogs.com/zwscode/p/14284057.html