本地文章上传&&阿里云文件上传

一、 本地文件上传的步骤

1.1 实现文件上传的service

package com.listudy.service.upload;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

@Service
public class UploadService {

    @Value("${file.uploadFolder}")
    private String uploadFolder;
    @Value("${file.staticPath}")
    private String staticPath;

    /**
     * MultipartFile 这个对象是springMvc提供的文件上传的接受的类,
     * 它的底层自动会去和HttpServletRequest request中的request.getInputStream()融合
     * 从而达到文件上传的效果。也就是告诉你一个道理:
     * 文件上传底层原理是:request.getInputStream()
     *
     * @param multipartFile
     * @param dir
     * @return
     */
    public String uploadImg(MultipartFile multipartFile, String dir) {
        try {
            String realfilename = multipartFile.getOriginalFilename(); // 上传的文件:aaa.jpg
            // 2:截图文件名的后缀
            String imgSuffix = realfilename.substring(realfilename.lastIndexOf("."));// 拿到:.jpg
            // 3:生成的唯一的文件名:能不能用中文名:不能因为统一用英文命名。
            String newFileName = UUID.randomUUID().toString()+imgSuffix;// 将aaa.jpg改写成:SD23423k324-23423ms.jpg
            // 4:日期目录
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd");
            String datePath = dateFormat.format(new Date());// 日期目录:2021/10/27
            // 5: 指定文件上传以后的目录
            String servrepath = uploadFolder;// 这不是tomcat服务目录,别人不认识
            File targetPath = new File(servrepath+dir,datePath);// 生成一个最终目录:F://tmp/avatar/2021/10/27
            if(!targetPath.exists()){
                targetPath.mkdirs(); // 如果目录不存在:F://tmp/avatar/2021/10/27 递归创建
            }
            // 6: 指定文件上传以后的服务器的完整的文件名
            File targetFileName = new File(targetPath,newFileName);// 文件上传以后在服务器上最终文件名和目录是:F://tmp/avatar/2021/10/27/SD23423k324-23423ms.jpg
            // 7: 文件上传到指定的目录
            multipartFile.transferTo(targetFileName);//将用户选择的aaa.jpg上传到F://tmp/avatar/2021/10/27/SD23423k324-23423ms.jpg
            // 可访问的路径要返回页面
            String filename = dir+"/"+datePath+"/"+newFileName;
            return staticPath+"/upimages/"+filename;
        } catch (IOException e) {
            e.printStackTrace();
            return "fail";
        }
    }


    /**
     * MultipartFile 这个对象是springMvc提供的文件上传的接受的类,
     * 它的底层自动会去和HttpServletRequest request中的request.getInputStream()融合
     * 从而达到文件上传的效果。也就是告诉你一个道理:
     * 文件上传底层原理是:request.getInputStream()
     *
     * @param multipartFile
     * @param dir
     * @return
     */
    public Map<String,Object> uploadImgMap(MultipartFile multipartFile, String dir) {
        try {
            String realfilename = multipartFile.getOriginalFilename(); // 上传的文件:aaa.jpg
            // 2:截图文件名的后缀
            String imgSuffix = realfilename.substring(realfilename.lastIndexOf("."));// 拿到:.jpg
            // 3:生成的唯一的文件名:能不能用中文名:不能因为统一用英文命名。
            String newFileName = UUID.randomUUID().toString()+imgSuffix;// 将aaa.jpg改写成:SD23423k324-23423ms.jpg
            // 4:日期目录
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd");
            String datePath = dateFormat.format(new Date());// 日期目录:2021/10/27
            // 5: 指定文件上传以后的目录
            String servrepath = uploadFolder;// 这不是tomcat服务目录,别人不认识
            File targetPath = new File(servrepath+dir,datePath);// 生成一个最终目录:F://tmp/avatar/2021/10/27
            if(!targetPath.exists()){
                targetPath.mkdirs(); // 如果目录不存在:F://tmp/avatar/2021/10/27 递归创建
            }
            // 6: 指定文件上传以后的服务器的完整的文件名
            File targetFileName = new File(targetPath,newFileName);// 文件上传以后在服务器上最终文件名和目录是:F://tmp/avatar/2021/10/27/SD23423k324-23423ms.jpg
            // 7: 文件上传到指定的目录
            multipartFile.transferTo(targetFileName);//将用户选择的aaa.jpg上传到F://tmp/avatar/2021/10/27/SD23423k324-23423ms.jpg
            // 可访问的路径要返回页面
            // http://localhpst:8777/bbs/2021/10/27/5f61dea2-4b77-4068-8d0b-fdf415eac6df.png
            String filename = dir+"/"+datePath+"/"+newFileName;

            Map<String,Object> map = new HashMap<>();
            map.put("url",staticPath+"/upimages/"+filename);
            map.put("size",multipartFile.getSize());
            map.put("ext",imgSuffix);
            map.put("filename",realfilename);
            map.put("rpath",dir+"/"+datePath+"/"+newFileName);

            // ftp 远程服务器文件io
            return map;
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }

}

1.2 实现文件上传controller

package com.listudy.controller.upload;

import com.alibaba.fastjson.JSONObject;
import com.kuangstudy.service.upload.UploadService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

/**
 * @Description
 * @Author lya
 * @Date 2021-12-15 14:04
 */
@Controller
public class UploadController {
    private static final Logger LOGGER = LoggerFactory.getLogger(UploadController.class);

