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 (仅供学习交流)非诚勿扰