1. 개요
사용자 입력의 유효성을 검사 할 때 Spring Boot 는이 일반적이지만 중요한 작업에 대한 강력한 지원을 제공합니다.
Spring Boot는 사용자 정의 유효성 검사기와의 완벽한 통합을 지원하지만 유효성 검사를 수행하는 사실상의 표준 은 Bean 유효성 검사 프레임 워크 의 참조 구현 인 Hibernate Validator 입니다.
이 튜토리얼에서는 Spring Boot에서 도메인 객체의 유효성을 검사하는 방법을 살펴 보겠습니다 .
2. Maven 의존성
이 경우 기본 REST 컨트롤러를 구축하여 Spring Boot에서 도메인 객체의 유효성을 검사하는 방법을 배웁니다 .
컨트롤러는 먼저 도메인 개체를 가져온 다음 Hibernate Validator로 유효성을 검사하고 마지막으로 메모리 내 H2 데이터베이스에 유지합니다.
프로젝트의 의존성은 상당히 표준입니다.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.4.197</version>
<scope>runtime</scope>
</dependency>
위와 같이 REST 컨트롤러를 생성하는 데 필요하므로 pom.xml 파일 에 spring-boot-starter-web 을 포함 시켰 습니다. 또한 Maven Central 에서 최신 버전의 spring-boot-starter-jpa 및 H2 데이터베이스 를 확인하십시오.
Boot 2.3부터는 spring-boot-starter-validation 의존성 도 명시 적으로 추가해야합니다 .
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
3. 간단한 도메인 클래스
프로젝트의 의존성이 이미 배치 된 상태에서 다음으로 사용자를 모델링하는 역할을하는 예제 JPA 엔티티 클래스를 정의해야합니다.
이 클래스를 살펴 보겠습니다.
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
@NotBlank(message = "Name is mandatory")
private String name;
@NotBlank(message = "Email is mandatory")
private String email;
// standard constructors / setters / getters / toString
}
User 엔티티 클래스 의 구현은 실제로 매우 빈약하지만 Bean Validation의 제약 조건을 사용하여 이름 및 이메일 필드 를 제한하는 방법을 간단히 보여줍니다 .
단순화를 위해 @NotBlank 제약 조건 만 사용하여 대상 필드를 제한했습니다. 또한 message 속성으로 오류 메시지를 지정했습니다 .
따라서 Spring Boot가 클래스 인스턴스의 유효성을 검사 할 때 제한된 필드 는 null이 아니어야하며 잘린 길이는 0보다 커야합니다 .
또한 Bean Validation 은 @NotBlank 외에 많은 다른 편리한 제약 조건을 제공합니다 . 이를 통해 제한된 클래스에 다른 유효성 검사 규칙을 적용하고 결합 할 수 있습니다. 자세한 내용은 공식 Bean 유효성 검사 문서를 참조하십시오 .
사용자를 메모리 내 H2 데이터베이스에 저장하기 위해 SpringData JPA 를 사용할 것이므로 User 객체 에 대한 기본 CRUD 기능을 갖기위한 간단한 저장소 인터페이스도 정의해야 합니다.
@Repository
public interface UserRepository extends CrudRepository<User, Long> {}
4. REST 컨트롤러 구현
물론 User 객체의 제한된 필드에 할당 된 값을 가져올 수있는 레이어를 구현해야 합니다.
따라서 유효성을 검사하고 유효성 검사 결과에 따라 몇 가지 추가 작업을 수행 할 수 있습니다.
Spring Boot는 REST 컨트롤러 구현을 통해 복잡해 보이는 프로세스를 정말 간단 하게 만듭니다 .
REST 컨트롤러 구현을 살펴 보겠습니다.
@RestController
public class UserController {
@PostMapping("/users")
ResponseEntity<String> addUser(@Valid @RequestBody User user) {
// persisting the user
return ResponseEntity.ok("User is valid");
}
// standard constructors / other methods
}
A의 스프링 REST 컨텍스트 의 구현 ADDUSER () 방법은 매우 표준이다.
물론 가장 관련성이 높은 부분은 @Valid 어노테이션을 사용하는 것입니다 .
Spring Boot가 @Valid 어노테이션이 달린 인수를 찾으면 자동으로 기본 JSR 380 구현 인 Hibernate Validator를 부트 스트랩하고 인수의 유효성을 검사합니다.
대상 인수가 유효성 검사를 통과하지 못하면 Spring Boot는 MethodArgumentNotValidException 예외를 throw합니다 .
5. @ExceptionHandler 어노테이션
addUser () 메서드 에 전달 된 User 객체를 자동으로 확인하는 Spring Boot를 사용하는 것이 정말 편리하지만 이 프로세스의 누락 된 측면은 유효성 검사 결과를 처리하는 방법입니다.
@ExceptionHandler의 어노테이션은 우리가 하나의 방법으로 예외 지정 유형을 처리 할 수 있습니다.
따라서 유효성 검사 오류를 처리하는 데 사용할 수 있습니다.
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(MethodArgumentNotValidException.class)
public Map<String, String> handleValidationExceptions(
MethodArgumentNotValidException ex) {
Map<String, String> errors = new HashMap<>();
ex.getBindingResult().getAllErrors().forEach((error) -> {
String fieldName = ((FieldError) error).getField();
String errorMessage = error.getDefaultMessage();
errors.put(fieldName, errorMessage);
});
return errors;
}
처리 할 예외로 MethodArgumentNotValidException 예외를 지정 했습니다 . 결과적으로 Spring Boot는 지정된 User 객체가 유효하지 않을 때이 메소드를 호출합니다 .
이 메서드는 Map 에있는 각 유효하지 않은 필드의 이름 및 사후 유효성 검사 오류 메시지를 저장합니다 . 그런 다음 추가 처리를 위해 Map 을 JSON 표현으로 클라이언트에 다시 보냅니다 .
간단히 말해 REST 컨트롤러를 사용하면 다른 엔드 포인트에 대한 요청을 쉽게 처리하고, 사용자 개체를 확인 하고, JSON 형식으로 응답을 보낼 수 있습니다.
이 디자인은 Thymeleaf 와 같은 템플릿 엔진에서 Angular 와 같은 완전한 기능을 갖춘 JavaScript 프레임 워크에 이르기까지 여러 웹 계층을 통해 컨트롤러 응답을 처리 할 수있을만큼 유연 합니다.
6. REST 컨트롤러 테스트
통합 테스트 를 통해 REST 컨트롤러의 기능을 쉽게 테스트 할 수 있습니다 .
UserController 인스턴스 및 MockMvc 객체 와 함께 UserRepository 인터페이스 구현을 모의 / 자동 연결하기 시작하겠습니다 .
@RunWith(SpringRunner.class)
@WebMvcTest
@AutoConfigureMockMvc
public class UserControllerIntegrationTest {
@MockBean
private UserRepository userRepository;
@Autowired
UserController userController;
@Autowired
private MockMvc mockMvc;
//...
}
웹 레이어 만 테스트하기 때문에 @WebMvcTest 어노테이션을 사용합니다 . MockMvcRequestBuilders 및 MockMvcResultMatchers 클래스로 구현 된 정적 메서드 집합을 사용하여 요청 및 응답을 쉽게 테스트 할 수 있습니다.
이제 요청 본문에 전달 된 유효하고 잘못된 User 객체를 사용 하여 addUser () 메서드를 테스트 해 보겠습니다 .
@Test
public void whenPostRequestToUsersAndValidUser_thenCorrectResponse() throws Exception {
MediaType textPlainUtf8 = new MediaType(MediaType.TEXT_PLAIN, Charset.forName("UTF-8"));
String user = "{\"name\": \"bob\", \"email\" : \"bob@domain.com\"}";
mockMvc.perform(MockMvcRequestBuilders.post("/users")
.content(user)
.contentType(MediaType.APPLICATION_JSON_UTF8))
.andExpect(MockMvcResultMatchers.status().isOk())
.andExpect(MockMvcResultMatchers.content()
.contentType(textPlainUtf8));
}
@Test
public void whenPostRequestToUsersAndInValidUser_thenCorrectResponse() throws Exception {
String user = "{\"name\": \"\", \"email\" : \"bob@domain.com\"}";
mockMvc.perform(MockMvcRequestBuilders.post("/users")
.content(user)
.contentType(MediaType.APPLICATION_JSON_UTF8))
.andExpect(MockMvcResultMatchers.status().isBadRequest())
.andExpect(MockMvcResultMatchers.jsonPath("$.name", Is.is("Name is mandatory")))
.andExpect(MockMvcResultMatchers.content()
.contentType(MediaType.APPLICATION_JSON_UTF8));
}
}
또한 Postman 과 같은 무료 API 수명주기 테스트 애플리케이션을 사용하여 REST 컨트롤러 API 를 테스트 할 수 있습니다 .
7. 샘플 애플리케이션 실행
마지막으로 표준 main () 메서드를 사용하여 예제 프로젝트를 실행할 수 있습니다 .
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Bean
public CommandLineRunner run(UserRepository userRepository) throws Exception {
return (String[] args) -> {
User user1 = new User("Bob", "bob@domain.com");
User user2 = new User("Jenny", "jenny@domain.com");
userRepository.save(user1);
userRepository.save(user2);
userRepository.findAll().forEach(System.out::println);
};
}
}
예상대로 콘솔에 두 개의 User 개체가 인쇄되는 것을 볼 수 있습니다.
유효한 User 개체 를 사용하여 http : // localhost : 8080 / users 끝점에 대한 POST 요청 은 "User is valid" 문자열 을 반환합니다 .
마찬가지로 이름 과 이메일 값이 없는 User 개체가 있는 POST 요청 은 다음 응답을 반환합니다.
{
"name":"Name is mandatory",
"email":"Email is mandatory"
}
8. 결론
이 기사에서는 Spring Boot에서 유효성 검사를 수행하는 기본 사항을 배웠습니다 .
- https://docs.spring.io/spring-framework/docs/current/reference/html
- https://www.baeldung.com/spring-boot-bean-validation
'Java' 카테고리의 다른 글
Spring REST API + OAuth2 + Angular (0) | 2021.03.13 |
---|---|
Spring의 @Scheduled Annotation (0) | 2021.03.12 |
자바에서 HashMap 초기화 (0) | 2021.03.12 |
Spring @Value 사용방법(예제) (0) | 2021.03.12 |
스프링 부트 액추에이터 (0) | 2021.03.12 |