    @Autowired
    private UploadService uploadService;

    /**
     * 本地文件直接返回图片地址
     * @param file
     * @param request
     * @return
     * @throws IOException
     * @throws ServletException
     */
    @PostMapping("/api/local/upload")
    @ResponseBody
    public String upload(@RequestParam("file") MultipartFile file, HttpServletRequest request) throws IOException, ServletException {
        if (file.isEmpty()) {
            return "上传失败,请选择文件";
        }
        String dir = request.getParameter("dir");
        if(StringUtils.isEmpty(dir)){
            dir = "course";
        }
        // handler调用文件上传的service 得到文件的虚拟路径
        String filepath = uploadService.uploadImg(file,dir);
        return filepath;
    }


    /**
     * 本地文件上传返回json
     * @param file
     * @param request
     * @return
     * @throws IOException
     * @throws ServletException
     */
    @PostMapping("/api/local/mdupload")
    @ResponseBody
    public Map<String,Object> uploadmdupload(@RequestParam("editormd-image-file") MultipartFile file, HttpServletRequest request) throws IOException, ServletException {
        if (file.isEmpty()) {
            return null;
        }
        String dir = request.getParameter("dir");
        if (StringUtils.isEmpty(dir)) {
            dir = "course";
        }
        // handler调用文件上传的service 得到文件的虚拟路径
        String filepath = uploadService.uploadImg(file, dir);
        Map<String, Object> map = new HashMap<>();
        map.put("path", filepath);
        map.put("url", filepath);
        map.put("success", "1");
        map.put("message", "upload success!");
        return map;
    }

    /**
     * 本地文件上传返回json
     * @param file
     * @param request
     * @return
     * @throws IOException
     * @throws ServletException
     */
    @PostMapping("/api/local/uploadjson")
    @ResponseBody
    public Map<String,Object> uploadJson(@RequestParam("file") MultipartFile file, HttpServletRequest request) throws IOException, ServletException {
        if (file.isEmpty()) {
            return null;
        }
        String dir = request.getParameter("dir");
        if(StringUtils.isEmpty(dir)){
            dir = "course";
        }
        // handler调用文件上传的service 得到文件的虚拟路径
        String filepath = uploadService.uploadImg(file,dir);
        Map<String,Object> map = new HashMap<>();
        map.put("path",filepath);
        map.put("url",filepath);
        return map;
    }
}

1.3 在application.yml配置即可

因为默认情况下,文件上传的限制大小是:1M 。可能是不够的。所以需要打开。

spring:
  servlet:
    multipart:
      enabled: true
      # 是单个文件大小 默认1M
      max-file-size: 5MB
      # 是设置总上传的数据大小
      max-request-size: 10MB
      #当文件达到多少时进行磁盘写入
      file-size-threshold: 20MB

application-dev.yml配置如下:

# 服务器配置
file:
  # 资源的服务
  staticPath: http://localhost:9888
  # 文件上传的映射路径
  staticPatternPath: /upimages/**
  # 文件上传的存储目录
  uploadFolder: F://tmp/

application-prod.yml配置如下:

# 服务器配置
file:
  # 资源的服务
  staticPath: http://localhost:9888
  # 文件上传的映射路径
  staticPatternPath: /upimages/**
  # 文件上传的存储目录
  uploadFolder: /www/upload/

1.4 配置静态资源服务目录映射

新建springmvc的配置类

/**
 * Description:
 * Author: lya
 * Version: 1.0
 * Create Date Time: 2021/11/15 21:49.
 * Update Date Time:
 *
 * @see
 */
@Configuration
public class WebMvcConfiguration implements WebMvcConfigurer {

