日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 前端技术 > vue >内容正文

vue

springboot+vue的前后端分离与合并方案

發(fā)布時(shí)間:2023/12/15 vue 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 springboot+vue的前后端分离与合并方案 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

pringboot和vue結(jié)合的方案網(wǎng)絡(luò)上的主要有以下兩種:

1. 【不推薦】在html中直接使用script標(biāo)簽引入vue和一些常用的組件,這種方式和以前傳統(tǒng)的開發(fā)是一樣的,只是可以很爽的使用vue的雙向數(shù)據(jù)綁定,這種方式只適合于普通的全棧開發(fā)。

2.【推薦】使用vue官方的腳手架創(chuàng)建單獨(dú)的前端工程項(xiàng)目,做到和后端完全獨(dú)立開發(fā)和部署,后端單獨(dú)部署一個(gè)純r(jià)estful的服務(wù),而前端直接采用nginx來部署,這種稱為完全的前后端分離架構(gòu)開發(fā)模式,但是在分離中有很多api權(quán)限的問題需要解決,包括部署后的vue router路由需要在nginx中配置rewrite規(guī)則。這種前后端完全分離的架構(gòu)也是目前互聯(lián)網(wǎng)公司所采用的,后端服務(wù)器不再需要處理靜態(tài)資源,也能減少后端服務(wù)器一些壓力。

一、為什么做前后端分離開發(fā)合并

在傳統(tǒng)行業(yè)中很多是以項(xiàng)目思想來主導(dǎo)的,而不是產(chǎn)品,一個(gè)項(xiàng)目會(huì)賣給很多的客戶,并且部署到客戶本地的機(jī)房里。在一些傳統(tǒng)行業(yè)里面,部署實(shí)施人員的技術(shù)無法和互聯(lián)網(wǎng)公司的運(yùn)維團(tuán)隊(duì)相比,由于各種不定的環(huán)境也無法做到自動(dòng)構(gòu)建,容器化部署等。因此在這種情況下盡量減少部署時(shí)的服務(wù)軟件需求,打出的包數(shù)量也盡量少。針對(duì)這種情況這里采用的在開發(fā)中做到前后端獨(dú)立開發(fā),整個(gè)開發(fā)方式和上面提到的第二種方式是相同的,但是在后端springboot打包發(fā)布時(shí)將前端的構(gòu)建輸出一起打入,最后只需部署springboot的項(xiàng)目即可,無需再安裝nginx服務(wù)器。

二、springboot和vue整合的關(guān)鍵操作

實(shí)際上本文中這種前后端分離的開發(fā),前端開發(fā)好后將build構(gòu)建好的dist下static中的文件拷貝到springboot的resource的static下,index.html則直接拷貝到springboot的resource的static下。下面是示例圖:

vue前端項(xiàng)目

springboot項(xiàng)目:

上面這是最簡單的合并方式,但是如果作為工程級(jí)的項(xiàng)目開發(fā),并不推薦使用手工合并,也不推薦將前端代碼構(gòu)建后提交到springboot的resouce下,好的方式應(yīng)該是保持前后端完全獨(dú)立開發(fā)代碼,項(xiàng)目代碼互不影響,借助jenkins這樣的構(gòu)建工具在構(gòu)建springboot時(shí)觸發(fā)前端構(gòu)建并編寫自動(dòng)化腳本將前端webpack構(gòu)建好的資源拷貝到springboot下再進(jìn)行jar的打包,最后就得到了一個(gè)完全包含前后端的springboot項(xiàng)目了。

三、整合的核心問題處理

通過上面的整合后會(huì)出現(xiàn)兩個(gè)比較大的問題:

1. 無法正常訪問靜態(tài)資源 。

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

解決第一個(gè)問題,我們必須重新指定springboot的靜態(tài)資源處理前綴,代碼:

@Configurationpublic class SpringWebMvcConfig extends WebMvcConfigurerAdapter { @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/"); super.addResourceHandlers(registry); }}

解決第二個(gè)問題的方式是對(duì)vue的路由的路徑做rewrite,交給router來處理,而不是springboot自己處理,rewrite時(shí)可以考慮路由的路徑統(tǒng)一增加后最,然后在springboot中編寫過濾攔截特定后綴來做請(qǐng)求轉(zhuǎn)發(fā)交給vue的路由處理。如:

const router = new VueRouter({ mode: 'history', base: __dirname, routes: [ { path: '/ui/first.vhtml', component: First }, { path: '/ui/second.vhtml', component: secondcomponent } ]})

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

另外一種方式是給前端的路由path統(tǒng)一加個(gè)前綴比如/ui,這時(shí)后端寫過濾器匹配該前綴,也不會(huì)影響前端單獨(dú)開發(fā)是的路由解析問題。過濾器參考如下:

?

/*** be used to rewrite vue router** @author yu on 2017-11-22 19:47:23.*/ public class RewriteFilter implements Filter { /** * 需要rewrite到的目的地址 */public static final String REWRITE_TO = "rewriteUrl"; /** * 攔截的url,url通配符之前用英文分號(hào)隔開 */public static final String REWRITE_PATTERNS = "urlPatterns"; private Set<String> urlPatterns = null;//配置url通配符 private String rewriteTo = null; @Override public void init(FilterConfig cfg) throws ServletException { //初始化攔截配置 rewriteTo = cfg.getInitParameter(REWRITE_TO); String exceptUrlString = cfg.getInitParameter(REWRITE_PATTERNS);if (StringUtil.isNotEmpty(exceptUrlString)) { urlPatterns = Collections.unmodifiableSet( new HashSet<>(Arrays.asList(exceptUrlString.split(";", 0)))); } else { urlPatterns = Collections.emptySet(); } }@Override public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) req; String servletPath = request.getServletPath(); String context = request.getContextPath(); //匹配的路徑重寫 if (isMatches(urlPatterns, servletPath)) { req.getRequestDispatcher(context+"/"+rewriteTo).forward(req, resp);}else{ chain.doFilter(req, resp); } }@Override public void destroy() { } /** * 匹配返回true,不匹配返回false * @param patterns 正則表達(dá)式或通配符 * @param url 請(qǐng)求的url * @return */private boolean isMatches(Set<String> patterns, String url) { if(null == patterns){ return false; }for (String str : patterns) {if (str.endsWith("/*")) { String name = str.substring(0, str.length() - 2); if (url.contains(name)) { return true; } } else { Pattern pattern = Pattern.compile(str); if (pattern.matcher(url).matches()) { return true; } } } return false; }}

?

過濾器的注冊(cè):

@SpringBootApplicationpublic 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());//注冊(cè)rewrite過濾器 registration.addUrlPatterns("/*"); registration.addInitParameter(RewriteFilter.REWRITE_TO,"/index.html"); registration.addInitParameter(RewriteFilter.REWRITE_PATTERNS, "/ui/*"); registration.setName("rewriteFilter"); registration.setOrder(1); return registration; }}

?

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

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

?

轉(zhuǎn)載于:https://www.cnblogs.com/zytrue/p/8489587.html

總結(jié)

以上是生活随笔為你收集整理的springboot+vue的前后端分离与合并方案的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。