JavaWeb基于servlet的文件上传与下载

serlvet进行文件上传

文件上传于下载是web应用的常见功能,本文主要书写了servlet的文件上传方法

基于servlet文件上传的方式有两种:

1.基于工具jar包的形式

2.servlet3.0提供的形式

一、使用第三方jar提供的工具类实现servlet文件上传

        文件上传基于form表单实现,就是在一个FORM中提交相应的信息,和之前我们的提交的注册信息之类的表单是不同的,所以要先改变一下FORM的属性,enctype="multipart/form-data“,这个属性告诉服务器,我们是要提交文件了,而不是一个表单。将文件对应的内容以二进制的形式传递给后台

<input type=“file” />这是表单中用来选择上传文件用的,在表单中有这个元素后,会会自动生成一个输入框和一个按钮

我们主要使用两个jar包 commons-fileupload.jar      commons-io.jar

主要使用的如下:

FileItem-------DiskFileItemFactory-----ServletFileUpload 

作用:
FileItem 用来封装表单中的元素和数据。
ServletFileUpload 处理表单数据,将数据封装到 FileItem 对象中。
DiskFileItemFactory FileItem 对象的工厂,可以设定缓冲区大小和存放临时文件目录。
ServletFileUpload 处理上传的文件的数据,优先保存在缓冲区,如果数据超过了缓冲区大小,则保存到硬盘上,存储在DiskFileItemFactory指定目录下的临时文件。数据都接收完后,它再在从临时文件中将数据写入到上传文件目录下的指定文件中,并删除临时文件。

上传页面

通过form表单进行文件上传,需要在form表单中设置enctype="multipart/form-data" 并且将提交方式设置为post


<h3>会员上传资料</h3>
 
<form action="/upload" method="post" enctype="multipart/form-data">
    姓名: <input type="text" name="uname"> <br>
    文件: <input type="file" name="ufile"> <br>
    <input type="submit" value="提交资料">
 </form>

接受上传的servlet服务文件相应doPost方法

//使用FileItem工场类创建相应工场对象
		FileItemFactory factory = new DiskFileItemFactory();
		//创建servlet文件上传对象并将指定工场对象传入
		ServletFileUpload fileUpload = new ServletFileUpload(factory);
		//声明文件集合
		List<FileItem> parseRequest = null;
        //声明其他数据保存的map集合
        hashMap<String,String>map=new HashMap<>();
		try {
			//使用servlet文件上传对象解析请求返回文件集合
			parseRequest = fileUpload.parseRequest(request);

			// 遍历文件对象集合   获取数据
			for (FileItem fileItem : parseRequest) {
			
				// 判断数据类型是不是普通的form表单字段
				if (!fileItem.isFormField()) {
					// 获取上传文件的文件名
					String fileName = fileItem.getName();
					//使用上传文件创建输入流
					InputStream fileStream = fileItem.getInputStream();
					
					// 使用UUID+文件名的方式生成保存文件的名称,避免文件重名
					String realFileName = UUID.randomUUID().toString() + "-" + fileName;
					// 定义保存的父路径
					File fileFatherPath=new File("F://Upload");
					//创建父路径 避免路径不存在保错
					fileFatherPath.mkdirs();
					// 创建要保存的文件
					File file = new File(fileFatherPath, realFileName);	
					// 创建输出流
					OutputStream out = new FileOutputStream(file);
					// 创建字节缓存
					byte[] buffer = new byte[1024];
					int len = -1;
					// 一次读取1kb(1024byte),返回-1表明读取完毕
					while ((len = fileStream.read(buffer)) != -1) {
						// 一次写入1kb(1024byte)
						out.write(buffer, 0, len);
					}
					// 冲刷流资源
					out.flush();
					// 关闭流
					out.close();
					fileStream.close();
				}else{
                    //如果是普通字段获取name与value存储至map集合中
			         map.put(fileItem.getFieldName(), fileItem.getString());
				  
                }
			}

		} catch (Exception e) {
			e.printStackTrace();
		}

多文件上传只需要在input处添加multiple属性 设置file可以选择上传多个文件

 

 

二、servlet3.0提供的源方式

servlet3.0提供的源方式的文件上传无需第三方jar包,但页面请求方式以及请求数据格式相同

Part:主要工具类,从前台获取的上传文件内容流存储位置Servlet3.0将multipart/form-data的POST请求封装成Part,通过Part对上传的文件进行操作,之后再part对象中获取输入流之后通过流操作保存数据

servlet是通过使用@MultipartConfig注解来完成文件的上传(用来标志当前servlet是处理文件上传的servlet)

@MultipartConfig
@WebServlet(name = "FileUploadServlet",urlPatterns = "/upload")
public class FileUploadServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        Part part = request.getPart("ufile");
        //Servlet3.0将multipart/form-data的POST请求封装成Part,通过Part对上传的文件进行操作。
        //Servlet3没有提供直接获取文件名的方法,需要从请求头中解析出来
        //获取请求头,请求头的格式:form-data; name="file"; filename="snmp4j--api.zip"
        String disposition = part.getHeader("Content-Disposition");
        //从请求头中获取文件后缀
        String suffix = disposition.substring(disposition.lastIndexOf("."),disposition.length()-1);
        //随机的生存一个32的字符串 用于避免上传文件同名
        String filename = UUID.randomUUID()+suffix;
        //获取上传的文件名
        InputStream is = part.getInputStream();
        //动态获取服务器的路径
        String serverpath = request.getServletContext().getRealPath("upload");
        new File(serverpath).mkdirs();
        System.out.println(serverpath);
        FileOutputStream fos = new FileOutputStream(serverpath+"/"+filename);
        byte[] bty = new byte[1024];
        int length =0;
        while((length=is.read(bty))!=-1){
            fos.write(bty,0,length);
        }
        fos.close();
        is.close();
    }

多文件上传的方式是通过修改获取part方法的形式实现的

          Collection<Part> parts = request.getParts();
		  for (Part p : parts) {
			.....
		  }

文件下载

就是在响应中设置响应类型之后,以流的形式将文件发送至客户端

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
        // request通过getParameter得到filename这个参数的值
         File f=new File("f://cxk.gif");
​
        //设置content-disposition响应头控制浏览器以下载的形式打开文件,中文文件名要使用URLEncoder.encode方法进行编码,否则会出现文件名乱码
       response.setHeader("content-disposition", "attachment;filename="+URLEncoder.encode("cxk.gif", "UTF-8"));
        FileInputStream fis=new FileInputStream(f);
        BufferedInputStream bis=new BufferedInputStream(fis);
        byte []b=new byte[2048];
        int len=-1;
        ServletOutputStream outputStream = response.getOutputStream();
        while((len=bis.read(b))!=-1) {
            outputStream.write(b,0,len);
        }
        bis.close();
    }

 

 

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值