目錄
- 簡介
- 1 技術介紹
- 1.1 個人博客功能
- 1.2 技術組合
- 1.3 工具與壞境
- 2 專案的環境配置
- 2.1 vue的環境配置
- 2.2 解決跨域問題
- 2.3 關于圖示的獲取
- 3 前端技術
- 3.1 element-ui的分頁使用介紹
- 3.2 發布博客
- 3.3 點贊功能的實作
- 3.4 評論
- 3.5 獲取B站用戶資訊
- 3.6 相冊的設計
- 3.7 圖片上傳
- 3.8 時光軸設計詳情
- 4 后端技術
- 4.1 SpringBoot環境配置
- 4.2 檔案上傳
- 4.3 檔案下載
- 4.4 發送郵箱
- 4.5 JAVA爬蟲
- 5 Redis
- 5.1 redis前言
- 5.2 redis的配置
- 6 專案打包
- 6.1 vue打包
- 6.2 SpringBoot打包
- 7 專案部署
- 7.1 docker安裝
- 7.2 vue部署
- 7.2.1 nginx下載
- 7.2.2 docker安裝nginx
- 7.2.3 docker掛載nginx
- 7.3 SpringBoot部署
- 8 總結
簡介
博客介紹: 第一個前后端分離的專案,想做個好的個人博客是很久之前的事,算上這個博客我一共做過三個,第一個是用jsp做的,因為沒有設計感頁面簡直不能直視,第二個是跟著B站上的做的,用thymeleaf模板做的博客,那時候才學SpringBoot沒多久,算是為了熟練SpringBoot才做的,這次是想做一個能長期維護的博客(就是一直會用這個,就算要改的話,整體架構也不會怎么變的),所以我打算就用vue來做,做前后端分離的專案,
技術講解: 這篇博客會詳細講解整個環境配置、開發流程、專案部署這些內容,比如說某些重要的內容,哪里容易出錯,哪一方面要注意一下,一些簡單的CURD操作就不會詳細講解了,
關于界面: 有些頁面是參照別人的做,例如首頁我是參照這個做的,并在基礎上修改了一下,https://xiaoyou66.com/
個人網站: 附上部署好的網站,可以更好的閱讀下面的文章http://liaojiale.com/
1 技術介紹
1.1 個人博客功能



1.2 技術組合
- 前端:vue + Semantic-ui框架
- 后端:SpringBoot + MyBatis-plus
- 資料庫: Mysql + Redis
- 運維:docker + nginx
1.3 工具與壞境
- IDEA
- Navicat
- Xshell
- Xftp
- Maven3.6
- JDK 8
2 專案的環境配置
2.1 vue的環境配置
首先進到放vue代碼的檔案下,在地址欄上輸入CMD就會跳到當前的目錄下,然后根據以下步驟去創建vue專案
vue init webpack 檔案名
# 進入工程目錄
cd 創建完的vue專案
# 安裝 vue-router
cnpm install vue-router --save-dev
# 安裝 element-ui
cnpm install element-ui --save-dev
# 安裝依賴
cnpm install
# 安裝 SASS 加載器
cnpm install sass-loader node-sass --save-dev
# 啟動測驗
npm run dev
npm isntall vue-router --save
npm install storage --save-dev
npm install semantic-ui --save-dev
npm install vue-jsonp --save
cnpm install axios --save-dev
cnpm install vue-axios --save-dev
1.環境配置好后首先進到main.js把安裝好的依賴到進去

- 配置路由
- 然后通過npm run dev進行訪問,訪問成功則環境配置好了,之后就可以進行前端頁面的操作啦~~~
2.2 解決跨域問題
在獲取后端資料時都會有一個跨域的問題要解決,所以我們去找到config目錄下的index.js的檔案進行如下的操作

