JS+Springboot做一个交互Demo

背景:老大做了一个 SDK,包含字符加解密、文件加解密,要求能从前端访问,并且能演示的 Demo。
思路:html 写页面,js 发送请求,freemarker 做简单的参数交互,JAVA 后端处理。
一、项目依赖
● java17
● springboot 3.1.2
● 模板技术:spring-boot-starter-freemarker 2.3.32
● 工具包:commons-io 2.16.0
● pom 文件:

<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">
    <parent>
        <groupId>com.xxx.xx.x</groupId>
        <artifactId>xx-x</artifactId>
        <version>3.0-SNAPSHOT</version>
    </parent>

    <artifactId>x-sdk-service</artifactId>
    <modelVersion>4.0.0</modelVersion>
    <description>sdk 项目服务</description>
    <packaging>jar</packaging>
    <name>sdk-service</name>

    <properties>
        <jdk.version>17</jdk.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <spring-boot.version>3.1.2</spring-boot.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.28</version>
        </dependency>

        <!-- SpringBoot 拦截器 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>
        <!-- Spring框架基本的核心工具 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
        </dependency>
        <!-- https://mvnrepository.com/artifact/ch.qos.logback/logback-classic -->
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.4.8</version>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <artifactId>slf4j-api</artifactId>
                    <groupId>org.slf4j</groupId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-logging</artifactId>
            <exclusions>
                <exclusion>
                    <artifactId>slf4j-api</artifactId>
                    <groupId>org.slf4j</groupId>
                </exclusion>
                <exclusion>
                    <artifactId>logback-classic</artifactId>
                    <groupId>ch.qos.logback</groupId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.30</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-simple</artifactId>
            <version>1.7.30</version>
            <exclusions>
                <exclusion>
                    <artifactId>slf4j-api</artifactId>
                    <groupId>org.slf4j</groupId>
                </exclusion>
            </exclusions>
        </dependency>
        <!-- 前端渲染视图技术 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-freemarker</artifactId>
        </dependency>
        <!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.16.1</version>
        </dependency>
    </dependencies>

  
</project>

二、前端代码

使用的模板技术,JS + Freemark。“${baseUrl}”指向的是后端配置的IP地址,可改为静态的,但是那样html页面就写死了。文件放在项目:resource/templates下,无则需要创建。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>演示页</title>
</head>
<script>

    // 访问地址
    const baseUrl = "${baseUrl}"

    /**
     * 加密
     */
    function getEnc() {
        // 处理传入数据
        let data = document.getElementById("encText").value;
        data = btoa(data);
        // 组装请求
        const oReq = new XMLHttpRequest();
        const url = baseUrl + "/enc?data=" + data;
        console.log("request " + url)
        oReq.open("GET", url, true);
        // 响应类型
        oReq.responseType = "text";
        oReq.onprogress = function (result) {
            console.log(result)
            // 失败处理
            if (fail(result)) {
                return;
            }
            // 处理响应
            const data = result.currentTarget.response;
            let parse = JSON.parse(data);
            const text = parse.data;
            document.getElementById("decText").value = String(text);
        };
        oReq.send();
    }

    /**
     * 解密
     */
    function getDec() {
        let data = document.getElementById("decText").value;
        const oReq = new XMLHttpRequest();
        data = btoa(data);
        const url = baseUrl + "/dec?data=" + data;
        console.log("request " + url)
        oReq.open("GET", url, true);
        // 响应类型
        oReq.responseType = "text";
        oReq.onprogress = function (result) {
            console.log(result)
            if (fail(result)) {
                return;
            }
            const data = result.currentTarget.response;
            let parse = JSON.parse(data);
            const text = parse.data;
            document.getElementById("encText").value = String(atob(text));
        };
        oReq.send();
    }

    /**
     * 文件加密
     */
    function getEncFile() {
        const fileInput = document.getElementById('encFile');
        const file = fileInput.files[0];
        let formData = new FormData();
        formData.append("file", file)
        const oReq = new XMLHttpRequest();
        const url = baseUrl + "/encFile";
        console.log("request " + url)
        oReq.open("POST", url, true);
        // 响应类型
        oReq.onprogress = function (result) {
            console.log(result)
            if (fail(result)) {
                return;
            }
            const data = result.currentTarget.response;
            let parse = JSON.parse(data);
            const fileName = parse.data;
            // 下载文件
            downloadFile(baseUrl + "/downLoadFile/" + fileName, fileName)
            // 原组件置空
            fileInput.value = '';
        };
        oReq.send(formData);
    }

    /**
     * 文件解密
     */
    function getDecFile() {
        const fileInput = document.getElementById('decFile');
        const file = fileInput.files[0];
        let formData = new FormData();
        formData.append("file", file)
        const oReq = new XMLHttpRequest();
        const url = baseUrl + "/decFile";
        console.log("request " + url)
        oReq.open("POST", url, true);
        // 响应类型
        oReq.onload = function (result) {
            console.log(result)
            if (fail(result)) {
                console.log("encFile:" + result)
                return;
            }
            const data = result.currentTarget.response;
            let parse = JSON.parse(data);
            const fileName = parse.data;
            downloadFile(baseUrl + "/downLoadFile/" + fileName, fileName)
            fileInput.value = '';
        };
        oReq.send(formData);
    }

    /**
     * 下载文件
     * @param url
     * @param fileName
     */
    function downloadFile(url, fileName) {
        console.log("downloadFile:" + url)
        console.log("downloadFile fileName:" + fileName)
        fetch(url)
            .then(response => response.blob())
            .then(blob => {
                const link = document.createElement('a');
                link.href = URL.createObjectURL(blob);
                link.download = fileName;
                link.target = "_blank"; // 可选,如果希望在新窗口中下载文件,请取消注释此行
                link.click();
            });
    }

    /**
     * 请求是否失败
     * @param result 请求
     * @returns {boolean} true 失败
     */
    function fail(result) {
        const data = result.currentTarget.response;
        let parse = JSON.parse(data);
        if (200 !== parse.code) {
            alert("请求失败:" + parse.msg)
            return true;
        }
        return false;
    }

</script>
<body style="text-align: center;margin-top: auto">
<h1>加密工具演示页</h1>
<!-- 文本加密 -->
<div style="margin-top: 48px">
    <h3>文本加密</h3>
    <div>
        <input id="encText" type="text" style="width: 200px;"/>
        <button onclick="getEnc();" style="margin-left: 12px">加密</button>
    </div>
    <div style="margin-top: 12px">
        <input id="decText" type="text" style="width: 200px;"/>
        <button onclick="getDec();" style="margin-left: 12px">解密</button>
    </div>
</div>
<!-- 文件加密 -->
<div style="margin-top: 48px;">
    <h3>文件加解密</h3>
    <div style="margin-top: 24px">
        文件加密:
        <input id="encFile" type="file" onchange="getEncFile()"/>
    </div>
    <div style="margin-top: 24px;">
        文件解密:
        <input id="decFile" type="file" onchange="getDecFile()"/>
    </div>
</div>
</body>
</html>

三、后端配置

application配置文件

server:
  port: 12321

tmv:
  
上一篇:Go 语言基础教程:4.常量的使用


下一篇:Android Kotlin中协程详解