博客地址: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 单文件、多文件上传 / 实现上传进度条的更多相关文章

  1. js实现图片上传预览及进度条

    原文js实现图片上传预览及进度条 最近在做图片上传的时候,由于产品设计的比较fashion,上网找了比较久还没有现成的,因此自己做了一个,实现的功能如下: 1:去除浏览器<input type= ...

  2. Progress.js – 为页面上的任意对象创建进度条效果

    Progress.js 是一个 JavaScript 和 CSS3 的库,它帮助开发人员为网页上的每个对象创建和管理进度条效果.你可以设计自己的模板,进度条或者干脆定制. 您可以使用 Progress ...

  3. ajax实现无刷新上传附件并且显示进度条的实例

    首先:得把php.ini中的post_max_size和upload_max_filesize改成200M或更大(进度条好看效果,默认是2M) html和js代码: <!DOCTYPE html ...

  4. android一个上传图片的样例,包含怎样终止上传过程,假设在上传的时候更新进度条(一)

    先上效果图: Layout为: <? xml version="1.0" encoding="utf-8"?> <LinearLayout x ...

  5. 项目一、ajax上传数据(显示进度条)

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  6. layui 魔改:上传时的真实进度条

    这个问题本身不复杂,难点在于需要改 layui 的源码. HTML略. 网页的JS域: layui.use(['upload','element','layer'], function(){ var ...

  7. asp.net 文件上传 Uploadify HTML5 带进度条

    参考的https://www.cnblogs.com/lvdabao/p/3452858.html这位,在此基础上略有修改: 1.根据Layer,将上传附件做成弹窗显示,引入frame弹窗,在项目当中 ...

  8. Ajax文件上传并添加Bootstrap进度条

    1.项目中需要用到文件上传和显示进度,网上各种插件搞得头晕,决定自己实现一个 三个步骤:Ajax上传文件,获取上传进度,显示进度 html: <!DOCTYPE HTML> <htm ...

  9. ajax +formdata ,后台为PHP 实现上传整个文件夹(只适合谷歌浏览器)带进度条

    PHP用超级全局变量数组$_FILES来记录文件上传相关信息的. 1.file_uploads=on/off 是否允许通过http方式上传文件 2.max_execution_time=30 允许脚本 ...

  10. 微信小程序-上传多张图片加进度条(支持预览、删除)

    2018-12-24 详情示例见:https://www.cnblogs.com/cisum/p/9564898.html 2018-12-29 组件下载见:https://www.cnblogs.c ...

随机推荐

  1. nodejs命令行执行时带参数

    nodejs命令行执行时带参数 转 https://www.jianshu.com/p/474e6d76f867   今天项目里突然想在初始化时跑一些数据,于是想起以前在python时可以在命令行里带 ...

  2. Centos7下的文件压缩

    [root@web01 ~]# yum provides zip 已加载插件:fastestmirror Loading mirror speeds from cached hostfile * ba ...

  3. 关于在windows平台下将应用制作成windows服务及服务依赖的感想

    在某些情况下,应用需要部署在windows平台下,单纯的手动点击exe执行文件或java -jar xxx.jar在实际生产环境中不是最佳实践(制作成bat启动文件置于启动项里,服务器启动后,需要人工 ...

  4. .Net Oracle TransactionScope的使用

    IIS服务器和Oracle服务器: 1.配置msdtc允许DTC访问及启用事务 2.配置msdtc程序入站出站例外 3.数据库连接字符串不能带enlist=false标识 如下这样带enlist=fa ...

  5. [Linux.centOS].安装Redis 腾讯云

    环境 { "服务器运营商":"腾讯云", "操作系统":"CentOS 7.5 64位", "CPU" ...

  6. Hadoop深入学习之HA

    1. 基本原理 2.x版本中,HDFS架构解决了单点故障问题,即引入双NameNode架构,同时借助共享存储系统来进行元数据的同步,共享存储系统类型一般有几类,如:Shared NAS+NFS.Boo ...

  7. [线性代数xOI/ACM]系数矩阵的QGXZ分解

    一些无关紧要的Q&A Q:你是怎么想到这个花里胡哨的算法的啊? A:前几天学习线性代数时有幸和Magolor大佬讨论到 $LU$ 分解在多解时的时间复杂度问题,于是yy出了这个奇怪(?)的算法 ...

  8. 多用户远程连接设置(WindowsServer2008/Win7)

    一.Windows server2008 1.点击计算机--->右键属性打开系统对话框.进行如图设置. 2.在开始菜单--->运行中输入gpedit.msc打开本地组策略编辑器对话框. 3 ...

  9. Redis 分布式锁,C#通过Redis实现分布式锁(转)

    目录(?)[+] 分布式锁一般有三种实现方式: 可靠性   分布式锁一般有三种实现方式: 1. 数据库乐观锁; 2. 基于Redis的分布式锁; 3. 基于ZooKeeper的分布式锁.本篇博客将介绍 ...

  10. python抓取不得姐动图(报错 urllib.error.HTTPError: HTTP Error 403: Forbidden)

    抓取不得姐动图(报错) # -*- coding:utf-8 -*- #__author__ :kusy #__content__:文件说明 #__date__:2018/7/23 17:01 imp ...