Spring Boot 는 일반적인 인터페이스 매개 변수 검증 을 실현 합 니 다.
연유
현재 매개 변수 검사 에서 자주 사용 하 는 방법 은 실체 류 에 주 해 를 추가 하 는 것 이지 만 서로 다른 방법 에 대해 사용 하 는 검사 규칙 도 다르다.예 를 들 어 AccountVO 실체 가 있다.
public class AccountVO {
private String name; //
private Integer age; //
}
이러한 업무 가 존재 한다 고 가정 합 니 다.사용자 가 등록 할 때 이름과 나 이 를 기입 해 야 합 니 다.사용자 가 로그 인 할 때 이름 만 기입 하면 됩 니 다.그러면 검사 규칙 을 실체 류 에 더 하면 분명히 적합 하지 않다.그래서 한 가지 방법 등급 의 매개 변수 검 사 를 실현 하고 싶 었 습 니 다.같은 실체 매개 변수 에 대해 서로 다른 방법 으로 서로 다른 검사 규칙 을 응용 할 수 있 기 때문에 이 도 구 를 탄생 시 켰 고 일상적인 업무 에서 오래 사용 되 었 습 니 다.
소개 하 다.
먼저 사용 방식 을 살 펴 보 자.
@Service
public class TestImpl implements ITestService {
@Override
@Check({"name", "age"})
public void testValid(AccountVO vo) {
// ...
}
}
이 방법 에 있 는@Check 주 해 는 인자 AccountVO 의 name,age 속성 이 비어 있 으 면 안 된다 는 것 을 가리 키 고 있 습 니 다.비 어 있 는 검사 외 에 크기 판단,여부 등 검사 도 지원 합 니 다.
@Check({"id>=8", "name!=aaa", "title<10"})
기본 오류 정 보 는 필드,오류 원인 과 호출 방법 을 되 돌려 줍 니 다.예 를 들 어:
updateUserId must not null while calling testValid
id must >= 8 while calling testValid
name must != aaa while calling testValid
사용자 정의 오류 반환 정보 도 지원 합 니 다:
@Check({"title<=8: 8 , "})
public void testValid(TestPO po) {
// ...
}
검사 규칙 뒤에 다음 을 추가 하면 사용자 정의 정 보 를 쓰 면 기본 오류 정 보 를 바 꿉 니 다.PS:핵심 원 리 는 매개 변수 실체 에 있 는 필드 의 값 을 반사 적 으로 가 져 온 다음 에 규칙 에 따라 검증 하 는 것 입 니 다.그래서 현 재 는 하나의 매개 변수 만 포함 하 는 방법 을 지원 하고 매개 변 수 는 기본 유형 이 될 수 없습니다.
쓰다
spring-boot 에서 AOP 를 어떻게 사용 하 는 지 는 더 이상 설명 하지 않 고 AOP 의 핵심 코드 를 소개 합 니 다.
Maven 의존
spring-boot 의존 을 제외 하고 필요 한 제3자 의존 은 핵심 적 인 의존 이 아니 라 개인 습관 에 따라 취사선택 할 수 있 습 니 다.
<!-- -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.3.2</version>
</dependency>
<!-- -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.25</version>
</dependency>
사용자 정의 주석
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
/**
*
* Created by cipher on 2017/9/20.
*/
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RUNTIME)
public @interface Check {
// , : + + + , :id<10:ID 10
String[] value();
}
핵심 코드절단면 차단 을 통 해@Check 주해 의 인터페이스 방법 을 추 가 했 습 니 다.방법 이 실행 되 기 전에 매개 변수 검 사 를 실 행 했 습 니 다.잘못된 정보 가 있 으 면 바로 돌아 갑 니 다.
@Around(value = "@com.cipher.checker.Check") //
public Object check(ProceedingJoinPoint point) throws Throwable {
Object obj;
//
String msg = doCheck(point);
if (!StringUtils.isEmpty(msg)) {
//
throw new IllegalArgumentException(msg);
}
obj = point.proceed();
return obj;
}
핵심 적 인 검사 방법 은 doCheck 방법 에서 주요 원 리 는 주해 에 지 정 된 필드 이름과 검사 규칙 을 가 져 오고 매개 변수 실체 에 대응 하 는 필드 의 값 을 반사 적 으로 가 져 와 서 검사 하 는 것 입 니 다.
/**
*
*
* @param point ProceedingJoinPoint
* @return
*/
private String doCheck(ProceedingJoinPoint point) {
//
Object[] arguments = point.getArgs();
//
Method method = getMethod(point);
String methodInfo = StringUtils.isEmpty(method.getName()) ? "" : " while calling " + method.getName();
String msg = "";
if (isCheck(method, arguments)) {
Check annotation = method.getAnnotation(Check.class);
String[] fields = annotation.value();
Object vo = arguments[0];
if (vo == null) {
msg = "param can not be null";
} else {
for (String field : fields) {
//
FieldInfo info = resolveField(field, methodInfo);
//
Object value = ReflectionUtil.invokeGetter(vo, info.field);
//
Boolean isValid = info.optEnum.fun.apply(value, info.operatorNum);
msg = isValid ? msg : info.innerMsg;
}
}
}
return msg;
}
주요 논 리 는:필드 분석->필드 값 가 져 오기->검사 규칙 실행
내부 유지보수 매 거 진 클래스 입 니 다.관련 검사 작업 은 모두 안에서 지정 합 니 다.
/**
*
*/
enum Operator {
/**
*
*/
GREATER_THAN(">", CheckParamAspect::isGreaterThan),
/**
*
*/
GREATER_THAN_EQUAL(">=", CheckParamAspect::isGreaterThanEqual),
/**
*
*/
LESS_THAN("<", CheckParamAspect::isLessThan),
/**
*
*/
LESS_THAN_EQUAL("<=", CheckParamAspect::isLessThanEqual),
/**
*
*/
NOT_EQUAL("!=", CheckParamAspect::isNotEqual),
/**
*
*/
NOT_NULL("not null", CheckParamAspect::isNotNull);
private String value;
private BiFunction<Object, String, Boolean> fun;
Operator(String value, BiFunction<Object, String, Boolean> fun) {
this.value = value;
this.fun = fun;
}
}
편폭 때문에 여 기 는 모든 코드 를 일일이 펼 치지 않 습 니 다.관심 이 있 는 친 구 는 다음 주소 로 모든 소스 코드 를 얻 을 수 있 습 니 다.ciphermagic/java-learn/sandbox/checkerTODO
읽 어 주 셔 서 감사합니다. 좋아 하 는 친 구 는github에 좋아요 를 누 를 수 있 습 니 다.질문 이 있 거나 아래 에 메 시 지 를 남 겨 주세요.답장 을 기대 하 세 요.
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
[MeU] Hashtag 기능 개발➡️ 기존 Tag 테이블에 존재하지 않는 해시태그라면 Tag , tagPostMapping 테이블에 모두 추가 ➡️ 기존에 존재하는 해시태그라면, tagPostMapping 테이블에만 추가 이후에 개발할 태그 기반 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.