栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

spring boot+vue 的前后端分离与合并方案实例详解

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

spring boot+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前端项目

 

springboot项目:

 

上面这是最简单的合并方式,但是如果作为工程级的项目开发,并不推荐使用手工合并,也不推荐将前端代码构建后提交到springboot的resouce下,好的方式应该是保持前后端完全独立开发代码,项目代码互不影响,借助jenkins这样的构建工具在构建springboot时触发前端构建并编写自动化脚本将前端webpack构建好的资源拷贝到springboot下再进行jar的打包,最后就得到了一个完全包含前后端的springboot项目了。

三、整合的核心问题处理

通过上面的整合后会出现两个比较大的问题:

1. 无法正常访问静态资源 。

2. vue router路由的路径无法正常解析 。

解决第一个问题,我们必须重新指定springboot的静态资源处理前缀,代码:

@Configuration
public class SpringWebMvcConfig extends WebMvcConfigurerAdapter {
  @Override
  public void addResourceHandlers(ResourceHandlerRegistry registry) {
    registry.addResourceHandler("/static
public class RewriteFilter implements Filter {
  
  public static final String REWRITE_TO = "rewriteUrl";
  
  public static final String REWRITE_PATTERNS = "urlPatterns";
  private Set 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() {
  }
  
  private boolean isMatches(Set 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;
  }
}

过滤器的注册:

@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就可以将前端的路由资源交给路由来处理了。至此整个完整前后端分离开发合并方案就完成了。这种方式在后期有条件情况下也可以很容易做到前后端的完全分离开发部署。

总结

以上所述是小编给大家介绍的spring boot+vue 的前后端分离与合并方案,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对考高分网网站的支持!

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/143017.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号