Streamline Spring Service Parameter Validation with AOP and Bean Validation
This article explains how to simplify Spring service method parameter checks by encapsulating inputs in POJOs, applying bean‑validation annotations, and using a custom AOP aspect or standard @AssertTrue to automatically enforce validation logic.
Background
First, we agree that a service method with many non‑POJO parameters can be cumbersome; it's better to encapsulate parameters in a POJO.
@Data
public class UserVo {
private String username;
private Integer age;
private List<String> hobby;
}Methods should validate inputs; simple generic checks (non‑empty strings, numeric ranges) should not be written inside the method body.
@Service
public class UserService {
public void addUser(UserVo userVo) {
// basic validation
if (StringUtils.isEmpty(userVo.getUsername())
|| userVo.getAge() < 0
|| userVo.getAge() > 200
|| CollectionUtils.isEmpty(userVo.getHobby())) {
throw new IllegalArgumentException();
}
// business logic
}
}Our project uses the Spring framework; service beans are invoked by callers.
Implementation Idea
Using Spring AOP we can intercept method calls, obtain arguments, and perform validation.
A common approach is to use Java bean‑validation annotations (e.g., Hibernate Validator) on POJOs, which Spring MVC already supports.
@Data
public class UserVo {
@NotEmpty
private String username;
@Max(200)
@Min(1)
private Integer age;
@NotEmpty
private List<String> hobby;
}Expose simple methods; keep POJO attributes concise with necessary comments.
We aim to extract repetitive validation logic into an aspect; different POJOs have different fields, so validation logic varies. Without annotation‑based validation, the aspect would need many instanceof checks or design‑pattern tricks.
Alternatively, place validation logic inside the POJO itself.
Specific Implementation
1. Define validation interface
public interface ValidationHandler {
/**
* Validate POJO properties
* @return true if valid, false otherwise
*/
boolean isValid();
}2. POJO implements the interface
@Data
public class UserVo implements ValidationHandler {
private String username;
private Integer age;
private List<String> hobby;
@Override
public boolean isValid() {
return StringUtils.isNotEmpty(username)
&& age > 0
&& age < 100
&& !hobby.isEmpty();
}
}3. Aspect
Define annotation @ParamValidation as pointcut.
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ParamValidation { }Use it on service methods.
@Service
public class UserService {
@ParamValidation
public void addUser(UserVo userVo) {
// business logic
}
}Aspect code that checks each argument implementing ValidationHandler and throws IllegalArgumentException if invalid.
@Component
@Aspect
public class ParamValidator {
@Pointcut("@annotation(com.ex.validator.ParamValidation)")
public void validate() { }
@Before("validate()")
public void before(JoinPoint joinPoint) {
for (Object arg : joinPoint.getArgs()) {
if (arg instanceof ValidationHandler) {
if (!((ValidationHandler) arg).isValid()) {
throw new IllegalArgumentException("参数校验不通过");
}
}
}
}
}4. Result
Calling the method triggers AOP validation.
Upgrade Version
Using standard bean‑validation annotations like @AssertTrue on a custom method (named isValid) can replace the custom interface and aspect.
@Data
public class UserVo {
private String username;
private Integer age;
private List<String> hobby;
@AssertTrue
public boolean isValid() {
return StringUtils.isNotEmpty(username)
&& age > 0
&& age < 100
&& !hobby.isEmpty();
}
}Service method simply uses @Validated and @Valid on the POJO.
@Validated
@Service
public class UserService {
public void addUser(@Valid UserVo userVo) {
// business logic
}
}The validation effect is the same.
Source: https://www.cnblogs.com/flylinran/p/10171485.html
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
ITFLY8 Architecture Home
ITFLY8 Architecture Home - focused on architecture knowledge sharing and exchange, covering project management and product design. Includes large-scale distributed website architecture (high performance, high availability, caching, message queues...), design patterns, architecture patterns, big data, project management (SCRUM, PMP, Prince2), product design, and more.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