下面的是以/api/代替了http://localhost:8081/這個ip和埠,這樣就能解決跨域的問題,
this.axios({
url: "/api/layer/getLayerInfo",
method: "get",
})
2.3 關于圖示的獲取
可以通過阿里巴巴矢量圖示庫獲取圖示(個人比較推薦,因為這個是真的很簡單方便)
步驟
- 先進入阿里巴巴矢量圖示庫
- 搜索你需要的圖示
- 找到喜歡的圖示并收藏
- 新建專案并添加至專案中
- 在Font Class里點擊更新代碼便會出現鏈接,然后打開鏈接并復制里面的內容
- 在vue專案里創建一個css檔案并復制進去,最后參考這個css檔案
- 在添加圖示的標簽里的class里面加入iconfont 圖示的class,例如:
<strong class="iconfont icon-shouye"></strong>
3 前端技術
3.1 element-ui的分頁使用介紹
<el-col>
<el-pagination
background
layout="prev, pager, next"
@current-change="selectPage()"
:total="blogsCount * 10 / size">
</el-pagination>
</el-col>
current-change當前頁面發生改變時會觸發
blogsCount是博客的數量,通過blogsCount * 10 / size就可以獲取到頁數
通過獲取active這個class獲取頁面發生改變時的值,再把這個值傳給后臺便可以獲取下一頁的資料
selectPage(){
let current = document.getElementsByClassName('active')[0].innerHTML
this.axios({
url:"/api/{{請求地址}}",
method:"get",
params:{
current:current - 1,
size:this.size
}
}).then(res => {
this.blogs = res.data.blog
})
},
3.2 發布博客
個人博客最核心的是什么,那當然是寫博客啊,要說寫博客首選的編輯器當然是markdown,功能多樣卻操作容易方便,有一個基于vue的markdow編輯插件mavon-edtior
步驟
- npm install mavon-editor --save
- 在main.js上參考
// 全域注冊
// import with ES6
import Vue from 'vue'
import mavonEditor from 'mavon-editor'
import 'mavon-editor/dist/css/index.css'
// use
Vue.use(mavonEditor)
new Vue({
'el': '#main',
data() {
return { value: '' }
}
})
- maven-editor配置

獲取md格式和html格式,md的格式內容是在修改博客時用的,html格式的內容是博客展示是用的,這樣就能把資料發到后臺在存進資料庫啦,記得兩種格式都要存進資料庫
updateDoc(markdown, render) {
this.html = render;
this.markdown = markdown;
},
saveDoc(markdown, render) {
this.html = render;
this.markdown = markdown;
},
- 圖片上傳
$imgAdd (pos, $file) {
// 第一步.將圖片上傳到服務器.
var formdata = new FormData()
formdata.append('image', $file)
this.img_file[pos] = $file
this.$http({
url: '/api/{{地址}}',
method: 'post',
data: formdata,
headers: { 'Content-Type': 'multipart/form-data' }
}).then((res) => {
let _res = res.data
// 第二步.將回傳的url替換到文本原位置 -> 
this.$refs.md.$img2Url(pos, _res.data)
})
},
- 圖片洗掉
下面的請求主要是洗掉圖片,洗掉服務器上的圖片
$imgDel (pos) {
delete this.img_file[pos]
var p = pos[0]
this.axios({
url:"/api/{{地址}}",
method:"get",
params:{
pos:p
}
})
}
- 代碼高亮
通過npm引入以下的三個插件,并在mavon-editor標簽上加入這段代碼 :ishljs = "true"
highlight.js
github-markdown-css
katex(v2.4.7)
小提示:如果你覺得這些高亮的顏色、字體大小不好看,可以通過f12查看這個高亮的代碼的class,然后通過權重(!important)對屬性進行自己喜歡的樣式修改,
- 展示博客的內容
通過以下代碼讓博客內容進行展示
content是從后臺請求到的博客內容,也就是html格式的內容
<div id="content" class="markdown-body" v-html="content">
- mavon-editor官方檔案
3.3 點贊功能的實作
點贊功能通常都是一個人只能點贊一次,不可以重復點贊,因為這個博客主要是個人博客,個人所有的,沒有其他用戶,所以在資料庫上沒有建用戶表,但要有點贊功能且不能重復點贊,我第一個想到的技術就是本地儲存技術也就是cookie,當你點贊時會在你的瀏覽器上加上一個cookie,例如:我在id為3的博客里點贊了就會在瀏覽器上儲存一個blogId:3這樣的一個cookie意思是你在id為3的博客里點贊了,如果識別到你本地上有這個cookie那你就不能繼續點贊了,
步驟
- 先建一個工具包把這個工具類放進去
var storage = {
/**
對本地資料進行操作的相關方法,如localStorage,sessionStorage的封裝
*/
setStorage: function(key, value, duration) {
var data = {
value: value,
expiryTime: !duration || isNaN(duration) ? 0 : this.getCurrentTimeStamp() + parseInt(duration)
};
localStorage[key] = JSON.stringify(data);
},
getStorage: function(key) {
var data = localStorage[key];
if (!data || data === "null") {
return null;
}
var now = this.getCurrentTimeStamp();
var obj;
try {
obj = JSON.parse(data);
} catch (e) {
return null;
}
if (obj.expiryTime === 0 || obj.expiryTime > now) {
return obj.value;
}
return null;
},
removeStorage: function(key){
localStorage.removeItem(key);
},
getSession: function(key) {
var data = sessionStorage[key];
if (!data || data === "null") {
return null;
}
return JSON.parse(data).value;
},
setSession: function(key, value) {
var data = {
value: value
}
sessionStorage[key] = JSON.stringify(data);
},
getCurrentTimeStamp: function() {
return Date.parse(new Date());
}
};
export default storage;
- 在main.js如下配置
import mavonEditor from "mavon-editor";
Vue.prototype.$storage=storage;
使用方法
this.$storage.setStorage(key,value) //設定cookie
this.$storage.getStorage(key) //獲取cookie
代碼如下
if (this.$storage.getStorage("good"+this.blogId)==this.blogId){
this.$message.warning("你已經點過贊了")
return
}
this.axios({
url:"/api/{{地址}}",
method:"get",
params:{blogId:this.blogId}
}).then(res=>{
if (res.data){
this.$message.success("點贊成功")
this.$storage.setStorage("good"+this.blogId,this.blogId)
}
})
3.4 評論
說到評論,幾乎每個博客都會加上這一點,畢竟這個能增加和別人的互動性,這個評論的難點是資料庫的設計,如果資料庫設計的不好,做出來是比較困難的,
評論的結構設計

