Springboot项目与vue项目整合打包的实现方式

我的环境

* JDK 1.8
 * maven 3.6.0
 * node环境

1.为什么需要前后端项目开发时分离,部署时合并?

在一些公司,部署实施人员的技术无法和互联网公司的运维团队相比,由于各种不定的环境也无法做到自动构建,容器化部署等。因此在这种情况下尽量减少部署时的服务软件需求,打出的包数量也尽量少。针对这种情况这里采用的在开发中做到前后端独立开发,打包时在后端springboot打包发布时将前端的构建输出一起打入,最后只需部署springboot的项目即可,无需再安装nginx服务器

在这里我有两种方式,一种是简单的,一种是复杂的,下边先来看一个简单的例子:

1)前端开发好后将build构建好的dist下的文件拷贝到springboot的resources的static下(boot项目默认没有static,需要自己新建)

操作步骤:前端vue项目使用命令 npm run build 或者 cnpm run build 打包生成dist文件,在springboot项目中resources下建立static文件夹,将dist文件中的文件复制到static中,然后去application中跑起来boot项目,这样直接访问index.html就可以访问到页面(api接口请求地址自己根据情况打包时配置或者在生成的dist文件中config文件夹中的index.js中配置)

项目结构如图:

鼠标选中的这几个就是从dist文件中复制过来的前端的包,然后我们直接启动boot项目就可以通过index.html访问了(ps:上面这是最简单的合并方式,但是如果作为工程级的项目开发,并不推荐使用手工合并,也不推荐将前端代码构建后提交到springboot的resouce下,好的方式应该是保持前后端完全独立开发代码,项目代码互不影响,借助jenkins这样的构建工具在构建springboot时触发前端构建并编写自动化脚本将前端webpack构建好的资源拷贝到springboot下再进行jar的打包,最后就得到了一个完全包含前后端的springboot项目了。不过上述方法操作简单,便于使用,如果想一次性打包完成的话,就看第二种)

2:第二种方法是在src/main下建立一个webapp文件夹,然后将前端项目的源文件复制到该文件夹下,具体结构如图:

然后使用maven命令执行本地node打包命令,这样就可以 在执行mvn clean package命令时,利用maven插件执行cnpm run build命令(我是使用的淘宝的镜像cnpm,国外的npm命令会相对慢一些,大家根据自己的条件选择,具体命令请看项目中前端vue文件的README.md),一次性完成整个过程

实现方法是这样的,我们要引入org.codehaus.mojo插件来进行maven调用node命令,pom.xml中为:

<plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>exec-maven-plugin</artifactId>
        <executions>
          <execution>
            <id>exec-cnpm-install</id>
            <phase>prepare-package</phase>
            <goals>
              <goal>exec</goal>
            </goals>
            <configuration>
              <executable>${cnpm}</executable>
              <arguments>
                <argument>install</argument>
              </arguments>
              <workingDirectory>${basedir}/src/main/webapp</workingDirectory>
            </configuration>
          </execution>
          <execution>
            <id>exec-cnpm-run-build</id>
            <phase>prepare-package</phase>
            <goals>
              <goal>exec</goal>
            </goals>
            <configuration>
              <executable>${cnpm}</executable>
              <arguments>
                <argument>run</argument>
                <argument>build</argument>
              </arguments>
              <workingDirectory>${basedir}/src/main/webapp</workingDirectory>
            </configuration>
          </execution>
        </executions>
      </plugin>

然后maven-resources-plugin插件将项目的前端文件打包到boot项目的classes中,具体的请参考pom.xml中的,

将webapp/dist文件夹中的文件复制到src/main/resources/static中,并打包到classes

<!--copy文件到指定目录下 -->
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-resources-plugin</artifactId>
        <configuration>
          <encoding>${project.build.sourceEncoding}</encoding>
        </configuration>
        <executions>
          <execution>
            <id>copy-spring-boot-webapp</id>
            <!-- here the phase you need -->
            <phase>validate</phase>
            <goals>
              <goal>copy-resources</goal>
            </goals>
            <configuration>
              <encoding>utf-8</encoding>
              <outputDirectory>${basedir}/src/main/resources/static</outputDirectory>
              <resources>
                <resource>
                  <directory>${basedir}/src/main/webapp/dist</directory>
                </resource>
              </resources>
            </configuration>
          </execution>
        </executions>
      </plugin>