    @Value("${file.staticPatternPath}")
    private String staticPatternPath;
    @Value("${file.uploadFolder}")
    private String uploadFolder;
    /*
     * @Author lya
     * @Description 静态资源路径映射
     *  其实就自定义静态资源服务器
     * @Date 20:11 2021/12/18
     * @Param [registry]
     * @return void
     **/
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler(staticPatternPath).addResourceLocations("file:" + uploadFolder);
    }
}

1.5 对接webuploader文件上传

官网地址:http://fex.baidu.com/webuploader/getting-started.html

  1. 先下载webuploader。把下载的文件放入到static/js目录下:
    在这里插入图片描述
  2. 打开add.html 引入依赖
<script src="/js/jquery.min.js"></script>
<link rel="stylesheet" type="text/css" href="/js/webuploader/webuploader.css">
<script  type="text/javascript"  src="/js/webuploader/webuploader.js"></script>
  1. 定义目标位置
  <span style="position: relative">
      <input type="text" id="article-img"  v-model="blog.img"  ref="blogimg" class="article-title"
      placeholder="上传封面图" style="width: 18%; font-weight:400;font-size: 12px;position: relative;top:-2px;">
      <span id="filePicker" style="position: absolute;top:-10px;right:20px;">选择图片</span>
      <img style="position: absolute;top:-10px;right:-40px;" width="48" height="40" id="imgshow" alt="">
  </span>
  1. 初始化文件上传
<script>

    // 初始化Web Uploader
    var uploader = WebUploader.create({
        // 选完文件后,是否自动上传。
        auto: true,
        // 内部根据当前运行是创建,可能是input元素,也可能是flash.
        pick:{
            id:'#filePicker',
            multiple:false // 默认是:true代表选择多张上传,false只能选择一张上传
        },
        // swf文件路径
        swf:  '/js/webuploader/Uploader.swf',
        // 文件接收服务端。
        server: '/api/local/uploadjson?dir=blogs',
        // 选择文件的按钮。可选。
        // 只允许选择图片文件。
        accept: {
            title: 'Images',
            extensions: 'gif,jpg,jpeg,bmp,png',
            mimeTypes: 'image/*'
        }
    });

    // 文件上传成功的回调
    uploader.on( 'uploadSuccess', function( file,response ) {
        // 把上传的图片放入到input框中
        document.getElementById("article-img").value = response.url;
        // 把图片放入到img标签进行展示
        document.getElementById("imgshow").src = response.url;
    });

</script>

二、 阿里云上传

2.1 申请oss阿里云服务

阿里云oss注册:https://oss.console.aliyun.com/overview
阿里云oss文件存储,默认情况下是免费上传,但是不能显示(不必须要购买流量才可以访问).

2.2 对接oss的sdk

参考地址:https://help.aliyun.com/document_detail/32009.html

2.3 添加oss的依赖

<dependency>
    <groupId>com.aliyun.oss</groupId>
    <artifactId>aliyun-sdk-oss</artifactId>
    <version>3.10.2</version>
</dependency>
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.72</version>
</dependency>

2.4 实现文件上传的功能

// yourEndpoint填写Bucket所在地域对应的Endpoint。以华东1(杭州)为例,Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。
String endpoint = "oss-cn-guangzhou.aliyuncs.com";
// 阿里云账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维,请登录RAM控制台创建RAM用户。
String accessKeyId = "LTAI5tKhZtakAU4JHciGtUvg";
String accessKeySecret = "yourAccessKeySecret";
// 填写Bucket名称,例如examplebucket。
String bucketName = "examplebucket";

