8 Must‑Use Spring Boot Code Snippets to Stop Re‑inventing the Wheel

This article presents eight ready‑to‑use Spring Boot 3.5.0 code snippets—including MapStruct converters, embeddable collections, i18n helpers, secure random generators, custom runtime exceptions, type‑safe configuration properties, JPA auditing, and custom validation annotations—each illustrated with concrete examples and runnable code.

Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
8 Must‑Use Spring Boot Code Snippets to Stop Re‑inventing the Wheel

Introduction

If you have worked on multiple Spring Boot projects, you have probably rewritten the same string‑handling logic, error‑handling utilities, or localization helpers again and again. Building a reusable component library can dramatically improve development efficiency and keep code style consistent.

1. Powerful MapStruct type conversion

MapStruct can map DTOs to entities, but basic type conversion is often ignored. The article shows how to centralise String‑to‑List and List‑to‑String conversion in a mapper.

public class MyDto { private String name; private String tags; }</code>
<code>public class MyEntity { private String name; private List<String> tags; }
@Mapper(componentModel = "spring")
public interface CommonMapper {
    @Named("stringToList")
    default List<String> stringToList(String source) {
        if (!StringUtils.hasText(source)) return new ArrayList<>();
        return Arrays.stream(source.split(","))
                     .map(String::trim)
                     .filter(StringUtils::hasText)
                     .collect(Collectors.toList());
    }
    @Named("listToString")
    default String listToString(List<String> source) {
        if (source == null || source.isEmpty()) return "";
        return String.join(",", source);
    }
}

Usage in a service demonstrates the conversion results:

@Service
public class CommonService {
    private final CommonMapper commonMapper;
    public CommonService(CommonMapper commonMapper) { this.commonMapper = commonMapper; }
    public void action() {
        List<String> list = commonMapper.stringToList("a, b, c");
        System.err.println(list);
        String str = commonMapper.listToString(Arrays.asList("x", "y", "z"));
        System.err.println(str);
    }
}
[a, b, c]
 x,y,z

2. Embedded collection usage

When a simple tag list or email list does not warrant a separate association table, an @Embeddable combined with a JPA AttributeConverter can store a Set<String> in a single column.

@Embeddable
public class EmailEmbeddable {
    private String value;
    public EmailEmbeddable() {}
    public EmailEmbeddable(Set<String> values) {
        if (values == null) { this.value = null; }
        else {
            Set<String> validated = values.stream()
                .filter(StringUtils::hasText)
                .map(String::trim)
                .collect(Collectors.toSet());
            this.value = String.join(",", validated);
        }
    }
    public Set<String> getValues() {
        if (!StringUtils.hasText(value)) return new HashSet<>();
        return Arrays.stream(value.split(","))
                     .map(String::trim)
                     .filter(StringUtils::hasText)
                     .collect(Collectors.toSet());
    }
}
@Entity
@Table(name = "x_customer")
public class Customer {
    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    @Embedded
    private EmailEmbeddable emails;
}

The resulting table (illustrated in the original image) stores the email set in a single column.

Embedded collection table
Embedded collection table

3. Internationalization helper

Injecting MessageSource in every service and handling LocaleContextHolder manually is cumbersome. A static‑or‑bean‑based helper simplifies i18n.

@Component
public class MessageHelper {
    private final MessageSource messageSource;
    public MessageHelper(MessageSource messageSource) { this.messageSource = messageSource; }
    public String getMessage(String code, Object... args) {
        return messageSource.getMessage(code, args, LocaleContextHolder.getLocale());
    }
    public String getMessageOrDefault(String code, String defaultMsg, Object... args) {
        return messageSource.getMessage(code, args, defaultMsg, LocaleContextHolder.getLocale());
    }
}

4. Secure random string generator

For temporary passwords, reference numbers or API tokens, a generator based on SecureRandom provides cryptographic safety.

@Component
public class RandomUtil {
    private static final SecureRandom SECURE_RANDOM = new SecureRandom();
    private static final String ALPHANUMERIC = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
    public static String generateReference(int length) {
        StringBuilder sb = new StringBuilder(length);
        for (int i = 0; i < length; i++) {
            sb.append(ALPHANUMERIC.charAt(SECURE_RANDOM.nextInt(ALPHANUMERIC.length())));
        }
        return sb.toString();
    }
    public static String generateToken() {
        byte[] randomBytes = new byte[24];
        SECURE_RANDOM.nextBytes(randomBytes);
        return Base64.getUrlEncoder().withoutPadding().encodeToString(randomBytes);
    }
}

5. Domain‑specific runtime exceptions

