### Create User API with Interceptor
Source: https://github.com/bitweb/java-core-lib/wiki/Retrofit
Example of creating a Retrofit API client using the builder, injecting a custom interceptor, and configuring it with properties.
```java
@Bean
public UserApi createUserApi(
@Qualifier("userApiServiceTokenRetrofitRequestInterceptor") ServiceTokenRetrofitRequestInterceptor interceptor
) {
log.info("Creating user api for {}", properties.getBaseUrl());
return retrofitBuilder
.create(properties.getBaseUrl(), UserApi.class)
.add(interceptor)
.build();
}
```
--------------------------------
### Recommended Logback-Spring Configuration
Source: https://github.com/bitweb/java-core-lib/wiki/Logging
Configure the SilencedGelfTcpAppender in your logback-spring.xml for production environments. This setup directs logs to Graylog via GELF TCP while also outputting to the console.
```xml
\\${host}
12201
2
0
100
100
application:${rootProject.name}
environment:${environment}
version:${rootProject.version}
build_number:${buildNumber}
```
--------------------------------
### TokenProvider for Auth Token Injection
Source: https://context7.com/bitweb/java-core-lib/llms.txt
Implement TokenProvider to supply authentication tokens for injection into API requests. This example retrieves a Bearer token from the SecurityContext.
```java
// Provide a TokenProvider bean for auth token injection
@Component
public class SecurityContextTokenProvider implements TokenProvider {
@Override
public String get() {
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
return (auth instanceof BearerTokenAuthentication b) ? b.getToken().getTokenValue() : null;
}
}
```
--------------------------------
### Custom AMQP Listener Interceptor Example
Source: https://github.com/bitweb/java-core-lib/wiki/AMQP-Support
Implement the AmqpListenerInterceptor interface to create a custom interceptor for processing messages before they reach the listener. Auto-configuration respects the @Order annotation.
```java
@Slf4j
@RequiredArgsConstructor
public class AmqpTraceBeforePublishMessageProcessor implements AmqpBeforePublishMessageProcessor {
private final AmqpTraceProperties properties;
private final TraceIdContext context;
@Override
public Message postProcessMessage(Message message) throws AmqpException {
log.debug("Adding trace id {} to AMQP message header {} ", context.get(), properties.getHeaderName());
message.getMessageProperties().setHeader(properties.getHeaderName(), context.get());
return message;
}
}
```
--------------------------------
### Update TrimmedStringDeserializer API for Jackson 3 in v5.0.0
Source: https://github.com/bitweb/java-core-lib/wiki/Migration-Guide
Use createModule() to get a SimpleModule for Jackson 3's TrimmedStringDeserializer in v5.0.0.
```java
// Before (v4.x)
TrimmedStringDeserializer.addToObjectMapper(objectMapper);
// After (v5.0.0) — for Jackson 3:
jsonMapperBuilder.addModule(TrimmedStringDeserializer.createModule());
// After (v5.0.0) — for Jackson 2 (Retrofit):
Jackson2TrimmedStringDeserializer.addToObjectMapper(objectMapper);
// or
objectMapper.registerModule(Jackson2TrimmedStringDeserializer.createModule());
```
--------------------------------
### Scheduled Job Implementation in Java
Source: https://github.com/bitweb/java-core-lib/wiki/Scheduled-job
Example of a scheduled job that extends ScheduledJob and uses a cron expression for scheduling. Ensure the SchedulerTraceIdResolver bean is present in the context.
```java
@Component
public class ProductionOrderUpdateScheduler extends ScheduledJob {
public ProductionOrderUpdateScheduler(
final ProductionOrderRowImportComponent runnable,
final SchedulerTraceIdResolver traceIdResolver
) {
super(runnable, traceIdResolver);
}
@Scheduled(cron = "${scheduled.production-order-row.cron}")
public void schedule() {
run();
}
}
```
--------------------------------
### Retrofit API Client Definition
Source: https://context7.com/bitweb/java-core-lib/llms.txt
Define Retrofit interfaces for API interactions using annotations like @GET, @POST, and @Path.
```java
// Declare the Retrofit interface
public interface UserApi {
@GET("users/{id}")
Call> getById(@Path("id") Long id);
@POST("users")
Call> create(@Body CreateUserRequest body);
}
```
--------------------------------
### Implement Custom Audit Log Data Mapper
Source: https://github.com/bitweb/java-core-lib/wiki/Audit-log
Example of creating a custom audit log data mapper to extract user-specific information, such as a person code from a JWT in a request header. Ensure the mapper is placed correctly in the filter chain.
```java
@Component
@RequiredArgsConstructor
public class PersonCodeDataMapper implements AuditLogDataMapper {
public static final String KEY = "person_code";
private final JwtProcessor processor;
private final AuthenticationProperties properties;
private final ValidateTokenFeature validateTokenFeature;
@Override
public String getValue(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) {
String token = httpServletRequest.getHeader(properties.getAccessTokenHeaderName());
if (token != null && validateTokenFeature.isValid(token)) {
return processor.getSubject(token);
}
return null;
}
@Override
public String getKey() {
return KEY;
}
}
```
--------------------------------
### Build Project with Gradle
Source: https://github.com/bitweb/java-core-lib/blob/master/CLAUDE.md
Standard Gradle command to build the entire project.
```bash
./gradlew build
```
--------------------------------
### Run Tests with Coverage Reports using Gradle
Source: https://github.com/bitweb/java-core-lib/blob/master/CLAUDE.md
Build the project and generate test coverage reports.
```bash
./gradlew testAndReport
```
--------------------------------
### Run All Tests with Gradle
Source: https://github.com/bitweb/java-core-lib/blob/master/CLAUDE.md
Execute all tests within the project using Gradle.
```bash
./gradlew test
```
--------------------------------
### Add Spring AMQP Starter Dependency
Source: https://github.com/bitweb/java-core-lib/wiki/AMQP-Support
Include the Spring Boot AMQP starter dependency for AMQP functionality.
```gradle
implementation 'org.springframework.boot:spring-boot-starter-amqp'
```
--------------------------------
### Run Single Test Class with Gradle
Source: https://github.com/bitweb/java-core-lib/blob/master/CLAUDE.md
Execute a specific test class using Gradle by providing its fully qualified name.
```bash
./gradlew test --tests "ee.bitweb.core.api.model.exception.ControllerAdvisorIntegrationTests"
```
--------------------------------
### Include Web Starter Dependency
Source: https://github.com/bitweb/java-core-lib/wiki/CORS-autoconfiguration
Include the Spring Boot Web starter dependency to use the CORS autoconfiguration feature.
```gradle
implementation 'org.springframework.boot:spring-boot-starter-web'
```
--------------------------------
### Spring Boot AMQP Starter Dependency
Source: https://context7.com/bitweb/java-core-lib/llms.txt
Include the Spring Boot Starter AMQP dependency in your build.gradle file to enable AMQP functionalities.
```groovy
// build.gradle
implementation 'org.springframework.boot:spring-boot-starter-amqp'
```
--------------------------------
### Configure Maven Repositories for Development
Source: https://github.com/bitweb/java-core-lib/wiki/Home
Define the repositories to use when building or publishing the library locally.
```gradle
repositories {
mavenLocal()
mavenCentral()
}
```
--------------------------------
### Migration from 2.* to 3.* for Controller Advisor
Source: https://github.com/bitweb/java-core-lib/wiki/Controller-advisor
Update the configuration property to enable the feature when migrating from version 2.* to 3.*. Error message formats have also changed for specific exceptions.
```text
ee.bitweb.core.controller-advice.enabled=true
to
ee.bitweb.core.controller-advice.auto-configuration=true
```
--------------------------------
### Enable Controller Advisor Auto-Configuration
Source: https://github.com/bitweb/java-core-lib/wiki/Controller-advisor
Add this property to your configuration to enable the auto-configuration mechanism for the Controller Advisor feature.
```text
ee.bitweb.core.controller-advice.auto-configuration=true
```
--------------------------------
### Run Integration Tests with Gradle
Source: https://github.com/bitweb/java-core-lib/blob/master/CLAUDE.md
Execute only integration tests, including those tagged with @Tag("integration").
```bash
./gradlew integrationTest
```
--------------------------------
### Run Unit Tests with Gradle
Source: https://github.com/bitweb/java-core-lib/blob/master/CLAUDE.md
Execute only unit tests, excluding those tagged as integration tests.
```bash
./gradlew unitTest
```
--------------------------------
### Implement Custom Audit Log Writer
Source: https://github.com/bitweb/java-core-lib/wiki/Audit-log
This Java class demonstrates how to implement a custom audit log writer by extending AuditLogWriteAdapter. It shows how to capture and log audit information, including request method, URL, response status, and duration, while preserving MDC context.
```java
public class AuditLogLoggerWriterAdapter implements AuditLogWriteAdapter {
public static final String AUDIT = "audit";
@Override
public void write(Map container) {
Map currentContext = MDC.getCopyOfContextMap();
container.put(AUDIT, "1");
MDC.setContextMap(container);
log.info(
"{} {} {} {} ms",
get(container, RequestMethodMapper.KEY),
get(container, RequestUrlDataMapper.KEY),
get(container, ResponseStatusMapper.KEY),
get(container, AuditLogFilter.DURATION_KEY));
if (currentContext != null) {
MDC.setContextMap(currentContext);
}
}
private String get(Map container, String key) {
if (container.containsKey(key)) {
return container.get(key);
}
return "UNKNOWN";
}
}
```
--------------------------------
### Enable AMQP Auto-Configuration
Source: https://github.com/bitweb/java-core-lib/wiki/AMQP-Support
Add this property to application.properties to enable automatic AMQP configuration, including JSON message conversion and Trace ID propagation.
```properties
ee.bitweb.core.amqp.auto-configuration=true
```
--------------------------------
### Required Dependencies for Controller Advisor
Source: https://github.com/bitweb/java-core-lib/wiki/Controller-advisor
Ensure these dependencies are added to your project as the core library does not provide transitive dependencies.
```gradle
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-validation'
```
--------------------------------
### Send Message using AmqpService
Source: https://github.com/bitweb/java-core-lib/wiki/AMQP-Support
Utilize the AmqpService helper class to send messages to a specified queue, with options to set message headers.
```java
amqpService.sendMessage(
REQUEST_QUEUE,
responseQueue,
request,
message -> {
message.getMessageProperties().setHeader(AmqpConstants.VERSION_HEADER_NAME, version.toString());
message.getMessageProperties().setHeader(AmqpConstants.PROCESSLOCK_HEADER_NAME, processLockName);
return null;
}
);
```
--------------------------------
### AMQP Auto-Configuration
Source: https://context7.com/bitweb/java-core-lib/llms.txt
Enable AMQP auto-configuration in application.yml to set up RabbitMQ support with a JSON message converter and listener/publisher interceptors.
```yaml
# application.yml
ee:
bitweb:
core:
amqp:
auto-configuration: true
```
--------------------------------
### Configure Base Package Scanning for Auto-Configured Components
Source: https://github.com/bitweb/java-core-lib/wiki/Home
Specify the base packages to scan for auto-configured components in your Spring Boot application.
```java
@SpringBootApplication(scanBasePackages = {"ee.bitweb.core.*", "com.example.*"})
```
--------------------------------
### Retrofit Configuration
Source: https://context7.com/bitweb/java-core-lib/llms.txt
Configure Retrofit client settings in application.yml, including timeouts, logging levels, and authentication.
```yaml
ee:
bitweb:
core:
retrofit:
auto-configuration: true
timeout:
call: 30000 # ms, 0 = no limit
connect: 10000
read: 10000
write: 10000
logging:
level: BASIC # NONE | BASIC | HEADERS | BODY | CUSTOM
max-loggable-request-body-size: 10240
max-loggable-response-body-size: 10240
redacted-body-urls:
- /upload
- /download
auth-token-injector:
enabled: true
header-name: Authorization
whitelist-urls[0]: "^https://internal\.mycompany\.com/.*"
```
--------------------------------
### Add logback-gelf Dependency
Source: https://github.com/bitweb/java-core-lib/wiki/Logging
Include this dependency in your project to use the logback-gelf library, which is required for the SilencedGelfTcpAppender.
```gradle
implementation group: 'de.siegmar', name: 'logback-gelf', version: '6.0.1'
```
--------------------------------
### Enable CORS Autoconfiguration
Source: https://github.com/bitweb/java-core-lib/wiki/CORS-autoconfiguration
Add this property to your `application.properties` file to enable CORS autoconfiguration.
```text
ee.bitweb.core.cors.auto-configuration=true
```
--------------------------------
### Enable ObjectMapper Auto-configuration
Source: https://github.com/bitweb/java-core-lib/wiki/Object-mapper-autoconfiguration
Add this property to your application.properties file to enable the ObjectMapper auto-configuration.
```properties
ee.bitweb.core.object-mapper.auto-configuration=true
```
--------------------------------
### Add Retrofit Dependencies
Source: https://github.com/bitweb/java-core-lib/wiki/Retrofit
Include these Gradle dependencies to use Retrofit and its Jackson converter. Ensure you specify the retrofitVersion.
```gradle
implementation group: 'com.squareup.retrofit2', name: 'retrofit', version: "${retrofitVersion}"
```
```gradle
implementation group: 'com.squareup.retrofit2', name: 'converter-jackson', version: "${retrofitVersion}"
```
--------------------------------
### Enable Retrofit Auto-Configuration
Source: https://github.com/bitweb/java-core-lib/wiki/Retrofit
Add this property to your application.properties file to enable automatic configuration for Retrofit components.
```properties
ee.bitweb.core.retrofit.auto-configuration=true
```
--------------------------------
### Enable Audit Logging Configuration
Source: https://github.com/bitweb/java-core-lib/wiki/Audit-log
Add this property to your application.properties file to enable audit log autoconfiguration.
```properties
ee.bitweb.core.audit.auto-configuration=true
```
--------------------------------
### Add Jackson Databind Dependency
Source: https://github.com/bitweb/java-core-lib/wiki/AMQP-Support
If not using spring-boot-starter-web, add the Jackson databind dependency for JSON serialization and deserialization.
```gradle
implementation group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: "${jacksonVersion}"
```
--------------------------------
### Add Spring Core Library Dependency
Source: https://context7.com/bitweb/java-core-lib/llms.txt
Include the `spring-core` library in your project's Gradle build file. Ensure auto-configured component scanning is enabled by including `ee.bitweb.core.*` in your `@SpringBootApplication`'s `scanBasePackages`.
```groovy
// build.gradle
implementation group: 'ee.bitweb', name: 'spring-core', version: '5.0.0'
// Required for auto-configured component scanning
@SpringBootApplication(scanBasePackages = {"ee.bitweb.core.*", "com.example.*"})
```
--------------------------------
### Migration from 2.x to 3.x
Source: https://github.com/bitweb/java-core-lib/wiki/Actuator-security
To enable the feature in newer versions, update the configuration property name. This change reflects the evolution of the autoconfiguration property.
```text
ee.bitweb.core.actuator.security.auto-configuration
```
--------------------------------
### Logback GELF Dependency
Source: https://context7.com/bitweb/java-core-lib/llms.txt
Add the logback-gelf dependency to your Gradle build file to enable GELF logging.
```groovy
// build.gradle
implementation 'de.siegmar:logback-gelf:6.1.2'
```
--------------------------------
### Implement Custom Retrofit Logging Mapper
Source: https://github.com/bitweb/java-core-lib/wiki/Retrofit
Create a custom mapper by implementing the RetrofitLoggingMapper interface, adding it as a Spring component, and configuring it to be included in logging.
```java
@Slf4j
@Component
public class ContentTypeRetrofitLoggerMapper implements RetrofitLoggingMapper {
@Override
public String getValue(Request request, Response response) {
return request.header("Content-Type");
}
@Override
public String getKey() {
return "ContentType";
}
}
```
--------------------------------
### SilencedGelfTcpAppender Configuration
Source: https://context7.com/bitweb/java-core-lib/llms.txt
Configure a fault-tolerant GELF TCP appender for Logback that silences connection and send exceptions. This prevents application crashes due to logging failures, dropping undeliverable messages.
```xml
${host}
12201
2
0
100
100
application:my-service
environment:production
```
--------------------------------
### Configure Logging Mappers and Level
Source: https://github.com/bitweb/java-core-lib/wiki/Retrofit
Configure Retrofit logging by setting the logging level and specifying mappers. Default and provided mappers are merged unless the level is CUSTOM.
```properties
ee.bitweb.core.retrofit.logging.level=basic
ee.bitweb.core.retrofit.logging.mappers=response_body
```
--------------------------------
### Sending Messages with AmqpService
Source: https://context7.com/bitweb/java-core-lib/llms.txt
Utilize AmqpService to send messages to RabbitMQ queues. Supports simple sends and sends with reply queues and custom headers.
```java
// Sending messages with AmqpService
@Service
@RequiredArgsConstructor
public class OrderPublisher {
private static final String ORDER_QUEUE = "orders.created";
private static final String REPLY_QUEUE = "orders.reply";
private final AmqpService amqpService;
// Simple send without reply queue
public void publish(OrderDto order) {
amqpService.sendMessage(ORDER_QUEUE, order);
}
// Send with reply queue and custom headers
public void publishWithVersion(OrderDto order, int version) {
amqpService.sendMessage(ORDER_QUEUE, REPLY_QUEUE, order, message -> {
message.getMessageProperties().setHeader("x-version", version);
message.getMessageProperties().setHeader("x-source", "order-service");
return message;
});
}
}
```
--------------------------------
### Add Bitweb Spring Core Dependency
Source: https://github.com/bitweb/java-core-lib/blob/master/README.md
Include this dependency in your project to use the Bitweb Spring Core library. Check Maven Central for the latest versions.
```gradle
implementation group: 'ee.bitweb', name: 'spring-core', version: '5.0.0'
```
--------------------------------
### Required Dependencies for Actuator Security
Source: https://github.com/bitweb/java-core-lib/wiki/Actuator-security
Include these dependencies in your project to ensure the actuator security autoconfiguration functions correctly. The core library does not provide transitive dependencies for these.
```gradle
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-actuator', version: "${springBootVersion}"
```
```gradle
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-security', version: "${springBootVersion}"
```
--------------------------------
### Enable Trace ID Auto-Configuration
Source: https://github.com/bitweb/java-core-lib/wiki/Trace-Id
Add this property to your configuration to enable the automatic addition and propagation of Trace ID to log entries. This requires the 'spring-boot-starter-web' dependency.
```properties
ee.bitweb.core.trace.auto-configuration=true
```
--------------------------------
### Configure Trace ID Properties
Source: https://context7.com/bitweb/java-core-lib/llms.txt
Configure trace ID generation and propagation using YAML properties. Customize prefixes, delimiters, lengths, and HTTP header names for trace IDs.
```yaml
# application.yml
ee:
bitweb:
core:
trace:
auto-configuration: true
invoker:
prefix: "my-svc" # added to trace ID for readability
delimiter: "-"
length: 20 # [10, 20]
http:
headerName: X-Trace-ID
thread:
delimiter: ":"
length: 10 # [5, 10]
scheduler:
length: 20
```
--------------------------------
### Update Jackson Imports for v5.0.0
Source: https://github.com/bitweb/java-core-lib/wiki/Migration-Guide
Update imports from com.fasterxml.jackson to tools.jackson when migrating to Jackson 3 in v5.0.0.
```java
// Before (v4.x)
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.DeserializationFeature;
// After (v5.0.0)
import tools.jackson.databind.ObjectMapper;
import tools.jackson.databind.DeserializationFeature;
```
--------------------------------
### StringUtil for String Manipulation
Source: https://context7.com/bitweb/java-core-lib/llms.txt
Provides null-safe string trimming and secure random alphanumeric string generation. Use StringUtil.trim for safe trimming and StringUtil.random for generating tokens or IDs.
```java
// StringUtil.trim – null-safe trim
String trimmed = StringUtil.trim(" hello world "); // "hello world"
String nullSafe = StringUtil.trim(null); // null
```
```java
// StringUtil.random – secure random alphanumeric string
String token = StringUtil.random(32); // e.g. "A3fK9mNqR2sT7uVwX1yZ0bCdEfGhIjKl"
String shortId = StringUtil.random(8); // e.g. "Tz4mR9kQ"
```
--------------------------------
### Configure CORS Auto-Configuration
Source: https://context7.com/bitweb/java-core-lib/llms.txt
Enable CORS for all paths by registering a CorsConfigurationSource bean. Configure allowed origins, methods, and credential support via application.yml.
```yaml
# application.yml
ee:
bitweb:
core:
cors:
auto-configuration: true
path: "/**"
allow-credentials: true
allowed-origins:
- https://app.example.com
- https://admin.example.com
allowed-methods:
- GET
- POST
- PUT
- DELETE
- OPTIONS
- PATCH
```
```bash
# Preflight request – browser sends before cross-origin POST
curl -X OPTIONS https://api.example.com/users \
-H "Origin: https://app.example.com" \
-H "Access-Control-Request-Method: POST" \
-H "Access-Control-Request-Headers: Content-Type" \
-i
# → HTTP 200
# Access-Control-Allow-Origin: https://app.example.com
# Access-Control-Allow-Methods: GET,POST,PUT,DELETE,OPTIONS,PATCH
# Access-Control-Allow-Credentials: true
```
--------------------------------
### Custom AmqpListenerInterceptor
Source: https://context7.com/bitweb/java-core-lib/llms.txt
Implement AmqpListenerInterceptor to intercept incoming messages before they are processed by the listener, useful for tasks like schema validation.
```java
// Custom listener interceptor (e.g., request validation)
@Component
@Order(2)
public class SchemaValidationInterceptor implements AmqpListenerInterceptor {
@Override
public Message preProcess(Message message) throws AmqpException {
// validate schema, throw AmqpRejectAndDontRequeueException to dead-letter
return message;
}
}
```
--------------------------------
### Enable Actuator Security Autoconfiguration
Source: https://github.com/bitweb/java-core-lib/wiki/Actuator-security
Add this property to your configuration to enable the autoconfiguration mechanism for actuator endpoint security. This is the primary step to activate the feature.
```text
ee.bitweb.core.actuator.security.auto-configuration=true
```
--------------------------------
### Async Thread Pool with MDC Trace Propagation
Source: https://context7.com/bitweb/java-core-lib/llms.txt
Configure an asynchronous thread pool using `ThreadPoolTaskExecutor` and apply `BasicMDCTaskDecorator` for MDC trace propagation. This ensures trace IDs are correctly managed across asynchronous operations.
```java
// Async thread pool with MDC trace propagation
@Slf4j
@EnableAsync
@Configuration
@RequiredArgsConstructor
public class AsyncConfig implements AsyncConfigurer {
private final ThreadTraceIdResolver resolver;
@Override
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setThreadNamePrefix("Async-");
executor.setTaskDecorator(new BasicMDCTaskDecorator(resolver));
executor.setCorePoolSize(10);
executor.setMaxPoolSize(20);
executor.initialize();
return executor;
}
}
```
--------------------------------
### Configure Persistence Exception Log Levels in v5.0.0
Source: https://github.com/bitweb/java-core-lib/wiki/Migration-Guide
Configure entity-not-found-exception and conflict-exception independently in v5.0.0, as the persistence-exception property is removed.
```yaml
# Before (v4.x)
ee.bitweb.core.api.controller-advisor.log-level:
persistence-exception: WARN # affected both entity-not-found and conflict
# After (v5.0.0) — configure each independently:
ee.bitweb.core.api.controller-advisor.log-level:
entity-not-found-exception: WARN
conflict-exception: WARN
```
--------------------------------
### TransactionHelper for Post-Commit Hooks
Source: https://context7.com/bitweb/java-core-lib/llms.txt
Register callbacks to execute after a database transaction commits successfully. This ensures actions like sending notifications only occur if the transaction succeeds.
```java
@Service
@RequiredArgsConstructor
public class UserRegistrationService {
private final UserRepository userRepository;
private final AmqpService amqpService;
@Transactional
public User register(CreateUserRequest req) {
User user = userRepository.save(new User(req.getEmail()));
// This lambda fires ONLY after the transaction commits successfully.
// If the transaction rolls back, the message is NOT sent.
TransactionHelper.afterCommit(() ->
amqpService.sendMessage("users.registered", new UserRegisteredEvent(user.getId()))
);
return user;
}
}
```
--------------------------------
### Custom Audit Log Mapper
Source: https://context7.com/bitweb/java-core-lib/llms.txt
Implements a custom audit log mapper to add specific data, such as the authenticated user's ID, to each audit log entry. This requires implementing the AuditLogDataMapper interface and defining a unique key for the data.
```java
// Custom audit mapper – adds authenticated user's ID to every log entry
@Component
@RequiredArgsConstructor
public class UserIdAuditMapper implements AuditLogDataMapper {
public static final String KEY = "user_id";
private final SecurityContextHolder securityContextHolder;
@Override
public String getValue(HttpServletRequest req, HttpServletResponse res) {
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if (auth != null && auth.isAuthenticated()) {
return auth.getName();
}
return null;
}
@Override
public String getKey() {
return KEY;
}
}
// Custom writer – sends audit entries to a dedicated queue instead of the app log
@Component
public class AmqpAuditLogWriter implements AuditLogWriteAdapter {
private final AmqpService amqpService;
@Override
public void write(Map container) {
amqpService.sendMessage("audit.log.queue", container);
}
}
// Produces INFO log (default writer):
// GET /api/users 200 42ms (MDC contains: method, url, status, duration, trace_id, user_id …)
```
--------------------------------
### Configure Async Executor with Task Decorator
Source: https://github.com/bitweb/java-core-lib/wiki/Trace-Id
When using @Async, configure a custom ThreadPoolTaskExecutor with a TaskDecorator to ensure Trace ID is propagated to background jobs. BasicMDCTaskDecorator is suitable when security context is not needed.
```java
@Slf4j
@EnableAsync
@Configuration
@RequiredArgsConstructor
public class AsyncConfig implements AsyncConfigurer {
private static final Integer CORE_POOL_SIZE = 10;
private static final Integer MAX_POOL_SIZE = 20;
private static final String DEFAULT_PREFIX = "CustomAsync-";
private final ThreadTraceIdResolver resolver;
@Override
public Executor getAsyncExecutor() {
log.info("Creating Async thread pool executor");
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setThreadNamePrefix(DEFAULT_PREFIX);
executor.setTaskDecorator(new BasicMDCTaskDecorator(resolver));
executor.setMaxPoolSize(MAX_POOL_SIZE);
executor.setCorePoolSize(CORE_POOL_SIZE);
executor.initialize();
return executor;
}
}
```
--------------------------------
### Update Spring Boot Test Imports
Source: https://github.com/bitweb/java-core-lib/wiki/Migration-Guide
The MockMvc auto-configuration has moved to a new package in Spring Boot 4. Update your import statements accordingly.
```java
// Before (v4.x)
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
```
```java
// After (v5.0.0)
import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc;
```
--------------------------------
### Include Jackson Java Time Module Dependency
Source: https://github.com/bitweb/java-core-lib/wiki/Object-mapper-autoconfiguration
Include this dependency in your build file to enable the Java Time module for ObjectMapper, allowing serialization and deserialization of java.time data types.
```gradle
implementation group: 'com.fasterxml.jackson.datatype', name: 'jackson-datatype-jsr310', version: "${jacksonVersion}"
```
--------------------------------
### Custom AmqpBeforePublishMessageProcessor
Source: https://context7.com/bitweb/java-core-lib/llms.txt
Implement AmqpBeforePublishMessageProcessor to modify messages before they are published, such as adding a correlation ID.
```java
// Custom before-publish processor (e.g., adding a correlation ID)
@Component
@Order(2)
public class CorrelationIdProcessor implements AmqpBeforePublishMessageProcessor {
@Override
public Message postProcessMessage(Message message) throws AmqpException {
message.getMessageProperties().setCorrelationId(UUID.randomUUID().toString());
return message;
}
}
```
--------------------------------
### Exception Handling with Custom Exceptions
Source: https://context7.com/bitweb/java-core-lib/llms.txt
Automatically handles custom exceptions like EntityNotFoundException, ConflictException, and MethodArgumentNotValidException by mapping them to appropriate HTTP status codes and response bodies. Throw exceptions from your service layer to leverage this feature.
```java
throw new EntityNotFoundException("User", "email", "john@example.com");
// → HTTP 404:
// {
// "id": "svc-Abc123",
// "message": "Entity User not found",
// "entity": "User",
// "criteria": [{"field": "email", "value": "john@example.com"}]
// }
```
```java
throw new ConflictException("User already exists", "User", "email", "john@example.com");
// → HTTP 409:
// {
// "id": "svc-Abc123",
// "message": "User already exists",
// "entity": "User",
// "criteria": [{"field": "email", "value": "john@example.com"}]
// }
```
```java
throw new ValidationException(Set.of(
new FieldError("email", "InvalidFormat", "Email is not valid")
));
// → HTTP 400:
// {
// "id": "svc-Abc123",
// "message": "Validation failed with errors",
// "errors": [{"field": "email", "message": "InvalidFormat", "reason": "Email is not valid"}]
// }
```
--------------------------------
### Configure Jackson for String Trimming
Source: https://context7.com/bitweb/java-core-lib/llms.txt
Enable automatic trimming of String fields during JSON deserialization by registering the TrimmedStringDeserializer module. This requires the jackson-datatype-jsr310 dependency for Java 8 Date/Time support.
```groovy
// build.gradle – required for JavaTimeModule (Jackson 2)
implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.21.2'
```
```java
// Using Jackson 3 module manually (e.g., for a custom JsonMapper)
JsonMapper jsonMapper = JsonMapper.builder()
.addModule(TrimmedStringDeserializer.createModule())
.disable(DateTimeFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE)
.disable(DeserializationFeature.ACCEPT_FLOAT_AS_INT)
.build();
```
```java
// Using Jackson 2 module manually (e.g., for a custom ObjectMapper)
ObjectMapper objectMapper = new ObjectMapper();
Jackson2TrimmedStringDeserializer.addToObjectMapper(objectMapper);
// or
objectMapper.registerModule(Jackson2TrimmedStringDeserializer.createModule());
objectMapper.registerModule(new JavaTimeModule());
objectMapper.disable(ADJUST_DATES_TO_CONTEXT_TIME_ZONE);
objectMapper.disable(ACCEPT_FLOAT_AS_INT);
```
--------------------------------
### Scheduled Job Scaffolding with ScheduledJob
Source: https://context7.com/bitweb/java-core-lib/llms.txt
Reduce boilerplate for cron jobs by extending ScheduledJob or ScheduledRunnable. This base class handles trace ID generation, error handling, and logging for job execution.
```java
// Step 1: implement the unit of work
@Component
public class CleanupExpiredTokensComponent implements ScheduledRunnable {
@Override
public void run() {
// business logic here – exceptions propagate to ScheduledJob.handleException()
tokenRepository.deleteExpiredBefore(Instant.now());
}
}
// Step 2: define the scheduler invocation class
@Component
public class CleanupTokensScheduler extends ScheduledJob {
public CleanupTokensScheduler(
CleanupExpiredTokensComponent runnable,
SchedulerTraceIdResolver traceIdResolver
) {
super(runnable, traceIdResolver);
}
@Scheduled(cron = "${scheduled.cleanup-tokens.cron:0 0 * * * *}")
public void schedule() {
run(); // handles trace ID, logging, and error handling automatically
}
}
// Logs on each invocation:
// INFO Started com.example.CleanupTokensScheduler
// INFO Finished com.example.CleanupTokensScheduler
// ERROR com.example.CleanupTokensScheduler failed: (on exception)
```
--------------------------------
### Audit Log Configuration
Source: https://context7.com/bitweb/java-core-lib/llms.txt
Configures the audit log servlet filter to capture HTTP request/response details. Customize loggable sizes, included/sensitive headers, paths to exclude, and whether to include request duration. Ensure the 'AuditLogger' is set to DEBUG level to log request and response bodies.
```yaml
ee:
bitweb:
core:
audit:
auto-configuration: true
max-loggable-response-size: 3072 # bytes
max-loggable-request-size: 3072
request-headers: User-Agent, Origin
sensitive-headers: Authorization # values are redacted
blacklist: /actuator/ # paths to skip
include-duration: true
# Enable body logging (DEBUG level)
logging:
level:
AuditLogger: DEBUG
```
--------------------------------
### Enable Request/Response Body Logging
Source: https://github.com/bitweb/java-core-lib/wiki/Audit-log
To include request and response bodies in audit logs, set the logging level for AuditLogger to DEBUG in your application's configuration properties.
```text
logging.level.AuditLogger=DEBUG
```
--------------------------------
### Update Spring Security & Actuator Imports
Source: https://github.com/bitweb/java-core-lib/wiki/Migration-Guide
Spring Boot 4 reorganized several actuator and security packages. Update your import statements to reflect these changes.
```java
// Before (v4.x)
import org.springframework.boot.actuate.autoconfigure.health.HealthEndpointProperties;
import org.springframework.boot.actuate.autoconfigure.security.servlet.EndpointRequest;
```
```java
// After (v5.0.0)
import org.springframework.boot.health.autoconfigure.actuate.endpoint.HealthEndpointProperties;
import org.springframework.boot.security.autoconfigure.actuate.web.servlet.EndpointRequest;
```
--------------------------------
### Spring Bean Registration for Retrofit API
Source: https://context7.com/bitweb/java-core-lib/llms.txt
Register the Retrofit API client as a Spring bean using SpringAwareRetrofitBuilder. Ensure the base URL is correctly configured.
```java
// Register the API client as a Spring bean using SpringAwareRetrofitBuilder
@Configuration
@RequiredArgsConstructor
@Slf4j
public class UserApiConfig {
private final SpringAwareRetrofitBuilder retrofitBuilder;
private final UserApiProperties properties; // holds baseUrl
@Bean
public UserApi userApi() {
log.info("Creating UserApi for {}", properties.getBaseUrl());
return retrofitBuilder
.create(properties.getBaseUrl(), UserApi.class)
.build();
}
}
```
--------------------------------
### Enable Actuator Security Auto-Configuration
Source: https://context7.com/bitweb/java-core-lib/llms.txt
Secure Spring Actuator endpoints using HTTP Basic Authentication. A default 'ACTUATOR' role is created with a random password, and the '/health' endpoint is accessible by default to 'ACTUATOR' and 'ANONYMOUS' roles.
```yaml
# application.yml
ee:
bitweb:
core:
actuator:
security:
auto-configuration: true
role: ACTUATOR
health-endpoint-roles:
- ACTUATOR
- ANONYMOUS
disable-unsafe-health-endpoint-warning: false
user:
name: actuator-user
password: my-secure-password # default: random UUID
roles:
- ACTUATOR
```
```groovy
// build.gradle
implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'org.springframework.boot:spring-boot-starter-security'
```
```bash
# Access actuator health (public)
curl http://localhost:8080/actuator/health
# → {"status":"UP"}
# Access protected actuator endpoint with Basic Auth
curl -u actuator-user:my-secure-password http://localhost:8080/actuator/env
# → {"activeProfiles": [...], "propertySources": [...]}
# Unauthorized access returns 401
curl http://localhost:8080/actuator/env
# → HTTP 401 Unauthorized
```
--------------------------------
### Custom Jakarta Validators: @FileType and @Uppercase
Source: https://context7.com/bitweb/java-core-lib/llms.txt
Use @FileType to validate MIME types of uploaded files and @Uppercase to ensure string fields are in uppercase. Both integrate with ControllerAdvisor for error handling.
```java
public class UploadRequest {
@NotNull
@FileType({FileTypeEnum.PDF, FileTypeEnum.JPEG, FileTypeEnum.PNG})
private MultipartFile document;
}
```
```java
public class CountryRequest {
@NotBlank
@Uppercase
private String countryCode; // "EST" ✓, "est" ✗ → "string must be uppercase"
}
```
--------------------------------
### Replace MDCTaskDecorator in v5.0.0
Source: https://github.com/bitweb/java-core-lib/wiki/Migration-Guide
Replace the removed MDCTaskDecorator with BasicMDCTaskDecorator or SecurityAwareMDCTaskDecorator in v5.0.0.
```java
// Before (v4.x)
new MDCTaskDecorator(resolver);
// After (v5.0.0) — choose one:
new BasicMDCTaskDecorator(resolver);
new SecurityAwareMDCTaskDecorator(resolver);
```
--------------------------------
### Execute API Call with RetrofitRequestExecutor
Source: https://github.com/bitweb/java-core-lib/wiki/Retrofit
Use RetrofitRequestExecutor to execute API calls, which handles response data extraction and basic error handling. It throws a RetrofitException on error.
```java
public UserResponse byPersonCode(String personCode) {
log.info("Requesting user from user server by personCode: {}", personCode);
return RetrofitRequestExecutor.execute(userApi.getByPersonCode(personCode));
}
```
--------------------------------
### Accessing Current Trace ID
Source: https://context7.com/bitweb/java-core-lib/llms.txt
Retrieve the current trace ID from the `TraceIdContext` within your application services. This allows for logging and tracking requests across different components.
```java
// Reading the current trace ID anywhere in the application
@Service
@RequiredArgsConstructor
public class MyService {
private final TraceIdContext traceIdContext;
public void doWork() {
String currentTraceId = traceIdContext.get(); // e.g. "my-svc-A3fK9....:tHs29"
log.info("Processing with trace {}", currentTraceId);
}
}
```
--------------------------------
### Safe Retrofit API Call Execution
Source: https://context7.com/bitweb/java-core-lib/llms.txt
Execute Retrofit API calls using RetrofitRequestExecutor for safe handling of responses and exceptions. This utility unwraps the Response and throws RetrofitException on failure.
```java
// Execute calls safely – throws RetrofitException on any error
@Service
@RequiredArgsConstructor
public class UserService {
private final UserApi userApi;
public UserResponse getById(Long id) {
// RetrofitRequestExecutor unwraps Response and throws RetrofitException on failure
return RetrofitRequestExecutor.execute(userApi.getById(id));
}
public UserResponse create(CreateUserRequest req) {
return RetrofitRequestExecutor.execute(userApi.create(req));
}
}
```
--------------------------------
### Handle InvalidFormatValidationException in v5.0.0
Source: https://github.com/bitweb/java-core-lib/wiki/Migration-Guide
Catch InvalidFormatValidationException as a RuntimeException in v5.0.0, using getCause() to access the original exception.
```java
// Before (v4.x)
catch (InvalidFormatValidationException e) {
// was a checked exception (InvalidFormatException → JsonProcessingException → IOException)
}
// After (v5.0.0)
catch (InvalidFormatValidationException e) {
// now a RuntimeException — no longer needs to be declared in throws clauses
e.getCause(); // returns the original InvalidFormatException
}
```
--------------------------------
### Update AMQP Message Converter
Source: https://github.com/bitweb/java-core-lib/wiki/Migration-Guide
When overriding the message converter bean, update to `JacksonJsonMessageConverter` and provide a `JsonMapper` instead of an `ObjectMapper`.
```java
// Before (v4.x)
Jackson2JsonMessageConverter converter = new Jackson2JsonMessageConverter(objectMapper);
```
```java
// After (v5.0.0)
JacksonJsonMessageConverter converter = new JacksonJsonMessageConverter(jsonMapper);
```
--------------------------------
### Add Jackson 2 JSR310 Datatype for v5.0.0
Source: https://github.com/bitweb/java-core-lib/wiki/Migration-Guide
Explicitly add jackson-datatype-jsr310 to the compile classpath if Jackson 2's JavaTimeModule is needed with a custom ObjectMapper bean in v5.0.0.
```groovy
implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310'
```
=== COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.