# Data Validation

X2BEE Framework에서 데이터 유효성 체크 방법을 설명합니다.

Bean Validation과 Custom Validator를 사용하여 유효성 체크를 구현하는 방법으로 데이터 통신에 사용되는 VO 개체나 특정 필드에 유효성 검증을 수행하는데 활용할 수 있습니다.

***

## 유효성 체크 방법

### Bean Validation

Alias 어노테이션으로 별칭 지정합니다. 데이터 통신을 VO로 함으로, jakarta.validation.constraints 패키지에서 제공하는 어노테이션을 VO 객체에 이용합니다.

{% code title="Group.java" %}

```java
package com.x2bee.api.bo.app.entity;

import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import org.apache.ibatis.type.Alias;
import com.x2bee.common.base.entity.AbstractEntity;
import lombok.Getter;
import lombok.Setter;

@Alias("group")
@Getter
@Setter
public class Group extends AbstractEntity {
    @NotNull
    String groupNo;

    @NotEmpty
    String groupName;
}
```

{% endcode %}

### @Valid 를 이용한 @RequestBody 에 대한 유효성 검증

{% code title="SampleController.java (excerpt)" %}

```java
public class SampleController {
    ...

    @PostMapping("")
    public Response<String> registerSample(@RequestBody @Valid Sample sample) throws InterruptedException {
        ...
    }

    ...
}
```

{% endcode %}

### @Validated 를 이용한 @PathVariable과 @RequestParam 에 대한 유효성 검증

{% code title="SampleController.java (excerpt)" %}

```java
@RestController
@Validated
public class SampleController {
    @GetMapping("/users/{email}")
    public String getUserInfoByEmail(@PathVariable("email") @Email String email) {
        ....
    }
}
```

{% endcode %}

## Custom Validator

jakarta.validation.constraints 패키지에서 제공되지 않는 validator를 구현하고자 하는 경우, 아래 방법으로 진행합니다.

### Custom annotation 생성

{% code title="LocaleConstraint.java" %}

```java
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 jakarta.validation.Constraint;
import jakarta.validation.Payload;

@Target({FIELD})
@Retention(RUNTIME)
@Constraint(validatedBy = LocaleValidator.class)
@Documented
public @interface LocaleConstraint {
    String message() default "Invalid Locale";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}
```

{% endcode %}

### Custom annotation을 처리할 Custom Validator 생성

{% code title="LocaleValidator.java" %}

```java
public class LocaleValidator implements ConstraintValidator<LocaleConstraint, String> {
    public static final List<String> locales = Arrays.asList("ko_KR", "en_US");

    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
        return value != null && locales.contains(value.toLowerCase());
    }
}
```

{% endcode %}

### Custom annotation @LocaleConstraint을 적용하여 유효성 검증

{% code title="Category.java" %}

```java
package com.plateer.x2co.api.prototype.entity;

import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotEmpty;
import lombok.Data;

@Data
public class Category {
    @NotEmpty
    private String catTpCd;

    @NotBlank
    private String siteNo;

    @NotEmpty
    private String dpmlNo;

    @NotEmpty
    @LocaleConstraint // 다음과 같이 어노테이션으로 적용
    private String dbLocaleLanguage;

    @NotEmpty
    private int maxLvl = 0;

    @NotEmpty
    private int minLvl = 0;
}
```

{% endcode %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://tech.x2bee.com/dev-guide/pjt-prepare/framework/data-validation.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
