文章目录
一、 本地文件上传的步骤1.1 实现文件上传的service1.2 实现文件上传controller1.3 在application.yml配置即可1.4 配置静态资源服务目录映射1.5 对接webuploader文件上传二、 阿里云上传2.1 申请oss阿里云服务2.2 对接oss的sdk2.3 添加oss的依赖2.4 实现文件上传的功能2.5 具体实现文件上传2.6 editormd对接文件上传一、 本地文件上传的步骤
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;@Servicepublic 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());// 日期目录:/10/27// 5: 指定文件上传以后的目录String servrepath = uploadFolder;// 这不是tomcat服务目录,别人不认识File targetPath = new File(servrepath+dir,datePath);// 生成一个最终目录:F://tmp/avatar//10/27if(!targetPath.exists()){targetPath.mkdirs(); // 如果目录不存在:F://tmp/avatar//10/27 递归创建}// 6: 指定文件上传以后的服务器的完整的文件名File targetFileName = new File(targetPath,newFileName);// 文件上传以后在服务器上最终文件名和目录是:F://tmp/avatar//10/27/SD23423k324-23423ms.jpg// 7: 文件上传到指定的目录multipartFile.transferTo(targetFileName);//将用户选择的aaa.jpg上传到F://tmp/avatar//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());// 日期目录:/10/27// 5: 指定文件上传以后的目录String servrepath = uploadFolder;// 这不是tomcat服务目录,别人不认识File targetPath = new File(servrepath+dir,datePath);// 生成一个最终目录:F://tmp/avatar//10/27if(!targetPath.exists()){targetPath.mkdirs(); // 如果目录不存在:F://tmp/avatar//10/27 递归创建}// 6: 指定文件上传以后的服务器的完整的文件名File targetFileName = new File(targetPath,newFileName);// 文件上传以后在服务器上最终文件名和目录是:F://tmp/avatar//10/27/SD23423k324-23423ms.jpg// 7: 文件上传到指定的目录multipartFile.transferTo(targetFileName);//将用户选择的aaa.jpg上传到F://tmp/avatar//10/27/SD23423k324-23423ms.jpg// 可访问的路径要返回页面// http://localhpst:8777/bbs//10/27/5f61dea2-4b77-4068-8d0b-fdf415eac6df.pngString 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 远程服务器文件ioreturn 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 -12-15 14:04*/@Controllerpublic class UploadController {private static final Logger LOGGER = LoggerFactory.getLogger(UploadController.class);@Autowiredprivate UploadService uploadService;/*** 本地文件直接返回图片地址* @param file* @param request* @return* @throws IOException* @throws ServletException*/@PostMapping("/api/local/upload")@ResponseBodypublic 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")@ResponseBodypublic 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")@ResponseBodypublic 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# 是单个文件大小 默认1Mmax-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: /11/15 21:49.* Update Date Time:** @see*/@Configurationpublic class WebMvcConfiguration implements WebMvcConfigurer {@Value("${file.staticPatternPath}")private String staticPatternPath;@Value("${file.uploadFolder}")private String uploadFolder;/** @Author lya* @Description 静态资源路径映射* 其实就自定义静态资源服务器* @Date 20:11 /12/18* @Param [registry]* @return void**/@Overridepublic void addResourceHandlers(ResourceHandlerRegistry registry) {registry.addResourceHandler(staticPatternPath).addResourceLocations("file:" + uploadFolder);}}
1.5 对接webuploader文件上传
官网地址:/webuploader/getting-started.html
先下载webuploader。把下载的文件放入到static/js目录下:
打开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>
定义目标位置
<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>
初始化文件上传
<script>// 初始化Web Uploadervar 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./overview
阿里云oss文件存储,默认情况下是免费上传,但是不能显示(不必须要购买流量才可以访问).
2.2 对接oss的sdk
参考地址:/document_detail/3.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-。String endpoint = "oss-cn-";// 阿里云账号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;@Servicepublic 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-。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)) {//创建bucketossClient.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());// 日期目录:/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-。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());// 日期目录:/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;@RestControllerpublic class OssController {@Autowiredprivate 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");// 上传图片文件到ossString 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");// 上传图片文件到ossString 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# 是单个文件大小 默认1Mmax-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 到 TextareasearchReplace: 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, // 设置弹出层对话框不锁屏,全局通用,默认为truedialogShowMask: false, // 设置弹出层对话框显示透明遮罩层,全局通用,默认为truedialogDraggable: false, // 设置弹出层对话框不可拖动,全局通用,默认为truedialogMaskOpacity: 0.4, // 设置透明遮罩层的透明度,全局通用,默认值为0.1dialogMaskBgColor: "#000", // 设置透明遮罩层的背景颜色,全局通用,默认为#fffimageUpload: 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();}});