寫在前面
又是一個學期又是一個課程設計,上學期寫了一個web前端課程設計——K.X的博客這學期老師給了一些SpringBoot的demo練習;明白瞭如何可以進行前後端分離開發。選擇這個課程設計也是給自己上學期的前端課程設計寫一個後端。
開發環境
- idea
- Visual Studio Code
- mysql 8.0
- jdk 10
服務器用的是SpringBoot內置的服務器
說明
本課程設計的前端目前還是直接引用的,後續會轉換成node.js環境下的前端項目
技術棧
- Spring Boot
- Mybatis
- Spring Security
- Vue
- Bootstrap
功能模塊圖
效果展示
博主模塊:
訪客模塊
大部分頁面效果和博主類似少了一些管理功能,添加了註冊和評論發佈功能。
PS:固定的底部欄的向上箭頭圖片添加了頁面回滾至頂的效果,我怕它太小大家看不到;哈哈哈哈哈
項目源碼:
項目源碼以及sql文件已託管至github需要自取,可能是因爲網絡的原因,託管至github的圖片顯示錯誤;但clone或下載下來的圖片顯示是正常的。
由於經過了Spring Security安全框架的加密,數據庫中看不到用戶密碼:在這裏說一下,所有用戶的密碼都爲:123456
K.X的博客開發過程種遇到問題及解決方法
問題一、
前端頁面加載正常,但瀏覽器F12查看會有一個404錯誤
undefined:1 GET http://localhost:8080/blog/undefined 404
但是我的前端頁面根本沒有這個請求,查了這個問題也有一些其他的人遇到了這個問題;好像是和vue-router的使用有關,也沒有找到具體的解決辦法。
解決方法:
未解決。
問題二、
數據查詢問題
由於想要實現在博客詳情頁面顯示博客內容,以及所有評論和對應評論的用戶和頭像,就需要涉及到article(文章表)、comment(評論表)和user(表)連接查詢問題。剛開始只是簡單的寫了三個表的連接查詢,查出對應的字段。對於含有評論的文章這樣查詢是沒有問題的,但當一個文章還沒有評論時,comment(評論表)中無該文章相關數據,直接三個表連接查詢查到爲空。
初始sql語句
select a.*,c.id c_id,c.content c_content,c.created c_created,u.nickname u_nickname,u.photo u_photo from article a,comment c,user u where a.id=c.articleid and c.userid=u.id and a.id=8 order by c_id desc;
解決方法:
查看了老師的博客例子發現老師使用的是左連接,兩個進行左連接左連接會讀取左邊數據表的全部數據,即使右邊數據表沒有對應數據。(如果兩個表中數據有相同部分,只顯示一個) 沒有寫過sql的左連接,查了網上的都是兩個表的左連接,自己試着照葫蘆畫瓢寫三個表的左連接,要麼語法錯誤要麼找不到字段;後來想到了嵌套查詢,先給user(用戶表)和comment(評論表)連接查詢,再與article(文章表)進行左連接查詢,成功查到,解決當文章沒有評論的不會報爲空的查詢。
sql語句
select a.*,c_id,c_content,c_created,u_nickname,u_photo from article a left join (select c.id c_id,c.articleid c_articleid,c.content c_content,c.created c_created,u.nickname u_nickname,u.photo u_photo from user u,comment c where c.userid=u.id) as b on a.id=c_articleid where a.id=1 order by c_id desc;
PS:我這種方法肯定影響效率,一定有更好的語句解決;有知道的大佬歡迎來留言,爲小弟指點迷津。
由於每個文章有多個評論,而每個評論又對應一個用戶,也就出現了一對多中含有多對一
ArticleMapper.xml中關於查詢文章詳情語句:
<!--根據id查詢文章詳情,包括所有評論-->
<select id="selectArticleByID" resultMap="articleWithComment">
select a.*,c_id,c_content,c_created,u_nickname,u_photo
from article a left join
(select c.id c_id,c.articleid c_articleid,c.content c_content,c.created c_created,u.nickname u_nickname,u.photo u_photo
from user u,comment c
where c.userid=u.id) as b
on a.id=c_articleid where a.id=#{id} order by c_id desc;
</select>
<resultMap id="articleWithComment" type="Article">
<id property="id" column="id"/>
<result property="title" column="title"/>
<result property="content" column="content"/>
<result property="created" column="created"/>
<result property="hits" column="hits"/>
<result property="zan" column="zan"/>
<result property="comments" column="comments"/>
<collection property="commentList" ofType="Comment">
<id property="id" column="c_id"/>
<result property="content" column="c_content"/>
<result property="created" column="c_created"/>
<association property="user" javaType="User">
<result property="nickname" column="u_nickname"/>
<result property="photo" column="u_photo"/>
</association>
</collection>
</resultMap>
評論管理時遇到類似問題,同樣思路解決;不說是先進行的嵌套查詢,再連接查詢的;因爲有些沒有評論的博客就不需要再顯示了。
問題三、
由於使用了Spring Security安全框架,User類實現了接口UserDetails;當通過Controller獲取User時 新增了一些屬性。
當更改用戶信息時,報錯無法構造實例
Cannot construct instance of `org.springframework.security.core.GrantedAuthority` (no Creators, like default construct, exist): abstract types either need to be mapped to concrete types, have custom deserializer, or contain additional type information
at [Source: (PushbackInputStream); line: 1, column: 487] (through reference chain: com.kx.pojo.User["authorities"]->java.util.ArrayList[1])
解決方法:
查了一圈博客發現問題是由於Jackson反序列化時,authorities字段無法進行序列化;可通過@JsonIgnore
註解在序列化或反序列化時忽略某屬性;Jackson提供了@JsonIgnore這個註解,用於在(反)序列化時,忽略bean的某項屬性;
參考博客:https://www.iteye.com/blog/wwwcomy-2397340
問題四、
由於獲取登錄用戶的信息,是通過Spring Security中的SecurityContextHolder獲取,在更改用戶信息後但是session中緩存的用戶信息未更新,所以當再次獲取登錄用戶的信息依舊是上次登錄session緩存中的信息。
獲取登錄用戶信息代碼:
@GetMapping("/getuser")
public User getuser(){
return (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
}
解決方法:
感謝江南一點雨大佬分享,無意間找到了大佬博客,有很多框架教學博客。具體解決文章:
https://mp.weixin.qq.com/s/jQZx4i4-vqjpBjpoJKJF4A
更新用戶信息代碼:
@PutMapping("/user")
public String updateUser(@RequestBody User user, Authentication authentication){
userService.updateUser(user);
SecurityContextHolder.getContext().setAuthentication(new UsernamePasswordAuthenticationToken(user,authentication.getCredentials(),authentication.getAuthorities()));
return "success";
}
問題五、
加入Spring Security安全框架後,發現新加博客時插入本地圖片顯示錯誤。
解決方法:
查看login_page頁面,提示未登錄,估計vue-heml5-editor富文本編輯器的原因,爲了使用方便在選擇導入圖片時,不用對用戶進行認證。
查看file請求錯誤狀態碼爲302;
並且請求的URL爲:
http://localhost:8080/blog/file。
在後端設置/file服務任何用戶都可以訪問,可以不用登錄。
選擇本地圖片顯示成功。
後來在註冊用戶時也遇到了類似的問題,請求靜態資源圖片默認頭像時顯示錯誤類似方法解決,開啓可不登錄訪問
歡迎大家運行測試,有問題隨時滴滴我