1. 개요

검증은 우리가 기대하는 것만 큼 간단하지 않습니다. 물론 사용자가 애플리케이션에 입력 한 값의 유효성을 검사하는 것은 데이터의 무결성을 유지하는 데 매우 중요합니다.

웹 애플리케이션의 맥락에서 데이터 입력은 일반적으로 HTML 양식을 사용하여 수행되며 클라이언트 측 및 서버 측 유효성 검사가 모두 필요합니다.

이 예제에서는 AngularJS를 사용하여 양식 입력의 클라이언트 측 유효성 검사구현하고 Spring MVC 프레임 워크를 사용하여 서버 측 유효성 검사구현 하는 방법을 살펴 봅니다 .

이 기사는 Spring MVC에 중점을 둡니다. Spring Boot의 유효성 검사 기사  에서는 Spring Boot에서 유효성 검사  를 수행하는 방법을 설명합니다.

2. Maven 의존성

시작하려면 다음 의존성을 추가해 보겠습니다.

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>4.3.7.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>5.4.0.Final</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.8.7</version>
</dependency>

Spring-webmvc , hibernate-validatorjackson-databind 의 최신 버전은 Maven Central에서 다운로드 할 수 있습니다.

3. Spring MVC를 사용한 유효성 검사

응용 프로그램은 쉽게 피할 수 있으므로 클라이언트 측 유효성 검사에만 의존해서는 안됩니다. 부정확하거나 악의적 인 값이 저장되거나 애플리케이션 로직이 부적절하게 실행되는 것을 방지하려면 서버 측에서도 입력 값의 유효성을 검사하는 것이 중요합니다.

Spring MVC는 JSR 349 ​​Bean Validation 사양 어노테이션 을 사용하여 서버 측 유효성 검증을 지원합니다 . 이 예에서는 hibernate-validator 인 사양의 참조 구현을 사용합니다 .

3.1. 데이터 모델

적절한 유효성 검사 어노테이션으로 어노테이션이 달린 속성이 있는 User 클래스를 만들어 보겠습니다 .

public class User {

    @NotNull
    @Email
    private String email;

    @NotNull
    @Size(min = 4, max = 15)
    private String password;

    @NotBlank
    private String name;

    @Min(18)
    @Digits(integer = 2, fraction = 0)
    private int age;

    // standard constructor, getters, setters
}

위에서 사용 된 어노테이션은 hibernate-validator 라이브러리에 특정한 @Email@NotBlank를 제외 하고 JSR 349 사양에 속합니다 .

3.2. Spring MVC 컨트롤러

User 객체를 List 에 저장하는 데 사용할 / user 끝점 을 정의하는 컨트롤러 클래스를 만들어 보겠습니다 .

요청 매개 변수를 통해 수신 User 객체의 유효성 검사를 활성화 하려면 선언 앞에 @Valid 어노테이션 이 와야 하며 유효성 검사 오류는 BindingResult 인스턴스에 보관됩니다 .

객체에 잘못된 값이 포함되어 있는지 확인하려면 BindingResulthasErrors () 메서드를 사용할 수 있습니다 .

경우 hasErrors () 반환 사실 , 우리는 반환 할 수 있습니다 JSON 배열 통과하지 못한 검증과 관련된 오류 메시지를 포함합니다. 그렇지 않으면 List에 개체를 추가합니다.

@PostMapping(value = "/user")
@ResponseBody
public ResponseEntity<Object> saveUser(@Valid User user, 
  BindingResult result, Model model) {
    if (result.hasErrors()) {
        List<String> errors = result.getAllErrors().stream()
          .map(DefaultMessageSourceResolvable::getDefaultMessage)
          .collect(Collectors.toList());
        return new ResponseEntity<>(errors, HttpStatus.OK);
    } else {
        if (users.stream().anyMatch(it -> user.getEmail().equals(it.getEmail()))) {
            return new ResponseEntity<>(
              Collections.singletonList("Email already exists!"), 
              HttpStatus.CONFLICT);
        } else {
            users.add(user);
            return new ResponseEntity<>(HttpStatus.CREATED);
        }
    }
}

