JavaWeb文件上传与下载

JavaWeb文件上传与下载
要实现Web开发的上传功能,通常需要完成两步操作:一是在Web页面中添加上传输入项;二是在Servlet中读取上传文件的数据,保存到数据库,然后从数据库拿到路径,进行下载。

上传大多数情况是通过表单的形式提交给服务器,使用标签。

使用标签需要注意以下两点:

1.必须设置name属性,不然浏览器不会发送上传文件的数据。

2.必须将method属性设置为post,ectype属性设置为“multipart/form-data”类型。
from会被分为两部分:表单字段和上传字段,然后通过FileItemFactory工厂类 将请求消息实体中的每一个项目封装成单独的DiskFileItem (FileItem接口的实现) 对象的任务。

在这里插入图片描述

由于在Servlet直接读取上传数据,并且解析出相应文件数据是一项非常麻烦的工作。为了方便处理上传数据,Apache组织提供了一个开源组件Commons-FileUpload。该组件可以将“multipart/form-data”类型请求的各种表单域解析出来,并实现一个或多个文件上传,同时也可以限制上传文件的大小等内容。其性能十分优异,使用极其简单。
jar下载地址

上传

1.创建一个上传表单

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>up.html</title>
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="this is my page">
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">  
    <!--<link rel="stylesheet" type="text/css" href="./styles.css">-->
  </head>
  <body>
 <form action="UploadServlet3" method="post" enctype="multipart/form-data" >
   id:<input type="text" name="user_id"><br>
   name:<input type="text" name="user_name"><br>
   file:<input type="file" name="file_name"><br>
   <input type="submit" value="提交">
   </form>
  </body>
</html>

2.创建一个Files容器存放文件

package com.it.bean;
import java.io.Serializable;
public class Files  implements Serializable{
	private static final long serialVersionUID = 1L;
	private String f_id;
	private String f_name;
	private String f_path;
	public Files() {
		super();
		// TODO Auto-generated constructor stub
	}
	public Files(String fId, String fName, String fPath) {
		super();
		f_id = fId;
		f_name = fName;
		f_path = fPath;
	}
	public String getF_id() {
		return f_id;
	}
	public void setF_id(String fId) {
		f_id = fId;
	}
	public String getF_name() {
		return f_name;
	}
	public void setF_name(String fName) {
		f_name = fName;
	}
	public String getF_path() {
		return f_path;
	}
	public void setF_path(String fPath) {
		f_path = fPath;
	}
}

3.数据库建表语句

create table users_file(
     f_id  varchar(200) primary key,
     f_name varchar(200),
     f_path varchar(200)
)

4.为了防止文件名重复问题我们存入的时候封装了一个类FileUtil来处理文件路径

package com.it.tools;
import java.util.UUID;
public class FileUtil {
//使用UUID处理文件名
	public static String getRealPath(String parent,String filename){
		String path =parent+"\\"+UUID.randomUUID()+getExt(filename);
		return path;
	}
	//获取后缀名
	public static String getExt(String filename){
		if(filename.lastIndexOf('.')!=-1){
			return filename.substring(filename.lastIndexOf('.'));
		}return "";
	}
}

5.创建上传文件的Servlet

package com.it.controller;
import com.it.bean.Files;
import com.it.service.FilesServices;
import com.it.service.impl.FilesServicesImpl;
import com.it.tools.FileUtil;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
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 java.io.*;
import java.util.List;
import java.util.Map;
@WebServlet(name = "UploadServlet3",urlPatterns = {"/UploadServlet3"})
public class UploadServlet3 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //使用uploadjar包
        //生成对象
        Files files=new Files();
        //生成services
        FilesServices filesServices=new FilesServicesImpl();
        //设置id为系统当前时间
        files.setF_id(String.valueOf(System.currentTimeMillis()));
        request.setCharacterEncoding("utf-8");
        //创建FileItemFactory工厂类     将请求消息实体中的每一个项目封装成单独的DiskFileItem (FileItem接口的实现) 对象的任务
        FileItemFactory fileItemFactory=new DiskFileItemFactory();
        //创建处理上传的核心 servlet servletFileupload
        ServletFileUpload servletFileUpload=new ServletFileUpload(fileItemFactory);
       // 解决上传表单项乱码问题
        servletFileUpload.setHeaderEncoding("utf-8");
        //解析上传文件的multipart/form-data流,返回按照传输顺序解析出的FileItem实例列表
        try {
            List<FileItem> fileItemList=servletFileUpload.parseRequest(request);
            //迭代列表
            for (FileItem fileItem:fileItemList) {
                //表单字段
                if(fileItem.isFormField()){
                    //getFieldName方法用于返回表单标签name属性的值。
                    if(fileItem.getFieldName().equals("user_id")){
                        //获取它对应的值  设置编码格式
                        System.out.println(fileItem.getString("utf-8"));
                    }
                 if(fileItem.getFieldName().equals("user_name")){
                     //获取它对应的值  设置编码格式
                        System.out.println(fileItem.getString("utf-8"));
                    }
                }else{
                    // getName方法用于获得文件上传字段中的文件名
                      files.setF_name(fileItem.getName());
                      //父级目录
                      String parent="d:\\upload";
                      //String path =parent+"\\"+UUID.randomUUID()+getExt(filename);
                      //父级路径+随机名+.后缀名
                      files.setF_path(FileUtil.getRealPath(parent,fileItem.getName()));
                       filesServices.add(files);
                       //将文件写入到指定文件夹下
                    InputStream in= fileItem.getInputStream();
                    OutputStream out=new FileOutputStream(new File(files.getF_path()));
                    //读取上传文件
                    byte b[]=new byte[1024*10];
                    int len=0;
                    while((len=in.read(b))!=-1){
                        //写文件
                        out.write(b);
                    }
                    out.flush();
                    out.close();
                    in.close();
                }
            }
        } catch (FileUploadException e) {
            e.printStackTrace();
        }
    }
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }
}

