인프런에서 백기선님의 스프링 프레임워크 핵심 기술 을 공부하며 개인적으로 정리한 글입니다.
Resource 추상화
애플리케이션에서 사용하는 리소스 인터페이스.
Resource
라는 인터페이스로 추상화 되어있으며, 기본적으로 java.net.URL
을 스프링 프레임워크에 맞게 추상화 한 것이다.
1) 주요 메쏘드
기본적으로 다음과 같은 메쏘드가 구현되어 있다.
InputStream getInputStream()
boolean exists()
boolean isOpen()
String getDescription()
2) 구현체
Resource
를 구체적으로 구현한 클래스는 다음과 같다.
UrlResource
java.net.URL
을 참고.http
,https
,ftp
,file
,jar
지원
ClassPathResource
- 클래스패스를 통해 가져온 리소스
- 지원하는 접두어가
classpath:
임
FileSystemResource
- 파일 시스템 경로를 통해 가져온 리소스
ServletContextResource
- 웹 애플리케이션 루트 경로를 통해 가져온 리소스
3) 리소스 읽어오기
실제로 리소스 구현체가 결정되는 것은 리소스 로더의 기능을 가지고 있는 ApplicationContext
의 타입에 따라 결정된다.
ClassPathXmlApplicationContext
->ClassPathResource
FileSystemXmlApplicationContext
->FileSystemResource
WebApplicationContext
->ServletContextResource
ApplicationContext
의 타입에 상관없이 리소스 타입을 결정하려면, java.net.URL
접두어 (+ classpath:
) 중 하나를 사용할 수 있다.
예를 들면 다음과 같다.
classpath:me/whiteship/config.xml
->ClassPathResource
file:///some/resource/path/config.xml
->FileSystemResource
그리고 실제로 이렇게 접두어를 통해서 직접 리소스 타입을 명시해주는게 좋다고 한다.
Validation 추상화
1) 방법 1
애플리케이션에서 사용하는 객체 검증용 인터페이스
Validator
라는 인터페이스로 추상화 되어있으며, 객체 내 속성 값이 null
인지, 0 이상의 값을 가지는 지 등등을 확인한다.Validator
를 구현하는 클래스는 직접 만들어야 하는데, 다음 예제를 보자.
먼저 검증 대상이 될 객체를 하나 만든다.
public class Event {
Integer id;
String title;
... getter and setter ...
}
검증을 수행할 객체를 Validator
로 구현한다.
import org.springframework.validation.Validator;
public class EventValidator implements Validator {
@Override
public boolean supports(Class<?> aClass) {
return Event.class.equals(aClass);
}
@Override
public void validate(Object o, Errors errors) {
ValidationUtils.rejectIfEmptyOrWhitespace(
errors,
"title",
"notEmpty",
"Empty title is not allowed");
}
}
validate
메쏘드안에서, ValidationUtils
의 메쏘드를 통해 어떤 검증할 지를 정한다.
위에서는 "공백인 경우, Reject" 하도록 검증했고, 검증할 속성은 title
, 에러 코드는 "notEmpty"
, 기본 에러메시지는 "Empty title is not allowed"
로 주었다.
이러한 정보는 errors
에 담기게 된다.
이제 Runner
를 통해 실제 검증작업을 수행해보자.
@Component
public class AppRunner implements ApplicationRunner {
@Override
public void run(ApplicationArguments args) throws Exception {
Event event = new Event();
EventValidator eventValidator = new EventValidator();
Errors errors = new BeanPropertyBindingResult(event, "event");
// event 를 eventValidator 로 검증하고, 결과가 errors 에 담김.
eventValidator.validate(event, errors);
// 에러가 있는지 확인하여 출력.
System.out.println(errors.hasErrors());
errors.getAllErrors().forEach(e -> {
// 각 에러에 대해 모든 에러 코드를 출력.
System.out.println("===== error code =====");
Arrays.stream(e.getCodes()).forEach(System.out::println);
// default 메시지도 출력
System.out.println(e.getDefaultMessage());
});
}
}
eventValidator.validate(event, errors)
와 같이 event
객체를 검증하면 된다. 이 과정 중에 생긴 에러코드들은 errors
에 담긴다.
위 Runner
를 실행하면 결과는 다음과 같다.
true
===== error code =====
notEmpty.event.title
notEmpty.title
notEmpty.java.lang.String
notEmpty
Empty title is not allowed
우리가 설정해준 에러 코드 notEmpty
말고도 기본적으로 제공되는 에러코드들도 같이 담겨져 있음을 알 수 있다.
2) 방법 2
스프링부트 2.0.5 이상 버전일 때 다음과 같은 어노테이션을 객체에 활용할 수 있다.
public class Event {
Integer id;
@NotEmpty
String title;
@Min(0)
int limit;
@Email
String email;
... getter and setter ...
}
또한 스프링 부트가 자동설정으로 Validator
를 등록해주기 때문에 별도의 Validator
를 만들 필요 없이 @Autowired
로 주입받아 사용하면 된다.
@Component
public class AppRunner implements ApplicationRunner {
// validator 는 스프링부트 통해 빈 등록이 되어져있고, 주입만 받으면 됨.
@Autowired
Validator validator;
@Override
public void run(ApplicationArguments args) throws Exception {
// 일부러 에러를 내기 위해 검증에 어긋나는 값들로 설정.
Event event = new Event();
event.setLimit(-1);
event.setEmail("aaaaa");
Errors errors = new BeanPropertyBindingResult(event, "event");
// event 를 validator 로 검증하고, 결과가 errors 에 담김.
validator.validate(event, errors);
// 에러가 있는지 확인하여 출력.
System.out.println(errors.hasErrors());
errors.getAllErrors().forEach(e -> {
// 각 에러에 대해 모든 에러 코드를 출력.
System.out.println("===== error code =====");
Arrays.stream(e.getCodes()).forEach(System.out::println);
// default 메시지도 출력
System.out.println(e.getDefaultMessage());
});
}
}
Runner
를 실행하면 다음과 같은 결과가 나온다.
true
===== error code =====
NotEmpty.event.title
NotEmpty.title
NotEmpty.java.lang.String
NotEmpty
반드시 값이 존재하고 길이 혹은 크기가 0보다 커야 합니다.
===== error code =====
Email.event.email
Email.email
Email.java.lang.String
Email
이메일 주소가 유효하지 않습니다.
===== error code =====
Min.event.limit
Min.limit
Min.int
Min
반드시 0보다 같거나 커야 합니다.
'더 나은 엔지니어가 되기 위해 > 지금은 안쓰는 자바' 카테고리의 다른 글
[더 자바] JVM 이해하기 (0) | 2020.02.21 |
---|---|
[스프링 프레임워크 핵심 기술] 데이터 바인딩 추상화 (0) | 2020.02.21 |
[스프링 프레임워크 핵심 기술] IoC 컨테이너 3 (0) | 2020.02.20 |
[스프링 프레임워크 핵심 기술] IoC 컨테이너 2 (0) | 2020.02.20 |
[스프링 프레임워크 핵심 기술] IoC 컨테이너 1 (0) | 2020.02.20 |