然后通过maven命令:

mvn clean package -P window 

打包成功后我们的前端项目就整个的打包到了boot项目的jar包中,然后启动项目,访问index.html页面就看到了项目启动成功。

打出来的jar包中如果static说明打包由于种种原因失败了,我就遇到过几次,这时候需要再来一次 mvn clean package -P window

ps:下面看下SprintBoot 整合vue实现上传下载

这里记录一下在Springboot中实现文件上传下载的核心代码

package com.file.demo.springbootfile;
import com.file.util.ResultUtil;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.apache.tomcat.util.http.fileupload.IOUtils;
import org.apache.tomcat.util.http.fileupload.util.Streams;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
/*
* springboot整合vue,文件上传下载
* */
//上传不要用@Controller,用@RestController
@RestController
@RequestMapping("/file")
public class FileController {
  private static final Logger logger = LoggerFactory.getLogger(FileController.class);
  //在文件中,不用/或者\最好,推荐使用File.separator
  private final static String fileDir="files";
  private final static String rootPath = System.getProperty("user.home")+ File.separator+fileDir+File.separator;
  /*
  * 文件上传
  * */
  @RequestMapping("/upload")
  public Object uploadFile(@RequestParam("file")MultipartFile[] multipartFiles, final HttpServletResponse response, final HttpServletRequest request){
    File fileDir = new File(rootPath);
    /*
    * exists():测试此抽象路径名表示的文件是否存在
    * isDirectory():检查一个对象是否是文件夹
    * isFile():判断是否为文件,也可能是文件目录
    * */
    if(!fileDir.exists() && !fileDir.isDirectory()){
      //检查到文件不存在则创建
      fileDir.mkdir();//创建文件,一级
      fileDir.mkdirs();//创建多级
    }
    try{
      if(multipartFiles != null && multipartFiles.length > 0){
        for ( int i = 0;i<multipartFiles.length;i++){
          try{
            String storagePath = rootPath+multipartFiles[i].getOriginalFilename();
            logger.info("上传的文件:" + multipartFiles[i].getName()+","+multipartFiles[i].getContentType()+","
                +multipartFiles[i].getOriginalFilename() + ",保持的路径为:" + storagePath);
            Streams.copy(multipartFiles[i].getInputStream(), new FileOutputStream(storagePath), true);
          }catch (IOException e){
            logger.info(ExceptionUtils.getFullStackTrace(e));
          }
        }
      }
    }catch (Exception e){
      return ResultUtil.error(e.getMessage());
    }
    return ResultUtil.success("上传成功!");
  }
  /*
  * 文件下载
  * */
  @RequestMapping("/download")
  public Object downkiadFile(@RequestParam String fileName,final HttpServletResponse response,final HttpServletRequest request){
    OutputStream os = null;
    InputStream is = null;
    try{
      //获取输出流rootPath
      os = response.getOutputStream();
      //重置输出流
      response.reset();
      response.setContentType("application/x-download;charset=GBK");
      response.setHeader("Content-Disposition", "attachment;filename="+ new String(fileName.getBytes("utf-8"), "iso-8859-1"));
      //读取流
      File f= new File(rootPath+fileName);
      is = new FileInputStream(f);
      if(is == null){
        logger.error("下载文件失败,请检查文件“"+ fileName +"”是否存在");
        return ResultUtil.error("下载附件失败,请检查文件“" + fileName + "”是否存在");
      }
      //复制文件
      IOUtils.copy(is,response.getOutputStream());
      //刷新缓冲
      response.getOutputStream().flush();
    }catch (IOException e){
      return ResultUtil.error("下载文件失败,error:" + e.getMessage());
    }
    //文件的关闭在finally中执行
    finally {
      {
        try {
          if(is != null){
            is.close();
          }
        }catch (IOException e){
          logger.error(ExceptionUtils.getFullStackTrace(e));
        }
        try{
          if(os != null){
            os.close();
          }
        }catch (IOException e){
          logger.info(ExceptionUtils.getFullStackTrace(e));
        }
      }
    }
    return null;
  }
}

