Spring boot项目jar包,线上发布。linux指令记录,静态文件处理(图片),yml文件配置,这里记录一波。
描述:
war包部署,jar部署。各自部署流程,以及自己的感受。
Spirng yml文件 配置.
项目部署: 项目线上部署时,以前一般都是 打个war包,放在配置好的tomcat /webapp里,./startup.sh 运行时,会自动解压文件,服务就启动了。Spring boot项目,是内嵌tomcat。在部署时,一般会选择用打jar包,用yml文件配置 端口号,静态文件路径,上传配置等,也可以用命令行处理.
jar包形式项目部署
Linux:运行命令, java -jar xx.jar
. 后台运行:nohup java -jar xxx.jar >logs.txt &
,这个logs.txt 时日志记录文件.
-防火墙:service iptables status
- -查 service iptables start
- -启
静态资源处理
web:
upload-path: e:/uploadImg
spring:
#静态资源配置
resources:
static-locations: file:${web.upload-path}
在yml文件中, 这样配置后, E盘的,uploadImg文件夹,路径就好比 /static文件夹了,比如:你图片上传到 uploadImg, 那访问路径: localhost:8080/xx.jpg .
在linux系统中呢,upload-path:就配置你jar包的,同级目录里,效果时一样的。 如:/user/tomcat8.5/webapps/officialWebsite/uccn/uploadImg 。
跨域问题
相信Spring boot项目,一般都是 前后分离。这是经常会遇到的。
上代码:
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* @author heyonghao
* @Title: WebMvcConfigurerAdapter
* @ProjectName xlkoffical
* @Description: 跨域问题解决
* @date 2019/7/1719:13
*/
@Configuration
public class CORSConfiguration implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**");
}
}
就这一个就行了。
下面就不BB了,直接上代码,干货。
我的Yml:
主配
spring:
profiles:
#active: prod #正式
active: dev #开发
servlet:
multipart:
enabled: true
max-file-size: 5MB
max-request-size: 10MB
environment: #当前环境指定
value: formal
#value: test
dev
# 端口配置
server:
port: 8080
servlet:
context-path: /
#图片访问路径,指定位置
web:
upload-path: e:/uploadImg
#多数据源配置
spring:
datasource:
#数据库一
xlkoffical:
jdbc-url: jdbc:mysql://127.0.0.1:3306/xlkoffical?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true
username: root
password: root
driver-class-name: com.mysql.jdbc.Driver
#数据库二
heal:
jdbc-url: jdbc:mysql://127.0.0.1:3306/heal?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true
username: root
password: root
driver-class-name: com.mysql.jdbc.Driver
#静态资源配置
resources:
static-locations: file:${web.upload-path}
redis:
database: 0
host: localhost
port: 6379
password:
jedis:
pool:
max-active: 8 # 连接池最大连接数(使用负值表示没有限制)
max-wait: -1 # 连接池最大阻塞等待时间(使用负值表示没有限制)
max-idle: 8 # 连接池中的最大空闲连接
min-idle: 0 # 连接池中的最小空闲连接
timeout: 10000
mybatis:
mapper-locations: classpath:mapper/*/*.xml
type-aliases-package: com.entity
configuration:
map-underscore-to-camel-case: true #开启驼峰映射
logging:
level:
com.dao: DEBUG
prod就不分享了 - -! ,多数据源在我有编文章有,还要加个配置类.
Controller层,全局异常处理,记录日志:
这里用到了Spring boot的 @RestControllerAdvice
;
在报错时,会拦截进这里,并存入数据库errorLog.
package com.config;
import com.common.Result;
import com.entity.ErrorLog;
import com.service.ErrorLogService;
import com.util.DateUtil;
import com.util.StringUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
/**
* @author heyonghao
* @Title: GlobalExceptionHandle
* @ProjectName xlkoffical
* @Description: 全局异常处理
* @date 2019/7/1214:31
*/
@RestControllerAdvice
public class GlobalExceptionHandle {
@Autowired
ErrorLogService errorLogService;
private static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandle.class);
@ExceptionHandler(value = Exception.class)
@ResponseBody
public Result handle(Exception e, HttpServletRequest request){
logger.error("服务器报错,"+"报错请求路径:"+request.getRequestURI());
e.printStackTrace();
StackTraceElement stackTraceElement= e.getStackTrace()[0];
Map<String,Object> map = new HashMap<>();
//报错路径
map.put("errorPath",stackTraceElement.getClassName());
//报错方法
map.put("errorMethod",stackTraceElement.getMethodName());
//报错行数
map.put("line",stackTraceElement.getLineNumber());
//报错描述
map.put("describe",e.toString());
//存入日志
ErrorLog errorLog = new ErrorLog();
errorLog.setUuid(StringUtil.getUUID());
errorLog.setCreateDate(DateUtil.NowDateAll());
errorLog.setErrorPath(stackTraceElement.getClassName());
errorLog.setErrorMethod(stackTraceElement.getMethodName());
errorLog.setErrorLine(stackTraceElement.getLineNumber());
errorLog.setErrorDescribe(e.toString());
errorLogService.addErrorLog(errorLog);
return Result.error("服务器内部错误",map);
}
}
图片上传util:
/**
* 项目jar 部署时,获取jar同级目录,用于图片存储等
* @param subdirectory
* @return
*/
public static String getJarPath(String subdirectory){
//获取跟目录---与jar包同级目录的upload目录下指定的子目录subdirectory
File upload = null;
try {
//本地测试时获取到的是"工程目录/target/upload/subdirectory
File path = new File(ResourceUtils.getURL("classpath:").getPath());
if(!path.exists()) path = new File("");
upload = new File(path.getAbsolutePath(),subdirectory);
if(!upload.exists()) upload.mkdirs();//如果不存在则创建目录
String realPath = upload + File.separator;
return realPath;
} catch (FileNotFoundException e) {
throw new RuntimeException("获取服务器路径发生错误!");
}
}
/**
* 单图上传
* @param file file
* @param fileUrl 图片保存分类路径
* @return 数据存储路径
*/
public static String uploadImg(MultipartFile file, String fileUrl){
//图片后缀
String fileSuffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
//图片全称
String fileName= DateUtil.NowDateYmd()+System.currentTimeMillis()+fileSuffix;
//存储路径
String path ;
//数据库路径
String dataBaseUrl;
path= getJarPath("uploadImg");
File newFile = new File(path+fileName);
//数据库存储路径
dataBaseUrl=fileName;
logger.info("数据库存储路径:"+dataBaseUrl);
logger.info("上传路径:"+newFile);
try {
file.transferTo(newFile);
logger.info("上传成功");
}catch (IOException e){
e.printStackTrace();
logger.info("上传失败");
return null;
}
return dataBaseUrl;
}
Maven 打包:
kill -9 PID //关闭服务