개요
개인의 취향 또는 조직의 컨벤션이 있겠지만 필자는 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 |