源码下载地址: https://github.com/struggle0903/SpringBootfiledemo.git

总结

以上所述是小编给大家介绍的Springboot项目与vue项目整合打包的实现方式,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对我们网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

时间: 2019-07-02

springboot整合vue项目(小试牛刀)

序 本文主要研究一下如何在springboot工程整合vue maven <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> 新建springboot的web工程,默认会在resources目录下生成static以及templates文件夹 temp

vue+springboot实现项目的CORS跨域请求

跨域资源共享CORS(Cross-origin Resource Sharing),是W3C的一个标准,允许浏览器向跨源的服务器发起XMLHttpRequest请求,克服ajax请求只能同源使用的限制.关于CORS的详细解读,可参考阮一峰大神的博客:跨域资源共享CORS详解.本文为通过一个小demo对该博客中分析内容的一些验证. 1.springboot+vue项目的构建和启动 细节不在此赘述,任何简单的springboot项目就可以,而前端vue项目只需用axios发ajax请求即可. 我的d

Spring Boot/VUE中路由传递参数的实现代码

在路由时传递参数,一般有两种形式,一种是拼接在url地址中,另一种是查询参数.如:http://localhost:8080/router/tang/101?type=spor&num=12.下面根据代码看一下,VUE 和 Spring Boot 中各自是如何处理传递和接受参数的. Spring Boot package com.tang.demo1.controller; import org.springframework.web.bind.annotation.*; @RestContro

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

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

Vue+SpringBoot开发V部落博客管理平台

V部落是一个多用户博客管理平台,采用Vue+SpringBoot开发. 演示地址: http://45.77.146.32:8081/index.html 项目地址: https://github.com/lenve/VBlog 登陆页面 文章列表 发表文章 用户管理 栏目管理 数据统计 技术栈 后端技术栈 后端主要采用了: 1.SpringBoot 2.SpringSecurity 3.MyBatis 4.部分接口遵循Restful风格 5.MySQL 前端技术栈 前端主要采用了: 1.Vue

SpringBoot+Vue.js实现前后端分离的文件上传功能

这篇文章需要一定Vue和SpringBoot的知识,分为两个项目,一个是前端Vue项目,一个是后端SpringBoot项目. 后端项目搭建 我使用的是SpringBoot1.5.10+JDK8+IDEA 使用IDEA新建一个SpringBoot项目,一直点next即可 项目创建成功后,maven的pom配置如下 <dependencies> <dependency> <groupId>org.springframework.boot</groupId> &l

如何把vuejs打包出来的文件整合到springboot里

这个需求不知道是不是合适,因为静态的vuejs项目,用nginx部署,听说很快. 一般有这个需求的,都是用tomcat来部署java项目,tomcat转发静态vuejs,应该不会很快. 好吧,以上都是听说...应该...实际嘛?... 废话不多讲,马上搞起. 这里第一句要说的是,目前这个方式我认为只支持#这个方式的路由,如果改成了html5的mode: 'history',应该是不支持的. 开始准备: 注意,我的springboot用的视图模板是thymeleaf,静态文件夹路径默认是resou

vue 打包后的文件部署到express服务器上的方法

vue 简介 Vue.js(读音 /vjuː/, 类似于 view) 是一套构建用户界面的渐进式框架. Vue 只关注视图层, 采用自底向上增量开发的设计. Vue 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件. vue是目前最流行的前端框架,今天要介绍的是如何利用vue+webpack+express的方式进行前后端分离的开发. 1.首先用vue-cli初始化项目目录 vue init webpack pro-name cd pro-name && npm ins

webpack打包并将文件加载到指定的位置方法

