关于SpringBoot + Vue,这里列出一个基本的项目实例。
源码:https://github.com/slhuang520/study/tree/master/spring-boot-vue-cli-parent

1. 环境

使用的开发工具为IDEA,最新版本,专为开发Springboot而制。

JDK 版本为8,
Apache Server 为 Tomcat,版本为8

使用Maven来管理开发项目,进行项目的整个合与编译。整个项目结构如下:

2. 项目架构

基本采用前后端分离,使用是的先分离后结合的方案,开发是独立进行的,但最后打包成一个项目进行发布。
前端使用 node js 环境,使用 Vue Cli 3.0以上版本。
后端使用 SpringBoot 搭建整体项目架构,版本为2.1.7-Release。
最后项目整合打包时,使用 Maven 工具。

3. 具体手顺

3.1 创建前后端管理父类

使用IDEA父级别的 Module:

然后,在新建 module中创建一个 Maven 项目:

指定groupId 和 artifactId,Next 创建好。

整个 parent 项目中,删除自动生成的一些目录,比如src | test,只留下 pom.xml 和 iml配置文件,其他的全部删除,没有用。
同时将 packaging 指定为 pom

<!-- parent pom.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>cn.com.love.hsl</groupId><artifactId>spring-boot-vue-cli-parent</artifactId><version>1.0-SNAPSHOT</version><packaging>pom</packaging></project>

3.2 创建前端 UI 项目

整体的项目结构图如下:

3.2.1 使用 IDEA 创建 UI 项目,使其作为之前创建的 Parent的一个 module

需要将目录结构指定在之前创建的 Parent 目录之下:

注意,这里前端我们还是创建一个带有 Maven 的 Module,跟之前的 Parent 项目一样。
将 packaging 也指定为 pom.

删除 src 目录下的其他所有子目录,那些是不需要的。
只需要留下:

  • src 空目录,
  • pom.xml
  • iml 配置文件

3.2.2 安装 vue

创建 Vue Cli 项目,可以完全参考官网给的手顺:
官网地址:https://cli.vuejs.org/zh/guide/installation.html

如果电脑Vue环境已经安装好了,需要确认一下版本是否对,若是不对的话,请按如下方式更新。

  • 关于旧版本

Vue CLI 的包名称由 vue-cli 改成了 @vue/cli。 如果你已经全局安装了旧版本的 vue-cli (1.x 或 2.x),你需要先通过 npm uninstall vue-cli -g 或 yarn global remove vue-cli 卸载它。

  • Node 版本要求

Vue CLI 需要 Node.js 8.9 或更高版本 (推荐 8.11.0+)。你可以使用 nvm 或 nvm-windows 在同一台电脑中管理多个 Node 版本。

可以使用下列任一命令安装这个新的包:

npm install -g @vue/cli

查看版本信息,确认是否安装成功:

vue --version

3.2.3 创建 Vue Cli 项目

打开 IDEA的 terminal 窗口(需要将路径调整到UI 项目下),在其中输入以下命令,创建项目:

vue create .

注意这里不需要再指定项目名称了,之前已经创建好的,只需要将 vue的环境配置好。
这个过程可能会有一点慢,需要下载第三方的一些包,在这之前,最好将 npm 的镜像使用为淘宝的,这样下载速度会快一些。

3.2.3.1 .eslintrc.js

配置好自己的编码规则:

module.exports = {root: true,env: {node: true},extends: ["plugin:vue/essential", "@vue/prettier"],rules: {"no-console": process.env.NODE_ENV === "production" ? "error" : "off","no-debugger": process.env.NODE_ENV === "production" ? "error" : "off","vue/html-indent": ["error",4,{attribute: 1,alignAttributesVertically: true,ignores: []}],"vue/max-attributes-per-line": [2,{singleline: 10,multiline: {max: 5,allowFirstLine: false}}],"vue/html-self-closing": "off","vue/name-property-casing": ["error", "PascalCase"],"prettier.jsxBracketSameLine": true,"editor.formatOnSave": true,"eslint.autoFixOnSave": true,"prettier/prettier": "off"},globals: {$: true,Vue: true},parserOptions: {parser: "babel-eslint"}
};

3.2.3.2 package.json

引入外部的 jquery bootstrap axios

{"name": "spring-boot-vue-cli-ui","version": "0.1.0","private": true,"scripts": {"serve": "vue-cli-service serve","build": "vue-cli-service build","lint": "vue-cli-service lint"},"dependencies": {"core-js": "^2.6.5","vue": "^2.6.10","vue-router": "^3.0.3"},"devDependencies": {"@vue/cli-plugin-babel": "^3.10.0","@vue/cli-plugin-eslint": "^3.10.0","@vue/cli-service": "^3.10.0","@vue/eslint-config-prettier": "^5.0.0","babel-eslint": "^10.0.1","eslint": "^5.16.0","eslint-plugin-prettier": "^3.1.0","eslint-plugin-vue": "^5.0.0","prettier": "^1.18.2","vue-template-compiler": "^2.6.10","webpack": "^4.33.0","jquery": "^3.4.1","bootstrap": "^4.3.1","popper.js": "^1.15.0","axios": "^0.19.0"}
}