OSS ossClient = null;
try {
    // 创建OSSClient实例。
    ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);

    // 创建存储空间。
    ossClient.createBucket(bucketName);
} catch (OSSException e){
    e.printStackTrace();
} finally {
    // 关闭OSSClient。
    ossClient.shutdown();
}

2.5 具体实现文件上传

常量类

package com.listudy.service.upload;

public class AliyunOssConstans {
    public static String endPoint = "xxxxxx";
    public static String accessKeyId = "xxx";
    public static String accessKeySecret = "xxxx";
    public static String bucketName = "xxxxxx";
}

具体的文件上传类:OssUploadService.java

package com.listudy.service.upload;

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.CannedAccessControlList;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;

@Service
public class OssUploadService {

    public static void main(String[] args) {
        String uploadfile = new OssUploadService().uploadfile(new File("f://a.txt"));
        System.out.println(uploadfile);
    }

    /**
     * 本地文件上传
     * @param multipartFile
     * @return
     */
    public String uploadfile(File multipartFile) {
        // yourEndpoint填写Bucket所在地域对应的Endpoint。以华东1(杭州)为例,Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。
        String endpoint = AliyunOssConstans.endPoint;
        // 阿里云账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维,请登录RAM控制台创建RAM用户。
        String accessKeyId = AliyunOssConstans.accessKeyId;
        String accessKeySecret =  AliyunOssConstans.accessKeySecret;
        // 填写Bucket名称,例如examplebucket。
        String bucketName = AliyunOssConstans.bucketName;
        OSS ossClient = null;
        try {
            // 创建OSSClient实例。
            ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
            if (!ossClient.doesBucketExist(bucketName)) {
                //创建bucket
                ossClient.createBucket(bucketName);
                //设置oss实例的访问权限:公共读
                ossClient.setBucketAcl(bucketName, CannedAccessControlList.PublicRead);
            }

            // 2: 获取文件上传的流
            InputStream inputStream = new FileInputStream(multipartFile);
            // 3:构建日期目录
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd");
            String datePath = dateFormat.format(new Date());// 日期目录:2021/10/27

            // 4: 获取文件名
            String originname = multipartFile.getName();
            String filename = UUID.randomUUID().toString();
            String suffix = originname.substring(originname.lastIndexOf("."));
            String newName = filename + suffix;
            String fileUrl = datePath + "/" + newName;
            //5:文件上传到阿里云服务器
            ossClient.putObject(bucketName, fileUrl, inputStream);
            return "https://" + bucketName + "." + endpoint + "/" + fileUrl;
        } catch (Exception e) {
            e.printStackTrace();
            return "fail";
        } finally {
            ossClient.shutdown();
        }
    }

    /**
     * 基础程序上传
     * @param multipartFile
     * @param dir
     * @return
     */
    public  String uploadfile(MultipartFile multipartFile,String dir) {
        // yourEndpoint填写Bucket所在地域对应的Endpoint。以华东1(杭州)为例,Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。
        String endpoint = AliyunOssConstans.endPoint;
        // 阿里云账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维,请登录RAM控制台创建RAM用户。
        String accessKeyId = AliyunOssConstans.accessKeyId;
        String accessKeySecret =  AliyunOssConstans.accessKeySecret;
        // 填写Bucket名称,例如examplebucket。
        String bucketName = AliyunOssConstans.bucketName;
        OSS ossClient = null;
        try {
            // 创建OSSClient实例。
            ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);

            // 2: 获取文件上传的流
            InputStream inputStream = multipartFile.getInputStream();
            // 3:构建日期目录
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd");
            String datePath = dateFormat.format(new Date());// 日期目录:2021/10/27

            // 4: 获取文件名
            String originname = multipartFile.getOriginalFilename();
            String filename = UUID.randomUUID().toString();
            String suffix = originname.substring(originname.lastIndexOf("."));
            String newName = filename + suffix;
            String fileUrl = dir+"/"+datePath + "/" + newName;
            //5:文件上传到阿里云服务器
            ossClient.putObject(bucketName, fileUrl, inputStream);

            return "https://" + bucketName + "." + endpoint + "/" + fileUrl;
        } catch (Exception e) {
            e.printStackTrace();
            return "fail";
        } finally {
            ossClient.shutdown();
        }

    }
}

