Spring应用-1-SpringBoot+Thymeleaf+Vue快速搭建前台项目
1. 前言
- 为什么这么选择?
Thymeleaf在这里仅仅负责跳转页面和引导资源用的,核心的数据交互展示使用的是引入的vue.js、element-ui、axios.js。 - 还有什么更好的方法?
目前我所知的,这样算是比较简单的,如果有更简单的方法欢迎在评论区指教,感激不尽。 - 起因?
项目中需要做一个大量数据的分析导出,分析数据量有近百万条长短不一、结构不定的报文,按照接口分为上千个,如果直接启动工程会全量分析,耗时长达4小时,而且只能通过控制台观察信息,使用体验十分不友好,所以搭建一个可视化的页面选择性解析接口报文生成接口协议,而且使用WebSocket由服务端实时发送重要的日志给前台客户端,有效提升了效率和体验。 - 鸣谢
2. 导入依赖
因为Thymeleaf是Spring推荐的模板引擎,所以SpringBoot已经内置了对Thymeleaf的自动配置和版本管理,只要声明引入即可,无需手动设置版本。
<?xml version="1.0" encoding="UTF-8"?>
<project>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.3.RELEASE</version>
<relativePath/>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
</dependencies>
</project>
如果想查看某个技术是否是SpringBoot支持自动配置的,可以按着Ctrl进入SpringBoot父版本pom文件,然后在spring-boot-starter-parent-x.x.x.RELEASE.pom文件中进入spring-boot-dependencies,就可以查看所有支持自动配置的技术和默认版本。
3. 下载vue.js、element-ui、axios
- 方式:
vue和element-ui都支持多种方式引入到页面中,这里是简单使用,如果使用网络文件链接导入,需要反复的从网络上获取,这里推荐将依赖文件下载到本地项目内,用静态资源加载方式使用。 - npm
虽然不使用npm方式管理依赖包,但是可以通过npm的官网来查找需要的依赖版本,然后使用CDN(内容分发网络)进行下载。 - CDN
国内用的比较多的就是 "cdn.jsdelivr.net" ,能获取到绝大多数的依赖包,而且更新及时。 - 需要下载的文件(基于上述CDN的目录,版本请自选)
- Vue.js
- 核心js文件:/dist/vue.js (有多个构建版本,按照官网介绍选择自己需要的版本)
- element-ui
- 主样式文件:/lib/theme-chalk/index.css
- 字体和矢量图标文件:/lib/theme-chalk/fonts/element-icons.ttf 和 /lib/theme-chalk/fonts/element-icons.woff (文件放置时注意保持fonts目录结构)
- 核心js文件:/lib/index.js
- axios
- 核心文件:/dist/axios.js (也有压缩版,开发阶段不建议)
- Vue.js
- 下载提示
如果直接在浏览器里面点击文件,极有可能会直接在网页里以文本形式打开,此时需要右键复制链接到专门的下载工具中下载(比如BitComet)。如果手头没有下载工具,可以使用命令行进行下载:- Windows:certutil -urlcahe -split -f <url file>
- macOS:curl -o <local file name> <url file>
- 文件放置
习惯上会将前端使用的静态资源放置到classpath:/static/下,按照各类文件分别创建文件夹进行放置。- static
- axios
- axios.js
- common
- axios.config.js (axios的配置文件,下述)
- element-ui
- index.css
- index.js
- fonts
- element-icons.ttf
- element-icons.woff
- vue
- vue.js
- axios
- static
4. 配置
- application.yml
本地简易开发项目没有什么需要配置的,只要配置好了服务的端口和关闭Thymeleaf的缓存即可。spring: thymeleaf: cache: false server: port: 8081 - 创建axios配置文件
在 "classpath:/static/common/" 目录下创建 "axios.config.js" 文件,根据需要自定义内容。// 后端地址,如果前后台是一个地址,而且Gateway没有配统一标识的话直接用 / 就可以,否则需要配置IP端口和统一标识 axios.defaults.baseURL = '/'; // 超时时长 axios.defaults.timeout = 300000; // 请求头 axios.defaults.headers.post['Content-Type'] = 'application/json;charset=UTF-8'; // 请求前拦截器 axios.interceptors.request.use(function (config) { // 发送前的操作,比如给请求头添加防CSRF攻击的token return config; }, function (error) { return Promise.reject(error); }) // 返回数据前拦截器,对状态码和数据进行预处理 axios.interceptors.response.use(function (res) { // 如果没有返回值,应当直接抛出错误 if (!res.data) { new Vue().$message({ type: 'error', message: '无响应数据', showClose: true }); return Promise.reject('response.data 无数据'); } return res; }, function (error) { // 未经授权的请求,设置跳转到其他路径 if (error.response.status === 401) { var topwindow = window; while (topwindow.self != topwindow.top) { topwindow = topwindow.parent; } topwindow.location.href = error.response.data; return; } else if (error.response.status === 500 && error.response.data.message !== undefined) { new Vue().$message({ type: 'error', message: error.response.data.message, showClose: true }); } else if (error.response.status !== 200 && error.response.data !== undefined) { // 跳转到异常页面 window.location.href = "/errorPage.html"; return; } }) - 给Thymeleaf配置静态资源文件路径
将静态文件放置在 "classpath:/static/" 路径下,如果不进行配置的话,Thymeleaf在引入静态资源时是获取不到的,需要添加配置指向这个路径。新增ResourceConfig.java文件:import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; public class ResourceConfig implements WebMvcConfigurer { @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/**").addResourceLocation("classpath:/static/"); } }
5. 页面
Thymeleaf作为模板引擎,模板的默认位置是 "classpath:/templates",也就是所有的模板放到这里,此时只需要导入依赖的js和css就可以往里面填充内容了。
示例:在"classpath:/templates"中直接创建名为"index.html"文件。
<!DOCTYPE html>
<html>
<head>
<title>示例首页</title>
<!-- 引入element-ui样式文件,由于文件是在本地的static目录下,而且给static定义为资源目录,href直接以static目录为基准 -->
<link rel="stylesheet" href="element-ui/index.css">
</head>
<body>
<div id="app" v-cloak>
<!-- 首页内容 -->
</div>
<!-- 在最后引入js -->
<script type="text/javascript" scr="vue/vue.js"></script>
<script type="text/javascript" scr="axios/axios.js"></script>
<script type="text/javascript" scr="common/axios.config.js"></script>
<!-- 还要导入自己的js和css文件 -->
</body>
</html>
示例js
new Vue({
el: '#app',
data: {},
methods: {
qryInitData() {
var _this = this;
axios.post("/tree", {}).then(function (response) {
// 请求成功后,需要判断一下返回值内填充的状态码
if (response.data && response.data.code == 0) {
// 成功,也就是返回值在最外层套了一个节点data,data中的内容才是后台返回的JSON对象
}
})
}
},
created: function () {
this.qryInitData();
}
})
6. Controller
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.bind.annotation.GetMapping;
import org.springframework.bind.annotation.PostMapping;
import org.springframework.bind.annotation.ResponseBody;
import com.alibaba.fastjson.JSONObject;
@Controller
public class IndexController {
// 直接用域名/IP或者后缀index.html都可以访问
@GetMapping({"/", "index.html"})
public String getIndexPage(Model model) {
// 数据可以放到Model中,不过这里的作用只是返回页面,内部数据由Vue处理
// 返回字符串为页面文件名,Thymeleaf会自动去 classpath:/templates/中找
return "index";
}
@PostMapping("/tree")
// 这里ResponseBody一定要加上,否则返回到前端是没有值的
@ResponseBody
public JSONObject getTree() {
JSONObject jo = new JSONObject();
jo.put("code", 0);
return jo;
}
}

浙公网安备 33010602011771号