一、图片上传介绍

JavaWeb方向编程过程中,实现图片上传有三种方式:

1、传统的基于springMVC的MultipartFile类实现图片上传。

2、基于Ajax的图片上传。

3、基于Base64压缩的图片上传。

二、springMVC图片上传(springboot通用)

此方法的优点是可以将图片和其他的表单元素一起提交到服务器,服务器接受到的图片其实已经存储于容器的临时文件中,进行文件拷贝工作比较简单。

缺点是无法及时看到图片上传的预览效果,图片一旦选择错误只能重新提交。

注:红色代码为关键代码。

1、页面代码

选择头像:

用户名字:

2、config.properties配置文件

创建名为config.properties的配置文件,并且再其中配置图片上传物理路径。注意window和linux的写法不同。

**此配置内容在springboot结构中的application.properties文件中配置**

file.location.path=d:/upload

3、spring-servlet.xml配置文件

**此配置文件在springboot中不需要配置 - “习惯大于配置”**

xmlns:context="http://www.springframework.org/schema/context"

xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:p="http://www.springframework.org/schema/p"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans.xsd

http://www.springframework.org/schema/context

http://www.springframework.org/schema/context/spring-context.xsd

http://www.springframework.org/schema/mvc

http://www.springframework.org/schema/mvc/spring-mvc.xsd">

p:prefix="/" p:suffix=".jsp"/>

4、controller代码

若是一次上传多个文件,需要使用注解@RequestParam("inputName") 指明该文件对应表单中的input标签的name属性。如果name都是同名的,可以使用MultipartFile [] 文件数组来接收

@Controller

public class UserController {

@Autowired

UserService userService;

@Value("${file.location.path}")

private String fileLocation;

@RequestMapping("/insert")

public String insert(User user, MultipartFile file){

String uri = FileUpload.upload(file,"/upload",fileLocation);

user.setFacePic(uri);

int ret = userService.insertUser(user);

if(ret > 0 ){

return "redirect:/get";

}else{

return "register";

}

}

}

5、上传工具类代码

public class FileUpload {

/**

* @param file 上传的文件

* @param path 文件的虚拟路径,例如 /upload

* @param fileLocation 文件的物理路径,例如d:/upload

* @return 文件的虚拟路径+文件名

*

* fileName.lastIndexOf(".")为获取后缀名

* UUID.randomUUID()为获取唯一标识,保证文件的唯一性

*/

public static String upload(MultipartFile file, String path, String fileLocation) {

String fileFinishName = null;

try {

// 如果目录不存在则创建

File uploadDir = new File(fileLocation);

if (!uploadDir.exists()) {

uploadDir.mkdir();

}

//获取源文件名称

String fileName = file.getOriginalFilename();

fileFinishName = UUID.randomUUID() + fileName.substring(fileName.lastIndexOf("."), fileName.length());

//上传文件到指定目录下

File uploadFile = new File(uploadDir + uploadDir.separator + fileFinishName);

file.transferTo(uploadFile);

} catch (Exception ex) {

ex.printStackTrace();

}

return path + "/" + fileFinishName;

}

}

三、基于Ajax的图片上传

这种方式同第一种方式一样都是使用multipart/form-data方式上传,服务器端同样使用springMVC(springboot)实现所以只有页面代码不一致,其他代码(2、3、4、5)同上。

该方式前端使用的是jQuery的jquery.fileupload.js插件来实现。详见大神文章:https://blog.csdn.net/qq_37936542/article/details/79258158

1、页面先一用jQuery的插件

下载地址:https://github.com/blueimp/jQuery-File-Upload

**顺序不能错误**

2、HTML代码编写

**不需要form标签**

3、js代码

