65일차 (2) - 스프링 (RESP API로 댓글 조회-생성구현, Log)

Yohan·2024년 5월 26일
0

코딩기록

목록 보기
98/156
post-custom-banner

Reply RESTAPI로 구현

ReplyApiController

  • Restful한 서비스 구축을 위해 RestAPI를 사용하여 Controller 수정
package com.study.springstudy.springmvc.chap05.api;

import com.study.springstudy.springmvc.chap05.dto.request.ReplyPostDto;
import com.study.springstudy.springmvc.chap05.dto.response.ReplyDetailDto;
import com.study.springstudy.springmvc.chap05.entity.Reply;
import com.study.springstudy.springmvc.chap05.service.ReplyService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController // Controller + 반환시 JSON형식으로 변환
@RequestMapping("/api/v1/replies")
@RequiredArgsConstructor
@Slf4j // 로그 라이브러리
public class ReplyApiController {

    private final ReplyService replyService;

    // 댓글 목록 조회 요청
    // URL : /api/v1/replies/원본글번호   -  GET -> 목록조회
    // @PathVariable : URL에 붙어있는 변수값을 읽는 어노테이션
    @GetMapping("/{bno}")
    public ResponseEntity<?> list(@PathVariable long bno) {

        if (bno == 0) {
            String message = "글 번호는 0번이 될 수 없습니다.";
            log.warn(message);
            return ResponseEntity
                    .badRequest()
                    .body(message);
        }

        log.info("/api/v1/replies/{} : GET", bno);

        List<ReplyDetailDto> replies = replyService.getReplies(bno);
        log.debug("first reply : {}", replies.get(0));

        return ResponseEntity
                .ok()
                .body(replies);
    }

    // 댓글 생성 요청 (요청할 때 JSON으로!!)
    // @RequestBody : 클라이언트가 전송한 데이터를 JSON으로 받아서 파싱
    // = JSON 데아터 -> 자바 객체로 파싱 
    @PostMapping
    public ResponseEntity<?> posts(@RequestBody ReplyPostDto dto) {

        log.info("/api/v1/replies : POST");
        log.debug("parameter: {}", dto);

        boolean flag = replyService.register(dto);

        if (!flag) return ResponseEntity
                .internalServerError()
                .body("댓글 등록 실패!");

        return ResponseEntity
                .ok()
                .body(replyService.getReplies(dto.getBno()));
    }
}

ReplyService

package com.study.springstudy.springmvc.chap05.service;

import com.study.springstudy.springmvc.chap05.dto.request.ReplyPostDto;
import com.study.springstudy.springmvc.chap05.dto.response.ReplyDetailDto;
import com.study.springstudy.springmvc.chap05.entity.Reply;
import com.study.springstudy.springmvc.chap05.mapper.ReplyMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
@Slf4j // 로그 라이브러리
public class ReplyService {

    private final ReplyMapper replyMapper;

    // 댓글 목록 전체조회
    public List<ReplyDetailDto> getReplies(long boardNo) {
        List<Reply> replies = replyMapper.findAll(boardNo);
        return replies.stream()
                .map(r -> new ReplyDetailDto(r))
                .collect(Collectors.toList());
    }

    // 댓글 입력
    public boolean register(ReplyPostDto dto) {
        Reply reply = Reply.builder()
                .replyText(dto.getText())
                .replyWriter(dto.getAuthor())
                .boardNo(dto.getBno())
                .build();

        boolean flag = replyMapper.save(reply);
        if (flag) log.info("댓글 등록 성공 - {}", dto);
        else log.warn("댓글 등록 실패");
        return flag;
    }

    // 댓글 수정
    public void modify() {

    }

    // 댓글 삭제
    public void remove() {

    }
}

ReplyDetailDto

  • 댓글 조회시 화면에 띄우고싶은 데이터들을 모아놓은 ResponseDto
    -> 필요에 의해 커스텀하여 사용가능
package com.study.springstudy.springmvc.chap05.dto.response;

import com.fasterxml.jackson.annotation.JsonFormat;
import com.study.springstudy.springmvc.chap05.entity.Reply;
import lombok.*;

import java.time.LocalDateTime;

@Getter @ToString
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode
@Builder
public class ReplyDetailDto {

    private long rno;
    private String text;
    private String writer;

    @JsonFormat(pattern = "yyyy년 MM월 dd일 HH:mm")
    private LocalDateTime createAt;

    // 엔터티를 DTO로 변환하는 생성자
    public ReplyDetailDto(Reply r) {
        this.rno = r.getReplyNo();
        this.text = r.getReplyText();
        this.writer = r.getReplyWriter();
        this.createAt = r.getReplyDate();
    }
}

ReplyPostDto

  • 댓글을 입력시 필요한 데이터들만 모아놓은 RequestDto
package com.study.springstudy.springmvc.chap05.dto.request;

import lombok.*;

@Getter @ToString
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode
@Builder
public class ReplyPostDto {

    private String text; // 댓글 내용
    private String author; // 댓글 작성자
    private Long bno; // 원본 글번호
}

로깅 레벨 설정

  • 로그: 발생시간, 로그 레벨, 파일저장
  • 로그 라이브러리: logback, log4j, slf4j
  • 로그 설정 : application.properties
  • 로그 레벨
  1. trace : 애플리케이션의 실행흐름 세부정보, 디버깅 목적
  2. debug : 변수값, 파라미터값 내부 정보 출력, 디버깅 목적
    ======= 운영 서버 ▽ ===============
  3. info : 운영환경에서 일반적인 작동 정보들, 시스템 상태, 진행중인 작업 정보
    ======== 개발 서버 ▲ =====================
  4. warn : 잠재적인 문제상황을 경고. 구성값이 예상 범위를 벗어났거나 시스템 리소스 부족
  5. error : 예외가 발생하거나 기능이 실패했을 때 심각한 문제상황
  6. fatal : 치명적인 오류 시스템이 지속될 수 없는 상황, 즉각 조치가 필요한 경우
  • trace가 내용이 가장 많이 뜬다.

application.properties

# log level setting
logging.level.root=info

logging.level.com.study.springstudy.springmvc=debug
  • 애플리케이션 전체의 기본 로깅 레벨을 info로 설정하고, 특정 패키지(com.study.springstudy.springmvc)에 대한 로깅 레벨을 debug로 설정
profile
백엔드 개발자
post-custom-banner

0개의 댓글