Creating a hierarchy of runtime exceptions allows @ControllerAdvice to return precise HTTP status codes.

// 404 – resource not found
public class ResourceNotFoundException extends RuntimeException {
    public ResourceNotFoundException(String resourceName, String fieldName, Object fieldValue) {
        super(String.format("%s not found with %s : '%s'", resourceName, fieldName, fieldValue));
    }
}
// 409 – duplicate resource
public class DuplicateResourceException extends RuntimeException {
    public DuplicateResourceException(String message) { super(message); }
}
@Service
@RequiredArgsConstructor
public class UserService {
    private final UserRepository userRepository;
    public User getUserById(Long id) {
        return userRepository.findById(id)
            .orElseThrow(() -> new ResourceNotFoundException("User", "id", id));
    }
    public User createUser(User user) {
        if (userRepository.existsByEmail(user.getEmail())) {
            throw new DuplicateResourceException("Email already registered: " + user.getEmail());
        }
        return userRepository.save(user);
    }
}
@RestControllerAdvice
public class GlobalExceptionHandler {
    @ExceptionHandler(ResourceNotFoundException.class)
    public ResponseEntity<ErrorResponse> handleResourceNotFound(ResourceNotFoundException ex) {
        ErrorResponse error = new ErrorResponse("NOT_FOUND", ex.getMessage(), LocalDateTime.now());
        return new ResponseEntity<>(error, HttpStatus.NOT_FOUND);
    }
    @ExceptionHandler(DuplicateResourceException.class)
    public ResponseEntity<ErrorResponse> handleDuplicateResource(DuplicateResourceException ex) {
        ErrorResponse error = new ErrorResponse("CONFLICT", ex.getMessage(), LocalDateTime.now());
        return new ResponseEntity<>(error, HttpStatus.CONFLICT);
    }
}

6. Type‑safe configuration properties

Instead of using primitive int or long for timeouts and file sizes, Spring Boot’s @ConfigurationProperties supports Duration and DataSize, making application.yml self‑documenting.

@Configuration
@ConfigurationProperties(prefix = "pack.app.upload")
public class UploadConfig {
    private Duration timeout = Duration.ofSeconds(30);
    private DataSize maxFileSize = DataSize.ofMegabytes(10);
}
pack:
  app:
    upload:
      timeout: 10s
      maxFileSize: 10MB

7. Automatic auditing

Using a @MappedSuperclass with @CreatedDate, @LastModifiedDate, @CreatedBy and @LastModifiedBy lets JPA automatically populate audit fields.

@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public abstract class AuditValue {
    @CreatedDate @Column(updatable = false) protected LocalDateTime createdAt;
    @LastModifiedDate protected LocalDateTime modifiedAt;
    @CreatedBy @Column(updatable = false) protected String createdBy;
    @LastModifiedBy protected String modifiedBy;
}
@Entity @Table(name = "t_name")
public class Product extends AuditValue { }
@Configuration
@EnableJpaAuditing(auditorAwareRef = "auditorAware")
public class JpaConfig {
    @Bean
    public AuditorAware<String> auditorAware() {
        // In a real project obtain the user from SecurityContext
        return () -> Optional.of("SYSTEM");
    }
}

8. Annotation‑based custom validation

Spring’s built‑in @Valid constraints sometimes lack the needed expressiveness. A custom @ValueOfEnum annotation validates that a String matches a specific enum.

@Target({ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Constraint(validatedBy = ValueOfEnumValidator.class)
public @interface ValueOfEnum {
    Class<? extends Enum<?>> enumClass();
    String message() default "must be a valid {enumClass} value";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}
public class ValueOfEnumValidator implements ConstraintValidator<ValueOfEnum, CharSequence> {
    private List<String> acceptedValues;
    @Override
    public void initialize(ValueOfEnum annotation) {
        acceptedValues = Stream.of(annotation.enumClass().getEnumConstants())
            .map(Enum::name)
            .collect(Collectors.toList());
    }
    @Override
    public boolean isValid(CharSequence value, ConstraintValidatorContext context) {
        if (value == null) return true; // let @NotNull handle nulls
        return acceptedValues.contains(value.toString().toUpperCase());
    }
}
@ValueOfEnum(enumClass = OrderStatus.class, message = "Invalid status")
private String status;
Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

validationSpring Bootmapstructi18ncustom-exceptionconfiguration-propertiesjpa-auditingsecure-random
Spring Full-Stack Practical Cases
Written by

Spring Full-Stack Practical Cases

Full-stack Java development with Vue 2/3 front-end suite; hands-on examples and source code analysis for Spring, Spring Boot 2/3, and Spring Cloud.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.