1. 程式人生 > >Vue-cli3.0專案部署到sping boot 方案

Vue-cli3.0專案部署到sping boot 方案

Vue前端打包部署到sping boot中

以靜態專案作為參考[前端vue-cli3+後臺sping boot]

  • 前端工程目錄如下:

    vue-cli3工程目錄

  • 後臺工程目錄如下:

    spring boot 工程目錄

  • 前後端整合:

    在專案整合的過程中,直接將前端開發好後將build構建好的dist下static中的檔案拷貝到spring boot的resource的static下,index.html則直接拷貝到spring boot的resource的static下。我們這樣就可以愉快的啟動sping boot,輸入網址就可以愉快的訪問啦!但是通過上面的整合後會出現兩個比較大的問題。vue-cli3打包部署到spring boot 工程目錄

  • 前後端整合核心問題處理:
    <p>1. 無法正常訪問靜態資源 。</p>
    
     > 解決該問題問題,我們必須重新指定spring boot的靜態資源處理字首,程式碼:
    
@Configuration
public class WebAppConfigurer extends WebMvcConfigurerAdapter {
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler
("/holmeslog/**").addResourceLocations("file:" + SystemConfig.getProperty("holmeslog.path")); registry.addResourceHandler("/processorlog/**").addResourceLocations("file:" + SystemConfig.getProperty("processorlog.path")); registry.addResourceHandler("/installtar/**").addResourceLocations("file:"
+ SystemConfig.getProperty("installtar.path")); registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/"); //重新指定spring boot的靜態資源處理字首 super.addResourceHandlers(registry); } }
  <p>2. vue router路由的路徑無法正常解析 。</p>

   > 對vue的路由的路徑做rewrite,交給router來處理,而不是spring boot自己處理,rewrite時可以考慮路由的路徑統一增加字尾,然後在spring boot中編寫過濾攔截特定字尾來做請求轉發交給vue的路由處理。前端路增加fe,如
export default {
  path: '/fe/regular',
  component: () => import('@/views/empty'),
  name: 'regular',
  meta: { title: '規則配置', icon: 'guize' },
  children: [{
    path: 'find',
    name: 'regular-find',
    meta: { hidden: true, title: '發現規則', icon: 'right' },
    component: () => import('@/views/regular/find')
  }, 
  ...... 
  {
    path: 'mask-edit/:id',
    name: 'regular-mask-edit',
    meta: { title: '編輯脫敏規則', icon: 'right', hidden: true, breadcrumb: [{ name: 'regular-mask', title: '規則配置' }, { name: 'regular-mask', title: '脫敏規則' }] },
    component: () => import('@/views/regular/mask-edit.js')
  }]
}

   > 後臺改變,如
Application.java

    public FilterRegistrationBean someFilterRegistration() {
        FilterRegistrationBean registration = new FilterRegistrationBean();
        registration.setFilter(XssFilter());
        registration.addUrlPatterns("/*");
        registration.addInitParameter("paramName", "paramValue");
        registration.addInitParameter(XssFilter.REWRITE_TO,"/index.html");  // 重點
        registration.addInitParameter(XssFilter.REWRITE_PATTERNS, "/fe/*");  // 重點
        registration.setName("XssFilter");
        return registration;
    }

XssFilter.java

public class XssFilter implements Filter {

    //需要rewrite的目的地址
    public static final String REWRITE_TO ="rewriteUrl";
    public static final String REWRITE_PATTERNS = "rewritePatterns";
    private Set<String> urlPatterns = null;//配置url萬用字元
    private String rewriteTo = null;
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        rewriteTo = filterConfig.getInitParameter(REWRITE_TO);
        String exceptUrlString = filterConfig.getInitParameter(REWRITE_PATTERNS);
        if(StringUtil.isEmpty(exceptUrlString)) {
            urlPatterns = Collections.emptySet();
        }else {
            urlPatterns = Collections.unmodifiableSet(new HashSet<>(Arrays.asList(exceptUrlString.split(";",0))));
        }
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        MHttpServletRequest xssRequest = new MHttpServletRequest((HttpServletRequest) request);
        HttpServletRequest request1 = xssRequest;
        String servletPath = request1.getServletPath();
        String context = request1.getContextPath();
        if(isMatches(urlPatterns, servletPath)) {
            request.getRequestDispatcher(context+ "/"+ rewriteTo).forward(xssRequest,response);
        } else if(servletPath.contains("main")) {//相容處理main和main#
            request.getRequestDispatcher(context+ "/"+ rewriteTo).forward(xssRequest,response);
        }else {
            chain.doFilter(xssRequest, response);
        }

    }

    @Override
    public void destroy() {
    }

    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;
    }
}

後端攔截到帶有/fe的都交給router來處理!(或者spring boot 的介面都增加標識,攔截spring boot的介面標識,非介面統一交給前端來處理)

重點:

   > 上面這是最簡單的合併方式,但是如果作為工程級的專案開發,並不推薦使用手工合併,也不推薦將前端程式碼構建後提交到spring boot的resouce下。好的方式應該是保持前後端完全獨立開發程式碼,專案程式碼互不影響,編寫指令碼在構建spring boot時觸發前端構建並編寫自動化指令碼將前端webpack構建好的資源拷貝到spring boot下再進行jar的打包,最後就得到了一個完全包含前後端的spring boot專案了。【在複製的時候,不要進行替換或者覆蓋,最好的方式,把原有的的檔案進行刪除之後在進行復制】
前端路由使用的是history模式
ps:本方案只是在靜態專案場景下的選擇,如果一切條件允許,強力推薦做完全的前後端分離。就算後期完全分開部署,也沒有影響。
如果文件有更好的補充和好的建議,歡迎聯絡@博主
如有雷同,請聯絡@博主。