Spring学习笔记(二十二)——实现图片上传功能(layui)

2022-09-26 18:05:29 浏览数 (1)

1. 实现步骤

  1. 根据layui官方文档实现前端相应页面 官方文档:https://www.layui.com/doc/modules/upload.html
  2. 根据官方的上传接口类型,后端使用springboot实现上传接口 接口类型:该接口返回的相应信息(response)必须是一个标准的 JSON 格式,如: json { "code": 0, "msg": "", "data": { "src": "http://cdn.layui.com/123.jpg" } }
  3. 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. 实现代码

  1. application.properties(配置文件)
代码语言:javascript复制
# 应用名称
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>
  1. FileUtils.java(文件上传工具包)
代码语言:javascript复制
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;
        }
    }
}
  1. FileNameUtils.java(生成新的文件名)
代码语言:javascript复制
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);
    }
}
  1. UUIDUtils.java(UUID工具类)
代码语言:javascript复制
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("-", "");
    }
}
  1. ResultVO.java(用来返回前端的json模板)
代码语言:javascript复制
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  
                '}';
    }
}
  1. CommonIntercepter.java(配置允许跨域请求)
代码语言:javascript复制
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);
    }
}
  1. ImgTestController.java
代码语言:javascript复制
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. 图片上传测试

  1. postman测试 测试路径:http://localhost:8080/fileUpload 测试结果:
  1. H5页面测试

后台返回

  1. 图片存储位置

4. 项目源码

链接:https://pan.baidu.com/s/1rkiT2z-Kt3ghbBeHaaEvVw 提取码:vkym 复制这段内容后打开百度网盘手机App,操作更方便哦

0 人点赞