Core Fundamentals and Common Utility Code for Spring Boot 3 and Vue 3

@Bean registers the return value of the annotated method as a managed bean in the Spring IoC container.

Composite annotations can be used to wrap repeated common annotation configurations for reuse.

Common core development topics:

  • JWT token parsing and validation
  • Uniform attachment of authenitcation tokens to requests
  • CamelCase to snake_case naming conversion for database ORM mapping
  • @NotEmpty is a commonly required validation annotation that should not be omitted in DTOs.

MyBatis Pagination with PageHelper

After calling PageHelper.startPage(pageNum, pageSize);, PageHelper automatically appends pagination parameters to the end of your Mapper query SQL. The result list returned by the Mapper can be safely cast to the Page type provided by PageHelper, which exposes helper methods like getTotal() to retrieve the full count of matching records. Complete basic usage examples can be found in the official SDK getting started guide.

Alibaba Cloud OSS Upload Utility

package com.example.backend.utils;

import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import java.io.InputStream;

public class AliOssUtils {
    private static final String ENDPOINT = "https://oss-cn-beijing.aliyuncs.com";
    private static final String ACCESS_KEY = "LTAI5tQ8e13igWZUMTjMEEQV";
    private static final String SECRET_KEY = "MffMJoM24sc59SEBEJQDb0cfBVOAC9";
    private static final String TARGET_BUCKET = "big-event-gwd";

    // Upload file and return public access URL
    public static String upload(String objectName, InputStream inputStream) {
        OSS ossClient = new OSSClientBuilder().build(ENDPOINT, ACCESS_KEY, SECRET_KEY);
        String publicUrl = "";
        try {
            ossClient.createBucket(TARGET_BUCKET);
            ossClient.putObject(TARGET_BUCKET, objectName, inputStream);
            String domain = ENDPOINT.substring(ENDPOINT.lastIndexOf("/") + 1);
            publicUrl = "https://" + TARGET_BUCKET + "." + domain + "/" + objectName;
        } catch (OSSException oe) {
            System.out.println("OSS request error: request reached OSS but was rejected");
            System.out.println("Error Message: " + oe.getErrorMessage());
            System.out.println("Error Code: " + oe.getErrorCode());
            System.out.println("Request ID: " + oe.getRequestId());
            System.out.println("Host ID: " + oe.getHostId());
        } catch (ClientException ce) {
            System.out.println("Client connection error: failed to communicate with OSS, likely network issue");
            System.out.println("Error Message: " + ce.getMessage());
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
        return publicUrl;
    }
}

JWT Token Utility

package com.example.backend.utils;

import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import java.util.Date;
import java.util.Map;

public class JwtUtils {

    private static final String SIGNING_KEY = "application-signing-secret";

    // Generate JWT token from input claims
    public static String generateToken(Map<String, Object> claims) {
        return JWT.create()
                .withClaim("claims", claims)
                .withExpiresAt(new Date(System.currentTimeMillis() + 1000 * 60 * 60 * 12))
                .sign(Algorithm.HMAC256(SIGNING_KEY));
    }

    // Validate token and extract stored claims
    public static Map<String, Object> validateAndParse(String token) {
        return JWT.require(Algorithm.HMAC256(SIGNING_KEY))
                .build()
                .verify(token)
                .getClaim("claims")
                .asMap();
    }
}

MD5 Hashing Utility

package com.example.backend.utils;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class Md5Utils {
    private static final char[] HEX_ARRAY = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
    private static MessageDigest mdInstance;

    static {
        try {
            mdInstance = MessageDigest.getInstance("MD5");
        } catch (NoSuchAlgorithmException e) {
            System.err.println(Md5Utils.class.getName() + " initialization failed: MD5 algorithm not available");
            e.printStackTrace();
        }
    }

    // Generate MD5 hash for input string
    public static String hash(String input) {
        return hash(input.getBytes());
    }

    // Verify input string matches stored MD5 hash
    public static boolean verifyPassword(String rawPassword, String storedHash) {
        return hash(rawPassword).equals(storedHash);
    }

    public static String hash(byte[] inputBytes) {
        mdInstance.update(inputBytes);
        return bytesToHex(mdInstance.digest());
    }

    private static String bytesToHex(byte[] bytes) {
        StringBuilder result = new StringBuilder(2 * bytes.length);
        for (byte b : bytes) {
            appendHexByte(b, result);
        }
        return result.toString();
    }

    private static void appendHexByte(byte b, StringBuilder builder) {
        char high = HEX_ARRAY[(b & 0xf0) >> 4];
        char low = HEX_ARRAY[b & 0x0f];
        builder.append(high).append(low);
    }
}

ThreadLocal Request-Scoped Storage Utility

package com.example.backend.utils;

/**
 * ThreadLocal based utility for storing request-scoped user data
 */
@SuppressWarnings("unchecked")
public class ThreadLocalUtils {
    private static final ThreadLocal<Object> THREAD_LOCAL_STORE = new ThreadLocal<>();

