Jackson JSON View를 활용해 원하는 필드만 JSON으로 직렬화 하기

Brant Hwang
QueryPie
Published in
8 min readNov 18, 2016

10분만에 JSON API 개발하기

JPA와 QueryDSL로 SQL한줄도 없이 JSON API 만들기

지난 편에 이어 이번 편에서는 Jackson JSON View 기능을 활용해서 API 별로 원하는 필드만 JSON으로 직렬화하는 방법을 살펴보겠습니다.

현재 고객 목록을 조회하는 /api/v1/customers API는 JSON 응답이 다음과 같습니다.

{
"page": {
"totalPages": 0,
"totalElements": 0,
"currentPage": 0,
"pageSize": 0
},
"list": [
{
"id": 1,
"customerName": "황인서",
"customerPhone": "010-1234-5555",
"customerAddr": "서울시 강서구",
"customerEmail": "brant@chequer.io",
"dataStatus": "ORIGIN",
"__deleted__": false,
"__created__": false,
"__modified__": false
},
{
"id": 2,
"customerName": "장기영",
"customerPhone": "010-8881-9136",
"customerAddr": "경기도 포천시 송우리",
"customerEmail": "tom@axisj.com",
"dataStatus": "ORIGIN",
"__deleted__": false,
"__created__": false,
"__modified__": false
},
{
"id": 3,
"customerName": "이서연",
"customerPhone": "010-3465-3362",
"customerAddr": "san francisco",
"customerEmail": "tiffy@chequer.io",
"dataStatus": "ORIGIN",
"__deleted__": false,
"__created__": false,
"__modified__": false
}
]
}

그리고 특정 고객 1명을 조회하는 API는 다음과 같이 JSON 응답이 오고 있습니다.

{
"id": 1,
"customerName": "황인서",
"customerPhone": "010-1234-5555",
"customerAddr": "서울시 강서구",
"customerEmail": "brant@chequer.io",
"dataStatus": "ORIGIN",
"__deleted__": false,
"__created__": false,
"__modified__": false
}

/api/v1/customers API를 사용해서 고객 목록을 표시하는 화면을 개발할 예정인데, 고객 목록에서 필요한 데이터는 id, customerName 2가지만 표시하면 된다고 가정해보죠. 지금은 고객수가 많지 않아서 JSON 응답 크기 작지만, 고객이 수천~수만 명이라면 JSON 응답이 상당히 크겠지요. (물론 페이징 처리 등의 다른 방법으로 처리할 수도 있습니다.)

이러한 상황에서 JSON View를 사용하면, 원하는 필드만 JSON에 포함해서 직렬화를 할 수 있습니다.

1. 사용자 정의 JsonView 클래스 생성하기

저는 json.view패키지에 ApiJsonView라는 클래스를 생성했습니다.

package com.chequer.app.api.json.view;import com.chequer.axboot.core.json.Views;public class ApiJsonView {public static class CustomerListJsonView extends Views.Root {}
}

중요한 부분 중 하나는, AXBoot가 내부적으로 제공하는 클래스들과 함께 API를 개발할 경우, AXBoot Core에서 제공하는 Views.Root를 상속받아야 합니다. (ListResponse, PageResponse 등의 클래스에 Views.Root에 정의된 클래스가 @JsonView로 추가되어 있기 때문입니다.)
2. Customer 클래스에 @JsonView 추가하기public class Customer extends SimpleJpaModel<Integer> {@Id
@Column(name = "ID", precision = 10, nullable = false)
@Comment(value = "ID")
@GeneratedValue(strategy = GenerationType.IDENTITY)
@ColumnPosition(1)
@JsonView(value = ApiJsonView.CustomerListJsonView.class)
private Integer id;
@Column(name = "CUSTOMER_NAME", length = 100)
@Comment(value = "고객명")
@ColumnPosition(2)
@JsonView(value = ApiJsonView.CustomerListJsonView.class)
private String customerName;
...
}
id 필드와 customerName 필드에 @JsonView 클래스를 지정해줍니다.
3. Controller에 @JsonView 추가하기@RequestMapping(method = RequestMethod.GET, produces = APPLICATION_JSON)
@ApiImplicitParams({
@ApiImplicitParam(name = "filter", value = "전체 고객데이터 검색을 위한 매개변수", dataType = "String", paramType = "query", required = false),
@ApiImplicitParam(name = "phone", value = "전화번호 검색 매개변수", dataType = "String", paramType = "query", required = false),
@ApiImplicitParam(name = "addr", value = "주소 검색 매개변수", dataType = "String", paramType = "query", required = false),
@ApiImplicitParam(name = "name", value = "이름검색 매개변수", dataType = "String", paramType = "query", required = false),
@ApiImplicitParam(name = "id", value = "ID", dataType = "Integer", paramType = "query", required = false)
})
@JsonView(value = ApiJsonView.CustomerListJsonView.class)
@ResponseBody
public Responses.ListResponse list(RequestParams<Customer> requestParams) {
List<Customer> list = customerService.gets(requestParams);
return Responses.ListResponse.of(list);
}
Jackson JSON View를 컨트롤러에서 사용하기 위한 몇몇 방법(http://docs.spring.io/spring/docs/current/spring-framework-reference/html/mvc.html#mvc-ann-jsonview)들 중 @ResponseBody를 추가하는 방법으로 JsonView를 적용해보겠습니다./api/v1/customers를 처리하는 메서드에 위 코드 처럼 @JsonView와 @ResponseBody를 추가하고, 서버를 재시작 합니다.4. API 테스트
screen-shot-2016-11-18-at-3-45-43-pm
screen-shot-2016-11-18-at-3-45-53-pm
이제 /api/v1/customers API는 id와 customerName만 있는 JSON 으로 변경되었습니다.JsonView를 잘 활용하면, 하나의 도메인 객체로 여러 형태의 JSON 응답을 만들 수 있습니다.다음편에서는 API 보안과 인증에 대한 내용을 살펴보겠습니다.도움이 되셨다면 Github Star 꼭 부탁드려요 :)Star
Star

--

--