3.2.3.3 配置 pom.xml 文件

需要让不同的用户,直接将项目拿过去可以进行编译打包,而不需要自己手动搭建环境。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>cn.com.love.hsl</groupId><artifactId>spring-boot-vue-cli-parent</artifactId><version>1.0-SNAPSHOT</version></parent><artifactId>spring-boot-vue-cli-ui</artifactId><packaging>pom</packaging><name>spring-boot-vue-cli-ui</name><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><node.version>v10.15.0</node.version><node.directory>${project.parent.build.directory}/${node.version}</node.directory><npm.version>6.10.3</npm.version><npm-cache.directory>${project.build.directory}\npm-cache</npm-cache.directory></properties><build><plugins><!--安装前端自己的编译环境--><plugin><groupId>com.github.eirslett</groupId><artifactId>frontend-maven-plugin</artifactId><version>1.3</version><configuration><installDirectory>${node.directory}</installDirectory></configuration><executions><execution><id>install node and npm</id><phase>initialize</phase><goals><goal>install-node-and-npm</goal></goals><configuration><nodeVersion>${node.version}</nodeVersion><npmVersion>${npm.version}</npmVersion></configuration></execution><execution><id>npm install</id><phase>initialize</phase><goals><goal>npm</goal></goals><configuration><npmRegistryURL>https://registry.npm.taobao.org</npmRegistryURL><arguments>install --no-optional --cache="${npm-cache.directory}"</arguments></configuration></execution><execution><id>npm run release</id><phase>compile</phase><goals><goal>npm</goal></goals><configuration><arguments>run build</arguments></configuration></execution></executions></plugin><!--将前端打印成 zip 包,方便后面自动拷贝到后端项目--><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-assembly-plugin</artifactId><version>3.1.1</version><executions><execution><id>make-bundles</id><phase>package</phase><goals><goal>single</goal></goals><configuration><descriptors><descriptor>assembly/zip.xml</descriptor></descriptors><appendAssemblyId>false</appendAssemblyId><finalName>${project.name}-${project.version}</finalName></configuration></execution></executions></plugin></plugins></build>
</project>

3.2.3.4 在根目录下面新建 Vue cli 的配置文件 vue.config.js

引入外部的 jquery,将jquery 作为一个全局的块,直接引入项目中,这样就不用在项目的每个块中再单独引入了。

并指定整个前端项目的 publicPath.
publicPath 其实就是后端项目指定的 context-path,如果后端没有指定的话,这里也可以不用指定。

const webpack = require("webpack");module.exports = {publicPath: "sbvc",configureWebpack: {plugins: [new webpack.ProvidePlugin({$: "jquery",jQuery: "jquery",Popper: ["popper.js", "default"]})]}/*,devServer: {proxy: {"/apis": {target: "http://localhost:8443/sbvc/",ws: true,changeOrigin: true,pathRewrite: {'^/apis': ''}}}}*/
};

这样在项目的任何地方都可以正常使用 $ 符号了。

3.2.3.5 引入外部 bootstrap

前面 package.json文件中,已经将需要的 jquery 和 bootstrap 下载下来了,这里只需要将其引入到项目模块中。

3.2.3.5.1 引入 bootstrap 的静态 css

在 src 目录下面新建一个 static 子目录,用于存放静态资源。

3.2.3.5.2 修改 main.js入口文件

引入 bootstrap.js 和 bootstrap.css.

后面需要使用 axios 发送 http 请求(跟 jquery 的 ajax 类似),这里也一起引入了。
并指定后端的接口,注意目前这个接口是无法使用的,都还没有搭建呢。。。。

import "bootstrap";
import "./static/bootstrap.css";
import Vue from "vue";
import App from "./App.vue";
import router from "./router";
import axios from "axios";Object.defineProperty(Vue.prototype, "$http", {value: axios
});Vue.config.productionTip = false;
//后台接口
axios.defaults.baseURL = 'http://localhost:8080/sbvc/';new Vue({router,render: h => h(App)
}).$mount("#app");

其他的都可以不用再另行配置了,使用默认的,到这里应该是可以正常启动前端项目了。

3.2.4 启动前端项目

在 IDEA 的 Terminal 窗口中(注意这里还是需要指定到 UI 目录下),输入如下命令启动前端项目:

npm run serve

启动成功后,直接在浏览器中访问:
http://localhost:8080/sbvc/

应该就可以直接看到画面了。

3.2.5 编写自己的前端页面

以下以创建部门列表页面为列:

3.2.5.1 Dept.vue

在 views 目录下创建页面。

