본문으로 바로가기

개요

개인의 취향 또는 조직의 컨벤션이 있겠지만 필자는 DB의 컬럼명을 Snake Case 로 작성하고, JSON 응답을 내릴 때에도 마찬가지로 컬럼명과 동일한 프로퍼티명을 사용하기 위해 Snake Case 를 사용하며, 이는 일반적인 JSON 의 컨벤션이기도 하다. 

그러나 Java 는 Camel Case 를 사용하기 떄문에 Client로 부터 받는 요청과 응답결과, DAO 객체와 DB간 통신에 Case 의 변환이 필요한데 Spring Boot 의 @Controller 또는 @RestControler 를 통해 Client 로 부터 요청을 받을 때 POST 요청의 경우 @RequestBody 를 통해 Entity 또는 Dto 객체를 전달 받을 수 있는데 이러한 Model 객체는 jackson 라이브러리의 @JsonProperty 와 같은 어노테이션을 통해 쉽게 변환이 가능하다.

 

하지만, GET 요청을 통해 전달되는 QueryString의 경우 @RequestParam 을 사용하게 되면 각각의 인자단위로 맵핑을 지정해야하며, @ModelAttribute 를 통한 객체 전달 시 상기 언급한 @JsonProperty 어노테이션을 사용하더라도 변환이 되지 않는다.

 

목적

GET 으로 요청된 QueryString 을 DTO 또는 Entity 와 같은 객체 타입으로 받되 Snake Case 로 요청된 프로퍼티를

Camel Case 로 변환 해 비즈니스 로직에서 Java 의 컨벤션을 유지할 수 있도록 한다.

 

package com.csd.asr.intra.data.dto;

import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.*;

import java.io.Serializable;
import java.sql.Timestamp;

@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class UserDto implements Serializable {

    private Long id;

    @JsonProperty("gw_id")
    private String gwId;

    @JsonProperty("user_name")
    private String userName;

    private String role;

    private String email;

    private String branch;

    private String department;

    private String cellular;

    @JsonProperty("deleted_at")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Timestamp deletedAt;

    @JsonProperty("updated_at")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Timestamp updatedAt;

    @JsonProperty("created_at")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Timestamp createdAt;

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public static class SearchCondition {
        private String columns;
        private String gwId;
        private String userName;
    }
}

상기와 같은 DTO 객체가 존재하며 @JsonProperty 라는 어노테이션은 실제 DB에서 사용하는 컬럼명 처럼 Snake Case 로 DB와 통신하며, Client 로 부터 요청을 받고, 응답을 내려주겠다고 선언했다.

위에 설명했듯 POST 를 통한 요청으로 @RequestBody 를 통한 객체 주입 시 이런 형 변환이 문제가 없으나 QueryString 에는 사용할 수가 없다.

 

@Slf4j
@RestController
@RequestMapping(value = "${routes.api-base-path}/users")
public class UserController extends BaseController {

    UserService userService;


    UserController(UserService userService) {
        this.userService = userService;
    }

    @PostMapping
    public UserDto createUser(@RequestBody UserDto userDto) {
        return userDto;
    }

    @GetMapping(value = "/search")
    public ArrayList<UserDto> search(@RequestParam Map<String, String> params) {
		
        // jackson 라이브러리의 ObjectMapper 클래스를 이용한다.
        ObjectMapper mapper = new ObjectMapper();
        UserDto user = mapper.convertValue(params, UserDto.class);
        ArrayList<UserDto> userList = userService.search();
        return userList;

    }

}

상기와 같이 jackson 라이브러리에서 제공하는 ObjectMapper 라이브러리를 통해 요청된 QueryString Parameter와 맵핑하고자 하는 UserDto 객체의 클래스를 인자로 전달하면 POST 요청과 마찬가지로 DTO 객체에 선언한 어노테이션을 그대로 적용할 수 있다.

'Framework > Spring' 카테고리의 다른 글

[Spring] Filter & Interceptor  (0) 2021.12.22
[Spring] MyBatis Log 설정하기  (0) 2021.12.16
[Spring] MyBatis 연동  (0) 2021.12.06
[Spring] Unit Test  (0) 2021.12.06
[Spring] Repository, Pageable, Sort  (0) 2021.12.04