### Maven Dependency Management Example
Source: https://github.com/opensabre/opensabre-framework/blob/main/CLAUDE.md
Illustrates how core dependencies like Spring Boot, Spring Cloud, and Spring Cloud Alibaba are managed centrally in the `opensabre-base-dependencies` module.
```xml
org.springframework.boot
spring-boot-dependencies
3.4.1
pom
import
org.springframework.cloud
spring-cloud-dependencies
2024.0.0
pom
import
com.alibaba.cloud
spring-cloud-alibaba-dependencies
2023.0.3.2
pom
import
```
--------------------------------
### Build Project Modules with Maven
Source: https://github.com/opensabre/opensabre-framework/blob/main/CLAUDE.md
Commands to build all modules of the Opensabre project using Maven. Includes options to clean, install, skip tests, and deploy to Maven Central.
```bash
# Build all modules
mvn clean install
# Build with tests
mvn clean install -DskipTests=false
# Skip tests for faster builds
mvn clean install -DskipTests=true
# Deploy to Maven Central (requires deploy profile)
mvn clean deploy -Pdeploy
```
--------------------------------
### Adding a New Module to Parent POM
Source: https://github.com/opensabre/opensabre-framework/blob/main/CLAUDE.md
Example of how to include a new module in the parent POM's `` section, which is a required step when adding new modules to the Opensabre project.
```xml
pom
opensabre-base-dependencies
opensabre-web
new-module-name
```
--------------------------------
### Unified Response Format Example (Conceptual)
Source: https://github.com/opensabre/opensabre-framework/blob/main/CLAUDE.md
Illustrates the standardized `Result` object structure used for all REST API responses in Opensabre. It includes fields for status code, message, timestamp, and the actual data payload.
```json
{
"code": "000000",
"mesg": "Success message",
"time": "2023-10-27T10:00:00Z",
"data": { ... }
}
```
--------------------------------
### Exception Handling Hierarchy
Source: https://github.com/opensabre/opensabre-framework/blob/main/CLAUDE.md
Shows the custom exception hierarchy in Opensabre, starting from `BaseException` and extending to `ServiceException`. It also references `ErrorType` and `SystemErrorType` for categorizing errors.
```java
// Global exception handler advice
// @ControllerAdvice
// public class DefaultGlobalExceptionHandlerAdvice { ... }
// Base custom exception
public abstract class BaseException extends RuntimeException {
}
// Service-level exception
public class ServiceException extends BaseException {
}
// Error type system
// public interface ErrorType { ... }
// public enum SystemErrorType implements ErrorType { ... }
```
--------------------------------
### Run Tests with Maven
Source: https://github.com/opensabre/opensabre-framework/blob/main/CLAUDE.md
Commands for executing tests within the Opensabre project using Maven. Supports running all tests, tests for a specific module, or a single test class.
```bash
# Run all tests
mvn test
# Run tests for specific module
cd opensabre-web && mvn test
# Run single test class
mvn test -Dtest=UserContextHolderTest
```
--------------------------------
### Docker Image Building with Maven Plugins
Source: https://github.com/opensabre/opensabre-framework/blob/main/CLAUDE.md
Specifies the Maven plugins used for Docker image building and containerization in Opensabre, including the Dockerfile Maven plugin and Jib Maven plugin, with a defined base image.
```xml
com.spotify
dockerfile-maven-plugin
1.4.13
com.google.cloud.tools
jib-maven-plugin
3.4.0
eclipse-temurin:21-jre-alpine
```
--------------------------------
### Global Exception Handling in Java
Source: https://context7.com/opensabre/opensabre-framework/llms.txt
Demonstrates how Opensabre automatically handles various exceptions by converting them into standardized `Result` responses. It also shows how to extend this functionality with a custom exception handler for `BusinessException`.
```java
// Exceptions are automatically handled by DefaultGlobalExceptionHandlerAdvice
// Validation errors (MethodArgumentNotValidException)
// Request: POST /api/users with invalid body
// Response: {"code":"020000","mesg":"Request parameter validation failed","data":"name cannot be empty"}
// Missing parameters (MissingServletRequestParameterException)
// Request: GET /api/users (missing required param)
// Response: {"code":"020000","mesg":"Request parameter validation failed"}
// Resource not found (NoHandlerFoundException)
// Request: GET /api/nonexistent
// Response: {"code":"000404","mesg":"Resource not found"}
// Method not allowed (HttpRequestMethodNotSupportedException)
// Request: DELETE /api/users (if only GET allowed)
// Response: {"code":"020001","mesg":"Request method not supported"}
// File upload size limit (MultipartException)
// Response: {"code":"020010","mesg":"Uploaded file size exceeds limit"}
// Custom BaseException
// Response: {"code":"","mesg":""}
// Unhandled exceptions
// Response: {"code":"-1","mesg":"System exception"}
// Custom exception handler extension
@RestControllerAdvice
@Order(Ordered.HIGHEST_PRECEDENCE) // Higher priority than default
public class CustomExceptionHandlerAdvice {
@ExceptionHandler(value = {BusinessException.class})
public Result> handleBusinessException(BusinessException ex) {
return Result.fail(ex.getErrorType(), ex.getData());
}
}
```
--------------------------------
### Generate Documentation and Flatten POM with Maven
Source: https://github.com/opensabre/opensabre-framework/blob/main/CLAUDE.md
Maven commands for code quality tasks. Generates JavaDoc for the project and creates a flattened POM file, typically used for deployment.
```bash
# Generate JavaDoc
mvn javadoc:javadoc
# Generate flattened POM (for deployment)
mvn flatten:flatten
```
--------------------------------
### Spring Boot Auto-Configuration Annotation
Source: https://github.com/opensabre/opensabre-framework/blob/main/CLAUDE.md
Demonstrates the use of the `@AutoConfiguration` annotation for creating Spring Boot auto-configuration classes, a key practice when developing starter modules in Opensabre.
```java
package com.opensabre.starter.example;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@AutoConfiguration
@ConditionalOnClass(SomeClass.class) // Example condition
public class ExampleAutoConfiguration {
@Bean
public ExampleService exampleService() {
return new ExampleService();
}
// Define other beans as needed
}
```
--------------------------------
### Service Communication with OpenFeign and Sentinel
Source: https://github.com/opensabre/opensabre-framework/blob/main/CLAUDE.md
Highlights the use of OpenFeign for inter-service communication, including custom load balancing (`OpensabreLoadBalancer`), header propagation (`FeignHeaderInterceptor`), and Sentinel integration for resilience.
```java
// Example OpenFeign client interface
// @FeignClient(name = "some-service", configuration = FeignConfig.class)
// public interface SomeServiceClient { ... }
// Custom Load Balancer
// public class OpensabreLoadBalancer implements LoadBalancerClient { ... }
// Header Propagation
// public class FeignHeaderInterceptor implements RequestInterceptor { ... }
// Sentinel Integration (typically configured via properties or annotations)
```
--------------------------------
### Unified REST Response Wrapper in Java
Source: https://context7.com/opensabre/opensabre-framework/llms.txt
Demonstrates the usage of the `Result` class for creating standardized REST API responses. It includes factory methods for success and failure scenarios, handling data, no data, and custom error types. This wrapper ensures consistent API output.
```java
import io.github.opensabre.common.core.entity.vo.Result;
import io.github.opensabre.common.core.exception.SystemErrorType;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/api/users")
public class UserController {
@GetMapping("/{id}")
public Result getUser(@PathVariable String id) {
// Success response with data
UserVo user = userService.findById(id);
return Result.success(user);
// Response: {"code":"000000","mesg":"Processing successful","time":"2024-01-01T12:00:00.000Z","data":{...}}
}
@PostMapping
public Result createUser(@RequestBody UserForm form) {
userService.create(form);
// Success response without data
return Result.success();
// Response: {"code":"000000","mesg":"Processing successful","time":"2024-01-01T12:00:00.000Z"}
}
@DeleteMapping("/{id}")
public Result deleteUser(@PathVariable String id) {
try {
userService.delete(id);
return Result.success("User deleted");
} catch (Exception e) {
// Failure response with error type
return Result.fail(SystemErrorType.SYSTEM_ERROR);
// Response: {"code":"-1","mesg":"System exception","time":"2024-01-01T12:00:00.000Z"}
}
}
@PutMapping("/{id}")
public Result> updateUser(@PathVariable String id, @RequestBody UserForm form) {
// Failure with specific error type and data
if (!userService.exists(id)) {
return Result.fail(SystemErrorType.RESOURCE_NOT_FOUND, "User not found: " + id);
}
userService.update(id, form);
return Result.success();
}
}
```
--------------------------------
### Opensabre Maven Dependency Configuration
Source: https://context7.com/opensabre/opensabre-framework/llms.txt
Provides the necessary Maven dependencies to integrate various Opensabre framework modules into a Spring Boot project. This includes core components, web utilities, service registration, RPC, persistence, caching, configuration, event-driven architecture, and testing utilities.
```xml
io.github.opensabre
opensabre-base-dependencies
0.2.0
io.github.opensabre
opensabre-starter-boot
io.github.opensabre
opensabre-web
io.github.opensabre
opensabre-starter-register
io.github.opensabre
opensabre-starter-rpc
io.github.opensabre
opensabre-starter-persistence
io.github.opensabre
opensabre-starter-cache
io.github.opensabre
opensabre-starter-config
io.github.opensabre
opensabre-starter-eda
io.github.opensabre
opensabre-test
test
```
--------------------------------
### Feign Client with Nacos Discovery and Fallback in Java
Source: https://context7.com/opensabre/opensabre-framework/llms.txt
Defines a Feign client interface for inter-service communication, integrating with Nacos for service discovery. Includes a fallback implementation for circuit breaker patterns to handle service unavailability gracefully. This requires Spring Cloud OpenFeign and Spring Cloud Alibaba Nacos Discovery dependencies.
```java
// Feign client with service discovery
@FeignClient(name = "user-service", fallback = UserClientFallback.class)
public interface UserClient {
@GetMapping("/api/users/{id}")
Result getUser(@PathVariable("id") String id);
@PostMapping("/api/users")
Result createUser(@RequestBody UserForm form);
}
// Fallback implementation for circuit breaker
@Component
public class UserClientFallback implements UserClient {
@Override
public Result getUser(String id) {
return Result.fail(SystemErrorType.GATEWAY_CONNECT_TIME_OUT);
}
@Override
public Result createUser(UserForm form) {
return Result.fail(SystemErrorType.GATEWAY_CONNECT_TIME_OUT);
}
}
// Using the client
@Service
public class OrderService {
@Autowired
private UserClient userClient;
public OrderVo createOrder(OrderForm form) {
Result userResult = userClient.getUser(form.getUserId());
if (userResult.isFail()) {
throw new BaseException(BusinessErrorType.USER_NOT_FOUND);
}
// Create order with user info
return doCreateOrder(form, userResult.getData());
}
}
```
--------------------------------
### JetCache Configuration for Multi-Level Caching in Java
Source: https://context7.com/opensabre/opensabre-framework/llms.txt
Demonstrates configuring JetCache for multi-level caching with local (Caffeine) and remote (Redis) cache types. It shows how to define different TTLs and cache invalidation strategies using annotations. Dependencies include JetCache core and Caffeine/Redis cache implementations.
```java
import com.alicp.jetcache.anno.*;
import com.alicp.jetcache.Cache;
@Service
public class ProductService {
// Default local cache (5 minutes)
@Cached(name = "product:", key = "#id", cacheType = CacheType.LOCAL)
public Product getProduct(String id) {
return productRepository.findById(id);
}
// Long-time local cache (1 hour)
@Cached(name = "category:", key = "#id",
area = "longTime", cacheType = CacheType.LOCAL)
public Category getCategory(String id) {
return categoryRepository.findById(id);
}
// Short-time local cache (1 minute) - for time-sensitive data
@Cached(name = "stock:", key = "#productId",
area = "shortTime", cacheType = CacheType.LOCAL)
public Integer getStock(String productId) {
return inventoryRepository.getStock(productId);
}
// Default remote Redis cache (2 hours)
@Cached(name = "user:profile:", key = "#userId", cacheType = CacheType.REMOTE)
public UserProfile getUserProfile(String userId) {
return userRepository.getProfile(userId);
}
// Long-time remote cache (12 hours)
@Cached(name = "config:", key = "#key",
area = "longTime", cacheType = CacheType.REMOTE)
public String getConfig(String key) {
return configRepository.getValue(key);
}
// Both local and remote (two-level cache)
@Cached(name = "hot:product:", key = "#id", cacheType = CacheType.BOTH)
public Product getHotProduct(String id) {
return productRepository.findById(id);
}
// Cache invalidation
@CacheInvalidate(name = "product:", key = "#product.id")
public void updateProduct(Product product) {
productRepository.save(product);
}
// Cache update
@CacheUpdate(name = "product:", key = "#product.id", value = "#product")
public Product saveProduct(Product product) {
return productRepository.save(product);
}
}
// Environment variables for Redis configuration:
// REDIS_HOST=localhost
// REDIS_PORT=6379
```
--------------------------------
### Maven Central Publishing Configuration
Source: https://github.com/opensabre/opensabre-framework/blob/main/CLAUDE.md
Details the Maven plugin used for publishing artifacts to Maven Central (`central-publishing-maven-plugin`) and the requirement to activate the `deploy` profile for this process.
```xml
io.github.gradle-nexus
central-publishing-maven-plugin
0.4.2
true
```
--------------------------------
### Manage Thread-Local User Context with UserContextHolder (Java)
Source: https://context7.com/opensabre/opensabre-framework/llms.txt
Illustrates using UserContextHolder for thread-safe access to user information. It shows how to set and clear the user context within a filter and how to retrieve user details in a service layer.
```java
import io.github.opensabre.common.core.util.UserContextHolder;
import java.util.Map;
import java.util.HashMap;
// Setting user context (typically done by interceptor)
public class AuthenticationFilter implements Filter {
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) {
Map userContext = new HashMap<>();
userContext.put("user_name", "johndoe");
userContext.put("user_id", "12345");
userContext.put("roles", "admin,user");
UserContextHolder.getInstance().setContext(userContext);
try {
chain.doFilter(req, res);
} finally {
// Always clear context after request
UserContextHolder.getInstance().clear();
}
}
}
// Accessing user context anywhere in the application
@Service
public class OrderService {
public Order createOrder(OrderForm form) {
// Get current username
String username = UserContextHolder.getInstance().getUsername();
// Get full context map
Map context = UserContextHolder.getInstance().getContext();
String userId = context.get("user_id");
String roles = context.get("roles");
Order order = new Order();
order.setCreatedBy(username);
order.setUserId(userId);
// ...
return orderRepository.save(order);
}
}
// UserInterceptor automatically sets context from gateway headers
// Header: x-client-token-user: {"user_name":"johndoe","user_id":"12345"}
```
--------------------------------
### Define User Entity and Related Forms/VOs with BasePo/BaseForm (Java)
Source: https://context7.com/opensabre/opensabre-framework/llms.txt
Demonstrates defining a User entity extending BasePo, along with UserVo, UserForm, UserQueryForm, and UserParam. These classes leverage BasePo and BaseForm for automatic audit field management and convenient conversion methods between different object types.
```java
import io.github.opensabre.persistence.entity.po.BasePo;
import io.github.opensabre.common.web.entity.vo.BaseVo;
import io.github.opensabre.common.web.entity.form.BaseForm;
import io.github.opensabre.persistence.entity.form.BaseQueryForm;
import io.github.opensabre.persistence.entity.param.BaseParam;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
// Entity (PO) - extends BasePo for auto audit fields
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("t_user")
public class User extends BasePo {
private String name;
private Integer age;
private String email;
private String mobile;
}
// Inherits: id, createdBy, createdTime, updatedBy, updatedTime
// View Object (VO)
@Data
@EqualsAndHashCode(callSuper = true)
public class UserVo extends BaseVo {
private String name;
private Integer age;
private String email;
}
// Form for create/update operations
@Data
@EqualsAndHashCode(callSuper = true)
public class UserForm extends BaseForm {
private String name;
private Integer age;
private String email;
private String mobile;
}
// Query form with pagination support
@Data
@EqualsAndHashCode(callSuper = true)
public class UserQueryForm extends BaseQueryForm {
private String name;
private Integer minAge;
private Integer maxAge;
}
// Query parameters
@Data
@EqualsAndHashCode(callSuper = true)
public class UserParam extends BaseParam {
private String name;
private Integer minAge;
private Integer maxAge;
}
// Usage in service/controller
@Service
public class UserService {
@Autowired
private UserMapper userMapper;
public UserVo createUser(UserForm form) {
// Convert form to entity (auto-mapping)
User user = form.toPo(User.class);
// createdBy, createdTime, updatedBy, updatedTime auto-filled on insert
userMapper.insert(user);
// Convert entity to VO
return user.toVo(UserVo.class);
}
public Page queryUsers(UserQueryForm form) {
// Get pagination parameters from form
Page page = form.getPage();
// Convert form to query param
UserParam param = form.toParam(UserParam.class);
return userMapper.selectPage(page, buildWrapper(param));
}
}
```
--------------------------------
### Custom Exception Handling with BaseException and ErrorType in Java
Source: https://context7.com/opensabre/opensabre-framework/llms.txt
Illustrates how to define custom business error types using the `ErrorType` interface and `BaseException` class for standardized exception handling. This enables clear communication of business-specific errors with codes and messages, which are automatically caught by a global exception handler.
```java
import io.github.opensabre.common.core.exception.BaseException;
import io.github.opensabre.common.core.exception.ErrorType;
import lombok.Getter;
// Define custom error types
@Getter
public enum BusinessErrorType implements ErrorType {
USER_NOT_FOUND("100001", "User not found"),
USER_ALREADY_EXISTS("100002", "User already exists"),
INVALID_CREDENTIALS("100003", "Invalid username or password"),
PERMISSION_DENIED("100004", "Permission denied");
private final String code;
private final String mesg;
BusinessErrorType(String code, String mesg) {
this.code = code;
this.mesg = mesg;
}
}
// Throw custom exceptions
public class UserService {
public User findById(String id) {
User user = userRepository.findById(id);
if (user == null) {
throw new BaseException(BusinessErrorType.USER_NOT_FOUND, "User ID: " + id);
}
return user;
}
public void authenticate(String username, String password) {
if (!isValidCredentials(username, password)) {
throw new BaseException(BusinessErrorType.INVALID_CREDENTIALS);
}
}
}
// Global exception handler auto-catches BaseException
// Returns: {"code":"100001","mesg":"User not found","time":"2024-01-01T12:00:00.000Z"}
```
--------------------------------
### Nacos Service Registration and Discovery Configuration in YAML
Source: https://context7.com/opensabre/opensabre-framework/llms.txt
Configures Spring Cloud application for Nacos service registration and discovery. It enables discovery, sets the Nacos server address, and defines a cluster name based on environment variables for availability zone awareness. Requires Spring Cloud Alibaba Nacos Discovery dependency.
```yaml
# application.yml - Service registration configuration
spring:
application:
name: order-service
cloud:
nacos:
discovery:
enabled: true
server-addr: ${REGISTER_HOST:localhost}:${REGISTER_PORT:8848}
cluster-name: CLUSTER-${CLOUD_AZ:LOCAL} # Cluster based on availability zone
# Environment variables:
# REGISTER_HOST=nacos-server.example.com
# REGISTER_PORT=8848
# CLOUD_AZ=SH # Results in cluster: CLUSTER-SH
```
--------------------------------
### Base Entity Classes for Persistence and API
Source: https://github.com/opensabre/opensabre-framework/blob/main/CLAUDE.md
Defines the base classes for entities in Opensabre, including `BasePo` for persistence with audit fields, `BaseVo` for API responses, `BaseForm` for requests, and `BaseQueryForm` for search operations.
```java
// Base persistence object with audit fields
public abstract class BasePo {
// createdBy, createdTime, updatedBy, updatedTime
}
// Base view object for API responses
public abstract class BaseVo {
}
// Base form object for API requests
public abstract class BaseForm {
}
// Base query form for search operations
public abstract class BaseQueryForm {
}
```
--------------------------------
### Enable Audit Logging with @Audit Annotation in Java
Source: https://context7.com/opensabre/opensabre-framework/llms.txt
The @Audit annotation automatically logs details of controller method executions. It captures operation type, description, module, request/response data, and execution time. Enable this feature by annotating the main application class with @EnabledAudit.
```java
import io.github.opensabre.boot.annotations.Audit;
import io.github.opensabre.boot.annotations.EnabledAudit;
import io.github.opensabre.boot.annotations.OperationType;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.*;
// Enable audit functionality on main application class
@SpringBootApplication
@EnabledAudit
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
@RestController
@RequestMapping("/api/orders")
public class OrderController {
@PostMapping
@Audit(operationType = OperationType.CREATE,
description = "Create new order",
module = "Order Management",
request = true,
response = true,
key = "#form.orderId") // SpEL expression to extract key
public Result createOrder(@RequestBody OrderForm form) {
return Result.success(orderService.create(form));
}
@PutMapping("/{id}")
@Audit(operationType = OperationType.UPDATE,
description = "Update order status",
module = "Order Management",
key = "#id")
public Result updateOrder(@PathVariable String id, @RequestBody OrderForm form) {
orderService.update(id, form);
return Result.success();
}
@DeleteMapping("/{id}")
@Audit(operationType = OperationType.DELETE,
description = "Delete order",
module = "Order Management",
request = true,
response = false)
public Result deleteOrder(@PathVariable String id) {
orderService.delete(id);
return Result.success();
}
@GetMapping
@Audit(operationType = OperationType.QUERY,
description = "Query order list",
module = "Order Management")
public Result> listOrders(@RequestParam String status) {
return Result.success(orderService.findByStatus(status));
}
}
// Operation types available: CREATE, UPDATE, DELETE, QUERY, LOGIN, LOGOUT, SCAN, EXPORT, IMPORT, DOWNLOAD, UPLOAD
```
--------------------------------
### Mask Sensitive Data with @Desensitization Annotation in Java
Source: https://context7.com/opensabre/opensabre-framework/llms.txt
The @Desensitization annotation automatically masks sensitive fields in REST responses using predefined rules or custom patterns. It supports common types like mobile numbers, ID cards, and emails, as well as custom masking logic.
```java
import io.github.opensabre.boot.annotations.Desensitization;
import io.github.opensabre.boot.sensitive.rule.DefaultSensitiveRule;
import lombok.Data;
@Data
public class UserProfileVo {
private String id;
private String username;
// Mask mobile number: 138****1234
@Desensitization(type = DefaultSensitiveRule.MOBILE)
private String mobile;
// Mask ID card: 110101****1234
@Desensitization(type = DefaultSensitiveRule.ID_CARD)
private String idCard;
// Mask bank card: 6222****1234
@Desensitization(type = DefaultSensitiveRule.BANK_CARD)
private String bankCard;
// Mask email: ab***@example.com
@Desensitization(type = DefaultSensitiveRule.EMAIL)
private String email;
// Mask name: 张*
@Desensitization(type = DefaultSensitiveRule.NAME)
private String realName;
// Custom masking: keep first 3 and last 2 characters
@Desensitization(type = DefaultSensitiveRule.CUSTOM,
retainPrefixCount = 3,
retainSuffixCount = 2,
replaceChar = '*')
private String accountNo;
// Mask address: 上海市**区****
@Desensitization(type = DefaultSensitiveRule.ADDRESS)
private String address;
// Complete password masking
@Desensitization(type = DefaultSensitiveRule.PASSWORD)
private String password;
}
// REST response will automatically mask sensitive data:
// {
// "id": "123",
// "username": "johndoe",
// "mobile": "138****1234",
// "idCard": "110101****1234",
// "bankCard": "6222****1234",
// "email": "jo***@example.com",
// "realName": "张*",
// "accountNo": "ACC***23",
// "address": "上海市**区 ****",
// "password": "******"
// }
```
=== COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.