博客地址: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. layui中select实现二级关联

    目的:实现店铺和仓库的二级关联,通过选择不同的店铺,来显示这个门店对应的库位信息. 1. 在select选项上添加lay-filter选择器. <div class="layui-in ...

  2. 安装MySQL Server

    之前安装了MySQL Workbench 8.0 CE,现在来安装MySQL Server. 点击 add next next next     完成 MySQL安装包地址: 链接:https://p ...

  3. [整理]如何撤销远程的git提交?

    确保你在你想要撤销的分支上. 第一步,本地使用 get reset --hard ,切换到特定的commit. 第二部,使用 --force推送到远程分支. git reset --hard cedc ...

  4. 设置驱动的方法(Chrome 亲测ok)

    驱动下载地址 http://selenium-release.storage.googleapis.com/index.html package com.selenium.java.webdriver ...

  5. jvm 性能调优工具之 jmap 命令详解

    jmap名称:Java Memory Map(内存映射) 官方文档:https://docs.oracle.com/javase/1.5.0/docs/tooldocs/share/jmap.html ...

  6. vs2015 debug时出现 C2039“cout”: 不是“std”的成员

    今天想起电脑上的vs2015,发现好久没用了,用了下,遇到了一个问题 由于不常用c++,还是觉得应该记录下来,以免下次遇到,不知怎么处理 新建项目Hello Hello.cpp #include &q ...

  7. AspNetCore 2.2 新特性---HealthCheck

    网站部署上线后, 总是担心网站是否工作正常, 内存压力是否很大, CPU是否超负荷了?当然, 我们有一大套系统, perfromance counter, 监控软件来监视运维生产系统.但是这些第三方软 ...

  8. python的帮助信息的写法

    # coding = utf-8from optparse import OptionParserfrom optparse import OptionGroup usage = 'Usage: %p ...

  9. kafka备份原理

  10. 如何使用RedisTemplate访问Redis数据结构之Zset

    Redis的ZSet数据结构 Redis 有序集合和无序集合一样也是string类型元素的集合,且不允许重复的成员. 不同的是每个元素都会关联一个double类型的分数.redis正是通过分数来为集合 ...