Java 单文件、多文件上传 / 实现上传进度条
博客地址:https://ainyi.com/76
日常,工作
在这里总结一下上传吧(是以前做过的练习,就汇总到个人博客吧)
java ssm 框架实现文件上传
实现:单文件上传、多文件上传(单选和多选),并且用 ajax 异步刷新,在当前界面显示上传的文件
后端
首先 springmvc 的配置文件要配置上传文件解析器:
<!-- 配置文件解析器 -->
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver"
p:defaultEncoding="utf-8">
<property name="uploadTempDir" value="/temp"></property>
<property name="maxUploadSize">
<value>209715200</value><!-- 200MB -->
</property>
<property name="maxInMemorySize">
<value>4096</value><!-- 4KB大小读写 -->
</property>
</bean>
其次在 pom.xml 中要配置上传文件的依赖
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.3.2</version>
</dependency>
单文件上传
/**
* 单文件上传
* @param file
* @param request
* @return
* @throws IllegalStateException
* @throws IOException
* @throws JSONException
*/
public static String simUpload(MultipartFile file, HttpServletRequest request)
throws IllegalStateException, IOException, JSONException{
if(!file.isEmpty()){
String path = request.getSession().getServletContext().getRealPath("/upload");
//定义文件
File parent = new File(path);
if(!parent.exists()) parent.mkdirs();
HashMap<String, Object> map = new HashMap<String,Object>();
String oldName = file.getOriginalFilename();
long size = file.getSize();
//使用TmFileUtil文件上传工具获取文件的各种信息
//优化文件大小
String sizeString = TmFileUtil.countFileSize(size);
//获取文件后缀名
String ext = TmFileUtil.getExtNoPoint(oldName);
//随机重命名,10位时间字符串
String newFileName = TmFileUtil.generateFileName(oldName, 10, "yyyyMMddHHmmss");
String url = "upload/"+newFileName;
//文件传输,parent文件
file.transferTo(new File(parent, newFileName));
map.put("oldname",oldName);//文件原名称
map.put("ext",ext);
map.put("size",sizeString);
map.put("name",newFileName);//文件新名称
map.put("url",url);
//以json方式输出到页面
return JSONUtil.serialize(map);
}else{
return null;
}
}
多文件上传(整合了单选文件和多选文件的两种)
/**
* 多文件上传
* @param files
* @param request
* @return
* @throws IllegalStateException
* @throws IOException
* @throws JSONException
*/
public static List<HashMap<String, Object>> mutlUpload(MultipartFile[] files, HttpServletRequest request)
throws IllegalStateException, IOException, JSONException{
if(files.length > 0){
String path = request.getSession().getServletContext().getRealPath("/upload");
//定义文件
File parent = new File(path);
if(!parent.exists()) parent.mkdirs();
//创建这个集合保存所有文件的信息
List<HashMap<String, Object>> listMap = new ArrayList<HashMap<String, Object>>();
//循环多次上传多个文件
for (MultipartFile file : files) {
//创建map对象保存每一个文件的信息
HashMap<String, Object> map = new HashMap<String,Object>();
String oldName = file.getOriginalFilename();
long size = file.getSize();
//使用TmFileUtil文件上传工具获取文件的各种信息
//优化文件大小
String sizeString = TmFileUtil.countFileSize(size);
//获取文件后缀名
String ext = TmFileUtil.getExtNoPoint(oldName);
//随机重命名,10位时间字符串
String newFileName = TmFileUtil.generateFileName(oldName, 10, "yyyyMMddHHmmss");
String url = "upload/"+newFileName;
//文件传输,parent文件
file.transferTo(new File(parent, newFileName));
map.put("oldname",oldName);//文件原名称
map.put("ext",ext);
map.put("size",sizeString);
map.put("name",newFileName);//文件新名称
map.put("url",url);
listMap.add(map);
}
//以json方式输出到页面
return listMap;
}else{
return null;
}
}
前端
前端代码:
文件多选,实际上在
<input type="file"
name="fileupmulti"
accept="image/jpeg,image/png"
onchange="mutiFiles(this)"
multiple/>
多加了一个 multiple 属性
onchange 事件代码
// 单文件上传
function uploadFile(obj){
// 创建一个 FormData 对象,用一些键值对来模拟一系列表单控件
// 即把 form 中所有表单元素的 name 与 value 组装成一个 queryString
let form = new FormData();
let fileObj = obj.files[0];
form.append('doc',fileObj);
// ajax 代码...
}
// 多文件上传(多选)
function mutiFiles(obj){
let form = new FormData();
let fileObj = obj.files;
let length = fileObj.length;
// 将 fileObj 转换成数组
// let filese = Array.from(fileObj);
for(let i = 0; i < length; i++){
form.append('doc', fileObj[i]);
}
// ajax 代码...
}
// 多文件上传(单选:一个一个选择文件,最后点击提交按钮触发的方法)
function multipartone(){
let file1 = $('.fileupon11').get(0).files[0];
let file2 = $('.fileupon12').get(0).files[0];
let file3 = $('.fileupon13').get(0).files[0];
//如果都是空,则直接退出
isEmpty(file1) && isEmpty(file2) && isEmpty(file3) return;
let form = new FormData();
//用同一个名字,注入到controller层的参数数组
form.append('doc', file1);
form.append('doc', file2);
form.append('doc', file3);
// ajax 代码...
}
要想在当前界面显示上传的文件,而不跳转,就利用 ajax 异步请求
不过需要注意的是,我这里使用 FormData() 储存文件对象, ajax 要配上这几个参数才可实现文件上传:
$.ajax({
type: "post",
data: form, // FormData()对象
url: basePath+"/upload/mutl",
contentType: false, // 必须false才会自动加上正确的Content-Type
processData: false, // 必须false才会避开 jQuery 对 formdata 的默认处理, XMLHttpRequest会对 formdata 进行正确的处理
success: function(data){
// TODO
}
})
controller 层调用
package com.krry.controller;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import org.apache.struts2.json.JSONException;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import com.krry.util.UploadUtil;
/**
* 文件上传类
* KrryUploadController
* @author krry
* @version 1.0.0
*
*/
@Controller
@RequestMapping("/upload")
public class KrryUploadController {
/**
* 单文件上传
* @param file
* @param request
* @return
* @throws IllegalStateException
* @throws IOException
* @throws JSONException
*/
@ResponseBody
@RequestMapping(value = "/file")
public String krryupload(@RequestParam("doc") MultipartFile file, HttpServletRequest request) throws IllegalStateException, IOException, JSONException{
//调用工具类完成上传,返回相关数据到页面
return UploadUtil.simUpload(file, request);
}
/**
* 多文件上传
* @param file
* @param request
* @return
* @throws IllegalStateException
* @throws IOException
* @throws JSONException
*/
// 这里的MultipartFile[] file表示前端页面上传过来的多个文件,file对应页面中多个file类型的input标签的name,但框架只会将一个文件封装进一个MultipartFile对象,
// 并不会将多个文件封装进一个MultipartFile[]数组,直接使用会报[Lorg.springframework.web.multipart.MultipartFile;.<init>()错误,
// 所以需要用@RequestParam校正参数(参数名与MultipartFile对象名一致),当然也可以这么写:@RequestParam("file") MultipartFile[] files。
@ResponseBody
@RequestMapping(value = "/mutl")
public List<HashMap<String, Object>> krryuploadMutl(@RequestParam("doc") MultipartFile[] file, HttpServletRequest request) throws IllegalStateException, IOException, JSONException{
//调用工具类完成上传,返回相关数据到页面
return UploadUtil.mutlUpload(file, request);
}
}
进度条
要显示上传进度条,我这里采用原生 ajax 方法
function uploadFile(obj) {
// ...
// 一些获取上传对象的相关代码
// 创建一个 ajax 对象
var xhr = new XMLHttpRequest();
// 规定请求的类型、URL 以及是否异步处理请求。true为异步
// 请求是异步的。因为要实时获取到上传的进度,则请求需是异步的,如果是同步的话,会直到请求完成才能获取到响应
xhr.open("post", basePath+"/upload/file", true);
// 上传成功进入的回调函数
xhr.onreadystatechange = function(){
if(xhr.readyState==4 && xhr.status==200){ // 状态 4 和 200 代表和服务器端交互成功
// 获取上传成功的返回数据
var data = xhr.responseText.trim();
jdata = eval("("+data+")");
krry_uploadsuccess(jdata);
}
};
// 监听文件上传的进度
xhr.upload.addEventListener("progress", progressFunction, false);
// 发送http请求:将请求发送到服务器,与后台交互
xhr.send(form);
}
// 上传进度的回调函数
function progressFunction(event) {
let prograssbarDom = document.getElementById("prograssbar");
let fileRea = document.getElementById("fileRea");
if (prograssbarDom && event.lengthComputable) {
let percent = event.loaded / event.total; //文件上传进度百分比
let p = Math.floor(percent*100);
prograssbarDom.style.width = p+"%";
fileRea.innerHTML = p+"%";
}
}
附上优化文件大小的代码:
/**
* 将文件的字节数转换成文件的大小
* com.krry.uitl
* 方法名:format
* @author krry
* @param size
* @return String
* @exception
* @since 1.0.0
*/
public static String format(long size){
float fsize = size;
String fileSizeString;
if (fsize < 1024) {
fileSizeString = String.format("%.2f", fsize) + "B"; //2f表示保留两位小数
} else if (fsize < 1048576) {
fileSizeString = String.format("%.2f", fsize/1024) + "KB";
} else if (fsize < 1073741824) {
fileSizeString = String.format("%.2f", fsize/1024/1024) + "MB";
} else if (fsize < 1024 * 1024 * 1024) {
fileSizeString = String.format("%.2f", fsize/1024/1024/1024) + "GB";
} else {
fileSizeString = "0B";
}
return fileSizeString;
}
博客地址:https://ainyi.com/76
Java 单文件、多文件上传 / 实现上传进度条的更多相关文章
- js实现图片上传预览及进度条
原文js实现图片上传预览及进度条 最近在做图片上传的时候,由于产品设计的比较fashion,上网找了比较久还没有现成的,因此自己做了一个,实现的功能如下: 1:去除浏览器<input type= ...
- Progress.js – 为页面上的任意对象创建进度条效果
Progress.js 是一个 JavaScript 和 CSS3 的库,它帮助开发人员为网页上的每个对象创建和管理进度条效果.你可以设计自己的模板,进度条或者干脆定制. 您可以使用 Progress ...
- ajax实现无刷新上传附件并且显示进度条的实例
首先:得把php.ini中的post_max_size和upload_max_filesize改成200M或更大(进度条好看效果,默认是2M) html和js代码: <!DOCTYPE html ...
- android一个上传图片的样例,包含怎样终止上传过程,假设在上传的时候更新进度条(一)
先上效果图: Layout为: <? xml version="1.0" encoding="utf-8"?> <LinearLayout x ...
- 项目一、ajax上传数据(显示进度条)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- layui 魔改:上传时的真实进度条
这个问题本身不复杂,难点在于需要改 layui 的源码. HTML略. 网页的JS域: layui.use(['upload','element','layer'], function(){ var ...
- asp.net 文件上传 Uploadify HTML5 带进度条
参考的https://www.cnblogs.com/lvdabao/p/3452858.html这位,在此基础上略有修改: 1.根据Layer,将上传附件做成弹窗显示,引入frame弹窗,在项目当中 ...
- Ajax文件上传并添加Bootstrap进度条
1.项目中需要用到文件上传和显示进度,网上各种插件搞得头晕,决定自己实现一个 三个步骤:Ajax上传文件,获取上传进度,显示进度 html: <!DOCTYPE HTML> <htm ...
- ajax +formdata ,后台为PHP 实现上传整个文件夹(只适合谷歌浏览器)带进度条
PHP用超级全局变量数组$_FILES来记录文件上传相关信息的. 1.file_uploads=on/off 是否允许通过http方式上传文件 2.max_execution_time=30 允许脚本 ...
- 微信小程序-上传多张图片加进度条(支持预览、删除)
2018-12-24 详情示例见:https://www.cnblogs.com/cisum/p/9564898.html 2018-12-29 组件下载见:https://www.cnblogs.c ...
随机推荐
- 关于使用sudo找不到环境变量的问题
参考这里:https://www.cnblogs.com/zhongshiqiang/p/10839666.html 使用sudo -E 保留当前用户环境,这时就不会存在找不到环境变量的问题了.
- python开发笔记-python调用webservice接口
环境描述: 操作系统版本: root@9deba54adab7:/# uname -a Linux 9deba54adab7 --generic #-Ubuntu SMP Thu Dec :: UTC ...
- [ kvm ] 三种基础网络模型创建及分析
1. 前言 最近在模拟生产环境在做测试,本来准备用 vmware 直接来实现的,本着学以致用的道理,选择直接在linux 环境使用 kvm 来模拟测试,遇到的第一个问题就是,网络环境的模拟.这里对比v ...
- 【软件工具】ImageMagick
如何安装; 如何检查是否安装成功呢: 如何使用: https://imagemagick.org/index.php 参考 1. 官网: 完
- mysql数据库每天备份
以备份mysql下的test数据库为例,备份到/home/data 使用mysqldunp命令 dump.sh mysqldump -h127. -uadmin -P3306 -ppassword t ...
- Java 中不允许使用静态局部变量
Java 中不允许使用静态局部变量
- Docker容器安装配置SQLServer服务(Linux)
一:前言 随着不断的对Docker容器的实践和学习,越来越觉得容器的强大,把 SQL Server 数据库服务放在docker容器中,比你自己在宿主服务器上面安装配置一个SQL Server服务器是要 ...
- .NET平台历程介绍
.Net平台的背景 1. 2010之前 的PC时代的时候,互联网规模还不是特别庞大,以静态编译式语言为代表的JAVA和.Net没什么太大区别,.net以windows自居. 2. 2010年以JAVA ...
- CORS解决跨域问题(403问题)
1.什么是跨域问题? 跨域问题是浏览器对于ajax请求的一种安全限制:一个页面发起的ajax请求,只能是用当前页同域名同端口的路径,这能有效的阻止跨站攻击. 2.跨域问题出现的条件: 1.跨域问题是a ...
- 记一次奇怪的python多个变量拼接后的字符串丢失事件
在一次脚本运行中出现了多个变量拼接后的值出现丢失情况. a = "hello " b = "ketty" c = a + b + "!" 预 ...