最近在搭建博客系统,使用的markdown编辑器是editor.md,这个编辑器虽然十分美观,但是作者已经很久不维护了,能用但是不怎么好用,尤其是图片上传十分蛋疼
以下皆来自大佬的博客内容
首先说遇到的问题,在搭建博客的过程中,我遇到了editor.md这个富文本编辑器,不能上传本地图片这样难受的事情,下面废话不多说,直接解决问题
在富文本编辑页面,在javascript中加上 imageUpload : true, //开启图片上传
//初始化Markdown编辑器
var contentEditor;
$(function() {
contentEditor = editormd("md-content", {//注意1:这里的就是上面的DIV的id属性值
placeholder:'本编辑器支持Markdown编辑,左边编写,右边预览', //默认显示的文字,这里就不解释了
width : "100%",
height : 640,
syncScrolling : "single",
// path : "../static/lib/editormd/lib/"
path : "/lib/editormd/lib/",//注意2:你的路径 就是editor的lib目录
saveHTMLToTextarea : true,//注意3:这个配置,方便post提交表单
theme: "dark",//工具栏主题
previewTheme: "dark",//预览主题
editorTheme: "pastel-on-dark",//编辑主题
saveHTMLToTextarea: true,
emoji: false,
taskList: true,
tocm: true, // Using [TOCM]
tex: true, // 开启科学公式TeX语言支持,默认关闭
flowChart: true, // 开启流程图支持,默认关闭
sequenceDiagram: true, // 开启时序/序列图支持,默认关闭,
/**上传图片相关配置如下*/
imageUpload : true, //开启图片上传
imageFormats : ["jpg", "jpeg", "gif", "png", "bmp", "webp"],
imageUploadURL : "/img/imgUpLoad", //上传的路径,就是mvc的controller路径
});
});
然后创建一个专门用于图片上传的控制类
import cn.hutool.json.JSONObject;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.UUID;
/**
* @ClassName FileUpController
* @Description
* @Author 51
* @Date 2019年11月28日 上午10:19:12
*/
@Controller
@RequestMapping("/img")
public class FileUploadController {
@RequestMapping("/imgUpLoad")
public void imageUpload(@RequestParam(value = "editormd-image-file", required = true) MultipartFile file,
HttpServletRequest request, HttpServletResponse response){
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
PrintWriter wirte = null;
JSONObject json = new JSONObject();
try {
wirte = response.getWriter();
//文件存放的路径
//得到工程的路径:
System.out.println("得到工程的路径:"+System.getProperty("user.dir"));//user.dir指定了当前的路径
//得到工程目录:
System.out.println( "得到工程目录:"+request.getSession().getServletContext().getRealPath("")); //参数可具体到包名
//得到IE地址栏地址 request.getRequestURL()
System.out.println( "得到IE地址栏地址 :"+ request.getRequestURL());
// 得到相对地址:request.getRequestURI()
System.out.println( "得到相对地址:"+ request.getRequestURI());
// String path=request.getServletContext().getRealPath("")+"uploaded";
String path=System.getProperty("user.dir")+"\\src\\main\\resources\\static\\upload\\";
String fileName = file.getOriginalFilename();
fileName= UUID.randomUUID()+fileName.substring(fileName.indexOf("."),fileName.length());
String destFileName=path+fileName;
System.out.println("path:"+path);
File destFile = new File(destFileName);
if(!destFile.exists()){
destFile.getParentFile().mkdirs();
}
//String url =destFileName;
//file.transferTo(destFile);
String url = "http://localhost:8080"
+ "//upload/"
+ fileName;
System.out.println("url:"+url);
file.transferTo(destFile);
json.put("success", 1);
json.put("message", "上传成功");
json.put("url", url);
} catch (IllegalStateException | IOException e) {
json.put("success", 0);
json.put("message", "上传失败");
}finally{
wirte.print(json);
wirte.flush();
wirte.close();
}
}
}
在这里我遇到了很多路径找不到的问题,我输出了很多路径,如果你正在看这篇文章的话,一定要注意好路径的输出,确定好你的图片要存储到那里,以及返回的时候要返回的路径,我这里把所有的路径都列了出来,自己再按自己需要拼接成字符串,进行存储访问,我的保存路径是
String path=System.getProperty("user.dir")+"\\src\\main\\resources\\static\\upload\\";
输出来应该是这个路径
D:\Workspaces\IDEA\blog\src\main\resources\static\upload\
我的返回路径是
String url = "http://localhost:8080"
+ "//upload/"
+ fileName;
输出来返回路径是这个
http://localhost:8080//upload/ad27e6b6-a38d-4afb-9d74-40c4257f107d.png
现在再存储图片发现,图片确实是存储进来了,但是,回显成了问题,访问地址没有出错为什么会显示不出来呢,经过几次是尝试,我发现,当springboot重启后,再访问图片就能回显出来了,那我就开始怀疑是缓存的问题,后来发现也不对,百度了一下,这里涉及到需要配置虚拟路径映射访问,因为对服务器的保护措施导致的,服务器不能对外部暴露真实的资源路径。
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
/**
* Created by limi on 2017/10/15.
*/
@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
//获取文件的真实路径 work_project代表项目工程名 需要更改
String path = System.getProperty("user.dir") + "\\src\\main\\resources\\static\\upload\\";
String os = System.getProperty("os.name");
if (os.toLowerCase().startsWith("win")) {
registry.addResourceHandler("/upload/**").
addResourceLocations("file:" + path);
} else {//linux和mac系统 可以根据逻辑再做处理
registry.addResourceHandler("/upload/**").
addResourceLocations("file:" + path);
}
super.addResourceHandlers(registry);
}
}
修改了一下,图片正常显示就可以了,问题解决!!!
这是上传到服务器项目包里,图片量小还能接受,但是如果大量就十分致命,所以我急需一个图床来保存我的图片,我的选择是七牛云和阿里云,但是阿里云现在改了,必须要有自己的域名,你上传图片显示出来的url在浏览器中打开才不会下载附件而是展示图片。七牛云是一个不错的选择,而且注册就送10GB容量,还会给你一个30天的测试域名,很不错。
以下是我在大佬的基础上进行修改
在项目配置文件中添加七牛云必要信息
建一个工具类QiNiuYunUtil
import com.google.gson.Gson;
import com.qiniu.common.QiniuException;
import com.qiniu.common.Zone;
import com.qiniu.http.Response;
import com.qiniu.storage.Configuration;
import com.qiniu.storage.UploadManager;
import com.qiniu.storage.model.DefaultPutRet;
import com.qiniu.util.Auth;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.io.FileInputStream;
/**
* @Author GongJing
* @Date 2020/12/1 11:08
* @Version 1.0
* @Component 将类实例化到SPRING容器中
* @ConfigurationProperties 指定前缀读取配置文件
*/
@Component
@ConfigurationProperties(prefix = "qiniu")
public class QiNiuYunUtil {
/**
* AccessKey
*/
private String accessKey;
/**
* SecretKey
*/
private String secretKey;
/**
* 存储空间名
*/
private String bucket;
/**
* 外链
*/
private String path;
/**
* 将图片上传到七牛云
*/
public String uploadQiniuYun(FileInputStream file) {
System.out.println("accessKey=" + accessKey);
// zone0华东区域,zone1是华北区域,zone2是华南区域
Configuration cfg = new Configuration(Zone.zone0());
UploadManager uploadManager = new UploadManager(cfg);
// 生成上传凭证,然后准备上传
try {
Auth auth = Auth.create(accessKey, secretKey);
String upToken = auth.uploadToken(bucket);
try {
Response response = uploadManager.put(file, null, upToken, null, null);
// 解析上传成功的结果
DefaultPutRet putRet = new Gson().fromJson(response.bodyString(), DefaultPutRet.class);
return path + "/" + putRet.key;
} catch (QiniuException ex) {
Response r = ex.response;
System.err.println(r.toString());
try {
System.err.println(r.bodyString());
} catch (QiniuException ex2) {
}
}
} catch (Exception e) {
e.printStackTrace();
}
return "";
}
public String getAccessKey() {
return accessKey;
}
public void setAccessKey(String accessKey) {
this.accessKey = accessKey;
}
public String getSecretKey() {
return secretKey;
}
public void setSecretKey(String secretKey) {
this.secretKey = secretKey;
}
public String getBucket() {
return bucket;
}
public void setBucket(String bucket) {
this.bucket = bucket;
}
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
}
上传控制层修改
import cn.hutool.json.JSONObject;
import com.gongjing.util.QiNiuYunUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.UUID;
/**
* @Author GongJing
* @Date 2020/11/29 16:25
* @Version 1.0
*/
@Controller
@RequestMapping("/img")
public class FileUploadController {
@Autowired
private QiNiuYunUtil qiNiuYunUtil;
@RequestMapping("/imgUpLoad")
public void imageUpload(@RequestParam(value = "editormd-image-file", required = true) MultipartFile[] files,
HttpServletRequest request, HttpServletResponse response){
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
PrintWriter wirte = null;
JSONObject json = new JSONObject();
if (files != null && files.length > 0) {
for (int i = 0; i < files.length; i++) {
try {
wirte = response.getWriter();
FileInputStream fileInputStream = (FileInputStream) files[i].getInputStream();
String url = "http://" + qiNiuYunUtil.uploadQiniuYun(fileInputStream);
//输出url上传后的,可以复制url到浏览器访问
System.out.println("url=" + url);
json.set("success", 1);
json.set("message", "上传成功");
json.set("url", url);
try {
//延迟两秒让七牛云缓一下
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
} catch (IOException e) {
json.set("success", 0);
json.set("message", "上传失败");
e.printStackTrace();
} finally {
wirte.print(json);
wirte.flush();
wirte.close();
}
}
}
// try {
// wirte = response.getWriter();
// //文件存放的路径
// //得到工程的路径:
// System.out.println("得到工程的路径:"+System.getProperty("user.dir"));//user.dir指定了当前的路径
// //得到工程目录:
// System.out.println( "得到工程目录:"+request.getSession().getServletContext().getRealPath("")); //参数可具体到包名
// //得到IE地址栏地址 request.getRequestURL()
// System.out.println( "得到IE地址栏地址 :"+ request.getRequestURL());
// // 得到相对地址:request.getRequestURI()
// System.out.println( "得到相对地址:"+ request.getRequestURI());
// // String path=request.getServletContext().getRealPath("")+"uploaded";
// String path=System.getProperty("user.dir")+"\\src\\main\\resources\\static\\upload\\";
// String fileName = file.getOriginalFilename();
// fileName= UUID.randomUUID()+fileName.substring(fileName.indexOf("."),fileName.length());
// String destFileName=path+fileName;
// System.out.println("path:"+path);
//
// File destFile = new File(destFileName);
// if(!destFile.exists()){
// destFile.getParentFile().mkdirs();
// }
// String url = "http://localhost:8080"
// + "//upload/"
// + fileName;
// System.out.println("url:"+url);
// file.transferTo(destFile); //保存文件
// json.set("success", 1);
// json.set("message", "上传成功");
// json.set("url", url);
// } catch (IllegalStateException | IOException e) {
// json.set("success", 0);
// json.set("message", "上传失败");
// }finally{
// wirte.print(json);
// wirte.flush();
// wirte.close();
// }
}
}
到此功能基本上就写好了