Javaweb实现上传下载文件的多种方法

 更新时间:2016年10月25日 08:39:35   作者:升少  
本篇文章主要介绍了Javaweb实现上传下载文件,有多种实现方式,需要的朋友可以参考下。

在Javaweb中,上传下载是经常用到的功能,对于文件上传,浏览器在上传的过程中是以流的过程将文件传给服务器,一般都是使用commons-fileupload这个包实现上传功能,因为commons-fileupload依赖于commons-io这个包,所以需要下载这两个包commons-fileupload-1.2.1.jar和commons-io-1.3.2.jar。

1、搭建环境

创建Web项目,将包导入到项目lib下

2、实现文件上传

(第一种上传的方法)

新建upload.jsp页面

<%@ page language="java" contentType="text/html; charset=UTF-8"
  pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>upload file</title>
</head>
<body>
  <!--这里的<%=request.getContextPath()%>是表示项目的绝对路径,也就是说不管你以后将项目拷贝到哪个位置,它都会找到准确的路径 -->
  <form action="<%=request.getContextPath()%>/uploadServlet" enctype="multipart/form-data" method="post">
    <span>选择文件:</span><input type="file" name="file1">
    <input type="submit" value="上传">
  </form>
</body>
</html>

新建处理文件上传的Servlet

package com.load;

import java.io.File;
import java.io.IOException;
import java.util.List;
import javax.servlet.ServletContext;
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;
@WebServlet("/uploadServlet")
public class uploadServlet extends HttpServlet {
  private static final long serialVersionUID = 1L;
  public uploadServlet() {
    super();
  }
  /* fileupload 包中, HTTP 请求中的复杂表单元素都被看做一个 FileItem 对象;
   * FileItem 对象必须由 ServletFileUpload 类中的 parseRequest() 方法解析 HTTP 请求
   * (即被包装之后的 HttpServletRequest 对象)出来,即分离出具体的文本表单和上传文件
   * */
  protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    //通过isMultipartContent()方法:分析请求里面是不是有文件上的请求,
    boolean isMultipart = ServletFileUpload.isMultipartContent(request);
    if(isMultipart){
      //创建可设置的磁盘节点工厂
      DiskFileItemFactory factory = new DiskFileItemFactory();
      //获取请求的上下文信息
      ServletContext servletContext = request.getServletContext();
      //缓存目录,每个服务器特定的目录
      File repository = (File) servletContext.getAttribute("javax.servlet.context.tempdir");
      //设置服务器的缓存目录
      factory.setRepository(repository);
      //ServletFileUpload 对象的创建需要依赖于 FileItemFactory 
      //工厂将获得的上传文件 FileItem 对象保存至服务器硬盘,即 DiskFileItem 对象。
      ServletFileUpload upload = new ServletFileUpload(factory);
      try {
        //解析即被包装之后的 HttpServletRequest对象,既是分离文本表单和上传文件(http请求会被包装为HttpServletRequest)
        List<FileItem> items = upload.parseRequest(request);
        for(FileItem item:items){
          String fieldName = item.getFieldName();  
          String fileName = item.getName();
          String contentType = item.getContentType();
          boolean isInMemory = item.isInMemory();
          long sizeInBytes = item.getSize();
          //实例化一个文件
          //request.getRealPath(获取真实路径)
          File file = new File(request.getRealPath("/")+"/loads"+fileName.substring(fileName.lastIndexOf("\\")+1,fileName.length()));
          item.write(file);
        }
      } catch (FileUploadException e) {
        e.printStackTrace();
      } catch (Exception e) {
        
        e.printStackTrace();
      }
    }
  }

  protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    doGet(request, response);
  }
}

(第二种上传的方法)

新建Jsp页面(同上,只是路径改变下)

<%@ page language="java" contentType="text/html; charset=UTF-8"
  pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>upload file</title>
</head>
<body>
  <!--这里的<%=request.getContextPath()%>是表示项目的绝对路径,也就是说不管你以后将项目拷贝到哪个位置,它都会找到准确的路径 -->
  <form action="<%=request.getContextPath()%>/uploadservlet1" enctype="multipart/form-data" method="post">
    <span>选择文件:</span><input type="file" name="file1">
    <input type="submit" value="上传">
  </form>
</body>
</html>

建立Servlet处理上传

