1. 实现步骤
- 根据layui官方文档实现前端相应页面 官方文档:https://www.layui.com/doc/modules/upload.html
- 根据官方的上传接口类型,后端使用springboot实现上传接口 接口类型:该接口返回的相应信息(response)必须是一个标准的 JSON 格式,如: json { "code": 0, "msg": "", "data": { "src": "http://cdn.layui.com/123.jpg" } }
- springboot接口实现思路
- 编写一个FileUtils.java工具类实现文件上传到对应的文件夹
- 编写一个FileNameUtils.java工具类实现使用UUID生成新的文件名
- 编写一个ResultVO.java的JavaBean文件用作返回前端的json模板
- Controller实现功能的细节: 1.在配置文件里配置项目部署的地址,在controller文件中获取 @Value("${web.dev-path}") private String path; 2.获取项目编译后的路径: String realPath = ClassUtils.getDefaultClassLoader().getResource("static/upload").getPath(); 3.获取文件名称:String fileName = file.getOriginalFilename(); 4.拼接图片地址 String src = path "upload/" fileName; 5.在返回json中返回拼接的地址,即是项目部署的地址 静态文件目录 文件名
注意:springboot项目启动编译后,会生成一个target的编译文件,图片必须放在该文件夹下面才能被动态映射。否则只能使用file:///E:/xxx.jpg映射本地的路径而无法实现动态映射,也可以另外部署一个映射的文件夹专门用来实现映射图片。
2. 实现代码
- application.properties(配置文件)
# 应用名称
spring.application.name=img-demo
# 应用服务 WEB 访问端口
server.port=8080
# 配置静态资源路径
spring.resources.static-locations=classpath:/resources/,classpath:/static/,classpath:/templates/
### FreeMarker 配置
spring.freemarker.allow-request-override=false
#Enable template caching.启用模板缓存。
spring.freemarker.cache=false
spring.freemarker.check-template-location=true
spring.freemarker.charset=UTF-8
spring.freemarker.content-type=text/html
spring.freemarker.expose-request-attributes=false
spring.freemarker.expose-session-attributes=false
spring.freemarker.expose-spring-macro-helpers=false
#设置面板后缀
spring.freemarker.suffix=.ftl
#Spring Boot修改最大上传文件限制
spring.servlet.multipart.max-file-size=10MB
spring.servlet.multipart.max-request-size=100MB
web.upload-path=D:/devImg
# 项目开发时的地址
web.dev-path=http://localhost:8080/
2.test.html(前端页面)
代码语言:javascript复制<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Layui</title>
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<link rel="stylesheet" href="https://www.layuicdn.com/layui-v2.5.6/css/layui.css" rel="nofollow noopener" media="all">
<!-- 注意:如果你直接复制所有代码到本地,上述css路径需要改成你本地的 -->
</head>
<body>
<h2 style="text-align: center;">图片上传示例</h2>
<fieldset class="layui-elem-field layui-field-title" style="margin-top: 30px;">
<legend>常规使用:普通图片上传</legend>
</fieldset>
<div class="layui-upload" style="text-align: center;">
<button type="button" class="layui-btn" id="test1">上传图片</button>
<div class="layui-upload-list">
<img class="layui-upload-img" id="demo1" width="200px" height="200">
<p id="demoText"></p>
</div>
</div>
<fieldset class="layui-elem-field layui-field-title" style="margin-top: 30px;">
<legend>拖拽上传</legend>
</fieldset>
<div style="display:flex;justify-content: center;">
<div class="layui-upload-drag" id="test2">
<i class="layui-icon"></i>
<p>点击上传,或将文件拖拽到此处</p>
<div class="layui-hide" id="uploadDemoView">
<hr>
<img src="" alt="上传成功后渲染" style="max-width: 196px">
</div>
</div>
</div>
<script src="https://www.layuicdn.com/layui-v2.5.6/layui.js "></script>
<!-- 注意:如果你直接复制所有代码到本地,上述js路径需要改成你本地的 -->
<script>
layui.use('upload', function () {
var $ = layui.jquery,
upload = layui.upload;
//普通图片上传
var uploadInst = upload.render({
elem: '#test1',
url: 'http://localhost:8080/fileUpload' //改成您自己的上传接口
,
before: function (obj) {
console.log('obj :>> ', obj);
//预读本地文件示例,不支持ie8
obj.preview(function (index, file, result) {
$('#demo1').attr('src', result); //图片链接(base64)
});
},
done: function (res) {
//如果上传失败
if (res.code > 0) {
return layer.msg('上传失败');
}
//上传成功
},
error: function () {
//演示失败状态,并实现重传
var demoText = $('#demoText');
demoText.html(
'<span style="color: #FF5722;">上传失败</span> <a class="layui-btn layui-btn-xs demo-reload">重试</a>'
);
demoText.find('.demo-reload').on('click', function () {
uploadInst.upload();
});
}
});
//拖拽上传
upload.render({
elem: '#test2',
url: 'http://localhost:8080/fileUpload' //改成您自己的上传接口
,
done: function (res) {
console.log('res :>> ', res);
layer.msg('上传成功');
layui.$('#uploadDemoView').removeClass('layui-hide').find('img').attr('src', res
.data.src);
console.log(res)
}
});
});
</script>
</body>
</html>
- FileUtils.java(文件上传工具包)
package cn.kt.imgdemo.utils;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;
/**
* @author tao
* @date 2021-02-16 20:05
* 概要:文件上传工具包
*/
public class FileUtils {
/**
*
* @param file 文件
* @param path 文件存放路径
* @param fileName 源文件名
* @return
*/
public static boolean upload(MultipartFile file, String path, String fileName){
// 生成新的文件名
//String realPath = path "/" FileNameUtils.getFileName(fileName);
System.out.println(path);
//使用原文件名
String realPath = path "/" fileName;
File dest = new File(realPath);
//判断文件父目录是否存在
if(!dest.getParentFile().exists()){
dest.getParentFile().mkdir();
}
try {
//保存文件
file.transferTo(dest);
return true;
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return false;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return false;
}
}
}
- FileNameUtils.java(生成新的文件名)
package cn.kt.imgdemo.utils;
/**
* @author tao
* @date 2021-02-16 22:37
* 概要:生成新的文件名
*/
public class FileNameUtils {
/**
* 获取文件后缀
* @param fileName
* @return
*/
public static String getSuffix(String fileName){
return fileName.substring(fileName.lastIndexOf("."));
}
/**
* 生成新的文件名
* @param fileOriginName 源文件名
* @return
*/
public static String getFileName(String fileOriginName){
return UUIDUtils.getUUID() FileNameUtils.getSuffix(fileOriginName);
}
}
- UUIDUtils.java(UUID工具类)
package cn.kt.imgdemo.utils;
import java.util.UUID;
/**
* @author tao
* @date 2021-02-16 20:01
* 概要:生成文件名
*/
public class UUIDUtils {
public static String getUUID(){
return UUID.randomUUID().toString().replace("-", "");
}
}
- ResultVO.java(用来返回前端的json模板)
package cn.kt.imgdemo.domain;
/**
* @author tao
* @date 2021-02-22 20:25
* 概要:用来返回前端的json模板
*/
public class ResultVO<T>{
/** 错误码. */
private Integer code;
/** 提示信息. */
private String msg;
/** 具体内容. */
private T data;
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
@Override
public String toString() {
return "ResultVO{"
"code=" code
", msg='" msg '''
", data=" data
'}';
}
}
- CommonIntercepter.java(配置允许跨域请求)
package cn.kt.imgdemo.config;
/**
* @author tao
* @date 2021-02-18 13:18
* 概要:
*/
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
/**
* @author tao
* @date 2021-01-25 4:08
* 概要:配置允许跨域请求
*/
@Configuration
public class CommonIntercepter {
private CorsConfiguration buildConfig() {
CorsConfiguration corsConfiguration = new CorsConfiguration();
//允许任何域名
corsConfiguration.addAllowedOrigin("*");
//允许任何头
corsConfiguration.addAllowedHeader("*");
//允许任何方法
corsConfiguration.addAllowedMethod("*");
return corsConfiguration;
}
@Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
//注册
source.registerCorsConfiguration("/**", buildConfig());
return new CorsFilter(source);
}
}
- ImgTestController.java
package cn.kt.imgdemo.controller;
import cn.kt.imgdemo.domain.ResultVO;
import cn.kt.imgdemo.utils.FileUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.ResourceLoader;
import org.springframework.stereotype.Controller;
import org.springframework.util.ClassUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import java.util.HashMap;
import java.util.Map;
/**
* @author tao
* @date 2021-02-16 20:10
* 概要:
*/
@Controller
public class ImgTestController {
private final ResourceLoader resourceLoader;
@Autowired
public ImgTestController(ResourceLoader resourceLoader) {
this.resourceLoader = resourceLoader;
}
@Value("${web.dev-path}")
private String path;
/**
* 跳转到文件上传页面
*
* @return
*/
@RequestMapping("test")
public String toUpload() {
return "test.html";
}
/**
* @param file 要上传的文件
* @return
*/
@RequestMapping("fileUpload")
@ResponseBody
public ResultVO upload(MultipartFile file) {
// 要上传的目标文件存放路径
//获取项目编译后的路径
String realPath = ClassUtils.getDefaultClassLoader().getResource("static/upload").getPath();
//System.out.println("我是编译后的路径" realPath);
// 上传成功或者失败的提示
String msg = "";
if (FileUtils.upload(file, realPath, file.getOriginalFilename())) {
// 上传成功,给出页面提示
msg = "上传成功!";
} else {
msg = "上传失败!";
}
//获取文件名称
String fileName = file.getOriginalFilename();
//拼接图片地址
String src = path "upload/" fileName;
/*
******** 在这里可以编写service层代码,对图片路径进行存储 ***************
*/
Map<String, String> map = new HashMap<>();
map.put("src", src);
/*返回给前端的json*/
ResultVO resultVO = new ResultVO();
resultVO.setCode(0);
resultVO.setMsg(msg);
resultVO.setData(map);
System.out.println(resultVO);
return resultVO;
}
}
3. 图片上传测试
- postman测试 测试路径:http://localhost:8080/fileUpload 测试结果:
- H5页面测试
后台返回
- 图片存储位置
4. 项目源码
链接:https://pan.baidu.com/s/1rkiT2z-Kt3ghbBeHaaEvVw 提取码:vkym 复制这段内容后打开百度网盘手机App,操作更方便哦