Maison Java javaDidacticiel Exemple de code pour utiliser le composant fileupload pour implémenter la fonction de téléchargement de fichiers en Java

Exemple de code pour utiliser le composant fileupload pour implémenter la fonction de téléchargement de fichiers en Java

May 21, 2017 am 10:31 AM

这篇文章主要介绍了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;
  }
}
Copier après la connexion

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>
Copier après la connexion

核心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);
Copier après la connexion

核心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);
Copier après la connexion

核心API: FileItem类

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

文件上传的几个注意点:

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、限制文件上传类型:截取后缀名进行判断(好像不太严格,还要研究一番…)


Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn

Outils d'IA chauds

Undresser.AI Undress

Undresser.AI Undress

Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover

AI Clothes Remover

Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool

Undress AI Tool

Images de déshabillage gratuites

Clothoff.io

Clothoff.io

Dissolvant de vêtements AI

AI Hentai Generator

AI Hentai Generator

Générez AI Hentai gratuitement.

Article chaud

R.E.P.O. Crystals d'énergie expliqués et ce qu'ils font (cristal jaune)
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Meilleurs paramètres graphiques
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Comment réparer l'audio si vous n'entendez personne
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
Où trouver la courte de la grue à atomide atomique
1 Il y a quelques semaines By DDD

Outils chauds

Bloc-notes++7.3.1

Bloc-notes++7.3.1

Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise

SublimeText3 version chinoise

Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1

Envoyer Studio 13.0.1

Puissant environnement de développement intégré PHP

Dreamweaver CS6

Dreamweaver CS6

Outils de développement Web visuel

SublimeText3 version Mac

SublimeText3 version Mac

Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Racine carrée en Java Racine carrée en Java Aug 30, 2024 pm 04:26 PM

Guide de la racine carrée en Java. Nous discutons ici du fonctionnement de Square Root en Java avec un exemple et son implémentation de code respectivement.

Nombre parfait en Java Nombre parfait en Java Aug 30, 2024 pm 04:28 PM

Guide du nombre parfait en Java. Nous discutons ici de la définition, comment vérifier le nombre parfait en Java ?, des exemples d'implémentation de code.

Numéro Armstrong en Java Numéro Armstrong en Java Aug 30, 2024 pm 04:26 PM

Guide du numéro Armstrong en Java. Nous discutons ici d'une introduction au numéro d'Armstrong en Java ainsi que d'une partie du code.

Générateur de nombres aléatoires en Java Générateur de nombres aléatoires en Java Aug 30, 2024 pm 04:27 PM

Guide du générateur de nombres aléatoires en Java. Nous discutons ici des fonctions en Java avec des exemples et de deux générateurs différents avec d'autres exemples.

Weka en Java Weka en Java Aug 30, 2024 pm 04:28 PM

Guide de Weka en Java. Nous discutons ici de l'introduction, de la façon d'utiliser Weka Java, du type de plate-forme et des avantages avec des exemples.

Numéro de Smith en Java Numéro de Smith en Java Aug 30, 2024 pm 04:28 PM

Guide du nombre de Smith en Java. Nous discutons ici de la définition, comment vérifier le numéro Smith en Java ? exemple avec implémentation de code.

Questions d'entretien chez Java Spring Questions d'entretien chez Java Spring Aug 30, 2024 pm 04:29 PM

Dans cet article, nous avons conservé les questions d'entretien Java Spring les plus posées avec leurs réponses détaillées. Pour que vous puissiez réussir l'interview.

Break or Return of Java 8 Stream Forach? Break or Return of Java 8 Stream Forach? Feb 07, 2025 pm 12:09 PM

Java 8 présente l'API Stream, fournissant un moyen puissant et expressif de traiter les collections de données. Cependant, une question courante lors de l'utilisation du flux est: comment se casser ou revenir d'une opération FOREAK? Les boucles traditionnelles permettent une interruption ou un retour précoce, mais la méthode Foreach de Stream ne prend pas directement en charge cette méthode. Cet article expliquera les raisons et explorera des méthodes alternatives pour la mise en œuvre de terminaison prématurée dans les systèmes de traitement de flux. Lire plus approfondie: Améliorations de l'API Java Stream Comprendre le flux Forach La méthode foreach est une opération terminale qui effectue une opération sur chaque élément du flux. Son intention de conception est

See all articles