사용자 정의 애너테이션을 이용한 유효성 검사
앞서 배운 사용자 정의 애너테이션을 이용해서 도서 등록 시
도서 ID가 중복여부를 확인하는 유효성 검사를 작성해보도록 하겠습니다.
만약 중복된 ID라면 적절한 오류 메시지가 출력되도록 해보겠습니다.
messages.properties
src/main/resources 폴더에 있는 위 파일에 다음과 같이 내용을 추가로 작성해줍니다.
Pattern.NewBook.bookId = \uC720\uD6A8\uD558\uC9C0 \uC54A\uC740 \uB3C4\uC11CID\uC785\uB2C8\uB2E4(\uC22B\uC790\uB85C \uC870\uD569\uD558\uACE0 ISBN\uC73C\uB85C \uC2DC\uC791\uD558\uC138\uC694).
Size.NewBook.name = \uC720\uD6A8\uD558\uC9C0 \uC54A\uC740 \uB3C4\uC11C\uBA85\uC785\uB2C8\uB2E4(\uCD5C\uC18C 4\uC790\uC5D0\uC11C \uCD5C\uB300 50\uC790\uAE4C\uC9C0 \uC785\uB825\uD558\uC138\uC694).
Min.NewBook.unitPrice = \uC720\uD6A8\uD558\uC9C0 \uC54A\uC740 \uAC00\uACA9\uC785\uB2C8\uB2E4(0\uC774\uC0C1\uC758 \uC218\uB97C \uC785\uB825\uD558\uC138\uC694).
Digits.NewBook.unitPrice = \uC720\uD6A8\uD558\uC9C0 \uC54A\uC740 \uAC00\uACA9\uC785\uB2C8\uB2E4(\uC18C\uC218\uC810 2\uC790\uB9AC\uAE4C\uC9C0, 8\uC790\uB9AC\uAE4C\uC9C0 \uC785\uB825\uD558\uC138\uC694).
NotNull.NewBook.unitPrice = \uC720\uD6A8\uD558\uC9C0 \uC54A\uC740 \uAC00\uACA9\uC785\uB2C8\uB2E4(\uAC00\uACA9\uC744 \uC785\uB825\uD558\uC138\uC694).
BookId.NewBook.bookId = \uB3C4\uC11CID\uAC00 \uC774\uBBF8 \uC874\uC7AC\uD569\uB2C8\uB2E4.
BookId 애너테이션에 대한 오류 메시지를 작성하였습니다.
Book.java
Book 클래스에 bookId 속성에 애너테이션을 선언하여 줍니다.
package com.springmvc.domain;
import javax.validation.constraints.Digits;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;
import com.springmvc.validator.BookId;
import org.springframework.web.multipart.MultipartFile;
public class Book {
@BookId
@Pattern(regexp="ISBN[1-9]+")
private String bookId;
@Size(min=4, max=50)
private String name;
@Min(value=0)
@Digits(integer=8, fraction=2)
@NotNull
private int unitPrice;
private String author;
private String description;
private String publisher;
private String category;
private long unitsInStock;
private String releaseDate;
private String condition;
private MultipartFile bookImage;
public Book() {
super();
// TODO Auto-generated constructor stub
}
public Book(String bookId, String name, int unitPrice) {
super();
this.bookId = bookId;
this.name = name;
this.unitPrice = unitPrice;
}
public String getBookId() {
return bookId;
}
public void setBookId(String bookId) {
this.bookId = bookId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getUnitPrice() {
return unitPrice;
}
public void setUnitPrice(int unitPrice) {
this.unitPrice = unitPrice;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getPublisher() {
return publisher;
}
public void setPublisher(String publisher) {
this.publisher = publisher;
}
public String getCategory() {
return category;
}
public void setCategory(String category) {
this.category = category;
}
public long getUnitsInStock() {
return unitsInStock;
}
public void setUnitsInStock(long unitsInStock) {
this.unitsInStock = unitsInStock;
}
public String getReleaseDate() {
return releaseDate;
}
public void setReleaseDate(String releaseDate) {
this.releaseDate = releaseDate;
}
public String getCondition() {
return condition;
}
public void setCondition(String condition) {
this.condition = condition;
}
public MultipartFile getBookImage() {
return bookImage;
}
public void setBookImage(MultipartFile bookImage) {
this.bookImage = bookImage;
}
}
bookId 필드는 중복 여부를 위한 유효성 검사를 위해서 @BookId 애너테이션을 선언해줍니다.
BookId.java
com.springmvc.validator 패키지를 생성하여줍니다.
이 패키지에 다음과 같이 bookId 클래스를 생성하여줍니다.
package com.springmvc.validator;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import javax.validation.Constraint;
@Constraint(validatedBy=BookIdValidator.class)
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface BookId {
String message() default "";
Class<?>[] groups() default {};
Class<?>[] payload() default {};
}
@BookId에 대해서 Method, Field, Annotation_type을 정의하고 런타임때까지도 유지되도록 합니다.
유효성 검사는 BookIdValidator 클래스로 실시합니다.
유효성 검사를 하기 위해서는 도메인 클래스에 @BookId를 부여해주면 됩니다.
@BookId는 앞서 배운 필수 속성들을 모두 포함하고 있습니다. (message, groups, payload)
유효성 검사를 하고 오류 발생하면 앞서 리소스 파일에 작성한 메시지가 출력될 것입니다.
BookIdValidator.java
마찬가지로 com.springmvc.validator 패키지에 생성하여 줍니다.
package com.springmvc.validator;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import org.springframework.beans.factory.annotation.Autowired;
import com.springmvc.domain.Book;
import com.springmvc.exception.BookIdException;
import com.springmvc.service.BookService;
public class BookIdValidator implements ConstraintValidator<BookId, String>{
@Autowired
private BookService bookService;
public void initialize(BookId constraintAnnotation) {
}
public boolean isValid(String value, ConstraintValidatorContext context) {
Book book;
try {
book = bookService.getBookById(value);
} catch (BookIdException e) {
return true;
}
if (book != null) {
return false;
}
return true;
}
}
initialize() 메소드는 @BookId의 관련 정보를 읽어서 초기화 시키는 메소드입니다.
isValid() 메소드는 bookid 속성 값을 읽어서 유효성 검사를 실시합니다.
만약 그 값이 기존에 이미 있다라고 하면 BookIdException 예외가 발생하여 false 값을 넘길 것입니다.
false 값을 받으면 앞서 실습한 것과 마찬가지로 오류 메시지가 출력될 것입니다.
실행 결과
/books/add를 입력하여 도서 등록 페이지르 들어갑니다.
그 후 기존에 이미 존재하는 도서 ID를 입력해보겠습니다.
다음과 같이 오류 메시지가 출력되는 것을 확인할 수 있습니다.
'SPRING' 카테고리의 다른 글
[SPRING]#54 도서 쇼핑몰 구현 (유효성 검사7) (0) | 2024.02.17 |
---|---|
[SPRING]#53 도서 쇼핑몰 구현 (유효성 검사6) (0) | 2024.02.17 |
[SPRING]#51 도서 쇼핑몰 구현 (유효성 검사4) (0) | 2024.02.13 |
[SPRING]#50 도서 쇼핑몰 구현 (유효성 검사3) (0) | 2024.02.12 |
[SPRING]#49 도서 쇼핑몰 구현 (유효성 검사2) (0) | 2024.01.23 |