package com.load;

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;
@WebServlet("/uploadservlet1")
@MultipartConfig(location="")
public class uploadservlet1 extends HttpServlet {
  private static final long serialVersionUID = 1L;
  public uploadservlet1() {
    super();
  }

  protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    response.setContentType("text/html;charset=UTF-8");
    request.setCharacterEncoding("utf-8");
    
    //取得上传文件,读取文件
    Part part = request.getPart("file1");
    //定义一个变量去接收文件名
    String filename = null;
    //Content-Disposition: 就是当用户想把请求所得的内容存为一个文件的时候提供一个默认的文件名
    //Content-Disposition:告诉浏览器以下载的方式打开文件
    for (String content : part.getHeader("content-disposition").split(";")) {
      System.out.println(content);
      //取得文件名
      if (content.trim().startsWith("filename")) {
        //截取文件名
        filename = content.substring(
            content.indexOf('=') + 1).trim().replace("\"", "");
      }
    }
    //输出流
     OutputStream out = null;
     //输入流
     InputStream filecontent = null;
     //File.separator 取得系统的分割线等数据
     out = new FileOutputStream(new File("e:/loads" + File.separator + filename));
     int read;
    //获得一个输入流
    filecontent = part.getInputStream();
    final byte[] bytes = new byte[1024];
    
    while ((read = filecontent.read(bytes)) != -1) {
      out.write(bytes, 0, read);
    }
    System.out.println("New file " + filename + " created at " + "/loads");
  }

  protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    // TODO Auto-generated method stub
    doGet(request, response);
  }
}

(第三种上传的方法)

这里使用的是jspSmartUpload包上传下载,笔者认为这种上传下载较为简单,但是好像不是很多人用,不懂。

创建HTML页面

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>上传文件</title>
</head>
<body>
  <p> </p>
  <p align="center">上传文件选择</p>
  <form method="post" Action="../DouploadServlet" enctype="multipart/form-data">
    <table width="75%" border="1" align="center">
      <tr><td><div align="center">
        1.<input type="file" name="file1" >
      </div></td></tr>
        <tr><td><div align="center">
        2.<input type="file" name="file2" >
      </div></td></tr>
        <tr><td><div align="center">
        3.<input type="file" name="file3" >
      </div></td></tr>
        <tr><td><div align="center">
        <input type="submit" name="Submit" value="上传他">
      </div></td></tr>
    </table>
  </form>
</body>
</html>

创建Servlet处理上传文件

package com.load;

import java.io.IOException;
import java.io.PrintWriter;

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 javax.servlet.jsp.JspFactory;
import javax.servlet.jsp.PageContext;

import com.jspsmart.upload.File;
import com.jspsmart.upload.SmartUpload;
import com.jspsmart.upload.SmartUploadException;
@WebServlet("/DouploadServlet")
public class DouploadServlet extends HttpServlet {
  private static final long serialVersionUID = 1L;
    
  public DouploadServlet() {
    super();
  }

  protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    response.setContentType("text/html;charset=UTF-8");
    PrintWriter out = response.getWriter();
    //新建一个智能上传对象
    SmartUpload su = new SmartUpload();
    /*
     * PageContext pageContext;
      HttpSession session;
      ServletContext application;
      ServletConfig config;
      JspWriter out;
      Object page = this;
      HttpServletRequest request, 
      HttpServletResponse response
      其中page对象,request和response已经完成了实例化,而其它5个没有实例化的对象通过下面的方式实例化
      pageContext = jspxFactory.getPageContext(this, request, response,null, true, 8192, true);
     */
    //通过Jsp工厂类获取上下文环境
    PageContext pagecontext = JspFactory.getDefaultFactory().getPageContext(this, request, response, null, true, 8192, true);
    //上传初始化
    su.initialize(pagecontext);

    //上传文件
    try {
      su.upload();
      //将上传文件保存到指定目录
      int count = su.save("/share");
      out.println(count+"个文件上传成功!<br>"+su.toString());
    } catch (SmartUploadException e) {
      e.printStackTrace();
    }
    