使用webpack打包,最爽的事情莫过于可以直接require文件了,但是这 同时带来了一个问题,就是所有的文件整合到一起,那这一个包就太大了. 基于此:下面我们来了解下webpack的打包(主要是将如何将我们需要的内容模块,分开打包, 并且按照我们自己设定的存放路径进行存放) 首先在webpack.config.js文件中 entry入口函数出表示出哪些是需要单独打包成一个js包的: entry: { main: path.resolve(__dirname,'src/index.js'),

把Java程序打包成jar文件包并执行的方法

本文介绍了把Java程序打包成jar文件包并执行的方法,分享给大家,具体如下: 1.首先要确认自己写的程序有没有报错. 2.第一次我写的是Web Project到现在,我一直没有执行成功,所以最好创建的是java Project 打包步骤: 1.在项目上,右键,选择Export. 2.进入到下图界面,选择Java 下面的JAR file 3.选择项目,确认必要的文件是否选中,选择保存jar文件包的路径,如下图 4.完成步骤3之后,点击Next,进入如下图界面: 5.直接点Next,进入下面的界面

linux中tar打包指定路径文件的实现方法

压缩: tar czvf /data/backup/test.tar.gz /data/a/b/directory 解压: cd /data/test tar xzvf /data/backup/test.tar.gz 问题是,解压后的文件,在/data/test/data/a/b/directory里面 要想解压在当前目录路径. 这样写就可以解决了 tar czvf /data/backup/test.tar.gz /data/a/b/directory 改成 tar czvf /data/b

php将文件夹打包成zip文件的简单实现方法

示例如下: function addFileToZip($path,$zip){ $handler=opendir($path); //打开当前文件夹由$path指定. while(($filename=readdir($handler))!==false){ if($filename != "." && $filename != ".."){//文件夹文件名字为'.'和'..',不要对他们进行操作 if(is_dir($path."/&q

用asp实现把文件打包成Xml文件包,带解包的ASP工具附下载

把文件打包成Xml文件包,带解包的ASP工具! 把网站源码全部打包到Xml文件里面,生成 updata.xml 文件,把xml文件上传到空间里面 然后通过 install.asp文件将文件全部释放出来. 就和z-blog的 自动安装包一样的功能呵呵. 代码是落伍的一位兄弟写的,不过代码好像有错误,这个是我参考他的 修改过了,可以正常运行!~~ 此代码可以应用到 asp程序的 自动升级服务上面.具体怎么来实现,欢迎探讨!~~ 就在下面回帖探讨!~~~ 不用设定打包目录版,需要设定打包目录版 这两个

node-webkit打包成exe文件被360误报木马的解决方法

最近项目需要用到node-webkit.处理古老级用户的兼容以及他们心里的'数据安全'问题. 1.下载完node-webkit 2.制作appName.nw文件 3.copy /b nw.exe+appName.nw  TestAppName.exe 到目前为止,目录下生成了TestAppName.exe文件 ,双击运行很完美. 但,直接将TestAppName.exe换个目录,却打不开. google+百度的解决方案:使用Enigma Virtual Box工具,打包成exe文件.(Enigm

webpack vue 项目打包生成的文件,资源文件报404问题的修复方法(总结篇)

最近在使用webpack + vue做个人娱乐项目时,发现npm run build后,css js img静态资源文件均找不到路径,报404错误...网上查找了一堆解决办法,总结如下 一.首先修改config目录下的index.js文件 将其中build的配置项assetsPublicPath进行修改,改为 目的是将资源文件的引入路径,改为相对地址(相对index.html) 二.此时html中的js.css.img引入均没有问题,但是css中的background-image还是报404 此

浅谈将JNI库打包入jar文件

在Java开发时,我们有时候会接触到很多本地库,这样在对项目打包的时候我们不得不面临一个选择:要么将库文件与包好的jar文件放在一起:要么将库文件包入jar. 将一个不大的项目包成一个jar有诸多发布优势,本次将分享一个将JNI包入jar的方法. [实现思路] 将JNI库(dll.so等)包入jar后,我们无法通过路径来访问它们,而库的读取依赖一个java.library.path下对应名称的外部库文件,我们仅仅需要在调用JNI前将其由jar包释放出来,这类似于文件的拷贝过程. [部署位置的选取