controller

package com.listudy.controller.upload;

import com.alibaba.fastjson.JSONObject;
import com.kuangstudy.service.upload.OssUploadService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.Optional;

@RestController
public class OssController {

    @Autowired
    private OssUploadService ossUploadService;

    @PostMapping("/api/oss/upload")
    public JSONObject fileUpload(@RequestParam(value = "editormd-image-file", required = true) MultipartFile file, HttpServletRequest request) throws IOException {
        String dir = Optional.ofNullable(request.getParameter("dir")).orElse("bbs");
        // 上传图片文件到oss
        String url = ossUploadService.uploadfile(file, dir);
        //给editormd进行回调
        JSONObject res = new JSONObject();
        res.put("url", url);
        res.put("success", "1");
        res.put("message", "upload success!");
        return res;
    }

    @PostMapping("/api/oss/uploadfile")
    public JSONObject fileUpload2(@RequestParam(value = "file", required = true) MultipartFile file, HttpServletRequest request) throws IOException {
        String dir = Optional.ofNullable(request.getParameter("dir")).orElse("bbs");
        // 上传图片文件到oss
        String url = ossUploadService.uploadfile(file, dir);
        //给editormd进行回调
        JSONObject res = new JSONObject();
        res.put("url", url);
        res.put("success", "1");
        res.put("message", "upload success!");
        return res;
    }
}

2.6 editormd对接文件上传

springboot默认情况下,文件上传的大小是:1M。如果异常,在application.yml配置即可:

spring:
  servlet:
    multipart:
      enabled: true
      # 是单个文件大小 默认1M
      max-file-size: 5MB
      # 是设置总上传的数据大小
      max-request-size: 10MB
      #当文件达到多少时进行磁盘写入
      file-size-threshold: 20MB

在editormd对接文件上传

testEditor = editormd("article-content", {
        width: "100%",
        height: "82vh",
        path: '/js/editormd/lib/',
        theme: "white",
        previewTheme: "white",
        editorTheme: "pastel-on-white",
        markdown: "",
        codeFold: true,
        saveHTMLToTextarea: true, // 保存 HTML 到 Textarea
        searchReplace: true,
        //watch : false,                // 关闭实时预览
        htmlDecode: "style,script,iframe|on*", // 开启 HTML 标签解析,为了安全性,默认不开启
        //toolbar  : false,             //关闭工具栏
        //previewCodeHighlight : false, // 关闭预览 HTML 的代码块高亮,默认开启
        emoji: true,
        taskList: true,
        tocm: true, // Using [TOCM]
        tex: true, // 开启科学公式TeX语言支持,默认关闭
        flowChart: true, // 开启流程图支持,默认关闭
        sequenceDiagram: true, // 开启时序/序列图支持,默认关闭,
        dialogLockScreen: false, // 设置弹出层对话框不锁屏,全局通用,默认为true
        dialogShowMask: false, // 设置弹出层对话框显示透明遮罩层,全局通用,默认为true
        dialogDraggable: false, // 设置弹出层对话框不可拖动,全局通用,默认为true
        dialogMaskOpacity: 0.4, // 设置透明遮罩层的透明度,全局通用,默认值为0.1
        dialogMaskBgColor: "#000", // 设置透明遮罩层的背景颜色,全局通用,默认为#fff
        imageUpload: true,
        imageFormats: ["jpg", "jpeg", "gif", "png", "bmp", "webp"],
        imageUploadURL: "/api/oss/upload?dir=blogs", // ***********************************在这个里指定文件上传即可
        onload: function () {
            var cacheContent = window.localStorage.getItem("kss_blog_content");
            if(cacheContent){
                testEditor.setMarkdown(cacheContent);
            }
        },
        onchange:function(){
            cacheBlog();
        }
    });
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值