想分享一下自己最近的项目中用到的文件上传(包括移动端的视频、图片、语音上传),也方面以后再复习;
1、基于java后台的form表单文件上传(包括文本数据和文件数据)
网页版本的前端布局很简单,在这里我直接引用外部的jquery和bootstrap
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>文件上传</title>
<script src="https://cdn.bootcss.com/jquery/1.8.1/jquery.js" type="text/javascript"></script>
<script src="https://cdn.bootcss.com/bootstrap/3.3.7/js/bootstrap.js"></script>
<link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" rel="stylesheet">
<link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.css" rel="stylesheet">
</head>
<body>
<div class="container">
<div class="row">
<form>
<div class="form-group">
<label for="name">yourName</label>
<input type="text" class="form-control" id="name" placeholder="YOUR_NAME">
</div>
<div class="form-group">
<label for="exampleInputPassword1">Password</label>
<input type="password" class="form-control" id="exampleInputPassword1" placeholder="Password">
</div>
<div class="form-group">
<label for="exampleInputFile">File input</label>
<input type="file" id="exampleInputFile">
<p class="help-block">Example block-level help text here.</p>
</div>
<button type="submit" class="btn btn-default">Submit</button>
</form>
</div>
</div>
<script>
$(function(){
})
</script>
</body>
</html>
接下来会介绍两种提交方式、以及自己所体会到的两种方法的适用范围,由于这两种方式都会要用到后台的servlet,所以我们先建立一个servlet以及他所用到的需要处理文件上传的第三方jar包
需要用到的第三方jar包地址 [文件上传下载第三方jar包地址](http://download.csdn.net/download/jayxujia123/5821353)`
下载完之后,把jar部署到javaweb项目中,这里就不强调如何使用编译器加载jar包
首先新建一个servlet,我这里取名为fileservlet
package com;
import java.io.IOException;
import javax.servlet.http.HttpServlet;
/**
* Created by koala on 2017/07/17.
*/
public class fileServlet extends javax.servlet.http.HttpServlet {
protected void doPost(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, IOException {
}
protected void doGet(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, IOException {
doPost(request,response);
}
}
接着我们在回到前端上来在form表单上面写上action地址
。。。
<form method="post" enctype="multipart/form-data" action="/fileServlet">
。。。
<button type="submit" class="btn btn-default">Submit</button>
</form>
。。。
这里有一点需要注意:enctype=”multipart/form-data” 这个类型是用来处理文件上传用的,如果不使用这个类型,后台是无法监测到是否有文件上传,接着我们看后台如果处理表单数据和文件上传的
package COM;
import com.sun.org.apache.xml.internal.security.Init;
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 java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
/**
* Created by koala on 2017/07/17.
*
*
* 文件上传 具体步骤:
* 1)获得磁盘文件条目工厂 DiskFileItemFactory 要导包
* 2) 利用 request 获取 真实路径,供临时文件存储,和 最终文件存储 ,这两个存储位置可不同,也可相同
* 3)对 DiskFileItemFactory 对象设置一些 属性
* 4)高水平的API文件上传处理 ServletFileUpload upload = new ServletFileUpload(factory);目的是调用 parseRequest(request)方法 获得 FileItem 集合list ,
* 5)在 FileItem 对象中 获取信息, 遍历, 判断 表单提交过来的信息 是否是 普通文本信息 另做处理
* 6) 第一种. 用第三方 提供的item.write( new File(path,filename) ); 直接写到磁盘上 第二种. 手动处理
*
*/
@WebServlet(name="userservlet",urlPatterns="/fileServlet")
public class fileServlet extends javax.servlet.http.HttpServlet {
// 保存文件的目录
private static String PATH_FOLDER = "/";
// 存放临时文件的目录
private static String TEMP_FOLDER = "/";
@Override
public void init(ServletConfig config) throws ServletException {
super.init();
ServletContext servletCtx = config.getServletContext();
// 初始化路径
// 保存文件的目录
PATH_FOLDER = servletCtx.getRealPath("/upload");
// 存放临时文件的目录,存放xxx.tmp文件的目录
TEMP_FOLDER = servletCtx.getRealPath("/uploadTemp");
newfolder(PATH_FOLDER);
newfolder(TEMP_FOLDER);
}
protected void doPost(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, IOException {
//设置请求的编码
request.setCharacterEncoding("utf-8");
//设置相应编码
response.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=UTF-8");
//监测是否有文件上传
boolean isMultipart = ServletFileUpload.isMultipartContent(request);
if(isMultipart){
// 获得磁盘文件条目工厂
DiskFileItemFactory factory = new DiskFileItemFactory();
// 如果没以下两行设置的话,上传大的 文件 会占用 很多内存,
// 设置暂时存放的 存储室 , 这个存储室,可以和 最终存储文件 的目录不同
/**
* 原理 它是先存到 暂时存储室,然后在真正写到 对应目录的硬盘上, 按理来说 当上传一个文件时,其实是上传了两份,第一个是以 .tem
* 格式的 然后再将其真正写到 对应目录的硬盘上
*/
//设置内存处理的最大容量 2M
factory.setSizeThreshold(2048*1024);
// 超出2M的文件放在硬盘上处理
factory.setRepository(new File(TEMP_FOLDER));
//调用API上传处理
ServletFileUpload upload = new ServletFileUpload(factory);
//设置一次性最大处理的文件字节数
upload.setFileSizeMax(20 * 1024 * 1024);
ArrayList<FileItem> items = null;
try {
//获取文件对象FileItem
items = (ArrayList<FileItem>) upload.parseRequest(request);
if(items!=null){
for(FileItem fileitem:items){
// 如果是表单元素,这里就可以去form表单里面的元素
if(fileitem.isFormField()){
if(fileitem.getFieldName().equals("name")){
// 表单数据name FileName 对应您上次是表单中的name名称
System.out.println(fileitem.getString("utf-8"));
}else if(fileitem.getFieldName().equals("password")){
//表单数据password
System.out.println(fileitem.getString());
}
}else{
String name = fileitem.getFieldName();
if(name.equals("file")){
// 上传的文件名
String filename = fileitem.getName();
// PATH_FOLDER:文件路径 :filename文件名
File f = new File(PATH_FOLDER,filename);
fileitem.write(f);
}
}
}
}
} catch (FileUploadException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
}
protected void doGet(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, IOException {
doPost(request,response);
}
/**
* 建立文件夹
* @param folder
*/
public void newfolder(String folder){
File filefolder = new File(folder);
if(!filefolder.isDirectory()){
filefolder.mkdir();
}
}
}
这里就是表单里面的含有单文件的上传方法了,如果您想通过form表单提交多个文件,你可以看如下操作
<input type="file" name="file" id="exampleInputFile" multiple="multiple">或者
<input type="file" name="file" id="exampleInputFile" multiple>
这样就是利用设置input file 对象的multiple属性,达到多文件上传;
第二:基于ajax的表单单文件上传和表单多文件上传
ajax在这里我就不介绍了,大家都知道,form表单提交后是会刷新页面的,而ajax提交却不会,接下来,让我们来看看如果做。
首先,我们把前台页面改变一下,去掉form表单标签中的action和submit标签
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>文件上传</title>
<script src="https://cdn.bootcss.com/jquery/1.8.1/jquery.js" type="text/javascript"></script>
<script src="https://cdn.bootcss.com/bootstrap/3.1.0/js/bootstrap.js"></script>
<link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" rel="stylesheet">
<link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.css" rel="stylesheet">
</head>
<body>
<div class="container">
<div class="row">
<form method="post" enctype="multipart/form-data" id="myform">
<div class="form-group">
<label for="name">yourName</label>
<input type="text" name="name" class="form-control" id="name" placeholder="YOUR_NAME">
</div>
<div class="form-group">
<label for="exampleInputPassword1">Password</label>
<input type="password" name = "password" class="form-control" id="exampleInputPassword1" placeholder="Password">
</div>
<div class="form-group">
<label for="exampleInputFile">File input</label>
<input type="file" name="file" id="exampleInputFile" MULTIPLE="multiple">
<p class="help-block">Example block-level help text here.</p>
</div>
</form>
<button type="button" id="btnUpload" class="btn btn-success">upload</button>
</div>
</div>
<script>
$(function(){
$("#btnUpload").click(function(e){
e.preventDefault();
var from = new FormData(document.getElementById("myform"))
$.ajax({
cache:false,
type:'post',
url:"/fileServlet",
data:from,
//数据序列化
processData:false,
contentType:false,
async:false,
// 发送错误
error:function(){},
// 正在上传,这里可以添加上传进度条
beforeSend:function(){},
//上传成功
success:function(data){
},
// 完成之后
complete:function(){}
})
})
})
</script>
</body>
</html>
第三种,通过DataForm对象上传文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>文件上传</title>
<script src="https://cdn.bootcss.com/jquery/1.8.1/jquery.js" type="text/javascript"></script>
<script src="https://cdn.bootcss.com/bootstrap/3.1.0/js/bootstrap.js"></script>
<link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" rel="stylesheet">
<link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.css" rel="stylesheet">
</head>
<body>
<div class="container">
<div class="row">
<form method="post" enctype="multipart/form-data" id="myform">
<div class="form-group">
<label for="name">yourName</label>
<input type="text" name="name" class="form-control" id="name" placeholder="YOUR_NAME">
</div>
<div class="form-group">
<label for="exampleInputPassword1">Password</label>
<input type="password" name = "password" class="form-control" id="exampleInputPassword1" placeholder="Password">
</div>
<div class="form-group">
<label for="exampleInputFile">File input</label>
<input type="file" name="file" id="exampleInputFile" MULTIPLE="multiple">
<p class="help-block">Example block-level help text here.</p>
</div>
</form>
<button type="button" id="btnUpload" class="btn btn-success">upload</button>
</div>
</div>
<script>
$(function(){
$("#btnUpload").click(function(e){
e.preventDefault();
var oMyForm = new FormData();
oMyForm.append("name", "file");
oMyForm.append("accountnum", 123456);
oMyForm.append("file", $('#exampleInputFile')[0].files[0]);
$.ajax({
url: '/fileServlet',
type: 'POST',
cache: false,
data: oMyForm,
processData: false,
contentType: false,
async: false
}).done(function(res) {}).fail(function(res) {});
})
})
</script>
</body>
</html>
再次提一点:
- Ajax的processData设置为false。因为data值是FormData对象,不需要对数据做处理。
第二种方式中标签加enctyp e=”multipart/form-data”属性。
- cache设置为false,上传文件不需要缓存。
- contentType设置为false。因为是由表单构造的FormData对象,且已经声明了属性enctype=”mutipart/form-data”,所以这里设置为false。
第四种,移动端视频、语音、音频上传
我们接下来要要通过HTML5API所提供的工具进行,主要用到以下三种
<input type="file" accept="image/*" capture="camera"> //图片
<input type="file" accept="video/*" capture="camcorder"> //视频
<input type="file" accept="audio/*" capture="microphone"> //音频
你将这个三个input标签嵌入网页,在移动端进行访问的时候,会自动调用手机里面的视频拍摄、图片拍摄以及音频录制等功能;
最后文件上传可以直接使用我在第二中方法所使用的,多个input提交(在这里我就不再重复写了,上传都一样,建立formData对象,关键是对图片的压缩,对视频、音频大小限制),这里我提供一个前端压缩图片的链接 https://my.oschina.net/zyxchuxin/blog/700381
如果大家有什么疑惑可以在下面留言,我会给大家回复的
———–水平有限,如果写的不正确之处,还请斧正!