java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的 Java 程序设计语言和 Java 平台(即 JavaEE(j2ee), JavaME(j2me), JavaSE(j2se))的总称。
这篇文章主要介绍了 Java 中使用 fileupload 组件实现文件上传功能的实例代码, 需要的朋友可以参考下
使用 fileupload 组件的原因:
Request 对象提供了一个 getInputStream() 方法,通过这个方法可以读取到客户端提交过来的数据,但是由于用户可能会同时上传多个文件,在 servlet 中编程解析这些上传数据是一件非常麻烦的工作。为方便开发人员处理文件上传数据,Apache 开源组织提供了一个用来处理表单文件上传的一个开源组件 (Commons-fileupload),该组件性能优异,并且使用及其简单,可以让开发人员轻松实现 web 文件上传功能。
使用 Commons-fileupload 组件实现文件上传,需要导入该组件相应的支撑 jar 包:
(commons-upload 组件从 1.1 版本开始,它的工作需要 commons-io 包的支持)
- commons-fileupload和connons-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 组件实现文件上传功能的实例代码,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 PHPERZ 网站的支持!
来源: http://www.phperz.com/article/17/1230/356962.html