Spring应用-1-SpringBoot+Thymeleaf+Vue快速搭建前台项目

1. 前言

  1. 为什么这么选择?
    Thymeleaf在这里仅仅负责跳转页面和引导资源用的,核心的数据交互展示使用的是引入的vue.js、element-ui、axios.js。
  2. 还有什么更好的方法?
    目前我所知的,这样算是比较简单的,如果有更简单的方法欢迎在评论区指教,感激不尽。
  3. 起因?
    项目中需要做一个大量数据的分析导出,分析数据量有近百万条长短不一、结构不定的报文,按照接口分为上千个,如果直接启动工程会全量分析,耗时长达4小时,而且只能通过控制台观察信息,使用体验十分不友好,所以搭建一个可视化的页面选择性解析接口报文生成接口协议,而且使用WebSocket由服务端实时发送重要的日志给前台客户端,有效提升了效率和体验。
  4. 鸣谢

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

  1. 方式:
    vue和element-ui都支持多种方式引入到页面中,这里是简单使用,如果使用网络文件链接导入,需要反复的从网络上获取,这里推荐将依赖文件下载到本地项目内,用静态资源加载方式使用。
  2. npm
    虽然不使用npm方式管理依赖包,但是可以通过npm的官网来查找需要的依赖版本,然后使用CDN(内容分发网络)进行下载。
  3. CDN
    国内用的比较多的就是 "cdn.jsdelivr.net" ,能获取到绝大多数的依赖包,而且更新及时。
  4. 需要下载的文件(基于上述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 (也有压缩版,开发阶段不建议)
  5. 下载提示
    如果直接在浏览器里面点击文件,极有可能会直接在网页里以文本形式打开,此时需要右键复制链接到专门的下载工具中下载(比如BitComet)。如果手头没有下载工具,可以使用命令行进行下载:
    • Windows:certutil -urlcahe -split -f <url file>
    • macOS:curl -o <local file name> <url file>
  6. 文件放置
    习惯上会将前端使用的静态资源放置到 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

4. 配置

  1. application.yml
    本地简易开发项目没有什么需要配置的,只要配置好了服务的端口和关闭Thymeleaf的缓存即可。
    spring:
      thymeleaf:
    	cache: false
    server:
      port: 8081
    
  2. 创建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;
        }
    })
    
  3. 给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;
    }
}
posted @ 2022-07-22 09:42  苍凉温暖  阅读(4994)  评论(1)    收藏  举报