思路: 根據這個設計,我們如何去設計呢?如果是建一張表如何設計才能做出樓和層的結構,他們的關系是怎樣表現的出來的?我想過用一張表設計,但這樣設計會很麻煩,所以我建了兩張表,一張是floor(樓)表和layer(層)表,如下:


floor表是專門放樓的評論的資料,而層表是專門放層評論的資料,層的資料是系結樓的id來獲取你是在哪一樓發言,這樣就能確定樓層之間的關系啦~~~
要展示哪一些層對應哪一樓這個最簡單不過了只要用v-if將系結在層的樓id等于樓的id就可,如下:
<div v-for="layer in allLayer" v-if="layer.floorId == floor.id">
3.5 獲取B站用戶資訊
既然做評論,當然要知道是誰評論,可這是個人博客誒,又沒有建用戶表,所以我想到獲取B站的個人資訊作為評論的前提,
步驟
- 打開在用戶資訊那里工具列抓包,你會發現有一個請求是獲取個人資訊的,介面如下:
https://api.bilibili.com/x/space/acc/infomid={{B站的UID}}&jsonp=jsonp
- 通過鍵盤輸入每一個字母就去請求一次介面
- 通過以下代碼展示圖片,不然展示不了
if( res.data.data.face !== undefined ){
let _u = res.data.data.face.substring( 7 );
this.BPhoto = res.data.data.face = 'https://images.weserv.nl/?url=' + _u;
}
這是完成后的樣子~

3.6 相冊的設計
相冊是用了不少的時間去做的,但仔細想想其實很多都是CURD操作和一下邏輯上的操作,其實沒有什么可以說的,我相信多人都是會做的,所以就不說了,但花費了這么多時間還是要講一下不說的原因的哈哈哈哈哈,
這個是相冊的鏈接可以點進去看一下哈------相冊鏈接
3.7 圖片上傳
vue提供的圖片上傳真的太容易了,只要貼上如下代碼就可了,詳細的介紹就看vue官方,
<el-upload
class="upload-demo"
drag
:action="'/api/{{請求地址}}"
list-type="picture"
:on-preview="handlePreview"
:on-remove="handleRemove"
multiple>
<i class="el-icon-upload"></i>
<div class="el-upload__text">將檔案拖到此處,或<em>點擊上傳</em></div>
</el-upload>
3.8 時光軸設計詳情
時光軸的設計結構

