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/**").addResourceLocations("classpath:/static/");
    super.addResourceHandlers(registry);
  }
}

解决第二个问题的方式是对vue的路由的路径做rewrite,交给router来处理,而不是springboot自己处理,rewrite时可以考虑路由的路径统一增加后最,然后在springboot中编写过滤拦截特定后缀来做请求转发交给vue的路由处理。如:

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

后端拦截到带有vhtml的都交给router来处理,这种方式在后端写过滤器拦截后打包是完全可行的,但是前端开发的直接访问带后缀的路径会有问题。

另外一种方式是给前端的路由path统一加个前缀比如/ui,这时后端写过滤器匹配该前缀,也不会影响前端单独开发是的路由解析问题。过滤器参考如下:

/**
 * 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通配符之前用英文分号隔开
   */
  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 正则表达式或通配符
   * @param url 请求的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;
  }
}

过滤器的注册:

@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 的前后端分离与合并方案,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对我们网站的支持!

(0)

相关推荐

  • Vue项目部署在Spring Boot出现页面空白问题的解决方案

    网上流行的解决方案是将assetsPublicPath: '/'改成'./',下面说一下这个解决方案的弊端: 通常页面空白的问题出现大多数是由于Spring Boot端配置了server.servlet.context-path,上下文改变了css, js等文件的访问路径,文件无法加载导致index.html显示空白.'/'改成'./'是将绝对路径变为相对路径,可以动态适应Spring Boot端上下文的改变,这是为什么这个解决方案起作用的原因. Vue项目部署在Spring Boot出现的另一

  • vue+springboot前后端分离实现单点登录跨域问题解决方法

    最近在做一个后台管理系统,前端是用时下火热的vue.js,后台是基于springboot的.因为后台系统没有登录功能,但是公司要求统一登录,登录认证统一使用.net项目组的认证系统.那就意味着做单点登录咯,至于不知道什么是单点登录的同学,建议去找一下万能的度娘. 刚接到这个需求的时候,老夫心里便不屑的认为:区区登录何足挂齿,但是,开发的过程狠狠的打了我一巴掌(火辣辣的一巴掌)...,所以这次必须得好好记录一下这次教训,以免以后再踩这样的坑. 我面临的第一个问题是跨域,浏览器控制台直接报CORS,

  • 详解Vue项目编译后部署在非网站根目录的解决方案

    同一个生产部署项目,基内外网的访问路径并不相同,内网是基于域名根目录来访问,而外网却指向了一个子目录. eg. : vue-router: history模式 内网环境:192.168.1.1:8080/index.html 外网环境:domain.com/ttsd/index.html 由于开发出来的项目是要部署在客户方,且客户并不想单独拿一个域名(或子域)来部署,这时,打包后的程序就要作一些配置方面的修改了. 修改配置文件 1.把打包后的资源引用修改为相对路径 找到 config/index

  • 在nginx上部署vue项目(history模式)的方法

    vue-router 默认是hash模式,使用url的hash来模拟一个完整的url,当url改变的时候,页面不会重新加载.但是如果我们不想hash这种以#号结尾的路径时候的话,我们可以使用路由的history的模式.比如如下网址: 使用hash模式的话,那么访问变成 http://localhost:8080/bank/page/count/#/ 这样的访问,如果路由使用 history的话,那么访问的路径变成 如下: http://localhost:8080/bank/page/count

  • Spring boot + mybatis + Vue.js + ElementUI 实现数据的增删改查实例代码(二)

    在上篇文章给大家介绍了Spring boot + mybatis + Vue.js + ElementUI 实现数据的增删改查实例代码(一),接下来我们添加分页相关的依赖,时间紧张,直接上代码了,贴上我的pom文件 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=

  • Vue项目webpack打包部署到Tomcat刷新报404错误问题的解决方案

    遇到的问题 使用webpack打包vue后,将打包好的文件,发布到Tomcat上,访问成功,但是刷新后页面报404错. 在网上查找了一下,原来是HTML5 History 模式引发的问题,具体为什么,vue官方已经给出了解释,你可以看https://router.vuejs.org/zh-cn/essentials/history-mode.html 但是看完问题又来了,官方给出的解决方案中没有说tomcat下,怎么决解. 解决方案 根据官方给出的解决方案原理 你要在服务端增加一个覆盖所有情况的

  • Spring boot + mybatis + Vue.js + ElementUI 实现数据的增删改查实例代码(一)

    环境搭建 spring boot的简介 以往我们开发时用到spring总是避免不了繁琐的配置,例如我们要配置一个数据库连接,可能需要以下几步: 1.编写jdbc.properties配置文件: 2.创建spring的配置文件,加入spring配置文件前缀.配置数据库连接信息以及sqlsessionFactory等等: 3.还要在web.xml文件中加入spring的监听. springboot的出现大大简化了项目的搭建过程(spring配置以及maven配置),让我们专注于应用功能的开发,而不是

  • vue项目部署上线遇到的问题及解决方法

    前言 今天把自己写的demo登录写完了,就想着试着走一下部署上线的流程.参考了很多的文档,终于成功进行了部署.在这里将服务器的搭建和vue项目的 部署上线进行整理(都是基础的知识,希望对大家有帮助.对我帮助是很大的) 2.流程 1.服务器搭建 这里我用的是腾讯云的服务器.买了一个域名.没有备案的域名也可以使用.买完服务器进行域名解析. 点击添加解析,按照下面这样填写就行 马赛克是你的外网ip 可以根据你需要的进行修改,我这只是最基本的绑定.其他请自行百度. 3.添加ssh密钥 第一步添加密钥,会

  • Vue 项目部署到服务器的问题解决方法

    相信很多小伙伴在用Vue-cli安装的脚手架开发的时候,在开发环境中项目可以很正常的运行,但是进入到生产环境,编译打包后,放入服务器,项目就不正常了,会出现空白页或者路由跳转404等问题.遇到这些问题不要慌张,正确的配置加上后端的简单配合就可以解决. 如何打包 基于Vue-Cli,通过npm run build来进行打包的操作 如何部署 将打包出来的资源,基于Vue-Cli的一般是dist目录下有static目录和index.html文件,可以直接将这两个文件扔到服务端 但有时候,我们会直接将d

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

    springboot和vue结合的方案网络上的主要有以下两种: 1. [不推荐]在html中直接使用script标签引入vue和一些常用的组件,这种方式和以前传统的开发是一样的,只是可以很爽的使用vue的双向数据绑定,这种方式只适合于普通的全栈开发. 2.[推荐]使用vue官方的脚手架创建单独的前端工程项目,做到和后端完全独立开发和部署,后端单独部署一个纯restful的服务,而前端直接采用nginx来部署,这种称为完全的前后端分离架构开发模式,但是在分离中有很多api权限的问题需要解决,包括部

  • Spring boot jpa 删除数据和事务管理的问题实例详解

    今天我们介绍的是jpa删除和事务的一些坑,接下来看看具体内容. 业务场景(这是一个在线考试系统)和代码:根据问题的id删除答案 repository层: int deleteByQuestionId(Integer questionId); service 层: public void deleteChoiceAnswerByQuestionId(Integer questionId) { choiceAnswerRepository.deleteByQuestionId(questionId)

  • Spring Boot 定制与优化内置的Tomcat容器实例详解

    1.Spring Boot 定制与优化内置Tomcat容器. > 内置的容器有三个分别是Undertow.Jetty.Tomcat,Spring Boot 对这三个容器分别进行了实现,它们上层接口都是EmbeddedServletContainerFactory,该接口也是本文的主要核心. 对于内置容器的定制与优化主要有两种方式,第一种方式是通过配置文件来配置,另外一种是通过码代码的方式.接下来主要对上述两种方式进行实现. 2.通过配置文件来定制与优化Tomcat > 配置的核心内容参考org

  • Java中Spring Boot+Socket实现与html页面的长连接实例详解

    Spring Boot+Socket实现与html页面的长连接,客户端给服务器端发消息,服务器给客户端轮询发送消息,附案例源码 功能介绍 客户端给所有在线用户发送消息客户端给指定在线用户发送消息服务器给客户端发送消息(轮询方式) 注意:socket只是实现一些简单的功能,具体的还需根据自身情况,代码稍微改造下 项目搭建 项目结构图 pom.xml <?xml version="1.0" encoding="UTF-8"?> <project xml

  • SpringBoot+VUE实现前后端分离的实战记录

    一,前端VUE项目 这里使用VUE UI创建一个VUE项目 命令行输入vue ui进入 手动配置项目 选中这三个 点击下一步->点击创建项目 用IDEA打开刚才创建的项目 IDEA中的安装vue插件并重启 IDEA控制台中输入vue add axios安装axios 新建一个Show.vue 在index,js的routes中配置它的路由 编写Show,vue向后端请求数据并展示 <template> <div> <table> <tr> <td

  • SpringBoot+mybatis+Vue实现前后端分离项目的示例

    目录 一.SpringBoot环境搭建 1.项目的数据库 2.项目所需依赖 3.application.yml文件 4.入口类 二.vue实现前后端分离 1.前端页面 2.springBoot控制层 3.mapper文件 4.项目完整源代码 vue前后端分离实现功能:员工的增删改(先实现数据回显之后,再进行修改)查 一.SpringBoot环境搭建 1.项目的数据库 /* Navicat Premium Data Transfer Source Server : windows Source S

  • 部署vue+Springboot前后端分离项目的步骤实现

    单页应用 vue经常被用来开发单页应用(SinglePage Web Application,SPA),什么叫做单页应用呢,也就是只有一张web页面的应用,单页应用的跳转只需要刷新局部资源,大大加快的了我们页面的响应速度 前端页面打包 打开vue工程,在项目根目录下创建一个配置文件:vue.config.js,然后在里面写入以下内容: module.exports = { assetsDir: 'static', // 静态资源保存路径 outputDir: 'dist', // 打包后生成的文

  • Vue+SpringBoot前后端分离中的跨域问题

    在前后端分离开发中,需要前端调用后端api并进行内容显示,如果前后端开发都在一台主机上,则会由于浏览器的同源策略限制,出现跨域问题(协议.域名.端口号不同等),导致不能正常调用api接口,给开发带来不便. 封装api请求 import axios from 'axios' //axios.create创建一个axios实例,并对该实例编写配置,后续所有通过实例发送的请求都受当前配置约束 const $http = axios.create({ baseURL: '', timeout: 1000

  • python框架django中结合vue进行前后端分离

    目录 一:创建django项目 二:安装vue 三:设置vue项目 四:vue项目写完后,打包vue项目,然后修改django配置,将vue集成到django中 五:修改django的主目录的urls文件 六:启动django服务,访问localhost:8000 则可以出现vue的首页 七:有时候并不能直接访问出首页,原因是路径不对 八:vue打包之后经常会出现fontawesome图标库不能使用的情况 一:创建django项目 django-admin startproject mysite

随机推荐