一、需求

  
    使用前后端分离编写了个小程序,前端使用的是vue-cli3创建的项目,后端使用的是springboot创建的项目,部署的时候一起打包部署,本文对一些细节部分进行了说明。
 

二、Vue项目具体配置

 
    (1) vue正常开发使用代理与后台交互,在打包时候,有些配置需要和后端保持一致
 
    (2)配置生产时环境变量: (file:  .env.production),
  .env.production是我自己配置的生产时环境变量,可以自己创建(具体可以参考:vue-cli3环境配置),也可以忽略这个,直接填写,例如,在axios的配置中,可以直接配置成Axios.defaults.baseURL = '/app_name/v1'

NODE_ENV = 'production'
VUE_APP_BASE_URL= /app_name/v1
VUE_APP_CONTEXT=/pre-lcas
VUE_APP_ASSETS=static
  1. VUE_APP_BASE_URL
          用于给所有http请求指定起始路径,前端项目中使用axios组件支持http请求,在axios的配置文件中指定 Axios.defaults.baseURL = process.env.VUE_APP_BASE_URL , 这样原本通过代理与后台进行的请求,都会加上`/app_name/v1`,
            例如: 在前端代码中使用的是: axios.get('/reqUrl/abc')......  向后台发起请求,根据上面配置后,打包后的工程请求路径会变成 {http://xxx:xx/app_name/v1/reqUrl/abc} 可以通过这个配置,匹配前端请求。
 
  1. VUE_APP_CONTEXT和VUE_APP_ASSETS
        用于设置打包后的成果物相关信息,在配置文件vue.config.js中使用,配置方式如下:
module.exports = {
// 设置路径
publicPath: process.env.VUE_APP_CONTEXT,
assetsDir: process.env.VUE_APP_ASSETS,
......
}
publicPath和assetsDir的作用可以参考官网,如果assetsDir不配置,默认会把index.html文件和css等目录都放到static目录下,这样复制springboot项目下会出现无法访问静态资源的问题,尝试了几种方法,还是将assetsDir配置成static比较好。打包后的资源目录结构如下:
dist
--static
----css
----fonts
----img
----js
--favicon.ico
--index.html
复制的时候,将static文件夹复制到springboot的/src/main/resource下,将favicon.ico和index.html也复制到static目录下。如果springboot是多module工程,静态文件放到启动文件所在模块下的resource目录中。复制后的springboot目录如下:
/src
--main
--|--java
--|--|--com.xx.xx.WebApplication
--|--resource
--|--|--static
--|--|--|--css
--|--|--|--fonts
--|--|--|--img
--|--|--|--js
--|--|--|--favicon.ico
--|--|--|--index.html
--|--|--application.properties

三、springboot项目配置

 
静态资源复制到springboot后,还是会出现无法访问资源的问题,需要设置资源访问规则。
 
具体代码是:

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/");
WebMvcConfigurer.super.addResourceHandlers(registry);
}
  /**
   * 路由过滤,如果路径中包含‘home’关键词(前端所有路由都包含‘home’)
   * @return
   */
  @Bean
  public FilterRegistrationBean filterRegistration() {
   FilterRegistrationBean<RewriteFilter> registration = new FilterRegistrationBean<>();
   //注册rewrite过滤器
   registration.setFilter(new RewriteFilter());
   registration.addUrlPatterns("/*");
   registration.addInitParameter(RewriteFilter.REWRITE_TO,"/index.html");
   registration.addInitParameter(RewriteFilter.REWRITE_PATTERNS, "/home/*");
   registration.setName("rewriteFilter");
   registration.setOrder(1);
   return registration;
  }
}

 RewriteFilter.java代码

