XML의 DTD나 스키마와 유사하게 json에도 스키마에 대한 표준적인 부분이 존재하고 있는데요(http://json-schema.org/), 스키마 포맷도 json 포맷입니다.
위의 예제 데이터에 대한 스키마를 작성하면 다음과 같이 작성할 수 있습니다.
스키마 포맷
- {
- "type": "object", // 루트 타입은 객체
- "properties": { // 속성 정의
- "contentsId": {
- "type": "string",
- "minLength": 1
- },
- "title": {
- "type": "string"
- },
- "metadata": {
- "type": "array",
- "items": {
- "$ref": "#/definitions/metadataItem" // definitions내의 정의 참조
- }
- }
- },
- "required": [ // 필수 속성
- "contentsId"
- ],
- "definitions": { // 루트 타입 외 타입 별도 정의
- "metadataItem": {
- "type": "object",
- "properties": {
- "propertyName": {
- "type": "string"
- },
- "propertyContent": {
- "type": "string"
- }
- },
- "required": [
- "propertyName",
- "propertyContent"
- ]
- }
- }
- }
위에 사용한 규칙 외에도 많은 규칙들이 있는데 몇 가지 예로 다음과 같은 것들이 있습니다.
- 값 pattern 체크 (pattern)
- 배열 내의 아이템 갯수 (minItems, maxItems)
- enum을 통한 값체크
- 여러 규칙 중 하나를 만족하는 경우 체크 (oneOf)
- 여러 규칙 중 적어도 하나를 만족하는 경우 체크 (anyOf)
더 상세한 내용은 json schema 사이트 내의 문서(http://json-schema.org/latest/json-schema-validation.html)에서 확인하실 수 있습니다.
항상 스키마를 통해서 유효성을 체크하는게 좋은 선택은 아니겠지만, 어느 정도 세세한 체크가 필요하다면
그 부분에 대한 로직을 작성하는 것보다 스키마를 활용하는게 좋을 선택이 될 수 있을 것 같습니다.
validator 라이브러리
jackson이나 Gson 라이브러리에 스키마를 통한 유효성 검증 기능이 있으면 좋겠지만
그렇지 않아서 외부 라이브러리를 사용해야합니다.
언어 별로 여러 구현 라이브러리들이 있는데
자바에서는 json-schema-validator(https://github.com/java-json-tools/json-schema-validator)가 많이 사용되는 것 같습니다.
json-schema-validator 사용 예제
- import java.io.IOException;
- import org.springframework.core.io.ClassPathResource;
- import com.fasterxml.jackson.databind.JsonNode;
- import com.fasterxml.jackson.databind.ObjectMapper;
- import com.github.fge.jsonschema.core.exceptions.ProcessingException;
- import com.github.fge.jsonschema.core.report.ProcessingReport;
- import com.github.fge.jsonschema.main.JsonSchema;
- import com.github.fge.jsonschema.main.JsonSchemaFactory;
- public class JsonValidation {
- private static ObjectMapper objectMapper = new ObjectMapper();
- public static void main(String[] args) throws IOException, ProcessingException {
- ClassPathResource jsonSchemaResource = new ClassPathResource("schema.json"); // schema 파일
- JsonNode schemaNode = objectMapper.readTree(jsonSchemaResource.getInputStream());
- ClassPathResource jsonResource = new ClassPathResource("sample.json"); // json 파일
- JsonNode jsonNode = objectMapper.readTree(jsonResource.getInputStream());
- JsonSchemaFactory factory = JsonSchemaFactory.byDefault();
- JsonSchema schema = factory.getJsonSchema(schemaNode);
- ProcessingReport report = schema.validate(jsonNode); // validation 체크
- if (report.isSuccess()) {
- System.out.println("json is valid.");
- } else {
- System.out.println("json is not valid.");
- System.out.println("report : " + report);
- }
- }
- }
다른 예제 코드들도 프로젝트 페이지(https://github.com/java-json-tools/json-schema-validator/tree/master/src/main/java/com/github/fge/jsonschema/examples)에서 확인할 수 있습니다.
validate 메소드를 호출하려면, validate할 jsonNode를 파서로 먼저 읽어와야 하기 때문에
만약 한번에 validate할 범위가 너무 크다면 메모리를 많이 사용할 수 있어서 주의가 필요한 부분입니다.
처리해야할 json 데이터양이 많다면 위 예제처럼 한번에 처리하는 방식 대신에
스키마 파일에는 반복되는 데이터 구조 부분만 정의해두고
streaming api로 부분부분 읽어와서 validate하는 방식으로 개발하는 방법을 활용해볼 수 있을 것 같습니다.
'개발 > 자바' 카테고리의 다른 글
Effective Java 3/E - 8장 메서드 요약정리 (0) | 2019.05.26 |
---|---|
Effective Java 3/E - 7장 람다와 스트림 요약정리 (0) | 2019.05.19 |
JSON STREAMING API (0) | 2017.06.30 |
FileLock (0) | 2017.01.11 |
checked exception과 unchecked exception (0) | 2016.07.18 |