Java中使用fileupload组件实现文件上传功能的实例代码

 更新时间:2017年05月19日 14:42:44   作者:msidolphin  
这篇文章主要介绍了Java中使用fileupload组件实现文件上传功能的实例代码,需要的朋友可以参考下

使用fileupload组件的原因:

Request对象提供了一个getInputStream()方法,通过这个方法可以读取到客户端提交过来的数据,但是由于用户可能会同时上传多个文件,在servlet中编程解析这些上传数据是一件非常麻烦的工作。为方便开发人员处理文件上传数据,Apache开源组织提供了一个用来处理表单文件上传的一个开源组件(Commons-fileupload),该组件性能优异,并且使用及其简单,可以让开发人员轻松实现web文件上传功能。

使用Commons-fileupload组件实现文件上传,需要导入该组件相应的支撑jar包:

commons-fileupload和connons-io(commons-upload组件从1.1版本开始,它的工作需要commons-io包的支持)

FileUpload组件工作流程:

这里写图片描述

相应的代码框架为:

package pers.msidolphin.uploadservlet.web;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
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.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
/**
 * Servlet implementation class UploadServlet
 */
public class UploadServlet extends HttpServlet {
 private static final long serialVersionUID = 1L;
 /**
  * @see HttpServlet#HttpServlet()
  */
 public UploadServlet() {
  super();
 }
 /**
  * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
  */
 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  //获取解析工厂
  DiskFileItemFactory factory = new DiskFileItemFactory();
  //得到解析器
  ServletFileUpload parser = new ServletFileUpload(factory);
  //解决文件名乱码问题
  parser.setHeaderEncoding("UTF-8");
  //判断上传表单类型
  if(!ServletFileUpload.isMultipartContent(request)) {
   return;
  }
  try {
   //调用解析器解析上传数据
   List<FileItem> fileItems = parser.parseRequest(request);
   //获得保存上传文件目录的路径
   String uploadPath = request.getServletContext().getRealPath("/WEB-INF/upload");
   //遍历List集合
   for (FileItem fileItem : fileItems) {
    //判断是否为普通表单字段
    if(fileItem.isFormField()) {
     //如果是普通表单字段则打印到控制台
     if(fileItem.getString() == null || "".equals(fileItem.getString().trim())) {
      continue;
     }
     System.out.println(fileItem.getFieldName() + " = " + new String(fileItem.getString().getBytes("ISO-8859-1"), "UTF-8"));
    }else {
     //获得文件路径
     String filePath = fileItem.getName();
     //如果并未上传文件,继续处理下一个字段
     if(filePath == null || "".equals(filePath.trim())) {
      continue;
     }
     System.out.println("处理文件:" + filePath);
     //截取文件名
     String fileName = filePath.substring(filePath.lastIndexOf("\\") + 1);
     String reallyName = this.createFileName(fileName);
     String reallyPath = this.mkDir(reallyName, uploadPath);
     //下面都是普通的IO操作了
     InputStream in = fileItem.getInputStream();
     FileOutputStream out = new FileOutputStream(reallyPath + "\\" + reallyName);
     byte[] buffer = new byte[1024];
     int len = 0;
     while((len = in.read(buffer)) > 0) {
      out.write(buffer, 0, len);
     }
     out.close();
     in.close();
    }
   }
   System.out.println("处理完毕...");
  } catch (Exception e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
 }
 /**
  * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
  */
 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  doGet(request, response);
 }
 //随机产生唯一的文件名
 private String createFileName(String fileName) throws NoSuchAlgorithmException, UnsupportedEncodingException {
  String extension = fileName.substring(fileName.lastIndexOf("."));
  MessageDigest md = MessageDigest.getInstance("md5");
  String currentTime = System.currentTimeMillis() + "";
  return UUID.randomUUID() + currentTime + extension;
 }
 //根据哈希值产生目录
 private String mkDir(String fileName, String uploadPath) {
  int hasCode = fileName.hashCode();
  //低四位作为一级目录
  int parentDir = hasCode & 0xf;
  //二级目录
  int childDir = hasCode & 0xff >> 2;
  File file = new File(uploadPath + "\\" + parentDir + "\\" + childDir);
  if(!file.exists()) {
   file.mkdirs();
  }
  uploadPath = uploadPath + "\\" + parentDir + "\\" + childDir;
  return uploadPath;
 }
}

JSP页面 :

<%@ page language="java" contentType="text/html; charset=UTF-8"
 pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<!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>Insert title here</title>
</head>
<body>
 <fmt:setBundle basename="pers.msidolphin.uploadservlet.lang.locale" var="bundle" scope="page"/>
 <form action="<c:url value="/UploadServlet"/>" method="post" enctype="multipart/form-data">
  <fmt:message key="username" bundle="${bundle}"/><input type="text" name="username"/>
  <br/>
  <br/>
  <fmt:message key="file1" bundle="${bundle}"/><input type="file" name="file1"/>
  <br/>
  <br/>
  <fmt:message key="file2" bundle="${bundle}"/><input type="file" name="file2"/>
  <br/>
  <br/>
  <input type="submit" value="<fmt:message key="submit" bundle="${bundle}"/>"/> 
 </form>