這個時光軸的設計難點就是sql陳述句和怎么展示出來,首先我們先寫獲取年份的sql陳述句,如下
SELECT DATE_FORMAT( b.createTime,'%Y') as years FROM blog b
GROUP BY years
ORDER BY years DESC;
然后獲取該年份下的博客
SELECT DATE_FORMAT( b.createTime,'%Y') as years FROM blog b
GROUP BY years
ORDER BY years DESC;
通過在兩條sql陳述句就能查詢出來啦~
那我們該怎么去展示在頁面呢?首先我們先把年份給遍歷出來,然后遍歷查詢出來博客,也就是第二條sql陳述句的資料,最后我們遍歷出該博客的資訊,并等于當前年份的博客才能展示出來,所以我們用到了v-if陳述句,這樣就完成了,如果有什么不明白可以在評論區問問我哈哈哈
<div v-for="year in allYears">
<div v-for="info in blogYearInfo">
<div v-for="i in info" v-if="i.createTime.split('-')[0]==year"></div>
</div>
</div>
關于前端的知識現在到這里已經結束了,接下來講一下關于后端方面的知識!!!
4 后端技術
4.1 SpringBoot環境配置
mybatis-plus里面有一個代碼自動生成,我們可以通過代碼來生成無聊且沒有意思的代碼,
- 我們先匯入需要的依賴包
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.0.5</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.0.5</version>
<scope>test</scope>
</dependency>
- 我可以通過以下代碼生成
public static void main(String[] args) {
// 需要構建一個 代碼自動生成器 物件
AutoGenerator mpg = new AutoGenerator();
// 配置策略
// 1、全域配置
GlobalConfig gc = new GlobalConfig();
String projectPath = System.getProperty("user.dir");
gc.setOutputDir(projectPath+"/src/main/java");
gc.setAuthor("Talisman");
gc.setOpen(false);
gc.setFileOverride(false); // 是否覆寫
gc.setServiceName("%sService"); // 去Service的I前綴
gc.setIdType(IdType.ID_WORKER);
gc.setDateType(DateType.ONLY_DATE);
// gc.setSwagger2(true);
mpg.setGlobalConfig(gc);
// 2、 配置資料源
DataSourceConfig dsc = new DataSourceConfig();
dsc.setUrl("jdbc:mysql://localhost:3306/yingmublog?useSSL=true&characterEncoding=utf8&useUnicode=true&autoReconnect=true&failOverReadOnly=false");
dsc.setDriverName("com.mysql.jdbc.Driver");
dsc.setUsername("賬號");
dsc.setPassword("密碼");
dsc.setDbType(DbType.MYSQL);
mpg.setDataSource(dsc);
// 3、包的配置
PackageConfig pc = new PackageConfig();
pc.setModuleName("yingmublog");
pc.setParent("com.jiale");
pc.setEntity("entity");
pc.setMapper("mapper");
pc.setService("service");
pc.setController("controller");
mpg.setPackageInfo(pc);
// 配置策略
StrategyConfig strategy = new StrategyConfig();
strategy.setInclude("admin","blog","blog_tag","comment","tag","type","topic","animation",
"friend","other","album_photo","album","floor","layer");// 設定要映射的表名
strategy.setNaming(NamingStrategy.underline_to_camel);
strategy.setColumnNaming(NamingStrategy.underline_to_camel);
strategy.setLogicDeleteFieldName("deleted");
// 自動填充配置
TableFill createTime = new TableFill("createTime", FieldFill.INSERT);
TableFill updateTime = new TableFill("updateTime", FieldFill.UPDATE);
ArrayList<TableFill> tableFills = new ArrayList<>();
tableFills.add(createTime);
tableFills.add(updateTime);
strategy.setTableFillList(tableFills);
// 樂觀鎖
strategy.setVersionFieldName("version");
strategy.setRestControllerStyle(true);
strategy.setControllerMappingHyphenStyle(true);
mpg.setStrategy(strategy);
mpg.execute();
}
通過這些代碼我們就能生成這樣的目錄結構


