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

66 篇文章 11 订阅

1. 实现步骤

  1. 根据layui官方文档实现前端相应页面
    官方文档:https://www.layui.com/doc/modules/upload.html
  2. 根据官方的上传接口类型,后端使用springboot实现上传接口
    接口类型:该接口返回的相应信息(response)必须是一个标准的 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(配置文件)
# 应用名称
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/

  1. test.html(前端页面)
<!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" media="all">
    <!-- 注意:如果你直接复制所有代码到本地,上述css路径需要改成你本地的 -->
</head>

<body>

<h1 style="text-align: center;">图片上传示例</h1>
<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(文件上传工具包)
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(生成新的文件名)
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工具类)
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模板)
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(配置允许跨域请求)
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
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
    测试结果:
    在这里插入图片描述
  2. H5页面测试
    在这里插入图片描述
    后台返回
    在这里插入图片描述
  3. 图片存储位置
    在这里插入图片描述

4. 项目源码

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

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不愿意做鱼的小鲸鱼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值