Java / Spring
Object Mapper [JSON -> Java 객체] 본문
Object Mapper 란 ?
Jackson 라이브러리에서 제공하는 클래스로 클라이언트에서 전송한 JSON 데이터를 Java 객체로 변환해주는 기능이다.
- JSON의 키와 Java 객체의 필드를 매칭하여 데이터를 역직렬화한다. 이 과정에서 ObjectMapper 가 사용되는 것이다.
그럼 ObjectMapper 는 내부적으로 어떻게 데이터를 읽는것일까?
1. 클라이언트의 JSON 요청 :
- 예를 들어 클라이언트에서 Login 을 시도할 때 username 과 password 데이터를 서버에 전송 후 검증을 해야할 때 클라이언트가 서버에 보내는 데이터는 보통 JSON 형식으로 보낸다.
이 데이터를 서버에서는 바로 읽을 수 없다. 해당 데이터를 Java 객체로 변환해야 된다.
@Override
public Authentication attemptAuthentication(HttpServletRequest request,
HttpServletResponse response) throws AuthenticationException {
try {
// JSON 데이터에서 username과 password 추출
// 클라이언트에서 넘어온
ObjectMapper objectMapper = new ObjectMapper();
LoginDTO loginRequest = objectMapper.readValue(request.getInputStream(), LoginDTO.class);
String username = loginRequest.getUsername();
String password = loginRequest.getPassword();
log.info("username={}", username);
log.info("password={}", password);
UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken(username, password, null);
log.info("authToken={}", authToken);
return authenticationManager.authenticate(authToken);
} catch (IOException e) {
throw new AuthenticationException("Invalid authentication data") {};
}
}
위의 로직은 JwtToken 을 생성하기 위해 클라이언트에서 보낸 JSON 형식의 username 과 password 데이터를 ObjectMapper 객체를 생성하여 Java 객체로 변환하는 과정이다.
2. ObjectMapper 의 역직렬화 과정
1) 입력 스트림 읽기 : 먼저 request.getInputStream() 을 통해 HTTP 요청 본문에 포함된 JSON 데이터를 읽어온다. 이 데이터는 바이트 스트림으로 전달되기 때문에, 이를 ObjectMapper 가 적절하게 처리해야 한다.
2) JSON 문자열 파싱 : ObjectMapper 는 JSON 형식을 파싱하여, 해당 JSON 데이터가 어떤 형태로 이루어졌는지 확인한다. JSON 객체의 키와 값들이 어떤 구조로 나열되어 있는지 파악한다.
3) Java 객체로 변환 (역직렬화) : ObjectMapper 는 JSON의 각 키와 값을 Java 객체의 필드와 매핑한다. 현재는 LoginDTO 클래스에 존재하는 DTO 내 필드에 존재하는 username 과 password 값을 읽어 이를 LoginDTO 객체의 해당 필드에 자동으로 할당한다. (LoginDTO 에는 Lombok 의 @Data 어노테이션을 추가해야 한다)
3. 사용된 ObjectMapper 메서드
1) HttpServlet 의 request.getInputStream():
- ObjectMapper 의 메서드가 아니지만 Mapper 가 읽어야 할 데이터에 접근 하기 위한 메서드
- HTTP 요청의 본문을 Byte Stream 으로 읽어들이고, 요청 본문에 포함된 데이터에 접근하기 위한 메서드
2) readValue() :
- JSON 데이터를 받아서 Java 객체로 변환하는 역할
- 내부 파라미터로 : 첫 번째 인자 = 입력스트림, 두 번째 인자 = 타입을 변환할 필드가 존재하는 객체 클래스 (LoginDTO.Class)
현재 프로젝트 구조는 로그인을 시도하면 SpringSecuriy 가 해당 데이터를 가로채서 자동으로 로그인을 처리하기 때문에
public Authentication attemptAuthentication(HttpServletRequest request,
HttpServletResponse response) throws AuthenticationException {
위의 메서드 내부에서 클라이언트가 보낸 JSON 형식의 데이터를 ObjectMapper 를 통해 Java 객체로 변환하고 아래의 메서드를 통해 사용자 인증정보 검증 후 authenticationManager 를 통해 다음 토큰 발급 로직이 진행되는 것이다.
UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken(username, password, null);
log.info("authToken={}", authToken);
return authenticationManager.authenticate(authToken);
ObjectMapper 의 사용법을 몰라서 모든 로직을 구현하고 컨트롤러를 생성하여 POSTMAN API 로 데이터를 보낼때는 컨트롤러에서 @RequstBody 를 통해 자동으로 json 데이터를 java 객체로 처리 하기 때문에 가능 했지만 실제 vue.js 의 로그인 로직에서 axios 로 데이터를 보내는 방식에서는 위의 objectmapper 를 사용하여 성공적으로 데이터를 전송하고 jwt 인증 token 을 발급 후 로컬 스토리지에 저장할 수 있었다.
'개인 공부 > JWT' 카테고리의 다른 글
Access Token 과 Refresh Token (0) | 2025.01.14 |
---|---|
JWT 토큰 발급 후 만료되는 문제 (0) | 2024.12.13 |