    // Get stored value from current thread
    public static <T> T get() {
        return (T) THREAD_LOCAL_STORE.get();
    }

    // Store value in current thread
    public static void set(Object value) {
        THREAD_LOCAL_STORE.set(value);
    }

    // Remove stored value to prevent memory leaks
    public static void clear() {
        THREAD_LOCAL_STORE.remove();
    }
}

Spring Boot Packaging Configuration

In Spring Boot build configuration, lower-listed dependency entries have higher priority for conflict resolution.


Frontend Vue 3 Examples

Basic Vue 3 CDN Example


<html>
<body>
    <div id="app">
        <h1>{{ greeting }}</h1>
    </div>
    <script type="module">
        import { createApp } from 'https://unpkg.com/vue@3/dist/vue.esm-browser.js';
        createApp({
            data() {
                return {
                    greeting: 'Hello Vue 3!'
                };
            }
        }).mount('#app');
    </script>
</body>
</html>

Basic Axios Request Example

<body>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script>
    // Sample article data
    const newArticle = {
        title: 'A Better Tomorrow',
        category: 'Lifestyle',
        publishDate: '2000-01-01',
        status: 'draft'
    };

    // Send POST request to create new article
    axios.post('http://localhost:8080/api/articles/create', newArticle)
        .then(response => {
            // response.data contains the core response data from the API
            console.log(response.data);
        })
        .catch(error => {
            console.log(error);
        });
</script>
</body>

Article Search with Vue 3 and Axios

<body>
    <div id="app">
        Article Category: <input type="text" v-model="filters.category">
        Publish Status: <input type="text" v-model="filters.status">
        <button @click="fetchArticles">Search</button>

        <br><br>
        | Title | Category | Publish Date | Status | Actions |
|---|---|---|---|---|
| {{ article.title }} | {{ article.category }} | {{ article.publishDate }} | {{ article.status }} | <button>Edit</button> <button>Delete</button> |
    </div>

    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
    <script type="module">
        import { createApp } from 'https://unpkg.com/vue@3/dist/vue.esm-browser.js';
        createApp({
            data() {
                return {
                    articles: [],
                    filters: {
                        category: '',
                        status: ''
                    }
                };
            },
            methods: {
                fetchArticles() {
                    axios.get('http://localhost:8080/api/articles/search', {
                        params: this.filters
                    })
                    .then(response => {
                        this.articles = response.data;
                    })
                    .catch(err => {
                        console.log(err);
                    });
                }
            },
            mounted() {
                // Load all articles on page load
                axios.get('http://localhost:8080/api/articles/list')
                    .then(response => {
                        this.articles = response.data;
                    })
                    .catch(err => {
                        console.log(err);
                    });
            }
        }).mount('#app');
    </script>
</body>

Note: GET request parameters passed in the format above are automatically encoded as query string parameters, matching common backend API requirements.

Common Interview Topic: Circular Dependency

To allow circular dependency in Spring Boot 3, you need to explicitly enable the corresponding configuration in your application settings.

Tags: Spring Boot 3 Vue 3 Java Backend Development Frontend Development Common Development Utilities

Posted on Wed, 12 Aug 2026 16:19:16 +0000 by Black Rider