[Toy Project] Java ModelMapper를 활용한 객체 변환

최지나·2024년 2월 29일
3
post-thumbnail

개요

자바 개발을 하다 보면 데이터 모델 간 변환을 흔히 겪는다. 특히 서비스 계층에서는 다양한 객체들 사이의 변환 작업이 필수적인데, 이러한 작업을 간편하게 해주는 도구 중 하나인 ModelMapper에 대해 기록하고자 한다

ModelMapper란?

자바 객체 간의 자동 매핑을 지원하는 라이브러리로, 복잡한 변환 로직 없이 소스 객체의 필드 값을 대상 객체의 필드에 자동으로 복사해준다.

사용 방법

Dependency 추가

<dependency>
  <groupId>org.modelmapper</groupId>
  <artifactId>modelmapper</artifactId>
  <version>3.2.0</version>
</dependency>

선언 및 매칭 전략 설정

  • ModelMapper의 사용을 위해서는 매칭 전략을 설정해서 선언해야 한다

  • 매칭 전략의 종류

매칭 전략설명
STANDARD소스 객체의 필드 이름과 대상 객체의 필드 이름이 완전히 일치할 필요는 없으며, 부분적으로 일치하는 경우에도 매핑을 시도. 이 전략은 이름의 유사성을 기반으로 매핑을 수행
STRICT엄격한 매칭 전략으로, 소스 객체와 대상 객체 간에 필드 이름이 정확히 일치해야 매핑 수행
LOOSE매핑을 수행할 수 있는 구조적 유사성이 있을 경우 매핑을 시도. ex) 소스 객체의 필드 이름이 userName이고 대상 객체의 필드 이름이 user_name인 경우에도 매핑
  • 선언 예시
  private final ModelMapper modelMapper;

  public UserServiceImpl(UserRepository userRepository, JwtUtil jwtUtil, PasswordEncoder passwordEncoder) {
    // ...
    this.modelMapper = new ModelMapper();  // 선언
    this.modelMapper.getConfiguration().setMatchingStrategy(MatchingStrategies.STRICT);  // STRICT 매칭 전략 설정
  }

사용 예시

  • 사용자 로그인 처리 예시 (UserServiceImpl.java)
    • 사용자 정보를 DB에서 검색하고 로그인 성공 시 jwt 토큰 발행하여 반환하는 메서드
    • ModelMapper는 DB에서 조회한 User 객체를 서비스 계층에서 사용할 UserLogin DTO로 복사해서 변환해준다.
    • User 객체에는 없으나, UserLogin 객체에 필요한 필드들(accessToken, refresthToken)은 setter를 통해 값을 설정할 수 있다
@Override
@Transactional
public UserLoginRes userLogin(UserLoginInput loginInfo) {
  User user = userRepository.findByUsername(loginInfo.getUserName());
  if (user == null) {
    return new UserLoginRes(ResponseCode.NOT_FOUND.getCode(), ResponseCode.NOT_FOUND.getMessage("사용자"), null);
  }

  if (!passwordEncoder.matches(loginInfo.getPassword(), user.getPassword())) {
    return new UserLoginRes(
        ResponseCode.BAD_REQUEST.getCode(),
        ResponseCode.BAD_REQUEST.getMessage("유효하지 않은 비밀번호입니다"), null);
  }

// ModelMapper의 사용
  UserLogin userLogin = modelMapper.map(user, UserLogin.class);
  userLogin.setAccessToken(jwtUtil.generateAccessToken(user.getUsername(), user.getRole()));
  userLogin.setRefreshToken(jwtUtil.generateRefreshToken(user.getUsername()));

  return new UserLoginRes(ResponseCode.RETRIEVED.getCode(),
      ResponseCode.RETRIEVED.getMessage("로그인 정보"),
      userLogin);
}

마무리

  • 복잡한 객체 변환 작업을 ModelMapper를 통해 단순화하고, 코드의 가독성을 향상시킬 수 있었다
  • 이번에는 STRICT 매핑 전략을 사용해 문제가 발생하지 않았으나, 다른 전략을 사용할 경우 매핑이 자동으로 이루어지기 때문에 예상치 못한 매핑 결과에 주의해야겠다고 생각했다 😚
profile
의견 나누는 것을 좋아합니다 ლ(・ヮ・ლ)

1개의 댓글

comment-user-thumbnail
2024년 3월 17일

저도 한번 써보고 싶네요!

답글 달기