TIL

250127 월 TIL

파란배개 2025. 1. 27. 17:18

클라이언트와 서버 간 데이터 전송 방식

데이터 전송 방법

JSON으로 데이터 전송 시

  • @RequestBody 어노테이션 사용.

Form 데이터 전송 시

  • @ModelAttribute 어노테이션 사용.

예제 코드

@AllArgsConstructor
@Getter
public static class ModifyForm {
    private String title;
    private String content;
}

@PutMapping("{id}")
public Map<String, Object> modify(
        @PathVariable long id,
        @RequestBody ModifyForm form
) {
    // 로직 구현
}

record의 활용

특징

  • 데이터를 저장하기 위한 객체로, 생성자, 게터, 세터, equals 등이 자동 생성됨.
  • 코드가 간결해짐.

기존 클래스와 비교

@AllArgsConstructor
@Getter
public static class ModifyReqBody {
    private String title;
    private String content;
}

이 코드는 다음과 같이 간략화할 수 있음:

record ModifyReqBody(String title, String content) {}

값 접근 방법

  • body.title() 또는 body.title 둘 다 가능.

DTO(Data Transfer Object)의 필요성

DTO를 사용하는 이유

  • 서버 코드 변경 시에도 프론트엔드가 기존 데이터 형식을 유지할 수 있도록 함.
  • 엔티티와 분리하여 확장성과 유지보수성을 높임.

JAVA Spring에서 DTO 예제

package com.example.rest.domain.post.post.dto;

import com.example.rest.domain.post.post.entity.Post;
import lombok.Getter;

@Getter
public class PostDto {

    private long id;
    private String name;
    private String body;

    public PostDto(Post post) {
        this.id = post.getId();
        this.name = post.getName();
        this.body = post.getBody();
    }
}

컨트롤러에서의 사용 예:

Post post = postService.getItem(id).get();
PostDto postDto = new PostDto(post);
return postDto;

@JsonProperty 사용

  • DTO 대신 @JsonProperty를 사용하여 엔티티를 직접 반환 가능하지만 추천되지 않음.
  • 복잡성이 증가하고 확장성이 낮아질 가능성 있음.

예:

@JsonProperty("createdAt")
private LocalDateTime createdDate;

원시 타입과 객체 타입의 차이

원시 타입의 한계

  • 원시 타입은 null을 표현할 수 없음.
  • 예: long id는 데이터가 없을 때 0을 반환.

객체 타입의 장점

  • Long id를 사용하여 null로 데이터 없음 상태를 명확히 표현 가능.

@JsonInclude 활용

  • @JsonInclude(JsonInclude.Include.NON_NULL)를 사용하면 null 필드를 JSON 응답에서 제외 가능.

제너릭 타입을 활용한 리턴값 처리

  • 값이 없을 때:
ResponseData<Void> result;

HTTP 응답 처리

ResponseEntity 사용

  • 상태 코드와 응답 메시지를 함께 처리 가능.

예:

return ResponseEntity.status(HttpStatus.CREATED).body(responseData);

또는:

return ResponseEntity.noContent().build(); // 상태 코드 204 반환

AOP를 이용한 전후 처리

AOP란?

  • 프록시를 이용해 특정 클래스나 메서드의 실행 전후 처리를 수행.

AOP 예제

package com.example.rest.global.aspect;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class ResponseAspect {

    @Around("""
            (
                within(@org.springframework.web.bind.annotation.RestController *)
            ) && (
                @annotation(org.springframework.web.bind.annotation.GetMapping) ||
                @annotation(org.springframework.web.bind.annotation.PostMapping) ||
                @annotation(org.springframework.web.bind.annotation.PutMapping) ||
                @annotation(org.springframework.web.bind.annotation.DeleteMapping)
            )
        """)
    public Object process(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("Pre-processing");

        Object result = joinPoint.proceed();

        System.out.println("Post-processing");

        return result;
    }
}
위 코드의 joinPoint.proceed()부분에서 원래 실하려던 메서드를 호출해 실행한다.
이를 통해 값을 가로채거나 추가적인 전, 후처리가 가능하다.

'TIL' 카테고리의 다른 글

250203 월 TIL  (0) 2025.02.03
250131 금 TIL  (0) 2025.01.31
250124 금 TIL  (0) 2025.01.24
250123 목 TIL  (0) 2025.01.23
250122 수 TIL  (0) 2025.01.22