下载

1.创建展示的servlet

package com.it.controller;

import com.it.bean.Files;
import com.it.service.FilesServices;
import com.it.service.impl.FilesServicesImpl;

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 java.io.File;
import java.io.IOException;
import java.util.List;

@WebServlet(name = "ShowServlet",urlPatterns = {"/ShowServlet"})
public class ShowServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
      response.setCharacterEncoding("utf-8");
        //生成对象
        Files files=new Files();
        //生成services
        FilesServices filesServices=new FilesServicesImpl();
        //查询所有
        List<Files> filesList =filesServices.queryAllFiles(files);
        //存入到request
        request.setAttribute("fileList",filesList);
        //转发
      request.getRequestDispatcher("downLoad.jsp").forward(request,response);
    }
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request,response);
    }
}

2.创建JSP(同步)使用EL表达式,从数据库中遍历文件名,设置为超级链接

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<%--同步遍历--%>
<c:forEach items="${fileList}" var="files" varStatus="i">
    ${i.index+1}.
    <a href="down.do?f_id=${files.f_id}">${files.f_name}</a><br>
</c:forEach>
</body>
</html>

3.创建一个Base64Util类用来重编码
关于Base64Util的作用可以参考:Base64Util的作用

package com.it.tools;
import java.io.UnsupportedEncodingException;
import sun.misc.BASE64Encoder;
public class Base64Util {
	public static String base64EncodeFileName(String fileName) {
		BASE64Encoder base64Encoder = new BASE64Encoder();
		try {
			return "=?UTF-8?B?"
					+ new String(base64Encoder.encode(fileName
							.getBytes("UTF-8"))) + "?=";
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		}
	}
}

3.当点击超级链接时,从数据库获取指定路径

package com.it.controller;
import com.it.bean.Files;
import com.it.service.FilesServices;
import com.it.service.impl.FilesServicesImpl;
import com.it.tools.Base64Util;
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 java.io.*;
import java.net.URLEncoder;
@WebServlet(name = "DownServlet",urlPatterns = {"/down.do"})
public class DownServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    //通过id找到路径   然后下载
        String f_id=request.getParameter("f_id");
        //生成对象
        Files files=new Files();
        files.setF_id(f_id);
        //生成services
        FilesServices filesServices=new FilesServicesImpl();
        //找路径  名字
        Files files1=filesServices.findById(files);
        String files_path=files1.getF_path();
        String files_name=files1.getF_name();
        //设置响应头MIME类型  获取文件的mime
        //MIME映射策略就是在网页中使用哪个应用程序(即插件),打开哪种文件
        //response.setContentType(MIME)的作用是使客户端浏览器,区分不同种类的数据,并根据不同的MIME调用浏览器内不同的程序嵌入模块来处理相应的数据。
         response.setContentType(this.getServletContext().getMimeType(files1.getF_name()));
        //User Agent中文名为用户代理,简称 UA,它是一个特殊字符串头,使得服务器能够识别客户使用的操作系统及版本、CPU 类型、浏览器及版本、浏览器渲染引擎、浏览器语言、浏览器插件等。
       //获得浏览器请求头中的User-Agent
        String agents=request.getHeader("user-agent");
        //判断浏览器的的不同对文件转码,文件名URL  BASE64 重编码    IE  火狐
        if(agents.contains("MSIE")){
            //编码
            files_name= URLEncoder.encode(files_name,"utf-8");
        }else if(agents.contains("Firefox")){
            files_name= Base64Util.base64EncodeFileName(files_name);
        }else{
            files_name=URLEncoder.encode(files_name,"utf-8");
        }
        //设置响应头下载附件格式  下载中文文件名乱码问题
        response.setHeader( "Content-Disposition", "attachment; filename="+files_name);
        //完成下载 先读取后写入
        InputStream in= new FileInputStream((new File(files_path)));
        //服务器给出响应  response
        OutputStream out=response.getOutputStream();
        byte b[]=new byte[1024*10];
        int len=0;
        while((len=in.read(b))!=-1){
            //写入到浏览器默认的下载路径
            out.write(b);
        }
        out.flush();
        out.close();
        in.close();
    }
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    doPost(request, response);
    }
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值