보시다시피 서버 측 유효성 검사는 클라이언트 측에서는 불가능한 추가 검사를 수행 할 수있는 기능을 추가합니다.

우리의 경우 동일한 이메일을 가진 사용자가 이미 존재하는지 확인할 수 있으며,이 경우 상태 409 CONFLICT를 반환합니다.

또한 사용자 List을 정의하고 몇 가지 값으로 초기화해야합니다.

private List<User> users = Arrays.asList(
  new User("ana@yahoo.com", "pass", "Ana", 20),
  new User("bob@yahoo.com", "pass", "Bob", 30),
  new User("john@yahoo.com", "pass", "John", 40),
  new User("mary@yahoo.com", "pass", "Mary", 30));

사용자 List을 JSON 개체로 검색하기위한 매핑도 추가해 보겠습니다.

@GetMapping(value = "/users")
@ResponseBody
public List<User> getUsers() {
    return users;
}

Spring MVC 컨트롤러에서 필요한 마지막 항목은 애플리케이션의 메인 페이지를 반환하는 매핑입니다.

@GetMapping("/userPage")
public String getUserProfilePage() {
    return "user";
}

우리는 한 번 봐 걸릴 것 user.html의 AngularJS와 섹션에서 더 자세히 페이지를.

3.3. Spring MVC 구성

애플리케이션에 기본 MVC 구성을 추가해 보겠습니다.

@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "com.baeldung.springmvcforms")
class ApplicationConfiguration implements WebMvcConfigurer {

    @Override
    public void configureDefaultServletHandling(
      DefaultServletHandlerConfigurer configurer) {
        configurer.enable();
    }

    @Bean
    public InternalResourceViewResolver htmlViewResolver() {
        InternalResourceViewResolver bean = new InternalResourceViewResolver();
        bean.setPrefix("/WEB-INF/html/");
        bean.setSuffix(".html");
        return bean;
    }
}

3.4. 응용 프로그램 초기화

애플리케이션을 실행하기 위해 WebApplicationInitializer 인터페이스를 구현하는 클래스를 만들어 보겠습니다 .

public class WebInitializer implements WebApplicationInitializer {

    public void onStartup(ServletContext container) throws ServletException {

        AnnotationConfigWebApplicationContext ctx
          = new AnnotationConfigWebApplicationContext();
        ctx.register(ApplicationConfiguration.class);
        ctx.setServletContext(container);
        container.addListener(new ContextLoaderListener(ctx));

        ServletRegistration.Dynamic servlet 
          = container.addServlet("dispatcher", new DispatcherServlet(ctx));
        servlet.setLoadOnStartup(1);
        servlet.addMapping("/");
    }
}

3.5. Curl을 사용하여 Spring Mvc 유효성 검사 테스트

AngularJS 클라이언트 섹션을 구현하기 전에 다음 명령과 함께 cURL을 사용하여 API를 테스트 할 수 있습니다.

curl -i -X POST -H "Accept:application/json" 
  "localhost:8080/spring-mvc-forms/user?email=aaa&password=12&age=12"

응답은 기본 오류 메시지가 포함 된 배열입니다.

[
    "not a well-formed email address",
    "size must be between 4 and 15",
    "may not be empty",
    "must be greater than or equal to 18"
]

4. AngularJS 검증

클라이언트 측 유효성 검사는 유효한 데이터를 성공적으로 제출하는 방법에 대한 정보를 사용자에게 제공하고 애플리케이션과 계속 상호 작용할 수 있도록하므로 더 나은 사용자 경험을 만드는 데 유용합니다.

AngularJS 라이브러리는 양식 필드에 유효성 검사 요구 사항을 추가하고, 오류 메시지를 처리하고, 유효하고 잘못된 양식을 스타일링하는 데 큰 지원을 제공합니다.