</body>
</html>

核心API: DiskFileItemFactory类

//设置内存缓冲区的大小,默认为10K,当上传文件大小大于缓冲区大小,fileupload组件将使用临时文件缓存上传文件
public void setSizeThreshold(int sizeThreshold);
//指定临时文件目录 默认值为System.getProperty("java.io.tmpdir")
public void setRepository(java.io.file respository); 
//构造方法
public DiskFileItemFactory(int sizeThreshold, java.io.file respository);

核心API: ServletFileUpload类

//判断上传表单是否为multipart/form-data类型
boolean isMultipartContent(HttpServletRequest request);
//解析request对象,并把表单中的每一个输入项包装成一个fileitem对象,返回这些对象的list集合
List<FileItem> parseRequest(HttpServletRequest request);
//设置上传文件总量的最大值 单位:字节
void setSizeMax(long sizeMax);
//设置单个上传文件的最大值 单位:字节
void setFileSizeMax(long fileSizeMax);
//设置编码格式,用于解决上传文件名的乱码问题
void setHeaderEncoding(String encoding);
//设置文件上传监听器,作用是实时获取已上传文件的大小
void setProgressListener(ProgressListener pListener);

核心API: FileItem类

//判断表单输入项是否为普通输入项(非文件输入项,如果是普通输入项返回true
boolean isFormField();
//获取输入项名称
String getFieldName();
//获得输入项的值
String getString();
String getString(String encoding); //可以设置编码,用于解决数据乱码问题
以下是针对非普通字段的:
//获取完整文件名(不同的浏览器可能会有所不同,有的可能包含路径,有的可能只有文件名)
String getName();
//获取文件输入流
InputStream getInputStream();

文件上传的几个注意点:

1、上传文件的文件名乱码问题:ServletFileUpload对象提供了setHeaderEncoding(String encoding)方法可以解决中文乱码问题

2、上传数据的中文乱码问题:

解决方法一:new String(fileItem.getString().getBytes(“ISO-8859-1”), “UTF-8”)

解决方法二:fileItem.getString(“UTF-8”)

解决方法三:fileItem.getString(request.getCharacterEncoding())

3、上传文件名的唯一性:UUID、MD5解决方法很多…

4、保存上传文件的目录最好不要对外公开

5、限制上传文件的大小: ServletFileUpload对象提供了setFileSizeMax(long fileSizeMax)和setSizeMax(long sizeMax)方法用于解决这个问题

6、限制文件上传类型:截取后缀名进行判断(好像不太严格,还要研究一番…)

以上所述是小编给大家介绍的Java中使用fileupload组件实现文件上传功能的实例代码,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!

相关文章

  • 解析Java中的static关键字

    解析Java中的static关键字

    static是方便在没有创建对象的情况下进行调用(方法/变量)。显然,被static关键字修饰的方法或者变量不需要依赖于对象来进行访问,只要类被加载了,就可以通过类名去进行访问。static可以用来修饰类的成员方法、类的成员变量,另外也可以编写static代码块来优化程序性能
    2021-06-06
  • Springboot多环境开发及使用方法

    Springboot多环境开发及使用方法

    这篇文章主要介绍了Springboot多环境开发及多环境设置使用、多环境分组管理的相关知识,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-03-03
  • SpringBoot中的PUT和Delete请求使用

    SpringBoot中的PUT和Delete请求使用

    这篇文章主要介绍了SpringBoot中的PUT和Delete请求使用,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-07-07
  • java实现打字游戏小程序

    java实现打字游戏小程序

    这篇文章主要为大家详细介绍了java实现打字游戏小程序,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-10-10
  • 详解Spring Cloud Gateway 限流操作

    详解Spring Cloud Gateway 限流操作

    这篇文章主要介绍了详解Spring Cloud Gateway 限流操作,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-07-07
  • mybatis plus动态数据源切换及查询过程浅析

    mybatis plus动态数据源切换及查询过程浅析

    这篇文章主要介绍了mybatis plus动态数据源切换及查询过程浅析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-12-12
  • Java+Spring+MySql环境中安装和配置MyBatis的教程

    Java+Spring+MySql环境中安装和配置MyBatis的教程

    这篇文章主要介绍了Java+Spring+MySql环境中安装和配置MyBatis的教程,MyBatis一般被用来增强数据库操作,文中对MyBatis的主配置文件有较为详细的讲解,需要的朋友可以参考下
    2016-04-04
  • 深入解析Java反射之基础篇

    深入解析Java反射之基础篇

    JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法,这篇文章主要给大家介绍了关于Java反射之基础篇的相关资料,需要的朋友可以参考下
    2021-11-11
  • Spring Boot 项目做性能监控的操作流程

    Spring Boot 项目做性能监控的操作流程

    这篇文章主要介绍了Spring Boot 项目如何做性能监控,本文通过实例代码图文相结合给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-07-07
  • Springmvc的运行流程图文详解

    Springmvc的运行流程图文详解

    今天小编就为大家分享一篇关于Springmvc的运行流程图文详解,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-01-01

最新评论