# springboot-vue
**Repository Path**: javafdx/spriingboot-vue
## Basic Information
- **Project Name**: springboot-vue
- **Description**: springboot
- **Primary Language**: Unknown
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 2
- **Forks**: 0
- **Created**: 2021-07-08
- **Last Updated**: 2023-05-29
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
### 修改启动图案
banner.txt
生成图案的网址
http://patorjk.com/software/taag/#p=display&f=Graffiti&t=Type%20Something%20
### 分层-Controller
### 新建一个接口类
1. @RestController 返回字符串
2. @Controller 返回页面
3. @ResponseBody 用来返回字符串或json对象
4. @RestController其实就是@Controller和@ResponseBody的结合
5. @RequestMapping 接口
如果只是简单的用@RequestMapping注解,表示这个接口支持所有的请求方式
(GET POST PUT DELETE)
6. 只支持GET请求用@GetMapping
以此类推@PostMapping @PutMapping @DeleteMapping
7. 或者可以:
@RequestMapping(value = "/hello", method = RequestMethod.GET)
### 请求方法不对 页面报405
@PostMapping("/hello")
前端页面报错:
`Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.
Thu Jul 08 13:50:08 CST 2021
There was an unexpected error (type=Method Not Allowed, status=405).`
后台打印:
Request method 'GET' not supported]
### 扫描包
@SpringBootApplication进入
@ComponentScan 这个注解作用:扫描项目所有的包
### 重构启动类
新建config,将启动类移动到此文件夹下
hello接口就访问不到了--
原因:
@ComponentScan只会扫描这个类下面的子包(启动类被重构到了Config文件下了)
解决:
在启动类加注解--@ComponentScan("com.jiawa")
支持扫描多个包 {"包1", "包2"}
jiawa不是正常的单词,可以保存到项目字典中,就不会有波浪线警告了
alt+enter 保存到字典
### 常见前端报错404
Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.
Thu Jul 08 13:58:02 CST 2021
There was an unexpected error (type=Not Found, status=404).
### 使用HTTP Client测试接口
--IDEA自带的测试接口
(总是用浏览器测试接口,会影响开发效率,浏览器不能发送post请求;postman工具也是要窗口切换)
1. 工具Tools-->HTTP Client
2. 新建文件夹http
test.http
缩写gtr
ptrp post请求
### Live Templates
IDEA设置项中:
对于常用的代码块,可以写成模板
### 接受post请求参数
` public String helloPost(String name){
return "post请求接受参数:"+ name;
}`
直接写name参数,和http测试的参数名字一样,Sping会自动映射
### 结构验证脚本
类似单元测试
`> {%
client.test("test-hello", function() {
client.log("测试/hello接口");
client.log(response.body);
client.log(JSON.stringify(response.body)); // 虽然idea没有提示JSON,但是可以用
client.assert(response.status === 200, "返回码不是200");
client.assert(response.body === "Hello World", "结果验证失败");
});
%}`
### idea自动去掉不引用依赖
设置-->auto-->勾选Optimize
快速添加清晰的导入(Add unambiguous import on the fly)
即时优化导入(Optimize imports on the fly)
###配置文件application.properties
1. 下边两种文件方式,都能识别
config-->application.properties(重构)
application.yml(改格式)
server:
port: 8882
yml格式网站:https://toyaml.com/index.html
2. 自定义配置:
test.hello = Hello
使用配置项:
@Value("${test.hello:TEST}") // :TEST默认配置值
private String testHello;
优先读取配置文件,没有就用默认值。
### 集成热部署
1. 引入依赖
`
org.springframework.boot
spring-boot-devtools
`
2. 配置idea
设置-->Complier(编译器)勾选Build project automatically(自动构建项目)
3. 查找操作--
Ctrl + Shift + Alt + /
Registry(注册表)
勾选
compiler.automake.allow.when.app.running -> 自动编译
4.顶部菜单 Run- >Edit Configurations->SpringBoot插件->目标项目->勾选热更新。
5. 或者按ctrl+f9 工具栏-->小锤子键
### 新建数据库
数据库名:wiki
字符集:utf8mb4
utf8mb4是真正的utf8,可以存放表情符号.
utf8是伪utf8,三个字节,不支持表情符号
排序规则:utf8mb4_general_ci
### 新建数据库用户
不能使用超级用户
1. Navcat点击用户--新建用户
2. 配置常规
3. 配置权限-->添加权限-->选择数据库-->全部勾选
### 链接数据库
1. idea打开数据库Database-->Data Source-->MySql
2. 首次链接需要下载驱动
drop table if exists `test`;
create table `test` (
`id` bigint not null comment 'id',
`name` varchar(50) comment '名称',
primary key (`id`)
) engine=innodb default charset=utf8mb4 comment='测试';
### 集成持久层Mybatis
跟数据库交互的这一层就叫持久层
1.
`
org.mybatis.spring.boot
mybatis-spring-boot-starter
2.1.3
mysql
mysql-connector-java
8.0.22
`
2. 配置数据源
application.properties(不配置,运行就会报错,因为mybatis会去读取配置)
spring.datasource.url=jdbc:mysql://localhost:3306/wiki?characterEncoding=UTF8&autoReconnect=true&serverTimezone=Asia/Shanghai&allowMultiQueries=true
spring.datasource.username=wiki
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
----------------------
MySQL连接数据库时,添加语句:“allowMultiQueries=true”的作用:
1.可以在sql语句后携带分号,实现多语句执行。
2.可以执行批处理,同时发出多个SQL语句。
-------------------------
UTC代表的是全球标准时间 ,但是我们使用的时间是北京时区也就是东八区,领先UTC八个小时。
1. 常用设置
//北京时间东八区即GMT+8
serverTimezone=GMT%2B8
//或者使用上海时间
serverTimezone=Asia/Shanghai
----------------------------
autoReconnect 当数据库连接异常中断时,是否自动重新连接?
-----------------------------
### 创建实体类
可以叫:domain,或entity.或POJO
总之这一层实体类就是和数据库表一一映射。
快捷键:
alt+insert
生成get,set
### 持久层Mapper层
持久层叫Mapper层。即广为人知的Dao层。因为后续要用官方代码生成器,其生成的代码就是xxxMapper
新建接口Interface-->TestMapper
`public List list(); `
### 新建sql脚本文件
1. resources-->mapper-->TestMapper.xml
不用去背
`
`
2. 安装插件Free MyBatis plugin
用来代码跳转
3. 启动类添加注解--扫描注解,扫描持久层
@MapperScan("com.jiawa.wikiwork.mapper")
4. 配置application.properties
# 配置mybatis所有Mapper.xml所在的路径
mybatis.mapper-locations=classpath:/mapper/**/*.xml
### service层--使用Mapper持久层
新建service-->TestService
使用@Service注解,将这个Service交给Spring来管理(扫描)
使用@Resource(jdk自带)或者@Autowired(spring自带)
引入TestMapper
Controller层----写入
@Resource
private TestService testService;
测试调用:
GET http://localhost:8880/test/list
Accept: application/json
### 集成MyBatis官方代码生成器
好处:单表的增删改查不用自己写代码;
1. 引入依赖
`
org.mybatis.generator
mybatis-generator-maven-plugin
1.4.0
src/main/resources/generator/generator-config.xml
true
true
mysql
mysql-connector-java
8.0.22
`
2. 新建generator-->generator-config.xml
直接粘贴代码,校对 数据库配置 ,和包名
` `
在数据库中增加一个demo表
3. 编辑运行配置:Run/Debug Configurations
增加一个Maven,
Name:mybatis-generator
Command line: mybatis-generator:generate -e
4. 运行:mybatis-generator
打印:BUILD SUCCESS
查看:自动生成-->(强烈提醒,四个文件不要修改)
domian-->Demo,DemoExample
mapper-->DemoMapper
mapper-->DemoMapper.xml
### 新建DemoService
ctrl + r
区分大小写,将 Test test 分别替换为 Demo demo
`return demoMapper.selectByExample(null); // 查询所表所有数据 相当于where`
### 新建DemoController
同上,替换单词
新建测试demo.http
发送请求
### 将url统一归属注解
@RequestMapping("/demo")
### 电子书列表接口开发
1. 创建ebook表,插入数据
2. mybatis生成代码
` `
3. 新增EbookService,EbookController
### 规范返回值(统一格式)
后端会有很多接口,为了让前端能够统一处理逻辑(登录校验,权限校验),
需要统一后端的返回值。
1. 新建resp(response缩写)
-->CommonResp(通用返回类)
2. 修改接口EbookController
new CommonResp<>();
ctrl + alt +v
快速生成变量
小提示:
实际工作中,有些项目会在CommonResp里加上其他通用的属性,
比如接口版本号,返回码等
### 分装请求参数节返回参数
1. 根据名称模糊查询电子书
模糊匹配:like
2. 修改Service
` EbookExample ebookExample = new EbookExample();
// createCriteria:相当于Where条件 ebookExample.createCriteria()
EbookExample.Criteria criteria = ebookExample.createCriteria();
criteria.andNameLike("%" + name + "%");
return ebookMapper.selectByExample(ebookExample);`
测试接口:
GET http://localhost:8880/ebook/list?name=Spring
### 请求的参数封装类
1. 新建req--(将Ebool类拷贝)
重命名快捷键(shift+f6)
修改参数名EbookReq req
2.同理修改返回的参数
新建resp-->EbookResp
修改Service
持久层返回List需要转成List,再返回controller
`
List respList = new ArrayList<>();
// 两种for循环模板 fori,iter
for (Ebook ebook : ebookList) {
EbookResp ebookResp = new EbookResp();
//ebookResp.setId(ebook.getId()); // 不用这个方法,用下方的属性
// 从source拷贝到target ---方法ccopyProperties(source,target)
BeanUtils.copyProperties(ebook, ebookResp);
respList.add(ebookResp);
}`
### 制作CopyUtil封装BeanUtils
为解决单个属性赋值和整个list的赋值
新建util-->CopyUtil
直接粘贴
使用:
`List respList = CopyUtil.copyList(ebookList, EbookResp.class); // 列表赋值
EbookResp ebookResp = CopyUtil.copy(ebook, EbookResp.class); // 单个对象赋值`
------------------------
### vue项目
vue create web
1. Manually select features
2. Choose Vue version, Babel, TypeScript, Router, Vuex, Linter/Formatter
3. 3.x
4. n n y
5. ESLint with error prevention only
6. >(*) Lint on save
7. > In dedicated config files
8. y
### 安装Ant-design
npm install ant-design-vue@next --save
@next:安装最新的未正式发布版本
单独安装图标库
npm install --save @ant-design/icons-vue
全局引用:
`import * as Icons from '@ant-design/icons-vue';
// 全局使用图标
const icons: any = Icons;
for (const i in icons) {
app.component(i, icons[i]);
}
`
### vue3语法
setup:记住他,Vue3新增的初始化方法
(没有vue2中的data和生命周期函数,methods,全部被setup方法给包括了)
请求不要直接放在setup中。setup执行的时候界面还没有渲染好,这时候如果去操作界面元素会报错
要引入onMounted并在setup中使用;
`setup(){
onMounted(() => {
})
}`
### 安装axios
npm install axios --save
`import axios from 'axios'; // 引入axios
axios.get("GET http://localhost:8880/ebook/list?name=Spring").then((response) => {
console.log('请求的结果')
console.log(response)
})
`
会发生跨域错误:
`Access to XMLHttpRequest at 'http://localhost:8880/ebook/list?name=Spring' from origin
'http://localhost:8080' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header
is present on the requested resource.`
跨域可以这样理解,来自一个IP端口的页面(vue项目),
要访问另一个IP端口的资源(springboot请求接口),会产生跨域访问。
解决:
新建:config-->CorsConfig
`.maxAge(3600); // 1小时内不需要再预检(发OPTIONS请求)`
在调用电子书接口之前,会先发一个OPTIONS请求;(不会去处理逻辑,只会校验有没有这个接口)
### 绑定数据
1. 响应式数据:ref关键字
const ebooks = ref(); // 定义变量
2. 赋值:
ebooks.value = data.content;
3. html代码要拿到响应式变量,需要在setup最后return
`return {
ebooks
}`
第二种方法:
利用reactive (vue3新增方法)
`const ebooks1 = reactive({books: []});
ebooks1.books = data.content;
return {
ebooks2: toRef(ebooks1,"books")
}`
### vueCLI多环境配置
新建开发环境文件(.env.dev):
`NODE_ENV=development
VUE_APP_SERVER=http://localhost:8880`
生产环境(.env.prod)
`NODE_ENV=production
VUE_APP_SERVER=http://wiki-server.courseimooc.com
VUE_APP_WS_SERVER=ws://wiki-server.courseimooc.com
`
修改package.json
` "serve": "vue-cli-service serve --mode dev",`
读取环境:
console.log('环境:', process.env.NODE_ENV);
console.log('服务端地址:', process.env.VUE_APP_SERVER);
可修改前端启动端口
` "serve": "vue-cli-service serve --mode dev --port 8081",`
全局引入域名
`import axios from 'axios'
axios.defaults.baseURL = process.env.VUE_APP_SERVER;`
### 使用axios拦截器打印前端日志
`/**
* axios拦截器
*/
axios.interceptors.request.use(function (config) {
console.log('请求参数:', config);
return config;
}, error => {
return Promise.reject(error);
});
axios.interceptors.response.use(function (response) {
console.log('返回结果:', response);
return response;
}, error => {
console.log('返回错误:', error);
return Promise.reject(error);
});`
### SpringBoot过滤器的使用
配置:打印接口耗时---
是一个非常重要的监控点,可以看出来你应用的处理能力。
1. 新建文件夹filter
LogFilter.java(固定粘贴)
使用Intellij的格式化快捷键”Ctrl+ALT+L”即可进行格式化。
### SpringBoot拦截器的使用
配置:打印接口耗时---
interceptor-->LogInterceptor.java(固定粘贴)
拦截器还需要增加一个配置类
config-->SpringMvcConfig.java(引用LogInterceptor类)
`.excludePathPatterns("/login");` 排除接口不做拦截
总结:
过滤器先开始--然后是拦截器
### SpringBoot AOP的使用
配置aop,打印接口耗时,请求参数,返回参数
新建aspect-->LogAspect.java(固定粘贴)
引入依赖:
`
org.springframework.boot
spring-boot-starter-aop
com.alibaba
fastjson
1.2.70
`
切点加通知就等于切面Aspect
filter过滤器,拦截器,aop使用一个就可以了
### 电子书管理功能开发
### 使用PageHelper实现后端分页
集成PageHepler插件
依赖
`
com.github.pagehelper
pagehelper-spring-boot-starter
1.2.13
`
// service层分页
PageHelper.startPage(1,3);
# 打印所有的sql日志:sql, 参数, 结果
logging.level.com.jiawa.wiki.mapper=trace
### 编辑打印快捷键
快捷键:logi
设置idea
private static final Logger LOG = LoggerFactory.getLogger($CLASS_NAME$.class);
### 打印总行数和总页数
`
// 使用PageInfo
PageInfo pageInfo = new PageInfo<>(ebookList);
LOG.info("总行数{}", pageInfo.getTotal());
LOG.info("总页数{}", pageInfo.getPages());`
### 封装分页请求参数和返回参数
新建req-->PageReq
测试-->GET http://localhost:8880/ebook/list?page=1&size=4
### post表单提交
@RequestBody
相当于Content-Type: application/json
如果是x-www-form-urlencoded就不用写注解
### 雪花算法
其实是一个工具类。是用来生成数据库id的。
### 参数校验Validation
依赖
`
org.springframework.boot
spring-boot-starter-validation
`
1. 在实体类中加入校验规则注解
2. 开启规则
在Controller中加入@Valid
3. 引入统一校验异常处理的类(返回给前端)
ControllerExceptionHandler.java
### 新建分类数据库表category
MyBatis生成代码
### 集成富文本wangEditor
https://www.wangeditor.com/
基本使用
下载
npm 安装 npm i wangeditor --save
CDN 链接 https://cdn.jsdelivr.net/npm/wangeditor@latest/dist/wangEditor.min.js
### 新建文档内容表
content
### 新建用户表
user
唯一键名字login_name_unique
对应的字段login_name
作用:对于一个系统来说,登录名是不能重复的;
unique key `login_name_unique` (`login_name`)
### 自定义异常类
新建exception
使用:抛出异常
// 用户名已存在
throw new BusinessException(BusinessExceptionCode.USER_LOGIN_NAME_EXIST);
### 密码加密
工具类
public-->js-->md5.js
### 单点登陆
token+redis
注解@NotEmpty
表示空字符串也会拦截
### 引入redis依赖
`
org.springframework.boot
spring-boot-starter-data-redis
`
将登陆信息保存到
`RedisTemplate`
需要将类序列化一下,做完成远程传输,还要再取出来,所以要序列化一下
下列方法二者选其一
`public class UserLoginResp implements Serializable {}`
`redisTemplate.opsForValue().set(token.toString(), JSONObject.toJSONString(userLoginResp), 3600 * 24, TimeUnit.SECONDS);`
### 本机安装redis
https://blog.csdn.net/weixin_41381863/article/details/88231397?utm_term=windows%E9%85%8D%E7%BD%AEredis&utm_medium=distribute.pc_aggpage_search_result.none-task-blog-2~all~sobaiduweb~default-0-88231397&spm=3001.4430
` # REDIS (RedisProperties)
# Redis数据库索引(默认为0)
spring.redis.database=0
# Redis服务器地址
spring.redis.host=localhost
# Redis服务器连接端口
spring.redis.port=6379
# Redis服务器连接密码(默认为空)
spring.redis.password=
# 连接池最大连接数(使用负值表示没有限制)
spring.redis.jedis.pool.max-active=8
# 连接池最大阻塞等待时间(使用负值表示没有限制)
spring.redis.jedis.pool.max-wait=-1
# 连接池中的最大空闲连接
spring.redis.jedis.pool.max-idle=8
# 连接池中的最小空闲连接
spring.redis.jedis.pool.min-idle=0
# 连接超时时间(毫秒)
spring.redis.timeout=5000`
报错
`rg.springframework.data.redis.RedisConnectionFailureException: Unable to connect to Redis; nested exception is io.lettuce.core.RedisConnectionException: Unable to connect to localhost:6379
at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory$ExceptionTranslatingConnectionProvider.translateException(LettuceConnectionFactory.java:1621)`
1.找到bind 127.0.0.1,把它进行注释
2.找到protected-mode yes 把它改成no。
修改密码之后,需要重新启动redis
### 测试redis接口
TestController.java
测试接口:
`
GET http://localhost:8880/test/redis/set/123/test
Accept: application/json
GET http://localhost:8880/redis/get/15271595887169536
Accept: application/json
`
### 前端集成本地缓存
session-storage.js
``
### 自定义sql
sql语句(用户阅读数量加1)
`update doc set view_count = view_count + 1 where id = 1`
复制TestMapper.xml改为DocMapperCust.xml
复制TestMapper.java改为DocMapperCust.java
### 电子书信息更新方案
更新方式:
1.实时更新
2.定时批量更新:(优点,改动的地方少,缺点,数据实时性差)
1.统计某一个电子书数据(文档数,点赞数,阅读数)
`select count(1), sum(view_count), sum(cote_count) from doc where ebook_id = 1;`
2. 批量分组查询group by
`select ebook_id, count(1), sum(view_count), sum(vote_count) from doc group by ebook_id;`
3. 两张表的关联更新
`update ebook t1, (select ebook_id, count(1) doc_count, sum(view_count) view_count, sum(vote_count) vote_count from doc group by ebook_id) t2
set t1.doc_count = t2.doc_count, t1.view_count = t2.view_count, t1.vote_count = t2.vote_count
where t1.id = t2.ebook_id;`
### 定时任务
1. 启动定时器,不需要引入依赖
2. 两种定时器写法
在启动类中加入注解(启动定时任务)
@EnableScheduling
定时每秒,或者指定时间
`在线cron表达式生成器`
### 日志流水号
方便日志查看
`%d{ss.SSS} %highlight(%-5level) %blue(%-30logger{30}:%-4line) %thread %green(%-18X{LOG_ID}) %msg%n`
LOG_ID可以在线程中随时设置
` MDC.put("LOG_ID", String.valueOf(snowFlake.nextId()));`
### WebSocket
1. 定时轮询(前端定时器)
2. 被动通知(websocket)一直会占用服务器链接
依赖
`
org.springframework.boot
spring-boot-starter-websocket
`
声明WebSocketConfig.java
开启websocket(
websocket--
WebsocketServer.java)
### websocket推送消息
` webSocketServer.sendInfo("【" + docDb.getName() + "】被点赞!");`
### 使用异步化解耦点赞通知功能
启动类加注解(@EnableAsync)
作用:防止点赞功能收到websocket出错的影响
### 事务
加注解(@Transactional)
同时对两张表有增删改的操作,就要考虑加事务,
否则会造成数据不准确。当然也有不加事务的场景,不能一概而论。
一张表成功,一张表失败,就会出现异常。这两张表具有关联性。
要做到:同时成功,同时失败
### 使用MQ解耦点赞通知
1. 使用RocketMQ
解决问题---不能使用Async注解(业务量大的时候,单线程阻塞)
2. MQ是消息队列,
第三方服务,需要下载(https://www.apache.org/dyn/closer.cgi?path=rocketmq/4.9.0/rocketmq-all-4.9.0-bin-release.zip)
启动应用:bin-->mqnamesrv.cmd(注册中心)
bin-->mqbroker.cmd(链接服务端)
配置环境变量 :系统变量 ROCKETMQ_HOME 添加:E:\RocketMQ\rocketmq-all-4.9.0-bin-release
进入bin目录:
`cmd: mqnamesrv.cmd
cmd: mqbroker.cmd -n 127.0.0.1:9876 autoCreateTopicEnable=true`
3. 服务端:
加入依赖:
`
org.apache.rocketmq
rocketmq-spring-boot-starter
2.0.3
`
配置:
`
rocketmq.name-server=127.0.0.1:9876
rocketmq.producer.group=default`
使用(参数:主题加内容)
` rocketMQTemplate.convertAndSend("VOTE_TOPIC","【" + docDb.getName() + "】被点赞!");`
4. 消费端:
消费端一般会写到另一个专门监听MQ的应用,我们只有一个应用,就写到一起了。
rocketmq-->VoteTopicConsumer.java
### 快照表
1. 方案二(ID连续)
--为所有的电子书生成一条今天的记录,如果还没有
--更新总阅读数,总点赞数
--更新今日阅读数,今日点赞数
`insert into ebook_snapshot(ebook_id, `date`, view_count, vote_count, view_increase, vote_increase)
select t1.id, curdate(), 0, 0, 0, 0 from ebook t1 where not exists (select 1 from ebook_snapshot t2 where
t1.id = t2.ebook_id and t2.`date` = curdate());`
第二步更新:
`update ebook_snapshot t1, ebook t2
set t1.view_count = t2.view_count, t1.vote_count = t2.vote_count
where t1.`date` = curdate() and t1.ebook_id = t2.id;`
第三部:(获取昨天的数据)
`select t1.ebook_id, view_count, vote_count from ebook_snapshot t1
where t1.`date` = date_sub(curdate(), interval 1 day);`
更新
`update ebook_snapshot t1, (select ebook_id, view_count, vote_count from ebook_snapshot
where `date` = date_sub(curdate(), interval 1 day)) t2
set t1.view_increase = (t1.view_count - t2.view_count),
t1.vote_increase = (t1.vote_count - t2.vote_count)
where t1.ebook_id = t2.ebook_id and t1.`date` = curdate();`
### 前端引入echarts
### 生产打包,部署
1. 购买RDS配置生产数据库
2. 购买ECS(服务器),安装JDK,nginx
3. SpringBoot项目发布,多环境配置
4. Vue项目发布
5. 域名配置
6. ECS镜像
### 链接ECS
工具Tools-->部署Deployment-->配置Configuration
新增SFTP
启动SSH会话--链接服务器命令窗口
### 创建prod配置
多环境打包配置
编辑配置-->环境Environment-->虚拟机选项VM options
-Dspring.profiles.active=prod(加这个配置项,启动就是prod环境)
### 打包Jar
maven-->项目名-->Lifecycle生命周期-->install
在target目录下生成
wikiwork-0.0.1.SNAPSHOT.jar
不要版本号
加上
`
${artifactId}
`
### 启动
java -jar wikiwork.jar 开发
生产
java -jar -Dspring.profiles.active=prod wikiwork.jar
自动启动脚本
doc-->deploy.sh
放到服务器中
vim deploy.sh
:set ff=unix
:wq
运行deploy.sh
查看进程
ps -ef | grep java
查看日志
cd log
tail -100 error.log
tail -100f trace.log