먼저 유효성 검사 메시지에 사용되는 ngMessages 모듈 을 삽입하는 AngularJS 모듈을 만들어 보겠습니다 .

var app = angular.module('app', ['ngMessages']);

다음으로, 이전 섹션에서 빌드 한 API를 사용할 AngularJS 서비스와 컨트롤러를 만들어 보겠습니다.

4.1. AngularJS 서비스

우리 서비스에는 MVC 컨트롤러 메서드를 호출하는 두 가지 메서드가 있습니다. 하나는 사용자를 저장하고 다른 하나는 사용자 List을 검색합니다.

app.service('UserService',['$http', function ($http) {
	
    this.saveUser = function saveUser(user){
        return $http({
          method: 'POST',
          url: 'user',
          params: {email:user.email, password:user.password, 
            name:user.name, age:user.age},
          headers: 'Accept:application/json'
        });
    }
	
    this.getUsers = function getUsers(){
        return $http({
          method: 'GET',
          url: 'users',
          headers:'Accept:application/json'
        }).then( function(response){
        	return response.data;
        } );
    }

}]);

4.2. AngularJS 컨트롤러

UserCtrl의 제어기이 주입 UserService는 서비스 방법 및 처리 응답하여 에러 메시지를 호출

app.controller('UserCtrl', ['$scope','UserService', function ($scope,UserService) {
	
	$scope.submitted = false;
	
	$scope.getUsers = function() {
		   UserService.getUsers().then(function(data) {
		       $scope.users = data;
	       });
	   }
    
    $scope.saveUser = function() {
    	$scope.submitted = true;
    	  if ($scope.userForm.$valid) {
            UserService.saveUser($scope.user)
              .then (function success(response) {
                  $scope.message = 'User added!';
                  $scope.errorMessage = '';
                  $scope.getUsers();
                  $scope.user = null;
                  $scope.submitted = false;
              },
              function error(response) {
                  if (response.status == 409) {
                    $scope.errorMessage = response.data.message;
            	  }
            	  else {
                    $scope.errorMessage = 'Error adding user!';
            	  }
                  $scope.message = '';
            });
    	  }
    }
   
   $scope.getUsers();
}]);

위의 예 에서 userForm$ valid 속성 이 true 인 경우에만 서비스 메서드가 호출되는 것을 볼 수 있습니다 . 그래도이 경우 중복 이메일에 대한 추가 검사가 있는데, 이는 서버에서만 수행 할 수 있으며 error () 함수 에서 별도로 처리됩니다 .

또한 양식이 제출되었는지 여부를 알려주 제출 된 변수가 정의되어 있습니다.

처음에이 변수는 false 이고 saveUser () 메서드 를 호출 하면 true가 됩니다. 사용자가 양식을 제출하기 전에 유효성 검사 메시지를 표시하지 않으려면 제출 된 변수를 사용하여 이를 방지 할 수 있습니다 .

4.3. AngularJS 유효성 검사를 사용한 양식

AngularJS 라이브러리와 AngularJS 모듈을 사용하려면 user.html 페이지에 스크립트를 추가해야 합니다.

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js">
</script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.0/angular-messages.js">
</script>
<script src="js/app.js"></script>

그런 다음 ng-appng-controller 속성 을 설정하여 모듈과 컨트롤러를 사용할 수 있습니다 .

<body ng-app="app" ng-controller="UserCtrl">

HTML 양식을 만들어 보겠습니다.

<form name="userForm" method="POST" novalidate 
  ng-class="{'form-error':submitted}" ng-submit="saveUser()" >
...
</form>

기본 HTML5 유효성 검사를 방지하고이를 우리 자신의 것으로 대체하려면 양식에 novalidate 속성 을 설정해야합니다 .

NG 수준의 속성은 추가 폼 오류 경우 폼에 동적으로 CSS 클래스를 제출 변수의 값이 사실을 .

