java后端实现文件的上传功能

核心API——DiskFileItemFactory

DiskFileItemFactory是创建FileItem对象的工厂,常用的方法有:

  • public void setRepository(Java.io.File respository):指定临时临时文件目录。
  • public void setSizeThreshold(int sizeThreshold):设置缓冲区的大小,默认值为10k
  • public DiskFileItemFactory(int SizeThreshold,Java.io.File respository):构造函数

核心API——ServletFileUpload

ServletFileUpload 负责处理上传的文件数据,并将表单中每个输入项封装成一个FileItem 对象中。常用方法有:

  • boolean isMultipartContent(HttpServletRequest request):判断上传表单是否是multipart/form-data类型
  • List parseRequest(HttpServletRequest request):解析request对象,把表单中的每一个输入项封装成一个fileItem对象并返回一个保存了所有fileitem对象的list集合
  • setFileSizeMax(long fileSizeMax) :设置上传文件的最大值(单个文件),用于设置单个上传文件的最大尺寸限制,以防止客户端恶意上传超大文件来浪费服务器端的存储空间。其参数是以字节为单位的long型数字。
  • setSizeMax(long sizeMax) :设置上传文件总量的最大值(所有上传文件),用于设置请求消息实体内容(即所有上传数据)的最大尺寸限制,以防止客户端恶意上传超大文件来浪费服务器端的存储空间。其参数是以字节为单位的long型数字。
  • setHeaderEncoding(java.lang.String encoding) :设置编码格式。在文件上传请求的消息体中,除了普通表单域的值是文本内容以外,文件上传字段中的文件路径名也是文本,在内存中保存的是它们的某种字符集编码的字节数组,Apache文件上传组件在读取这些内容时,必须知道它们所采用的字符集编码,才能将它们转换成正确的字符文本返回。

核心API——FileItem

  • boolean isFormField(): isFormField方法用于判断FileItem类对象封装的数据是一个普通文本表单字段,还是一个文件表单字段,如果是普通表单字段则返回true,否则返回false。
  • String getName()用于获得文件上传字段中的文件名。注意IE或FireFox中获取的文件名是不一样的,IE中是绝对路径,FireFox中只是文件名。
  • String getFieldName():用于返回表单标签name属性的值。
  • void write(File file):用于将FileItem对象中保存的主体内容保存到某个指定的文件中。如果FileItem对象中的主体内容是保存在某个临时文件中,该方法顺利完成后,临时文件有可能会被清除。该方法也可将普通表单字段内容写入到一个文件中,但它主要用途是将上传的文件内容保存在本地文件系统中。
  • String getString():用于将FileItem对象中保存的数据流内容以一个字符串返回,它有两个重载的定义形式:
    public Java.lang.String getString();
    public java.lang.String getString(java.lang.String encoding) throws java.io.UnsupportedEncodingException
    前者使用缺省的字符集编码将主体内容转换成字符串,后者使用参数指定的字符集编码将主体内容转换成字符串。如果在读取普通表单字段元素的内容时出现了中文乱码现象,请调用第二个getString方法,并为之传递正确的字符集编码名称。
  • void delete():delete方法用来清空FileItem类对象中存放的主体内容,如果主体内容被保存在临时文件中,delete方法将删除该临时文件。尽管当FileItem对象被垃圾收集器收集时会自动清除临时文件,但及时调用delete方法可以更早的清除临时文件,释放系统存储资源。

实现步骤:

  1. 创建DiskFileItemFactory对象,设置缓冲区大小和临时文件目录。
  2. 使用DiskFileItemFactory 对象创建ServletFileUpload对象,并设置上传文件的大小限制。
  3. 调用ServletFileUpload.parseRequest方法解析request对象,得到一个保存了所有上传内容的List对象。
  4. 对list进行迭代,每迭代一个FileItem对象,调用其isFormField方法判断是否是上传文件:

    4.1: 为普通表单字段,则调用getFieldName、getString方法得到字段名和字段值。

    4.2: 为上传文件,则调用getInputStream方法得到数据输入流,从而读取上传数据。

所需jar包
java后端实现文件的上传功能_第1张图片
需要的可以Q我:2634306580

代码实现:

