web开发上传文件(学习笔记)

Web开发上传文件

首先前端方面

使用form表单进行交互
这里需要注意的是form要添加一个属性编码类型 (enctype="“multipart/form-data”)
//其次文件类型 (file)

<form method="post" action="FileUploadService" enctype="multipart/form-data">

<input type="file" name="fileUpload" /> <br>

<input type="submit" value="上传" /> <br>

</form>

后端方面的处理

  • 这里需要添加commnos的支持

commons-fileupload-1.3.1.jar
commons-io-2.4.jar
它们都是 apache.org 提供的基础开发包 免费开源

需要引入的jar包
json-org.jar
commons-fileupload-1.3.1.jar
commons-io-2.4.jar

添加 FileUploadApi
这个Servlet来负责处理接收到的数据
基本过程:
(1) 取得上传文件的信息
(2) 创建一个本地临时文件,从上传里读取数据,写入到临时文件
(3) 返回结果给客户端
其中, ServletFileUpload 是 apache commons库里的一个工具类,使用它可以解析带文件的POST请求。

以下是FileUploadApi的代码

package my;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.Writer;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;

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.FileItemIterator;
import org.apache.commons.fileupload.FileItemStream;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.fileupload.util.Streams;
import org.json.JSONObject;

@WebServlet("/UploadApi")
public class FileUploadApi extends HttpServlet
{
	File tmpDir;// 文件上传的临时目录

	@Override
	public void init() throws ServletException
	{
		// 初始化
		File webroot = new File(getServletContext().getRealPath("/"));// 获取到读取文件的路径
		tmpDir = new File(webroot, "upload");// 创建一个uoload目录
		tmpDir.mkdirs();// 不存在则创建 上传进来的文件存放在WebRoot/upload/下
	}

	@Override
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
	{
		JSONObject jreq = new JSONObject();// 创建一个JSONbject对象
		try
		{
			Object data = doUpload(request, response);
			jreq.put("error", 0);
			jreq.put("reason", "OK");
			if (data != null)
			{
				jreq.put("data", data);
			}
		} catch (Exception e)
		{
			jreq.put("error", -1);
			jreq.put("reason", e.getMessage());

		}
		response.setCharacterEncoding("UTF-8");
		response.setContentType("text/plain");
		PrintWriter writer=response.getWriter();
		writer.append(jreq.toString(2));
		writer.close();
				
	}

	private Object doUpload(HttpServletRequest request, HttpServletResponse response) throws Exception
	{
		boolean isMultipart = ServletFileUpload.isMultipartContent(request);// 获取上传的文件
		if (!isMultipart)
			throw new Exception("请求编码必须为:mutipart/form-data !");// 如果请求的编码不对则抛出异常

		request.setCharacterEncoding("UTF-8");// 设置请求的字符集

		// ServletFileUpload :是commons包提供的工具类
		ServletFileUpload upload = new ServletFileUpload();// 创建文件上传的对象
		FileUploadInfo info = new FileUploadInfo();// 创建一个文件记录的对象

		FileItemIterator iter = upload.getItemIterator(request);///// 解析请求的数据
		while (iter.hasNext())
		{
			// 表单域
			FileItemStream item = iter.next();
			String fielName = item.getFieldName();// 获取文件名
			InputStream fieldStream = item.openStream();//
			if (item.isFormField())
			{
				// 如果是普通表单:直接读取值
				// 指的是<input>,<select>,<textarea>输入控件的值,字符串类型
				String fieldValue = Streams.asString(fieldStream, "UTF-8");// 读取
				System.out.println("表单域:" + fielName + "=" + fieldValue);
			} else
			{
				// 如果是文件域 ,指的是<file>控件的值,指文件的数据
				// 生成唯一的文件名
				info.readName = item.getName();// 原始文件名
				info.suffix = fileSuffix(info.readName);// 后缀
				info.temFileName = createTmpFileName(info.suffix);// 服务器临时文件名
				info.temfile = new File(tmpDir, info.temFileName);// 存放的位置
				info.filesize = 0;
				System.out.println("文件上传开始:" + info.readName + ">>" + info.temfile);

				// 从FieldStream读取数据,保存到目标文件
				info.temfile.getParentFile().mkdirs();// 文件路径
				FileOutputStream fileOutputStream = new FileOutputStream(info.temfile);
				try
				{
					info.filesize = copy(fieldStream, fileOutputStream);
				} finally
				{
					tryieldStream.close();} catch (Exception e){}
					try{fileOutputStream.close();} catch (Exception e)	{}
				}
				System.out.println("上传完成 :" + info.readName + "大小" + info.filesize);
			}
		}
		return info.temFileName;
	}
	// 读取文件的工具类
	private long copy(InputStream in, OutputStream out) throws Exception
	{
		long count = 0;
		byte[] buf = new byte[8192];// 每次8个字节
		while (true)
		{
			int n = in.read(buf);
			if (n < 0)
				break;
			if (n == 0)
				continue;
			out.write(buf, 0, n);
			count += n;
		}
		return count;
	}
	// 生成一个唯一的ID
	private String createUUID()
	{
		String s = UUID.randomUUID().toString();
		String s2 = s.substring(0, 8) + s.substring(9, 13) + s.substring(14, 18) + s.substring(19, 23)
				+ s.substring(24);
		return s2.toUpperCase();
	}

	// 得到一个保证不重复的临时文件名
	private String createTmpFileName(String suffix)
	{
		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd-HHmmss");// 获取时间
		String datastr = sdf.format(new Date());
		String name = datastr + "-" + createUUID() + "." + suffix;// 当前时间+生成的唯一ID+后缀名
		return name;
	}
    // 得到文件的后缀名
	public String fileSuffix(String fileName)
	{
		int p = fileName.lastIndexOf('.');// 获取到后面的"."
		if (p >= 0)
		{
			return fileName.substring(p + 1).toLowerCase();// 默认转换成小写
		}
		return "";
	}
}

//记录文件上传信息 FileUploadInfo.java

package my;

import java.io.File;

public class FileUploadInfo
{
	public String readName;//原名称
	public String suffix;//文件后缀名
	public String temFileName;//服务器临时名字
	public File temfile;
	public long filesize;//文件大小
}
  • 这就完成了文件上传 文件上传的目录是可以任意的 这里是上传到Webroot/upload/

  • 本次源码参照于“afanihao.cn

  • 欢迎一起学习交流的小伙伴

  • 联系qq:2116365116 (仅供学习交流)非诚勿扰

猜你喜欢

转载自blog.csdn.net/wumingxiaozuzha/article/details/89281405
今日推荐