NG 제출 속성은 폼이 제출 될 때 호출 될 AngularJS와 컨트롤러 기능을 정의합니다. 사용하여 제출 NG 대신 ng를 클릭하면 그것은 또한 Enter 키를 사용하여 양식을 제출에 응답하는 장점이있다.

이제 사용자 속성에 대한 4 개의 입력 필드를 추가하겠습니다.

<label class="form-label">Email:</label>
<input type="email" name="email" required ng-model="user.email" class="form-input"/>

<label class="form-label">Password:</label>
<input type="password" name="password" required ng-model="user.password" 
  ng-minlength="4" ng-maxlength="15" class="form-input"/>

<label class="form-label">Name:</label>
<input type="text" name="name" ng-model="user.name" ng-trim="true" 
  required class="form-input" />

<label class="form-label">Age:</label>
<input type="number" name="age" ng-model="user.age" ng-min="18"
  class="form-input" required/>

각 입력 필드에는 ng-model 속성을 통해 사용자 변수 의 속성에 대한 바인딩이 있습니다.

유효성 검사 규칙을 설정 하기 위해 HTML5 필수 속성과 여러 AngularJS 관련 속성 ( ng-minglength, ng-maxlength, ng-minng-trim)을 사용 합니다.

를 들어 이메일 필드, 우리는 또한 사용 유형 의 값을 가진 속성 이메일 클라이언트 측 이메일 검증을.

각 필드에 해당하는 오류 메시지를 추가하기 위해 AngularJS는 입력의 $ errors 객체 를 반복 하고 각 유효성 검사 규칙에 따라 메시지를 표시 하는 ng-messages 지시문을 제공합니다 .

입력 정의 바로 뒤에 이메일 필드에 대한 지시문을 추가해 보겠습니다 .

<div ng-messages="userForm.email.$error" 
  ng-show="submitted && userForm.email.$invalid" class="error-messages">
    <p ng-message="email">Invalid email!</p>
    <p ng-message="required">Email is required!</p>
</div>

다른 입력 필드에 대해서도 유사한 오류 메시지를 추가 할 수 있습니다.

부울 표현식과 함께 ng-show 속성을 사용하여 이메일 필드에 대한 지시문이 표시 되는 시기를 제어 할 수 있습니다 . 이 예에서는 필드에 잘못된 값이있을 때 지시문을 표시합니다. 즉, $ invalid 속성이 true 이고 제출 된 변수도 true 입니다.

필드에 대해 한 번에 하나의 오류 메시지 만 표시됩니다.

$ valid 속성 에 따라 필드가 유효한 경우 입력 필드 뒤에 확인 표시 기호 (HEX 코드 문자 ✓로 표시됨)를 추가 할 수도 있습니다 .

<div class="check" ng-show="userForm.email.$valid"></div>

AngularJS 유효성 검사는 또한 ng-validng-invalid같은 CSS 클래스 또는 ng-invalid-requiredng-invalid-minlength같은보다 구체적인 CSS 클래스를 사용하여 스타일링을 지원합니다 .

양식의 양식 오류 클래스 내부에 잘못된 입력에 대해 CSS 속성 border-color : red추가해 보겠습니다 .

.form-error input.ng-invalid {
    border-color:red;
}

CSS 클래스를 사용하여 오류 메시지를 빨간색으로 표시 할 수도 있습니다.

.error-messages {
    color:red;
}

모든 것을 합친 후 유효한 값과 유효하지 않은 값을 혼합하여 채울 때 클라이언트 측 양식 유효성 검사가 어떻게 보이는지 예를 살펴 보겠습니다.

AngularJS 양식 유효성 검사 예제

5. 결론

이 예제에서는 AngularJS와 Spring MVC를 사용하여 클라이언트 측과 서버 측 검증을 결합하는 방법을 보여주었습니다.

항상 그렇듯이 예제의 전체 소스 코드는 GitHub 에서 찾을 수 있습니다 .

애플리케이션을 보려면 실행 한 후 / userPage URL에 액세스하십시오 .