import org.springframework.util.StringUtils;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.regex.Pattern; /**
* 过滤后端请求,不属于后端的请求,交由前端路由处理
* @author: 2019/11/1 9:50
* @since: 0.0.1-SNAPSHOT
* @modified By:
*/
public class RewriteFilter implements Filter {
/**
* 需要rewrite到的目的地址
*/
public static final String REWRITE_TO = "rewriteUrl"; /**
* 拦截的url,url通配符之前用英文分号隔开
*/
public static final String REWRITE_PATTERNS = "urlPatterns"; /** 配置url通配符 */
private Set<String> urlPatterns = null; private String rewriteTo = null;
@Override
public void init(FilterConfig cfg) throws ServletException {
//初始化拦截配置
rewriteTo = cfg.getInitParameter(REWRITE_TO);
String exceptUrlString = cfg.getInitParameter(REWRITE_PATTERNS);
if (!StringUtils.isEmpty(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();
//匹配到后端路径标识,放行,否则,交给前端路由
if (isMatches(urlPatterns, servletPath)) {
req.getRequestDispatcher(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;
}
}

RewriteFilter.java

四、说明

有的文章在前后端分离后再整合打包这个问题上,都说明了两个问题,
一个是要保证整合后静态资源可以被访问到,这个问题需要确保打包时的路径,因为如果打包失误,会在加载index.html时候找不到css/js等资源;
另一个是要保证请求路径的分离,用户看到地址栏的是vue-router中的指定路径,页面渲染获取数据使用的是axios请求路径,后台开放的是服务路径,一定要确保axios路径与后台开放的服务路径匹配上。
 
有的文章中提到,需要后端对router中的路径进行处理,我测试的过程中,并没有出现异常,把访问不到的路径交给前端处理就行了,前端会统一处理404异常,跳转到缺省的404错误页面。
 
2019年11月20日 19:49:04修改:
补充了后端对前端路由的处理,前面有相关代码。 
如果后端不对前端路由进行处理,也就是说明把前端路由交个前端进行处理,正常访问不会出现问题,如果用户刷新浏览器,会出现404异常,因为后端代码无法处理前端路由请求。

参考文章:

vue-cli3.0配置开发环境,测试环境,线上环境(https://blog.csdn.net/qq_37055675/article/details/85047451
 
springboot+vue的前后端分离与合并方案( https://my.oschina.net/u/1760791/blog/1577662
 
 
 

Vue-cli3与springboot项目整合打包的更多相关文章

  1. springboot项目,打包时携带所有依赖

    springboot项目,打包时携带所有依赖 本文主要解决springboot打包时,如何设置才能把当前项目的所有依赖都打进去. Springboot 的自带spring-boot-maven-plu ...

  2. Flowable与springBoot项目整合及出现的问题

    Flowable与springBoot项目整合及出现的问题 单纯地将Flowable和springBoot整合,使用mysql作为数据库,整合中踩了两个坑,见文末. 在pom中添加依赖 <?xm ...

  3. springboot项目整合druid数据库连接池

    Druid连接池是阿里巴巴开源的数据库连接池项目,后来贡献给Apache开源: Druid的作用是负责分配.管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个: D ...

  4. Springboot项目与vue项目整合打包

    我的环境 * JDK 1.8 * maven 3.6.0 * node环境 1.为什么需要前后端项目开发时分离,部署时合并? 在一些公司,部署实施人员的技术无法和互联网公司的运维团队相比,由于各种不定 ...

  5. vue和cordova项目整合打包,并实现vue调用android的相机的demo

    经过网上查找很多资料,发现很多只有vue+cordova的项目整合,但是vue使用cordova插件的文章很少,现在把从创建cordova和创建vue到vue使用插件到项目打包到android手机运行 ...

  6. VUE CLI3.X 创建项目

    Node.js环境搭建 Node.js基于V8引擎,可以让js代码脱离浏览器运行 Vue CLI3.0 需要Node.js 8.9或者更高版本. 用nvm或者nvm-windows在同一台电脑中管理多 ...

  7. vue cli3以上的项目中如何使用axois请求本地json文件

    首先明确一点,在vue cli3以上的版本中,存放静态资源的文件是public 我刚开始以为是和vue cli2一样需要放在static文件夹下,但是项目中没有这个文件夹,我就自己创建了一个,结果请求 ...

  8. 使用maven构建项目时,SSM和springboot项目的打包与云服务器部署

    下面讲讲如何打包SSM和springboot项目,并部署到云服务器上. 由于使用的IDE不同,有的使用eclipse,有的使用idea,所以如果在IDE中按照 maven clean 再 maven ...

  9. SpringBoot项目整合Retrofit最佳实践,这才是最优雅的HTTP客户端工具!

    大家都知道okhttp是一款由square公司开源的java版本http客户端工具.实际上,square公司还开源了基于okhttp进一步封装的retrofit工具,用来支持通过接口的方式发起http ...

随机推荐

  1. kafka start bat

    start D:\Homes\kafka_2.12-2.3.0\bin\windows\kafka-server-start.bat D:\Homes\kafka_2.12-2.3.0\config\ ...

  2. JAVAWeb问题总结(持续更新)

    1.在JSP页面头部,出现如下错误: 错误文本: Multiple annotations found at this line: - The superclass "javax.servl ...

  3. a链接内容过长,换行

    上图为溢出情况,此情况均为 英文或数字,但亲测,中文也可正常换行. 添加   word-wrap: break-word;  后,正常换行. 若不希望换行,设为  white-space: nowra ...

  4. Java中的基本数据类型语法补充

    变量要先赋值后使用 不给变量赋值代表什么 不赋值就使用会怎样 (会报错) 计算并赋值运算符 作用是为了让代码更加简洁.比如 a = a + 10,可以简化为 a+=10 += -= *= /= %= ...

  5. 【协作式原创】查漏补缺之Golang中mutex源码实现

    概览最简单版的mutex(go1.3版本) 预备知识 主要结构体 type Mutex struct { state int32 // 指代mutex锁当前的状态 sema uint32 // 信号量 ...

  6. 标签UILabel的讲解

    首先,我先自定义几个名词,方便接下来的讲解工作.如下图所示: 接下来,通过五个方面来讲解我们能对UILabel做出哪些改变或者称之为设置: 1.文字 1.1普通文字:内容text.字体大小font.字 ...

  7. Airless Pump Bottle For The Rise Of Cosmetic Packaging Solutions

    Airless Pump Bottle    are used in the rise of cosmetic packaging solutions. According to the suppli ...

  8. Python回收机制

    1.小整数对象池 整数在程序中的使用非常广泛,python 为了优化速度,使用了小整数对象池,避免整数频繁申请和销毁和内存空间. Python 对小整数的定义事[-5, 257]这些整数对象的hi提前 ...

  9. PAT T1016 Uniqueness of MST

    dfs判断连通块的数量,prim算法建立最小生成树并判断是否唯一~ #include<bits/stdc++.h> using namespace std; ; const int inf ...

  10. 五 Spring的配置:Bean的配置,生命周期和作用范围

    Bean相关的配置: <bean>标签的id和name的配置: id:使用了约束中的唯一约束,里面不能出现特殊字符 name:没有使用唯一约束,理论上可以重复,实际上开发不行,里面可以出现 ...