這段代碼是映射你表里的欄位,如果你每增加一個表可以寫進去再運行代碼,他就會生成對應的,這個真的很方便,大力推薦一下,它可以減少我們不必要浪費的時間,
strategy.setInclude("admin","blog","blog_tag","comment","tag","type","topic","animation",
"friend","other","album_photo","album","floor","layer");// 設定要映射的表名
4.2 檔案上傳
關于java檔案上傳,如果我上傳到target的話,服務器每一次重啟上傳的檔案就會沒有了,所以我們上傳到磁盤那里就能防止檔案的丟失了,
JAVA代碼如下:
// 上傳博客圖片
@PostMapping("/uploadPhoto")
public R<Object> uploadPhoto(@RequestParam("image") MultipartFile file){
SimpleDateFormat sdf= new SimpleDateFormat("yyyyMMddhhmmss");
Date date = new Date();// 獲取當前時間
String randomNumber = sdf.format(date);
//創建一個唯一標識作為評論的主鍵以及隊伍的一個欄位,方便用來保存資料將隊伍與隊伍描述建立起關系
//使用FilenameUtils獲得檔案的后綴(先導依賴Commons-fileUpload)
String extension = FilenameUtils.getExtension(file.getOriginalFilename());
//生成新的檔案名(隊伍名+亂數+后綴名)
String newFileName = randomNumber + "." + extension;
//使用ResourceUtils類路徑再獲取檔案保存的路徑
File dateDir = new File(FinalData.UPLOAD_FOLDER);
if (!dateDir.exists()) {
//判斷目錄是否存在,不存在則直接創建
dateDir.mkdirs();
}
try {
file.transferTo(new File(FinalData.UPLOAD_FOLDER, newFileName));
} catch (IOException e) {
e.printStackTrace();
return R.failed("上傳失敗");
}
//上傳完畢,存入資料庫中的地址為:
String invented_address="/static/uploadImage/" + newFileName;
return R.ok(invented_address);
}
Configuration配置如下
@Configuration
public class UploadFilePathConfig implements WebMvcConfigurer {
@Value("${file.staticAccessPath}")
private String staticAccessPath;
@Value("${file.uploadFolder}")
private String uploadFolder;
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler(staticAccessPath).addResourceLocations("file:" + uploadFolder);
}
}
yml配置如下
###檔案上傳
file:
###靜態資源對外暴露的訪問路徑
staticAccessPath: /api/file/**
###靜態資源實際存盤路徑
uploadFolder: /usr/local/nginx/html/static/
###專案名
servlet:
context-path:
###檔案上傳
multipart:
enabled: true
max-file-size: 10mb
max-request-size: 10mb
uploadFolder: /usr/local/nginx/html/static/ 這個是我的服務器路徑,如果放在d盤upload目錄的話就配置 D:/upload
4.3 檔案下載
特別注意一下如果使用axios是下載不了檔案的,前端要通過window.open來下載,這個我就浪費了不少時間
public static void download(String fileName, HttpServletResponse response) throws IOException {
File file = new File(FinalData.PATH,fileName);
if (file.exists()) {
response.setContentType("application/force-download");// 設定強制下載不打開
response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("cc2da5fe-552b-4e30-acea-180f5c2e9419.jpeg", "UTF-8"));// 設定檔案名和編碼格式
byte[] buffer = new byte[1024];
FileInputStream fis = null;
BufferedInputStream bis = null;
try {
fis = new FileInputStream(file);
bis = new BufferedInputStream(fis);
OutputStream os = response.getOutputStream();
int i = bis.read(buffer);
while (i != -1) {
os.write(buffer, 0, i);
i = bis.read(buffer);
}
} catch (Exception e) {
e.printStackTrace();
}
finally {
if (bis != null) {
try {
bis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
4.4 發送郵箱
在評論那里我加入了發送郵箱功能來讓我知道有人給我評論了,發郵箱的前提是他輸入了郵箱才能發送,不然只是單純的評論,發送郵箱是要獲取qq郵箱的stmp,但我只能獲取到自己的stmp,所以評論的人是發不了郵箱給我的,所以出現了這樣兩個模式,
1. 甲評論,我自己給自己發郵箱,這樣我就知道別人發郵箱給我了,
2. 甲回復乙,我用我的郵箱替甲發郵箱給乙,乙給甲回復,同理,這樣就能完成互相通知的情況了,
郵箱的配置如下
server.max-http-header-size=50000
spring.mail.host=smtp.qq.com
spring.mail.username=自己的QQ郵箱
spring.mail.password=獲取到的密碼
spring.mail.protocol=smtp
spring.mail.default-encoding=UTF-8
spring.mail.port=465
spring.mail.properties.mail.smtp.socketFactory.class=javax.net.ssl.SSLSocketFactory
java配置如下
@PostMapping("/qqEmail")
public Object qqEmail(String email,String title,String content) throws MessagingException {
MimeMessage mimeMessage = this.mailSender.createMimeMessage();
MimeMessageHelper message = new MimeMessageHelper(mimeMessage);
message.setFrom("qq郵箱"); //設定發件qq郵箱
message.setTo(email); //設定收件人
message.setSubject(title); //設定標題
message.setText(content); //第二個引數true表示使用HTML語言來撰寫郵件
this.mailSender.send(mimeMessage);
return "發送成功";
}
4.5 JAVA爬蟲
我本來是想增加一個追番的功能,在B站那里爬取每一部番的資訊,這樣就不用自己去添加,可爬取時發現除了圖片的資料其他的資料都能爬取,因為這一點我才沒有發布追番這個功能,這個爬取的代碼如下:
// 依賴包
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.13.1</version>
</dependency>
Java代碼
@GetMapping("/getSearchSource")
public ArrayList<Animation>getSearchSource(String keyWork) throws Exception {
ArrayList<Animation> animations = new ArrayList<>();
String encode = URLEncoder.encode(keyWork, "UTF-8");
String url = "https://search.bilibili.com/all?keyword="+encode+"&from_source=web_search";
Document document = Jsoup.parse(new URL(url), 30000);
Elements elements = document.getElementsByClass("bangumi-item");
for (Element element : elements) {
Animation animation = new Animation();
Elements link = element.getElementsByClass("left-img");
animation.setName(element.getElementsByClass("title").attr("title"));
animation.setRemarks(element.getElementsByClass("desc").text());
animation.setLink(link.attr("href").split("//")[1]);
animations.add(animation);
}
return animations;
}
請求的時候要加上url的加密,到后臺那里要進行解密,不然會爬取不了的
爬取出來是這么一個效果

圖片不知道為什么沒有,所以這個功能暫時沒做,有爬蟲的大佬知道的話,就告訴我一下哈!!!
5 Redis
5.1 redis前言
前言: 在講redis前,我先說一下在服務器上部署的redis,一開始時我就打算用上redis去做,也好補一下這方面的知識,因為要部署網站時redis要用服務器上的而不是本地,為了測驗我就把服務器上的redis弄成所有ip都可以連接,不然我的本地電腦就連接不上,問題就出在于我沒設定密碼,然后就被別人攻擊了,造成服務的cpu和負載狀態100%,服務直接卡炸了,并且一些基本的liunx命令都使用不了,我就直接重裝系統,那時我還不知道這個原因,然后又開始把redis設定成所有ip都可以連接,過了沒多久又開始受到攻擊,無奈下又重裝系統,這我才知道是redis的原因,
總結: 服務器上的redis不用設定成所有ip都能連接直接把專案部署上去就能直接連接了,如果真要弄成所有ip都可以連接的話,切記一定要設定密碼,這個可是血的教訓,
5.2 redis的配置
在這里我用redis只做了自動登錄功能,主要存盤登錄后的cookie并存盤七天的時間,時間一過這個資料就會消失,本地存盤的cookie和redis存盤的資料不相等,則不會自動登錄,
依賴包
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
Configuration配置
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<String, Object> template = new RedisTemplate();
template.setConnectionFactory(redisConnectionFactory);
//序列化配置
Jackson2JsonRedisSerializer<Object> jack = new Jackson2JsonRedisSerializer<>(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL);
jack.setObjectMapper(om);
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
//key采用string型別的序列化
template.setKeySerializer(stringRedisSerializer);
//hash的key也采用序列化方式
template.setHashKeySerializer(stringRedisSerializer);
//value序列化方式采用jackson
template.setValueSerializer(jack);
hash的value序列化方式采用jackson
template.setHashValueSerializer(jack);
template.afterPropertiesSet();
return template;
}
}
redis的工具包
因為代碼太長了我就不放出來了,直接上鏈接下載 http://liaojiale.com/RedisUtil.java
redis設定值和獲取值的用法
redisUtil.set(key, value,time);
redisUtil.get(key);
登錄功能如下
@Autowired
private RedisUtil redisUtil;
@PostMapping("/adminLogin")
public String adminLogin(Admin admin){
QueryWrapper<Admin> wrapper = new QueryWrapper<>();
wrapper.eq("username",admin.getUsername());
wrapper.eq("password",admin.getPassword());
if (adminService.getOne(wrapper)!=null){
String uid = UUID.randomUUID().toString();
redisUtil.set("login", uid,60*60*24*7);
return uid;
}
return null;
}
自動登錄功能
@Autowired
private RedisUtil redisUtil;
@GetMapping("/autoLogin")
public boolean autoLogin(String value){
if (redisUtil.get("login")==null)return false;
if (redisUtil.get("login").equals(value))return true;
return false;
}
6 專案打包
6.1 vue打包
- 首先要在config/index.js的dev的 / 改為 ./

- 在bulid里的 / 也改為 ./

- 路由配置那里的mode為 history

- 輸入 npm run build命令進行打包
打包后的目錄結構如下

6.2 SpringBoot打包
- 在pom.xml上配置如下:

- 先點擊clean在點擊package

- 打開target就會發現多出的jar包,就能直接把jar包放上服務器部署
7 專案部署
7.1 docker安裝
# 1、需要的安裝包
yum install -y yum-utils
# 2、設定鏡像倉庫,我們選第二個阿里云鏡像
yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo #默認是國外的!
yum-config-manager \
--add-repo \
http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo #阿里云鏡像
#更新yum軟體包索引
yum makecache fast
# 3、安裝docker相關的
yum install docker-ce docker-ce-cli containerd.io
# 4、啟動docker
systemctl start docker
# 5、docker version 是否安裝成功
# 6、配置阿里云鏡像服務
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://be29yayj.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
7.2 vue部署
我們要把專案放進nginx上運行,所以我們先在本地下載nginx,
7.2.1 nginx下載
- 我們先從網上下載nginx
- 下載完后通過tar -zvvf nginx-1.9.9.tar.gz 命令解壓
- 進到解壓后的目錄執行 ./configure && make && make install 命令安裝
- 進入到 /usr/local/nginx/conf
- 通過vim對nginx.conf進行如下配置:
如果配置到本地要注釋第二個 root /usr/share/nginx/html;把第一個root的注釋取消掉,因為我們要配置到docker上就要如下配置

7.2.2 docker安裝nginx
docker pull nginx
7.2.3 docker掛載nginx
docker run --name 容器名 -d -p 80:80 -v /usr/local/nginx/conf/nginx.conf:/etc/nginx/nginx.conf -v /usr/local/nginx/html/:/usr/share/nginx/html nginx
-d 后臺運行
–name 給容器命名
-p 宿主埠,容器內部埠
-v 掛載的目錄或檔案
1.掛載完之后就能通過ip地址直接訪問啦~
2. 我們先通過Xftp工具把vue專案放到/usr/local/nginx/html里面
3. 因為我們掛載了相應的目錄和檔案,所以vue專案也在docker容器里上傳好了,vue專案也就部署完了
7.3 SpringBoot部署
- 通過Xftp工具把SpringBoot放去你想放入的目錄上,并進入該目錄,
- 使用如下命令進行SpringBoot專案的部署
nohup java -jar 檔案名.jar >/home/admin/檔案名.jar.out 2>&1 &java -jar 檔案名.jar &
8 總結
整個專案我用了20天的時間完成,主要前端花費了很多時間,因為我前端的技術一般般,加上審美這方面真的是硬傷,通過這個專案我對所使用的到的技術更加了解,如果想要學好編程真的要做專案,做專案是成長最快的一個方法,如果要大佬看見這篇博客覺得哪些地方可以改進一下,希望指教一下哈哈哈!!!
最后附上我的博客的頁面!






轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/291849.html
標籤:java
上一篇:超詳細Java基礎-抽象
