博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
20160420javaweb之文件上传和下载
阅读量:6378 次
发布时间:2019-06-23

本文共 12454 字,大约阅读时间需要 41 分钟。

一、文件上传

1.提供表单允许用户通过表单选择文件进行上传
表单必须是POST提交
文件输入框必须有name属性,只有有name属性的输入项浏览器才会进行提交
需要设置enctype属性值为multipart/form-data

POST /Day15/upload.jsp HTTP/1.1

Accept: text/html, application/xhtml+xml, */*
Referer: http://localhost/Day15/upload.jsp
Accept-Language: zh-CN
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)
Content-Type: multipart/form-data; boundary=---------------------------7de1e62806e0
Accept-Encoding: gzip, deflate
Host: localhost
Content-Length: 394
Connection: Keep-Alive
Cache-Control: no-cache
Cookie: JSESSIONID=818C14110CA7BFD1FC90610866A220E8

-----------------------------7de1e62806e0

Content-Disposition: form-data; name="description1"

xxxx

-----------------------------7de1e62806e0
Content-Disposition: form-data; name="description2"

zzzz

-----------------------------7de1e62806e0
Content-Disposition: form-data; name="file1"; filename="ip.txt"
Content-Type: text/plain

192

-----------------------------7de1e62806e0--

2.在Servlet中将上传的文件保存在服务器的硬盘中

DiskFileItemFactory
public DiskFileItemFactory(int sizeThreshold, java.io.File repository)
public DiskFileItemFactory()
public void setSizeThreshold(int sizeThreshold) --用来设定内存缓冲区的大小,默认是10k
public void setRepository(java.io.File repository) --设定临时文件夹的大小

ServletFileUpload

boolean isMultipartContent(HttpServletRequest request) 判断上传表单是否为multipart/form-data类型
List parseRequest(HttpServletRequest request) 解析request对象,并把表单中的每一个输入项包装成一个fileItem 对象,并返回一个保存了所有FileItem的list集合。
setFileSizeMax(long fileSizeMax) 设置单个上传文件的最大值
setSizeMax(long sizeMax) 设置上传文件总量的最大值
setHeaderEncoding(java.lang.String encoding) 设置编码格式,解决上传文件名乱码问题
setProgressListener(ProgressListener pListener) 实时监听文件上传状态
FileItem
boolean isFormField() 判断FileItem是一个文件上传对象还是普通表单对象
示例代码:

<%@ page language="java" contentType="text/html; charset=UTF-8"    pageEncoding="UTF-8"%>
Insert title here

文件上传


描述信息1:
描述信息2:
package com.dzq.web;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.util.List;import javax.servlet.ServletException;import javax.servlet.annotation.WebServlet;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;import com.dzq.utils.IOUtils;@WebServlet("/UploadFileServlet")public class UploadFileServlet extends HttpServlet {    private static final long serialVersionUID = 1L;              protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {        /*InputStream is=request.getInputStream();        byte[] bs=new byte[1024];        int i=0;        while((i=is.read(bs))!=-1){            System.out.write(bs,0,i);        }        is.close();*/                try {            //1.创建工厂            DiskFileItemFactory factory =new DiskFileItemFactory();            //2.生产文件上传核心类            ServletFileUpload fileupload=new ServletFileUpload(factory);            //3.利用文件上传核心类解析request            List
list=fileupload.parseRequest(request); //4.遍历所有的fileitem for(FileItem item:list){ if(item.isFormField()){ //当前是普通字段项 String name=item.getFieldName(); String value=item.getString(); System.out.println(name+":"+value); }else{ //当前是一个文件上传项 String filename=item.getName(); InputStream in=item.getInputStream(); OutputStream out=new FileOutputStream(this.getServletContext().getRealPath("/upload"+filename)); IOUtils.In2Out(in, out); IOUtils.close(in, out); } } } catch (Exception e) { e.printStackTrace(); } } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); }}
package com.dzq.utils;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;public class IOUtils {   private IOUtils(){          }      public static void In2Out(InputStream in,OutputStream out) throws IOException{       byte[] bs=new byte[1024];       int i=0;       while ((i=in.read(bs))!=-1) {        out.write(bs,0,i);    }   }      public static void close(InputStream in,OutputStream out){       if(in!=null){           try {            in.close();        } catch (IOException e) {            e.printStackTrace();        }finally{            in=null;        }       }              if(out!=null){           try {            out.close();        } catch (IOException e) {            e.printStackTrace();        }finally{            out=null;        }       }   }}

 

如果是一个普通字段项可以调用:
String getFieldName() 获得普通表单对象的name属性
String getString(String encoding) 获得普通表单对象的value属性,可以用encoding进行编码设置
如果是一个文件上传项:
String getName() 获得上传文件的文件名(有些浏览器会携带客户端路径)
InputStream getInputStream() 获得上传文件的输入流
delete() 在关闭FileItem输入流后,删除临时文件

文件存放应该注意的问题:
1.upload文件夹和temp文件夹都要放在web-inf目录下保护起来,防止上传入侵和访问其他用户上传资源的问题
2.文件名要拼接uuid保证唯一
3.文件要分目录存储保证同一目录下不要有过多的文件,分目录的算法有很多,介绍了一种根据hash值分目录算法

 

文件上传的一些细节:

package com.itheima.web;import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.math.BigDecimal;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.ProgressListener;import org.apache.commons.fileupload.FileUploadBase.FileSizeLimitExceededException;import org.apache.commons.fileupload.disk.DiskFileItemFactory;import org.apache.commons.fileupload.servlet.ServletFileUpload;import com.itheima.util.IOUtils;public class UploadServlet extends HttpServlet {    public void doGet(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {        response.setContentType("text/html;charset=utf-8");        try{            //1.创建工厂            DiskFileItemFactory factory = new DiskFileItemFactory();            factory.setSizeThreshold(100*1024);            factory.setRepository(new File(this.getServletContext().getRealPath("WEB-INF/temp")));            //2.生产文件上传核心类            ServletFileUpload fileUpload = new ServletFileUpload(factory);                        //--检查是否是正确的文件上传表单            if(!fileUpload.isMultipartContent(request)){                throw new RuntimeException("请用正确的表单进行上传!");            }            //--设置文件上传的大小限制//            fileUpload.setFileSizeMax(1024*1024*100);//单个文件不大于10M//            fileUpload.setSizeMax(1024*1024*100);//总大小不大于100M                        //--设置编码集,解决上传文件名的乱码问题            fileUpload.setHeaderEncoding("utf-8");                        //--设置文件上传监听            fileUpload.setProgressListener(new ProgressListener(){                Long beginTime = System.currentTimeMillis();                public void update(long bytesRead, long contentLength, int items) {                    BigDecimal br = new BigDecimal(bytesRead).divide(new BigDecimal(1024),2,BigDecimal.ROUND_HALF_UP);                    BigDecimal cl = new BigDecimal(contentLength).divide(new BigDecimal(1024),2,BigDecimal.ROUND_HALF_UP);                    System.out.print("当前读取的是第"+items+"个上传项,总大小"+cl+"KB,已经读取"+br+"KB");                    //剩余字节数                    BigDecimal ll = cl.subtract(br);                    System.out.print("剩余"+ll+"KB");                    //上传百分比                    BigDecimal per = br.multiply(new BigDecimal(100)).divide(cl,2,BigDecimal.ROUND_HALF_UP);                    System.out.print("已经完成"+per+"%");                    //上传用时                    Long nowTime = System.currentTimeMillis();                    Long useTime = (nowTime - beginTime)/1000;                    System.out.print("已经用时"+useTime+"秒");                    //上传速度                    BigDecimal speed = new BigDecimal(0);                    if(useTime!=0){                        speed = br.divide(new BigDecimal(useTime),2,BigDecimal.ROUND_HALF_UP);                    }                    System.out.print("上传速度为"+speed+"KB/S");                    //大致剩余时间                    BigDecimal ltime = new BigDecimal(0);                    if(!speed.equals(new BigDecimal(0))){                        ltime = ll.divide(speed,0,BigDecimal.ROUND_HALF_UP);                    }                    System.out.print("大致剩余时间为"+ltime+"秒");                                        System.out.println();                }                            });                        //3.利用文件上传核心类解析request            List
list = fileUpload.parseRequest(request); //4.遍历所有的FileItem for(FileItem item : list){ if(item.isFormField()){ //当前是一个普通的字段项 String name = item.getFieldName(); String value = item.getString("utf-8"); System.out.println(name+":"+value); }else{ //当前是一个文件上传项 String filename = item.getName(); String uuidName = UUID.randomUUID().toString()+"_"+filename; int hash = uuidName.hashCode(); String hashStr = Integer.toHexString(hash); char [] hss = hashStr.toCharArray(); String path = this.getServletContext().getRealPath("WEB-INF/upload"); for(char c : hss){ path+="/"+c; } new File(path).mkdirs(); InputStream in = item.getInputStream(); OutputStream out = new FileOutputStream(new File(path,uuidName)); IOUtils.In2Out(in, out); IOUtils.close(in, out); //--删除临时文件 item.delete(); } } }catch (FileSizeLimitExceededException e) { response.getWriter().write("单个文件不超过10M,总大小不超过100M!"); return; }catch (Exception e) { e.printStackTrace(); throw new RuntimeException(e); } } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); }}

二、文件下载

response.setHeader("Content-Disposition", "attachment;filename="+URLEncoder.encode(filename,"utf-8"));
response.setContentType(this.getServletContext().getMimeType(filename));//MIME类型

 

下载示例源码:

package com.dzq.web;import java.io.FileInputStream;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.net.URLEncoder;import javax.servlet.ServletException;import javax.servlet.annotation.WebServlet;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import com.dzq.utils.IOUtils;@WebServlet("/DownServlet")public class DownServlet extends HttpServlet {    private static final long serialVersionUID = 1L;              protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {        //1.获取要下载的资源的名称             String filename = request.getParameter("file");        response.setHeader("Content-Disposition", "attachment;filename="+URLEncoder.encode(filename,"utf-8"));        response.setContentType(this.getServletContext().getMimeType(filename));//MIME类型                InputStream in = new FileInputStream(this.getServletContext().getRealPath("/"+filename));        OutputStream out = response.getOutputStream();        IOUtils.In2Out(in, out);        IOUtils.close(in, null);        //2.读取资源            }        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {        doGet(request, response);    }}

 

转载于:https://www.cnblogs.com/xiaoduc-org/p/5411881.html

你可能感兴趣的文章
Java8 函数式编程之函数接口(下)
查看>>
【本人秃顶程序员】MySQL 全表 COUNT(*) 简述
查看>>
centos7中使用febootstrap自制一个基础的centos 7.2的docker镜像
查看>>
C#开发Unity游戏教程之判断语句
查看>>
安装 SharePoint Server 2007
查看>>
springmvc mybatis 调用sql , 转成json
查看>>
linux centos 7 网卡突然不能上网异常解决
查看>>
授之以渔-运维平台发布模块一(Jenkins篇)
查看>>
DedeCMS操作基础(一)
查看>>
实现MySQL允许远程连接
查看>>
Java Outputstream to String
查看>>
RS232C串口通信接线方法(三线制)
查看>>
Android 自定义View属性相关细节
查看>>
type already defined error in Eclipse
查看>>
OSA 安装
查看>>
先安装.Framework然后再安装IIS,ASP.NET程序不能运行
查看>>
NPOI Excel下拉项生成设置
查看>>
360该不该拍?
查看>>
用Xib创建控制器
查看>>
oracle的sqlplus和dos的中文乱码问题
查看>>