    //逐个提取上传文件信息
    for(int i=0;i<su.getFiles().getCount();i++){
      File file = su.getFiles().getFile(i);
      //如果文件不存在
      if(file.isMissing()) continue;
      
      //显示当前文件信息
      out.println("<table border=1>");
      out.println("<tr><td>表单项名(FieldName)</td></td>"+file.getFieldName()+"</td></tr>");
      out.println("<tr><td>文件长度</td><td>"+file.getSize()+"</td></tr>");
      out.println("<tr><td>文件名</td><td>"+file.getFileName()+"</td></tr>");
      out.println("<tr><td>文件扩展名</td><td>"+file.getFileExt()+"</td></tr>");
      out.println("<tr><td>文件全名</td><td>"+file.getFilePathName()+"</td></tr>");
      out.println("</table><br>");
    }
  }

  /**
   * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
   */
  protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    // TODO Auto-generated method stub
    doGet(request, response);
  }

}

注意:代码 int count = su.save("/share");表示你需要先建个文件夹,所以你可以先在Webcontent建立一个,然后将项目取消部署,再重新部署进去之后就会在运行那边建立起一个文件夹了!

或者你可以直接找到运行的路径,然后建立share文件夹。

3、实现文件下载

(第一种文件下载)

注意:该代码是直接访问Servlet类的

package com.load;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


//直接使用Http://localhost:8080/Test1/download进行下载,但是这个有缺陷,如果下载文件名中有中文,就会变成乱码现象!
@WebServlet("/download")
public class download extends HttpServlet {
  private static final long serialVersionUID = 1L;

  public download() {
    super();
  }
  protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
     response.setContentType("text/plain;charset=utf-8");
     response.setCharacterEncoding("utf-8");
     response.setHeader("Location","中文.txt");
     response.setHeader("Content-Disposition", "attachment; filename=" + "账号.txt");
     OutputStream outputStream = response.getOutputStream();
     InputStream inputStream = new FileInputStream("E:/loads"+"/账号.txt");
     byte[] buffer = new byte[1024];
     int i = -1;
     while ((i = inputStream.read(buffer)) != -1) {
     outputStream.write(buffer, 0, i);
     }
     outputStream.flush();
     outputStream.close();
  }
  protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    doGet(request, response);
  }

}

(第二种下载方法)

新建jsp页面选择下载

<%@ page language="java" contentType="text/html; charset=UTF-8"
  pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>下载</title>
</head>
<body>
  <a href="../DoDownloadServlet?filename=呵呵.txt">点击下载</a>
</body>
</html>

创建Servlet类进行下载(注意:该下载如果文件名是中文的话,一样会出现乱码现象)

package com.load;

import java.io.BufferedInputStream;
import java.io.File;
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 javax.servlet.jsp.JspFactory;
import javax.servlet.jsp.PageContext;

import org.hsqldb.lib.StringUtil;

import com.jspsmart.upload.SmartUpload;
import com.jspsmart.upload.SmartUploadException;

@WebServlet("/DoDownloadServlet")
public class DoDownloadServlet extends HttpServlet {
  private static final long serialVersionUID = 1L;

  public DoDownloadServlet() {
    super();
  }

  protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    //得到下载文件的名称
    //String filename = request.getParameter("filename");
    //String filename = new String(FileName.getBytes("iso8859-1"),"UTF-8");
    //新建SmartUpload对象
    SmartUpload su = new SmartUpload();
    PageContext pagecontext = JspFactory.getDefaultFactory().getPageContext(this, request, response, null, true, 8192, true);
    //上传初始化
    su.initialize(pagecontext);
    //设置禁止打开该文件
    su.setContentDisposition(null);
    //下载文件
    try {
      su.downloadFile("/listener/"+filename);
    } catch (SmartUploadException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
  }

  protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    doGet(request, response);
  }
}

(第三种下载的方法)

同上的jsp页面代码,这里就不再重复了。

新建Serlvet类,实现下载功能(注意:这里文件名就算是中文名,也不会出现乱码问题了!)

package com.load;

import java.io.BufferedInputStream;
import java.io.File;
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 javax.servlet.jsp.JspFactory;
import javax.servlet.jsp.PageContext;

import org.hsqldb.lib.StringUtil;

import com.jspsmart.upload.SmartUpload;
import com.jspsmart.upload.SmartUploadException;

@WebServlet("/DoDownloadServlet")
public class DoDownloadServlet extends HttpServlet {
  private static final long serialVersionUID = 1L;

  public DoDownloadServlet() {
    super();
  }


  protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    //获得文件名称
    String path1 = request.getParameter("filename");
    //获得路径名称
    String path = request.getSession().getServletContext().getRealPath("/listener/"+path1);
     // path是根据日志路径和文件名拼接出来的
     File file = new File(path);
     String filename = file.getName();
    try {
       //判断是否是IE11
       Boolean flag= request.getHeader("User-Agent").indexOf("like Gecko")>0;
      //IE11 User-Agent字符串:Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko
      //IE6~IE10版本的User-Agent字符串:Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.0; Trident/6.0)
        if (request.getHeader("User-Agent").toLowerCase().indexOf("msie") >0||flag){
          filename = URLEncoder.encode(filename, "UTF-8");//IE浏览器
        }else {
        //先去掉文件名称中的空格,然后转换编码格式为utf-8,保证不出现乱码,
        //这个文件名称用于浏览器的下载框中自动显示的文件名
        filename = new String(filename.replaceAll(" ", "").getBytes("UTF-8"), "ISO8859-1");
        //firefox浏览器
        //firefox浏览器User-Agent字符串: 
        //Mozilla/5.0 (Windows NT 6.1; WOW64; rv:36.0) Gecko/20100101 Firefox/36.0
        } InputStream fis = new BufferedInputStream(new FileInputStream(path));
        byte[] buffer;
        buffer = new byte[fis.available()];
         fis.read(buffer);
         fis.close();
         response.reset();
         response.addHeader("Content-Disposition", "attachment;filename=" +filename);
         response.addHeader("Content-Length", "" + file.length());
         OutputStream os = response.getOutputStream();
         response.setContentType("application/octet-stream");
         os.write(buffer);// 输出文件
         os.flush();
         os.close();
       } catch (IOException e) {
        e.printStackTrace();
       }
        System.out.println(filename);
  }

  protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    doGet(request, response);
  }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • 详解Java中异步转同步的六种方法

    详解Java中异步转同步的六种方法

    针对应用中异步调用,能不能像同步调用一样立刻获取到命令的执行结果,如何实现异步转同步?不要担心,本文就来为大家详细讲讲Java中异步转同步的六种方法,感兴趣的可以了解一下
    2022-06-06
  • SpringBoot 动态定时器的使用方法

    SpringBoot 动态定时器的使用方法

    这篇文章主要介绍了SpringBoot 动态定时器的使用方法,非常不错,具有一定的参考借鉴借鉴价值,需要的朋友可以参考下
    2018-05-05
  • Java中字符串和byte数组之间的简单转换方法

    Java中字符串和byte数组之间的简单转换方法

    这篇文章主要给大家介绍了关于Java中字符串和byte数组之间的简单转换方法,Java中将String类型转换为byte[]类型,可以使用String的getBytes()方法,还有很多其他的办法,需要的朋友可以参考下
    2023-08-08
  • java 两阶段终止线程的正确做法

    java 两阶段终止线程的正确做法

    这篇文章主要给大家分享了java 两阶段终止线程的正确做法,文章列举出错误的做法与正确做法做对比,具有一定的参考价值,需要的小伙伴可以参考一下,希望对你有所帮助
    2021-12-12
  • Java中常用缓存Cache机制的实现

    Java中常用缓存Cache机制的实现

    这篇文章主要介绍了Java中常用缓存Cache机制的实现代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-10-10
  • JavaMail实现邮件发送的方法

    JavaMail实现邮件发送的方法

    这篇文章主要介绍了JavaMail实现邮件发送的方法,实例分析了java实现邮件发送的相关技巧,非常具有实用价值,需要的朋友可以参考下
    2015-04-04
  • SpringMVC实现用户登录全过程

    SpringMVC实现用户登录全过程

    这篇文章主要介绍了SpringMVC实现用户登录全过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-09-09
  • 如何利用Retrofit+RxJava实现网络请求的异常处理

    如何利用Retrofit+RxJava实现网络请求的异常处理

    这篇文章主要介绍了如何利用Retrofit+RxJava实现网络请求的异常处理,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2019-04-04
  • 解决spring boot 配置文件后缀的一个坑

    解决spring boot 配置文件后缀的一个坑

    这篇文章主要介绍了spring boot 配置文件后缀的一个坑,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-09-09
  • JAVA序列化Serializable及Externalizable区别详解

    JAVA序列化Serializable及Externalizable区别详解

    这篇文章主要介绍了JAVA序列化Serializable及Externalizable区别详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-07-07

最新评论