1. 程式人生 > >Springboot+Vue 的前後端分離與合併方案

Springboot+Vue 的前後端分離與合併方案

0?wx_fmt=gif&wxfrom=5&wx_lazy=1

摘要: springboot+vue的前後端分離與合併

springboot和vue結合的方案網路上的主要有以下兩種:

1. 【不推薦】在html中直接使用script標籤引入vue和一些常用的元件,這種方式和以前傳統的開發是一樣的,只是可以很爽的使用vue的雙向資料繫結,這種方式只適合於普通的全棧開發。

2.【推薦】使用vue官方的腳手架建立單獨的前端工程專案,做到和後端完全獨立開發和部署,後端單獨部署一個純restful的服務,而前端直接採用nginx來部署,這種稱為完全的前後端分離架構開發模式,但是在分離中有很多api許可權的問題需要解決,包括部署後的vue router路由需要在nginx中配置rewrite規則。

這種前後端完全分離的架構也是目前網際網路公司所採用的,後端伺服器不再需要處理靜態資源,也能減少後端伺服器一些壓力。

為什麼做前後端分離開發合併

在傳統行業中很多是以專案思想來主導的,而不是產品,一個專案會賣給很多的客戶,並且部署到客戶本地的機房裡。在一些傳統行業裡面,部署實施人員的技術無法和網際網路公司的運維團隊相比,由於各種不定的環境也無法做到自動構建,容器化部署等。因此在這種情況下儘量減少部署時的服務軟體需求,打出的包數量也儘量少。

針對這種情況這裡採用的在開發中做到前後端獨立開發,整個開發方式和上面提到的第二種方式是相同的,但是在後端springboot打包釋出時將前端的構建輸出一起打入,最後只需部署springboot的專案即可,無需再安裝nginx伺服器。

Springboot 和 Vue 整合的關鍵操作

實際上本文中這種前後端分離的開發,前端開發好後將build構建好的dist下static中的檔案拷貝到springboot的resource的static下,index.html則直接拷貝到springboot的resource的static下。下面是示例圖:

vue 前端專案

640?wx_fmt=png

springboot 專案:

640?wx_fmt=png

重點:上面這是最簡單的合併方式,但是如果作為工程級的專案開發,並不推薦使用手工合併,也不推薦將前端程式碼構建後提交到springboot的resouce下。

好的方式應該是保持前後端完全獨立開發程式碼,專案程式碼互不影響,藉助jenkins這樣的構建工具在構建springboot時觸發前端構建並編寫自動化指令碼將前端webpack構建好的資源拷貝到springboot下再進行jar的打包,最後就得到了一個完全包含前後端的springboot專案了。

整合的核心問題處理

通過上面的整合後會出現兩個比較大的問題:

    1. 無法正常訪問靜態資源 。

    2. vue router路由的路徑無法正常解析 。

解決第一個問題,我們必須重新指定springboot的靜態資源處理字首,程式碼:

640?wx_fmt=png

解決第二個問題的方式是對vue的路由的路徑做rewrite,交給router來處理,而不是springboot自己處理,rewrite時可以考慮路由的路徑統一增加字尾,然後在springboot中編寫過濾攔截特定字尾來做請求轉發交給vue的路由處理。如:

640?wx_fmt=png

後端攔截到帶有vhtml的都交給router來處理,這種方式在後端寫過濾器攔截後打包是完全可行的,但是前端開發的直接訪問帶字尾的路徑會有問題。

另外一種方式是給前端的路由path統一加個字首比如/ui,當然就可以把之前的字尾刪除了,這時後端寫過濾器匹配該字首,也不會影響前端單獨開發是的路由解析問題。過濾器參考如下:

640?wx_fmt=jpeg

過濾器的註冊:

@SpringBootApplication

public class SpringBootMainApplication {

    public static void main(String[] args) {

        SpringApplication.run(SpringBootMainApplication.class, args);

    }

    @Bean

    public EmbeddedServletContainerCustomizer containerCustomizer() {

        return (container -> {

                ErrorPage error401Page = new ErrorPage(HttpStatus.UNAUTHORIZED, "/errors/401.html");

                ErrorPage error404Page = new ErrorPage(HttpStatus.NOT_FOUND, "/errors/404.html");

                ErrorPage error500Page = new ErrorPage(HttpStatus.INTERNAL_SERVER_ERROR, "/errors/500.html");

                container.addErrorPages(error401Page, error404Page, error500Page);

        });

    }

    @Bean

    public FilterRegistrationBean testFilterRegistration() {

        FilterRegistrationBean registration = new FilterRegistrationBean();

        registration.setFilter(new RewriteFilter());//註冊rewrite過濾器

        registration.addUrlPatterns("/*");

        registration.addInitParameter(RewriteFilter.REWRITE_TO,"/index.html");

        registration.addInitParameter(RewriteFilter.REWRITE_PATTERNS, "/ui/*");

        registration.setName("rewriteFilter");

        registration.setOrder(1);

        return registration;

    }

}

這時springboot就可以將前端的路由資源交給路由來處理了。至此整個完整前後端分離開發合併方案就完成了。這種方式在後期有條件情況下也可以很容易做到前後端的完全分離開發部署。

ps:本方案只是在特定場景下的選擇,如果一切條件允許,強力推薦做完全的前後端分離

640?wx_fmt=png

看完本文有收穫?請轉發分享給更多人

歡迎關注“暢聊架構”,我們分享最有價值的網際網路技術乾貨文章,助力您成為有思想的全棧架構師,我們只聊網際網路、只聊架構!打造最有價值的架構師圈子和社群。

長按下方的二維碼可以快速關注我們

640?wx_fmt=jpeg