背景:公司想做一个网站,技术点为springboot+docker的形式,前期有单独图片上传以及百度富文本编辑器ueditor图片上传功能。
碰到的问题:第一:服务器是centos,开发环境是window7。由于在docker里面把项目打成jar包,所有图片上传路径都无法按照window下写,解决过程如下:
一. 百度富文本在springboot下使用
关于百度富文本编辑器也说一下,我下载的并不是源码,是jsp那个版本的,默认是找controller.jsp来进行返回解析数据的。controller.jsp里面的数据如下:
<%@ page language="java" contentType="text/html; charset=UTF-8" import="com.baidu.ueditor.ActionEnter" pageEncoding="UTF-8"%> <%@ page trimDirectiveWhitespaces="true" %> <% request.setCharacterEncoding( "utf-8" ); response.setHeader("Content-Type" , "text/html"); String rootPath = application.getRealPath( "/" ); out.write( new ActionEnter( request, rootPath ).exec() ); %>
因为springboot默认是不支持jsp的,所以需要改一下请求路径,不让ueditor访问controller.jsp.变成访问自己定义方法即可。这个是我的项目层次
改ueditor只改一个文件即可,就是ueditor.config.js,找到下面红色的代码,这样就请求自己的controller了。
window.UEDITOR_CONFIG = {
//为编辑器实例添加一个路径,这个不能被注释
UEDITOR_HOME_URL: URL
// 服务器统一请求接口路径
, serverUrl:"/ueditor"
关于ueditor方法的代码在下面会给出。这样就解决了百度富文本在springboot里面访问的问题。
第二:图片上传以及uditor图片上传路径问题。
在window下上传文件可以采用
ClassUtils.getDefaultClassLoader().getResource("static").getPath()
这种方法获取路径,但是如果你打成jar包,这种方式获取的就是这种格式,而且带有!这种
file:/official.jar!/BOOT-INF/classes!/static/imageupload
这种格式你是无论如何都无法上传的!然后打开进入docker的容器看一下,docker容器的目录格式跟linux一样的,可以很清楚的看到docker是以jar包的形式存在,是无法上传图片到jar包里面的。jar包存在docker容器里面是我用dockerfile进行build的时候,用Add命令添加进来的。
解决办法:可以采用挂载的形式,把宿主机器/user/local/下的文件夹挂载到容器目录下。详细步骤如下
先解决百度ueditor图片上传问题,其他图片上传问题就会连带解决。在前面我说了,会把ueditor发放贴出来。下面就是
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.util.ClassUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
@Controller
public class UeditorController {
private static final Logger logger = LoggerFactory.getLogger(UeditorController.class);
private String configJsonParentPath ="";
@Value("${web.upload-path}")
private String fileRelativePath;
/**
* UEditor初始化时会以get方式请求serverUrl地址,并且需要在action=config时返回UEditor配置文件信息
* 描述:使用ueditor.jar包中的ActionEnter的话,就不需要自己再去实现其上传功能,因为ActionEnter已经帮我们实现了
*/
@RequestMapping("ueditor")
public void getEditorConfig(HttpServletRequest request, HttpServletResponse response, String action) {
response.setContentType("application/json");
try {
String os = System.getProperty("os.name");//判断操作系统
if(os.toLowerCase().startsWith("win")){
configJsonParentPath = ClassUtils.getDefaultClassLoader().getResource("").getPath() + "static/ueditor";
}
else {
configJsonParentPath = fileRelativePath+"/ueditor";
}
String exec = new UeditorActionEnter(request, configJsonParentPath).exec();
logger.info("exec为"+exec);
logger.info("configJsonParentPath为"+configJsonParentPath);
if(action!=null && (action.equals("listfile") || action.equals("listimage"))) {
exec = exec.replace(configJsonParentPath.substring(1), "/");
}
PrintWriter writer = response.getWriter();
writer.write(exec);
writer.flush();
writer.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
看上面标红的地方,这个是关键。然后根据操作系统判断路径。因为jar里面无法上传图片,那么我就挂载一个文件夹到容器,然后一箭三雕,
第一:解决了图片持久化的问题,否则容器停止,图片消失。
第二:当有多个容器需要共享一个文件夹的时候,可以都挂载宿主同一个文件夹
第三:可以实现静态与动态的分离。
标红的地方是在application.properties里面进行配置
web.upload-path=/usr/local/ueditorUpload/ web.front-path=/usr/local/ueditorUpload/ spring.resources.static-locations= classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/,classpath:/public/,file:${web.upload-path},file:${web.front-path},
简单解释一下,web.upload-path定义了一个路径。然后我把这个路径当做静态路径去访问不就可以了。也就是说,除了static下面,web.upload-path我也当做静态路径,当static下没有的时候,就去web.upload-path下面找
然后重新打jar包,上传到服务器。千万别忘记了,把ueditor这个文件夹单独上传到宿主机器的/usr/local/ueditorUpload这个文件夹下面,因为下面会通过挂载的形式把文件放到到容器里面 通过build来重新编译镜像文件。
docker build -t <你自己的镜像文件名称> .
然后运行运行容器,同时挂载目录
docker run -d -p 80:8080 -v /usr/local/ueditorUpload:/usr/local/ueditorUpload -v /home/official/logs:/home/official/logs < 镜像文件名称>
查看结果,上传文件
回显也没问题
然后它就会去找jar包外的那个静态文件。
解决完毕,同时如果是图片上传,也是这个道理!希望能帮助大家解决问题