<template><div class="dept"><table id="dept_table" class="table table-striped"><thead><tr><th>ID</th><th>Name</th></tr></thead><tbody><tr :key="dept.id" v-for="dept in deptList"><td>{{dept.id}}</td><td>{{dept.name}}</td></tr></tbody></table></div>
</template><style>.dept {width: 80%;margin: 0 auto;}
</style><script>export default {name: "Dept",data() {return {deptList: []}},created() {//this.deptList.push({id: 1, name: "dept1"}, {id: 2, name: "dept2"});this.getDeptList();},watch: {},methods: {getDeptList() {//这里的请求只是模拟的,只获取一个dept信息,而没有获取列表信息this.$http.get("/dept/get?id=6abad1b324fd438a9cfe1099ab4c78d7").then(res => {this.deptList = [res.data];});}},computed: {},mounted() {},components: {}};
</script>

3.2.5.2 修改 App.vue

<template><div id="app"><div id="nav"><router-link to="/">Home</router-link>|<router-link to="/about">About</router-link>|<router-link to="/dept">Dept</router-link></div><router-view /></div>
</template><style>#app {font-family: "Avenir", Helvetica, Arial, sans-serif;-webkit-font-smoothing: antialiased;-moz-osx-font-smoothing: grayscale;text-align: center;color: #2c3e50;}#nav {padding: 30px;}#nav a {font-weight: bold;color: #2c3e50;}#nav a.router-link-exact-active {color: #42b983;}
</style>

3.2.5.3 修改router.js

import Vue from "vue";
import Router from "vue-router";
import Home from "./views/Home.vue";Vue.use(Router);export default new Router({mode: "history",base: process.env.BASE_URL,routes: [{path: "/",name: "home",component: Home},{path: "/about",name: "about",// route level code-splitting// this generates a separate chunk (about.[hash].js) for this route// which is lazy-loaded when the route is visited.component: () =>import(/* webpackChunkName: "about" */ "./views/About.vue")},{path: "/dept",name: "dept",// route level code-splitting// this generates a separate chunk (about.[hash].js) for this route// which is lazy-loaded when the route is visited.component: () =>import(/* webpackChunkName: "about" */ "./views/Dept.vue")}]
});

注意,这些修改后,前端环境是会自动编译的,不用我们再次手动编译,并且页面也会刷新,如果页面有打开的话。

3.3 创建后端SpringBoot项目

使用 IDEA 的 Spring Initializr 功能模块,生成 SpringBoot 项目架构。

3.3.1 创建项目

3.3.1.1 New Project

注意这里使用的是 project,而不再是 module。

3.3.1.2 选择 Spring Initializr 功能, next >

3.3.1.3 指定自己的 gourp 和 artical,并将 packaging 修改为war。

3.3.1.4 选择自己的功能。

我这里选择的功能如下:
Spring Boot DevTools
Spring Web Strarter
MYSQL Driver
JDBC API
MyBatis Framework

3.3.1.5 指定项目名称

注意需要在最开始创建的 parent 目录之下。

3.3.2 项目整体结构图

3.3.3 添加自己的配置

3.3.3.1 修改 pom.xml

  • 引入 Log4j2 并引入 yml 的配置方式。
  • 使用自己配置的 tomcat
  • 修改一些打war包的配置
  • 结合前端的项目,将前端编译好的文件,直接解压过来,然后再生成 war 包
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.1.7.RELEASE</version><relativePath/> <!-- lookup parent from repository --></parent><artifactId>spring-boot-vue-cli</artifactId><name>spring-boot-vue-cli</name><description>Spring Boot Vue Cli</description><packaging>war</packaging><properties><java.version>1.8</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><exclusions><exclusion><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-tomcat</artifactId></exclusion><exclusion><groupId>org.slf4j</groupId><artifactId>slf4j-log4j12</artifactId></exclusion></exclusions></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId><exclusions><exclusion><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-logging</artifactId></exclusion></exclusions></dependency><!--Read application.yml--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId><optional>true</optional></dependency><!--log4j2--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-log4j2</artifactId></dependency><dependency><groupId>com.fasterxml.jackson.dataformat</groupId><artifactId>jackson-dataformat-yaml</artifactId></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope></dependency><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.1.0</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-tomcat</artifactId><scope>provided</scope></dependency><!--<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency>--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><scope>runtime</scope><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies><build><resources><resource><directory>src/main/java</directory><includes><include>**/*.xml</include></includes><filtering>true</filtering></resource><!--<resource><directory>src/main/resources</directory><includes><include>**/*.xml</include><include>**/*.css</include><include>**/*.js</include></includes><filtering>true</filtering></resource>--></resources><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-dependency-plugin</artifactId><version>3.1.1</version><executions><execution><id>prepare-package</id><phase>process-resources</phase><goals><goal>unpack</goal></goals><configuration><artifactItems><artifactItem><groupId>cn.com.love.hsl</groupId><artifactId>spring-boot-vue-cli-ui</artifactId><version>1.0-SNAPSHOT</version><type>zip</type></artifactItem></artifactItems><outputDirectory>${project.basedir}/src/main/resources/static/</outputDirectory></configuration></execution></executions></plugin><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><version>1.5.3.RELEASE</version><configuration><mainClass>cn.com.love.hsl.Application</mainClass><fork>true</fork></configuration><executions><execution><goals><goal>repackage</goal><goal>build-info</goal></goals></execution></executions></plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-surefire-plugin</artifactId><version>2.4.2</version><configuration><skipTests>true</skipTests></configuration></plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-war-plugin</artifactId><configuration><!--<webResources><resource><directory>src/main/resources/lib</directory><targetPath>WEB-INF/lib</targetPath><filtering>false</filtering><includes><include>**/*.jar</include></includes></resource></webResources>--><attachClasses>true</attachClasses><classesClassifier>api</classesClassifier><failOnMissingWebXml>false</failOnMissingWebXml></configuration></plugin><!--<plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.6.0</version><configuration><source>1.8</source><target>1.8</target><encoding>UTF-8</encoding></configuration></plugin>--></plugins></build></project>

3.3.3.2 配置application.yml

  • 不使用SpringBoot 提供的模板。
  • 配置context-path(这里需要与前端配置的 pubicPaht一致)
  • 配置 datasource
  • 配置 Logging
  • 配置静态资源处理
  • 指定配置环境(生产还是开发,目前这里只做的生产)
  • 开启SSL,注入 server-key(有需要的就添加,具体生成方式,请百度)
debug: false
trace: falseserver:port: 8080servlet:context-path: /sbvc
#    session:
#      timeout: 30#  ssl:
#    enabled: true
#    ## server single ssl auth
#    key-store: classpath:key/server.key.p12
#    key-store-password: welcome02@
#    key-store-type: PKCS12
#    key-alias: fx_cq.alias
#
#    ## client more ssl auth
#    trust-store: classpath:key/server.key.p12
#    trust-store-password: welcome02@
#    trust-store-type: PKCS12
#    client-auth: needmybatis:mapper-locations: classpath:mapper/*.xmltype-aliases-package: jp.co.fujixerox.log.analysis.modelconfiguration:log-impl: org.apache.ibatis.logging.log4j2.Log4j2Impl #这里需要使用log4j2生成日志,因为整个项目都是使用的log4j2spring:profiles:active: proddevtools:restart:enabled: trueadditional-paths: src/main/javadatasource:hikari:idle-timeout: 300000minimum-idle: 5auto-commit: truemax-lifetime: 1200000connection-timeout: 20000maximum-pool-size: 12mvc:view:suffix: .htmlstatic-path-pattern: /**resources:static-locations: classpath:/templates/,classpath:/static/#  thymeleaf:
#    prefix: classpath:/templates/
#    suffix: .htmllogging:config: classpath:log4j2.yml

3.3.3.3 配置生产环境数据源

注意:如果mysql版本使用得比较高,在url 中需要如下配置:

&characterEncoding=utf-8&allowMultiQueries=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC

否则不能成功连接DB。

spring:datasource:
#    driver-class-name: com.mysql.jdbc.Driver
#    url: jdbc:mysql://127.0.0.1:3306/chat?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTCurl: jdbc:mysql://127.0.0.1:3306/sbvc?useSSL=false&useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTCusername: rootpassword: rootname: mysql

3.3.3.4 log4j2.yml

Configuration:status: warnmonitorInterval: 30Properties:Property:- name: log.level.consolevalue: info- name: log.pathvalue: log- name: project.namevalue: sbvc- name: log.patternvalue: "%d{yyyy-MM-dd HH:mm:ss.SSS} -%5p ${PID:-} [%15.15t] %-30.30C{1.} : %m%n"Appenders:Console:name: CONSOLEtarget: SYSTEM_OUTPatternLayout:pattern: ${log.pattern}RollingFile:- name: ROLLING_FILEfileName: ${log.path}/${project.name}.logfilePattern: "${log.path}/historyRunLog/$${date:yyyy-MM}/${project.name}-%d{yyyy-MM-dd}-%i.log.gz"PatternLayout:pattern: ${log.pattern}Filters:ThresholdFilter:- level: erroronMatch: DENYonMismatch: NEUTRAL- level: infoonMatch: ACCEPTonMismatch: DENYPolicies:TimeBasedTriggeringPolicy:modulate: trueinterval: 1DefaultRolloverStrategy:max: 100- name: PLATFORM_ROLLING_FILEignoreExceptions: falsefileName: ${log.path}/platform/${project.name}_platform.logfilePattern: "${log.path}/platform/$${date:yyyy-MM}/${project.name}-%d{yyyy-MM-dd}-%i.log.gz"PatternLayout:pattern: ${log.pattern}Policies:TimeBasedTriggeringPolicy:modulate: trueinterval: 1DefaultRolloverStrategy:max: 100- name: BUSINESS_ROLLING_FILEignoreExceptions: falsefileName: ${log.path}/business/${project.name}_business.logfilePattern: "${log.path}/business/$${date:yyyy-MM}/${project.name}-%d{yyyy-MM-dd}-%i.log.gz"PatternLayout:pattern: ${log.pattern}Policies:TimeBasedTriggeringPolicy:modulate: trueinterval: 1DefaultRolloverStrategy:max: 100- name: EXCEPTION_ROLLING_FILEignoreExceptions: falsefileName: ${log.path}/exception/${project.name}_exception.logfilePattern: "${log.path}/exception/$${date:yyyy-MM}/${project.name}-%d{yyyy-MM-dd}-%i.log.gz"ThresholdFilter:level: erroronMatch: ACCEPTonMismatch: DENYPatternLayout:pattern: ${log.pattern}Policies:TimeBasedTriggeringPolicy:modulate: trueinterval: 1DefaultRolloverStrategy:max: 100- name: DB_ROLLING_FILEignoreExceptions: falsefileName: ${log.path}/db/${project.name}_db.logfilePattern: "${log.path}/db/$${date:yyyy-MM}/${project.name}-%d{yyyy-MM-dd}-%i.log.gz"PatternLayout:pattern: ${log.pattern}Policies:TimeBasedTriggeringPolicy:modulate: trueinterval: 1DefaultRolloverStrategy:max: 100Loggers:Root:level: infoAppenderRef:- ref: CONSOLE- ref: ROLLING_FILE- ref: EXCEPTION_ROLLING_FILELogger:- name: platformlevel: infoadditivity: falseAppenderRef:- ref: CONSOLE- ref: PLATFORM_ROLLING_FILE- name: businesslevel: debugadditivity: falseAppenderRef:- ref: BUSINESS_ROLLING_FILE- name: exceptionlevel: debugadditivity: trueAppenderRef:- ref: EXCEPTION_ROLLING_FILE- name: dblevel: debugadditivity: trueAppenderRef:- ref: DB_ROLLING_FILE- name: jp.co.fujixerox.log.analysis.mapperlevel: debugadditivity: falseAppenderRef:- ref: DB_ROLLING_FILE- ref: CONSOLE- name: jp.co.fujixerox.log.analysis.modellevel: debugadditivity: falseAppenderRef:- ref: DB_ROLLING_FILE- ref: CONSOLE- name: jp.co.fujixerox.log.analysis.servicelevel: debugadditivity: falseAppenderRef:- ref: BUSINESS_ROLLING_FILE- ref: CONSOLE- name: jp.co.fujixerox.log.analysis.controllerlevel: debugadditivity: falseAppenderRef:- ref: BUSINESS_ROLLING_FILE- ref: CONSOLE- name: org.springframeworklevel: infoadditivity: falseAppenderRef:- ref: PLATFORM_ROLLING_FILE- ref: CONSOLE- name: javax.servletlevel: infoadditivity: falseAppenderRef:- ref: PLATFORM_ROLLING_FILE- ref: CONSOLE- name: org.mybatislevel: debugadditivity: falseAppenderRef:- ref: DB_ROLLING_FILE- ref: CONSOLE- name: java.sqllevel: debugadditivity: falseAppenderRef:- ref: DB_ROLLING_FILE- ref: CONSOLE- name: java.sql.Connectionlevel: debugadditivity: falseAppenderRef:- ref: DB_ROLLING_FILE- ref: CONSOLE- name: java.sql.Statementlevel: debugadditivity: falseAppenderRef:- ref: DB_ROLLING_FILE- ref: CONSOLE- name: java.sql.PreparedStatementlevel: debugadditivity: falseAppenderRef:- ref: DB_ROLLING_FILE- ref: CONSOLE- name: java.sql.ResultSetlevel: debugadditivity: falseAppenderRef:- ref: DB_ROLLING_FILE- ref: CONSOLE- name: javax.sqllevel: debugadditivity: falseAppenderRef:- ref: DB_ROLLING_FILE- ref: CONSOLE- name: com.ibatislevel: debugadditivity: falseAppenderRef:- ref: DB_ROLLING_FILE- ref: CONSOLE- name: org.apache.ibatislevel: debugadditivity: falseAppenderRef:- ref: DB_ROLLING_FILE- ref: CONSOLE- name: org.mybatis.springlevel: debugadditivity: falseAppenderRef:- ref: DB_ROLLING_FILE- ref: CONSOLE- name: com.zaxxer.hikarilevel: debugadditivity: falseAppenderRef:- ref: DB_ROLLING_FILE- ref: CONSOLE- name: org.springframework.jdbclevel: debugadditivity: falseAppenderRef:- ref: DB_ROLLING_FILE- ref: CONSOLE- name: org.springframework.transactionlevel: debugadditivity: falseAppenderRef:- ref: DB_ROLLING_FILE- ref: CONSOLE- name: javax.sql.DataSourcelevel: debugadditivity: falseAppenderRef:- ref: DB_ROLLING_FILE- ref: CONSOLE

3.3.3.5 处理静态资源 WebMvcConfig.java

这个是必须处理的,不然static下面的 html 无法获取css 或是 js 资源。

package cn.com.love.hsl.config;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 WebMvcConfig implements WebMvcConfigurer {@Overridepublic void addResourceHandlers(ResourceHandlerRegistry registry) {registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/");}}

3.3.3.6 编写启动类Application.java

package cn.com.love.hsl;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;import java.util.UUID;@Controller
@SpringBootApplication
public class Application extends SpringBootServletInitializer {/*** war package required* @param builder* @return*/@Overrideprotected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {return builder.sources(Application.class);}public static void main(String[] args) {System.out.println(UUID.randomUUID().toString().replaceAll("-", ""));SpringApplication.run(Application.class, args);}@GetMapping({"/index/", "/"})public String index() {return "index";}//    /**
//     * Open http and https two port
//     */
//    @Bean
//    public ServletWebServerFactory servletContainer() {//        TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory();
//        tomcat.addAdditionalTomcatConnectors(createHTTPConnector());
//        return tomcat;
//    }
//
//    private Connector createHTTPConnector() {//        Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
//        //open http(8080)、https(8443)two ports
//        connector.setScheme("http");
//        connector.setSecure(false);
//        connector.setPort(8080);
//        connector.setRedirectPort(8443);
//        return connector;
//    }//    /**
//     * http redirect to https
//     */
//    @Bean
//    public TomcatServletWebServerFactory servletContainer() {//        TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory() {//            @Override
//            protected void postProcessContext(Context context) {//                SecurityConstraint constraint = new SecurityConstraint();
//                constraint.setUserConstraint("CONFIDENTIAL");
//                SecurityCollection collection = new SecurityCollection();
//                collection.addPattern("/*");
//                constraint.addCollection(collection);
//                context.addConstraint(constraint);
//            }
//        };
//        tomcat.addAdditionalTomcatConnectors(httpConnector());
//        return tomcat;
//    }
//    @Bean
//    public Connector httpConnector() {//        Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
//        connector.setScheme("http");
//        //Connector listening http port
//        connector.setPort(8080);
//        connector.setSecure(false);
//        //and the redirect to https port
//        connector.setRedirectPort(8443);
//        return connector;
//    }
}

其他的一些都可以使用 SpringBoot的默认配置。
目前整个后端项目应该是可以正常启动了。

3.3.4 启动后端项目

直接运行 Application.java 文件的 main 类就可以了。能正常启动说明配置就好了。
若是不能,请具体查找一下相应的错误,比如:
An incompatible version [1.1.32] of the APR based Apache Tomcat Native library is installed

3.3.5 编写业务逻辑代码

3.3.5.1 Controller(DeptController.java)

package cn.com.love.hsl.controller;import cn.com.love.hsl.model.Dept;
import cn.com.love.hsl.service.DeptService;
import cn.com.love.hsl.utils.ContextProp;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;@Controller
@RequestMapping("/dept")
public class DeptController {@Autowiredprivate DeptService deptService;@Autowiredprivate ContextProp prop;private final static Logger logger = LoggerFactory.getLogger(DeptController.class);@RequestMapping("/get")public ResponseEntity get(String id) {logger.info(this.getClass().getName() + "{} {}", ".get(" + id + ")", "started..");System.out.println(1222222222);logger.debug(prop.getName());return ResponseEntity.ok(deptService.get(id));}@RequestMapping("/save")public ResponseEntity save(Dept dept) {if (StringUtils.isEmpty(dept.getId()))return ResponseEntity.ok(deptService.insert(dept));elsereturn ResponseEntity.ok(deptService.update(dept));}@RequestMapping("/delete")
//    public ResponseEntity delete(Integer id) {//        deptService.delete(id);
//        return ResponseEntity.ok("Delete success!");
//    }public @ResponseBody String delete(String id) {deptService.delete(id);return "Delete success!";}@RequestMapping("/list")public ResponseEntity find() {return ResponseEntity.ok(deptService.findAll());}
}

3.3.5.2 Mapper (DeptMapper.java)

package cn.com.love.hsl.mapper;import cn.com.love.hsl.model.Dept;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Component;import java.util.List;@Mapper
@Component
public interface DeptMapper {List<Dept> findAll();int insert(Dept dept);int update(Dept dept);void delete(String id);Dept get(String id);
}

3.3.5.3 Model

3.3.5.3.1 BaseModel.java
package cn.com.love.hsl.model;import org.slf4j.Logger;
import org.slf4j.LoggerFactory;import java.io.Serializable;
import java.util.Date;public class BaseModel implements Serializable {private String id;private User creator;private Date createDate;private User Updater;private Date updateDate;private final static Logger logger = LoggerFactory.getLogger(BaseModel.class);public String getId() {//String.format("Hello, %s!", name);logger.info(this.getClass().getName() + "{} {}", ".get(" + id + ")", "started..");return id;}public void setId(String id) {this.id = id;}public User getCreator() {return creator;}public void setCreator(User creator) {this.creator = creator;}public Date getCreateDate() {return createDate;}public void setCreateDate(Date createDate) {this.createDate = createDate;}public User getUpdater() {return Updater;}public void setUpdater(User updater) {Updater = updater;}public Date getUpdateDate() {return updateDate;}public void setUpdateDate(Date updateDate) {this.updateDate = updateDate;}
}
3.3.5.3.2 Dept.java
package cn.com.love.hsl.model;import cn.com.love.hsl.controller.DeptController;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;@Component
public class Dept extends BaseModel {private String name;private final static Logger logger = LoggerFactory.getLogger(DeptController.class);public String getName() {return name;}public void setName(String name) {this.name = name;}
}
3.3.5.3.3 User.java
package cn.com.love.hsl.model;import org.springframework.stereotype.Component;@Component
public class User extends BaseModel {}

3.3.5.4 Service

3.3.5.4.1 BaseService.java
package cn.com.love.hsl.service;import cn.com.love.hsl.model.BaseModel;
import cn.com.love.hsl.model.User;import java.util.Date;
import java.util.UUID;public class BaseService {protected void preInsert(BaseModel entity) {entity.setId(UUID.randomUUID().toString().replaceAll("-", ""));entity.setCreator(new User());entity.setCreateDate(new Date());entity.setUpdater(new User());entity.setUpdateDate(new Date());}protected void preUpdate(BaseModel entity) {entity.setUpdater(new User());entity.setUpdateDate(new Date());}
}
3.3.5.4.2 DeptService.java
package cn.com.love.hsl.service;import java.util.List;public interface DeptService<T> {List<T> findAll();int insert(T dept);int update(T dept);void delete(String id);T get(String id);
}
3.3.5.4.3 DeptServiceImpl.java
package cn.com.love.hsl.service.impl;import cn.com.love.hsl.controller.DeptController;
import cn.com.love.hsl.mapper.DeptMapper;
import cn.com.love.hsl.model.Dept;
import cn.com.love.hsl.service.BaseService;
import cn.com.love.hsl.service.DeptService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;import java.util.List;@Service
public class DeptServiceImpl extends BaseService implements DeptService<Dept> {@Autowiredprivate DeptMapper deptMapper;private final static Logger logger = LoggerFactory.getLogger(DeptController.class);@Overridepublic List<Dept> findAll() {return deptMapper.findAll();}@Override@Transactionalpublic int insert(Dept dept) {this.preInsert(dept);return deptMapper.insert(dept);}@Override@Transactionalpublic int update(Dept dept) {this.preUpdate(dept);return deptMapper.update(dept);}@Override@Transactionalpublic void delete(String id) {deptMapper.delete(id);}@Overridepublic Dept get(String id) {logger.info(this.getClass().getName() + "{} {}", ".get(" + id + ")", "started..");return deptMapper.get(id);}
}

3.3.5.5 Utils

3.3.5.5.1 LogEnum.java
package cn.com.love.hsl.utils;public enum LogEnum {BUSINESS("business"),PLATFORM("platform"),DB("db"),EXCEPTION("exception"),;private String category;LogEnum(String category) {this.category = category;}public String getCategory() {return category;}public void setCategory(String category) {this.category = category;}}
3.3.5.5.2 LogUtils.java
package cn.com.love.hsl.utils;import org.slf4j.Logger;
import org.slf4j.LoggerFactory;public class LogUtils {/*** Get Business logger*/public static Logger getBusinessLogger() {return LoggerFactory.getLogger(LogEnum.BUSINESS.getCategory());}/*** Get Platform logger*/public static Logger getPlatformLogger() {return LoggerFactory.getLogger(LogEnum.PLATFORM.getCategory());}/*** Get DB logger*/public static Logger getDBLogger() {return LoggerFactory.getLogger(LogEnum.DB.getCategory());}/*** Get normal exception logger*/public static Logger getExceptionLogger() {return LoggerFactory.getLogger(LogEnum.EXCEPTION.getCategory());}
}
3.3.5.5.3 ContextProp.java
package cn.com.love.hsl.utils;import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;@Component
@ConfigurationProperties(prefix = "spring.datasource")
public class ContextProp {private String name;public String getName() {return name;}public void setName(String name) {this.name = name;}
}

3.3.5.6 DB Mapper(DeptMapper.xml)

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.com.love.hsl.mapper.DeptMapper"><select id="get" resultType="cn.com.love.hsl.model.Dept" parameterType="java.lang.String">select * from dept where id= #{id};</select><select id="findAll" resultType="cn.com.love.hsl.model.Dept">SELECT * from dept;</select><insert id="insert">insert into dept ( name ) values (#{name});</insert><delete id="delete" parameterType="java.lang.String">delete from dept where id= #{id};</delete><update id="update">update dept set name=#{name} where id=#{id};</update>
</mapper>

业务逻辑编写完了,这时项目应该会自动重启,若是启动成功,说明环境是好的。

4 发布项目

4.1 环境的整合

之前已经将前端的打包,以及后台拷贝前端的文件的逻辑,都已经实现了。
现在只需要整合一下两个项目,在parent 中配置一下,使得一步操作,可以完成所有的编译。

4.2 修改 parent 的 pom.xml 文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>cn.com.love.hsl</groupId><artifactId>spring-boot-vue-cli-parent</artifactId><version>1.0-SNAPSHOT</version><packaging>pom</packaging><-- 将前后端作为模块管理 --><modules><module>spring-boot-vue-cli-ui</module><module>spring-boot-vue-cli</module></modules>
</project>

4.3 打包整个项目

在 IDEA 的 Terminal 窗口中(注意这里的路径需要指向 parent,也就是在 parent 项目中进行编译),输入如下命令:

mvn clean package

慢慢等。

这里会:

  • 下载前端使用需要的 node 和 npm 环境,并进行安装。
  • 编译前端并打成 zip 包
  • 后端拷贝前端的 zip 文件,并解压到 java/main/resources/static 目录下
  • 后台生成 war 包

4.4 发面项目

将生成好的 war 包拷贝到指定的 Apache server 中,比如Tomcat,如果是 Tomcat的话,需要使用Tomcat8,并启动server .
启动成功后, 直接在浏览器中访问,就可以了。

4.5 最终画面效果

Springboot Vue 前后端先分离后结合,闻名已久,今日实战相关推荐

  1. 从0搭建一个Springboot+vue前后端分离项目(一)安装工具,创建项目

    从0搭建一个Springboot+vue前后端分离项目(二)使用idea进行页面搭建+页面搭建 参考学习vue官网文档 https://v3.cn.vuejs.org/guide/installati ...

  2. SpringBoot + Vue前后端分离开发:全局异常处理及统一结果封装

    SpringBoot + Vue前后端分离开发:全局异常处理及统一结果封装 文章目录 SpringBoot + Vue前后端分离开发:全局异常处理及统一结果封装 前后端分离开发中的异常处理 统一结果封 ...

  3. 适合新手拿来练习的springboot+vue前后端分离小Demo

    前言: 作者:神的孩子在歌唱 大家好,我叫智 练习springboot+vue前后端分离的Demo 一. 设计数据库 二 . springboot项目创建 2.1 基本配置 2.2 创建dao层 三. ...

  4. 基于springboot+vue前后端分离的学生在线考试管理系统

    一.基于springboot+vue前后端分离的学生在线考试管理系统 本系统通过教师用户创建班级编写试卷信息然后发布到班级.学生用户进入班级,在线作答,考试结果数据通过网络回收,系统自动进行判分,生成 ...

  5. SpringBoot+Vue前后端分离,使用SpringSecurity完美处理权限问题(二)

    关注公众号[江南一点雨],专注于 Spring Boot+微服务以及前后端分离等全栈技术,定期视频教程分享,关注后回复 Java ,领取松哥为你精心准备的 Java 干货! 当前后端分离时,权限问题的 ...

  6. SpringBoot + Vue 前后端分离(用户信息更新头像上传Markdown图片上传)

    文章目录 前言 用户信息更新 前端发送 后端接口 修改用户头像 前端 前端图片显示 图片上传 完整 代码 后端代码 图片存储 图片上传工具类 图片工具类的配置 工具类实现 效果 Markdown 图片 ...

  7. SpringBoot+Vue前后端分离

    文章目录 前言 一.vue项目创建 二.SpringBoot项目创建 使用IDEA创建一个简单的SpringBoot项目,这里随便百度,参考很多 三.前后端整合 1.vue配置跨域跳转 2.sprin ...

  8. 阿里服务器部署springboot+vue前后端分离项目

    服务器部署springboot+vue前后端分离项目 最近刚刚在实习熟悉公司的业务,所有尝试着自己将项目部署到服务器上.本次部署的项目是Spring Boot+Vue前后端分离项目,后端使用的技术有M ...

  9. 基于SpringBoot+Vue前后端分离的在线教育平台项目

    基于SpringBoot+Vue前后端分离的在线教育平台项目 赠给有缘人,希望能帮助到你!也请不要吝惜你的大拇指,你的Star.点赞将是对我最大的鼓励与支持! 开源传送门: 后台:Gitee | Gi ...

最新文章

  1. 关于zipfile解压出现的字符编码问题
  2. DOM Node Element Attr 的联系与区别汇总
  3. 团队-石头剪刀布-模块测试过程
  4. 网络请求可以返回数据的网站_实例解析|Python加解密VIP网站反爬请求头实现数据爬取...
  5. java中各进制之间的转换(十进制转十六进制、十进制转二进制、二进制转十进制、二进制转十六进制)...
  6. [计算机视觉:算法与应用]学习笔记一:图像形成
  7. ASP.NET Core Web API
  8. [css] box-sizing常用的属性有哪些?分别有什么作用?
  9. Android加载大图片不OutOfMemoryError
  10. 黑马程序员—多线程,单线程
  11. bfv同态加密_lattigo: 基于Lattice代数结构的Go同态加密库
  12. 【吐血经验】在 windows 上安装 spark 遇到的一些坑 | 避坑指南
  13. python 写配置文件,python配置文件写入过程详解
  14. 如何在中实现++中的splitterwnd的四分裂视图功能
  15. 飞鸽传书2007绿色版还需要遵循些基本的原则
  16. csm和uefi_UEFI和Legacy的区别是什么,请尽量从原理上说明?
  17. mips架构中断流程
  18. Python中的爬虫
  19. matlab制作钟表,利用Matlab制作钟表实例教程
  20. 《咏怀古迹五首·其三》.唐.杜甫

热门文章

  1. 如何对图片进行旋转?这些工具能将图片进行旋转
  2. 正睿19暑期B班DAY7 数论
  3. 测试人员常见的面试题(一)
  4. 一桩考研”趣事“(或考研事故)
  5. linux写脚本:一键更新打包部署maven工程
  6. 单片机难学吗?单片机培训机构哪个好?
  7. linux chattr命令的使用
  8. 回家了,过年了.给所有不能回家过年的拜早年了!
  9. Android设备管理器DevicePolicyManager的使用和理解
  10. 天馈线测试仪都有什么功能和特点 推荐哪个品牌