package com.api;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.List;

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;

import net.sf.json.JSON;
import net.sf.json.JSONObject;

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

    /**
     * @see HttpServlet#HttpServlet()
     */
    public upload() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		response.getWriter().append("Served at: ").append(request.getContextPath());
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
	        //创建文件需要上传到的路径
			String path = request.getServletContext().getRealPath("/upload") ;
	        File dir = new File(path);
	        System.out.println("path"+path);
	        //判断文件是否存在,如果不存在就创建一个文件夹
	        if (!dir.exists()) {
	            dir.mkdir();
	        }

	        request.setCharacterEncoding("utf-8");  //设置编码
	        
	        JSONObject res = new JSONObject();
		
	      //使用Apache文件上传组件处理文件上传步骤: 
	        try {
	        //1、创建一个DiskFileItemFactory工厂
	        DiskFileItemFactory factory = new DiskFileItemFactory();
	        //设置暂时存放的存储室,这个存储室可以和最终存储文件的目录不同
	        factory.setRepository(dir);
	        //设置缓存的大小,当上传文件的容量超过该缓存时,直接放到暂时存储室
	        factory.setSizeThreshold(1024 * 1024);
	        
	        //2、创建文件上传解析器
	        ServletFileUpload upload = new ServletFileUpload(factory);
	        
	        //3、判断提交上来的数据是否是上传表单的数据 
	        if(!ServletFileUpload.isMultipartContent(request)){ 
	        	//按照传统方式获取数据 
	        	return; 
	        	} 

	        //4、使用ServletFileUpload解析器解析上传数据,解析结果返回的是一个List集合,每一个FileItem对应一个Form表单的输入项 
	        List<FileItem> list = upload.parseRequest(request); 
	        for(FileItem item : list){ 
	        //如果fileitem中封装的是普通输入项的数据 
	        if(item.isFormField()){ 
	        String name = item.getFieldName(); 
	        //解决普通输入项的数据的中文乱码问题 
	        String value = item.getString("UTF-8"); 
	        //value = new String(value.getBytes("iso8859-1"),"UTF-8"); 
	        System.out.println(name + "=" + value); 
	        }else{//如果fileitem中封装的是上传文件 
	        //得到上传的文件名称, 
	        String filename = item.getName(); 
	        System.out.println("fileName:" + filename); 
	        res.put(filename,path+filename );
	        if(filename==null || filename.trim().equals("")){ 
	        continue; 
	        } 
	        //注意:不同的浏览器提交的文件名是不一样的,有些浏览器提交上来的文件名是带有路径的,如: c:\a\b\1.txt,而有些只是单纯的文件名,如:1.txt 
	        //处理获取到的上传文件的文件名的路径部分,只保留文件名部分 
	        filename = filename.substring(filename.lastIndexOf("/")+1); 
	        //获取item中的上传文件的输入流 
	        InputStream in = item.getInputStream(); 
	        //创建一个文件输出流 
	        FileOutputStream out = new FileOutputStream(path + "/" + filename); 
	        //创建一个缓冲区 
	        byte buffer[] = new byte[1024]; 
	        //判断输入流中的数据是否已经读完的标识 
	        int len = 0; 
	        //循环将输入流读入到缓冲区当中,(len=in.read(buffer))>0就表示in里面还有数据 
	        while((len=in.read(buffer))>0){ 
	        //使用FileOutputStream输出流将缓冲区的数据写入到指定的目录(savePath + "\\" + filename)当中 
	        out.write(buffer, 0, len); 
	        } 
	        //关闭输入流 
	        in.close(); 
	        //关闭输出流 
	        out.close(); 
	        //删除处理文件上传时生成的临时文件 
	        item.delete(); 
	        } 
	        }
	        }catch (Exception e) { 
	        e.printStackTrace(); 
	        } 

	        PrintWriter printWriter = response.getWriter();
	        response.setContentType("application/json");
	        response.setCharacterEncoding("utf-8");
	        res.put("success", true);
	        printWriter.write(res.toString());
	        printWriter.flush();
	        }
}

参考博客:https://blog.csdn.net/u014785687/article/details/73863964

你可能感兴趣的:(java后端实现文件的上传功能)