$(function() {

$("#chooseFile").on("click", function() {

$("#uploadImg").click();

});

$('#uploadImg').fileupload({

url : '/upload',//请求发送的目标地址

Type : 'POST',//请求方式 ,可以选择POST,PUT或者PATCH,默认POST

//dataType : 'json',//服务器返回的数据类型

autoUpload : false,

acceptFileTypes : /(gif|jpe?g|png)$/i,//验证图片格式

maxNumberOfFiles : 1,//最大上传文件数目

maxFileSize : 1000000, // 文件上限1MB

minFileSize : 100,//文件下限 100b

messages : {//文件错误信息

acceptFileTypes : '文件类型不匹配',

maxFileSize : '文件过大',

minFileSize : '文件过小'

}

})

//图片添加完成后触发的事件

.on("fileuploadadd", function(e, data) {

//validate(data.files[0])这里也可以手动来验证文件格式和大小

//隐藏或显示页面元素

$('#progress .bar').css(

'width', '0%'

);

$('#progress').hide();

$("#chooseFile").hide();

$("#uploadFile").show();

$("#rechooseFile").show();

//获取图片路径并显示

var url = getUrl(data.files[0]);

$("#image").attr("src", url);

//绑定开始上传事件

$('#uploadFile').click(function() {

$("#uploadFile").hide();

jqXHR = data.submit();

//解绑,防止重复执行

$("#uploadFile").off("click");

})

//绑定点击重选事件

$("#rechooseFile").click(function(){

$("#uploadImg").click();

//解绑,防止重复执行

$("#rechooseFile").off("click");

})

})

//当一个单独的文件处理队列结束触发(验证文件格式和大小)

.on("fileuploadprocessalways", function(e, data) {

//获取文件

file = data.files[0];

//获取错误信息

if (file.error) {

console.log(file.error);

$("#uploadFile").hide();

}

})

//显示上传进度条

.on("fileuploadprogressall", function(e, data) {

$('#progress').show();

var progress = parseInt(data.loaded / data.total * 100, 10);

$('#progress').css(

'width','15%'

);

$('#progress .bar').css(

'width',progress + '%'

);

})

//上传请求失败时触发的回调函数

.on("fileuploadfail", function(e, data) {

console.log(data.errorThrown);

})

//上传请求成功时触发的回调函数

.on("fileuploaddone", function(e, data) {

alert(data.result);

})

//上传请求结束后,不管成功,错误或者中止都会被触发

.on("fileuploadalways", function(e, data) {

})

//手动验证

function validate(file) {

//获取文件名称

var fileName = file.name;

//验证图片格式

if (!/.(gif|jpg|jpeg|png|gif|jpg|png)$/.test(fileName)) {

console.log("文件格式不正确");

return true;

}

//验证excell表格式

/* if(!/.(xls|xlsx)$/.test(fileName)){

alert("文件格式不正确");

return true;

} */

//获取文件大小

var fileSize = file.size;

if (fileSize > 1024 * 1024) {

alert("文件不得大于一兆")

return true;

}

return false;

}

//获取图片地址

function getUrl(file) {

var url = null;

if (window.createObjectURL != undefined) {

url = window.createObjectURL(file);

} else if (window.URL != undefined) {

url = window.URL.createObjectURL(file);

} else if (window.webkitURL != undefined) {

url = window.webkitURL.createObjectURL(file);

}

return url;

}

});

四、基于Base64压缩的图片上传

图片的Base64 编码就是可以将一副图片数据编码成一串字符串,使用该字符串代替图像地址。例如:

基于Base64实现图片上传其实就是在浏览器端先将图片转换成字符串,然后将代表图片的字符串传输到服务器进行存储。需要显示的时候可以将字符串写入直接显示。

该图片上传的方式比较简单,且没有其他的例如跨域提交、头文件等问题。但是其编码后的字符串大小远远大于实际的图片大小。所以只适合上传小尺寸的图片,例如用户头像等。

1、页面代码

$("#img").change(function (e) {

var img = e.target.files[0];

var reader = new FileReader();

reader.readAsDataURL(img);

reader.onload = function (e) {

// ajax 上传图片

$.post("uploadPic", {img: e.target.result}, function (ret) {

if (ret.img != '') {

//显示图片

$('#showimg').attr("src", ret.imgUrl);

}

}, 'json'); }

});

2、服务器接收到Base64字符串,就可以得到图片并且将图片直接存入数据库。这里不再描述。

五、配置图片访问路径

1、Springboot中可以使用下面的代码将虚拟路径/image/**下的图片映射成到D://盘下。

import org.springframework.context.annotation.Configuration;

import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;

import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;

/**

* 图片绝对地址与虚拟地址映射

* 访问地址示例:http://localhost:8080/image/1.png

*/

@Configuration

public class WebMvcConfig extends WebMvcConfigurationSupport {

@Override

public void addResourceHandlers(ResourceHandlerRegistry registry) {

//windows

//registry.addResourceHandler("/image/**").addResourceLocations("file:d://upload/");

//linux和mac

registry.addResourceHandler("/image/**").addResourceLocations("file:/Users/David/upload/");

registry.addResourceHandler("/**").addResourceLocations("classpath:/static/");

}

}

2、如果使用springMVC的SSM框架,则可以在tomcat的service.xml文件中直接配置虚拟路径,代码如下:

参考资料:

https://www.imooc.com/article/27804