@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
@NotEmptyis 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.