🚩오전 :
페이징, 검색 : 상품목록 : 조건 - 상품분류, 상품 거래처, 상품 이름 - 상세검색
🚩오후 : 어떻게 검증을 없애고, H/V을 사용할 것인가
검증도구 중 H/V 선택한 이유 : simple(어노테이션사용) , 범용성(spring)
<< H/V 사이트 >>
https://hibernate.org/validator/
The Bean Validation reference implementation. - Hibernate Validator
Express validation rules in a standardized way using annotation-based constraints and benefit from transparent integration with a wide variety of frameworks.
hibernate.org
메이븐 프로젝트를 사용하기 있기 때문에 dependency만 가져와서 pom.xml에 설치하면 아래와 같이 파일이 추가된 것을 볼 수 있다.
이렇게 javax로 되어있는 패키지는 자바에서 기본적으로 사용하는 패키지라고 생각하면 될 것 같다.
https://desperategirl.tistory.com/37
2020-02-17 javax의 정의
자바의 초기버전인 1.02와 1.1에서는 자바에 내장된 클래스가 모두 java로 시작한는 이름을 가진 패키지에 들어있었습니다. 하지만 표준 라이브러리에 속하지 않는 다른 다양한 패키지가 등장하기
desperategirl.tistory.com
H/V는 어노테이션의 형태로 사용한다.
H/V는 DB 의 제약사항을 Domain Layer에 적용시켜 검증을 위한 처리를 하는 도구이다.
private int rnum;
@NotBlank(groups = InsertGroup.class)
private String memId;
@NotBlank(groups = {Default.class, DeleteGroup.class})
@JsonIgnore
private transient String memPass;
@NotBlank(groups = InsertGroup.class)
private String memName;
@Size(min = 6, max = 6)
@JsonIgnore
private transient String memRegno1;
@Size(min = 7, max = 7)
@JsonIgnore
private transient String memRegno2;
// private Timestamp memBir;
private LocalDateTime memBir; //UTC방식
@NotBlank
private String memZip;
@NotBlank
private String memAdd1;
@NotBlank
private String memAdd2;
@Pattern(regexp = "\\d{2,3}-\\d{3,4}-\\d{4}")
private String memHometel;
@Pattern(regexp = "\\d{2,3}-\\d{3,4}-\\d{4}")
private String memComtel;
@Pattern(regexp = "010-\\d{3,4}-\\d{4}")
private String memHp;
@NotBlank //마크 어노테이션
@Email
private String memMail;
private String memJob;
private String memLike;
private String memMemorial;
// private Date memMemorialday;
private LocalDate memMemorialday; //UTC방식
@Min(0) // single value 어노테이션
private Integer memMileage;
private boolean memDelete;
}
@NotBlank : not null
@Pattern : 정규식으로 패턴을 설정할 수 있다.
@Email : 이메일 양식을 검증할 수 있다.
@NoBlank (groups = {}) : 그룹힌트. 사용될 디폴트 그룹을 설정하고 특정 그룹은 이 그룹어노테이션으로 설정해줄 수도있다.
⛑️마커인터페이스 : body가 없고 인터페이스만 생성한 것. ex)serializable
약간... omr카드에 마킹하듯이 그냥 표시한다는 느낌인 것 같다.
왜냐하면 insertGroup이름으로 마커 인터페이스 만들었는데, 디폴트 그룹으로 설정하기 위해서 그냥 표시만하는 용도로 사용중이다.
// 정말 이 코드가 끝이다.
public interface InsertGroup extends Default{}
저렇게 Default를 상속받아서 기본 그룹으로 설정한다.
그리고 도메인 레이어에서 이 그룹힌트를 주지 않으면 Default를 상속받은 그룹에서만 사용한다는 뜻이고, 설정을 새로 해준다면 그 설정한 그룹에서만 사용한다는 것이다.
public class ValidateUtils {
// 검증도구 Validator 선언
private static Validator validator;
// class가 로딩되고 제일 먼저 자동으로 실행되는 유일한 static블럭
static {
//Factory method pattern으로 공장 생성.
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
validator = factory.getValidator();
}
// Generic타입(<T>)으로 생성하여 여러 곳에서 사용할 수 있도록 한다.
// 결과를 참과 거짓으로 리턴 받는다.
// 파라미터로 target을 받고
// 하나의 대상에 여러 에러메세지들을 담을 Map<String, List<String>>을 받고
// 어느 상황에 사용할지 groupHints들을 받는다.
public static <T> boolean validate(T target, Map<String, List<String>> errors, Class<?>...groupHints){
Set<ConstraintViolation<T>> violations = validator.validate(target, groupHints);
// 에러 메세지가 비어있다면? 검증에 통과한것.
boolean valid = violations.isEmpty();
//통과하지 못했다면
if(! valid){
// 반복문 안에서 키와 메세지로 나누어 받아 리스트에 추가한다.
for( ConstraintViolation<T> single: violations) {
String propertyName = single.getPropertyPath().toString();
String message = single.getMessage();
// 이미 리스트가 있는지 확인하는 작업
List<String> already = errors.get(propertyName);
// 아직 없다면 새로 생성
if(already==null) {
already = new ArrayList<>();
}
already.add(message);
errors.put(propertyName, already);
}
}
//결과 리턴
return valid;
}
먼저 계속 반복되는 검증 내용을 Util로 만들어보자.
//update할때 사용한 예
Map<String, List<String>> errors = new LinkedHashMap<>();
req.setAttribute("errors", errors);
ValidateUtils.validate(buyer, errors, UpdateGroup.class);
일단, validator를 이용하여 검증을 하면 에러 메세지가 나오는데 하나의 데이터에 여러 검증 항목과 메세지가 있을 수 있으므로 키를 String, 값을 List로 하는 Map을 생성한다.
그리고 미리 만들어 놓은 ValidateUtils의 validate에 조건에 맞는 인수들을 넣어 실행한다. update를 할 것이므로 updateGroup.class를 넣는데, 이렇게 되면 Default그룹인 대상들이랑 updateGroup대상들이 검증된다.
💊어노테이션 문법구조 ( 3가지 )
- 마커 어노테이션(속성들이 기본값)
- 멀티벨류 어노테이션(속성이름 생략 불가)
- 싱글벨류 어노테이션(속성의 이름이 value일때만, 생략가능)
Call By Reference / Call By Value
참조 주소 호출 / 값 호출
BuyerVO buyer = new BuyerVO();
req.setAttribute("buyer", buyer);
BuyerVO의 참조 주소를 호출하여 그 주소의 값을 변경할 수 있다.
< 내일 지영씨한테 자세히 더 물어보기 !! >
https://www.tutorialspoint.com/index.htm
Online Tutorials Library
1.2 M+ Certificates Delivered
www.tutorialspoint.com
자바 공부하기
스프링과 자바 공부하기
오늘의 과제 : 스프링 관련 다이어그램 보기
📖시퀀스 다이어그램
📖클래스 다이어그램
'내가 보려고 정리하는 > Spring' 카테고리의 다른 글
웹 : D.F.P으로 필터 만들어보기 : 0331 (0) | 2023.03.31 |
---|---|
웹 : 필터와 이진데이터, 보안 : 0330 (0) | 2023.03.30 |
웹 : 페이징, 검색: 0328 (0) | 2023.03.28 |
웹 : DomainLayer myBatis 적용 : 0327 (0) | 2023.03.27 |
웹 : 0324 (0) | 2023.03.24 |