본문 바로가기

Spring boot/Blog 프로젝트 만들기(JPA)

[Blog] 블로그 프로젝트 만들기 - 5 (글 목록 조회 API )

BlogService 파일에 게시글 전체 조회 기능 추가 하기 - 1
package com.example.demo._domain.blog.service;

import java.util.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.example.demo._domain.blog.dto.ArticleDTO;
import com.example.demo._domain.blog.entity.Article;
import com.example.demo._domain.blog.repository.PostRepository;

import lombok.RequiredArgsConstructor;

@RequiredArgsConstructor
@Service // IoC (빈으로 등록)
public class BlogService {

    @Autowired // DI <- 개발자들이 가독성 때문에 작성을 해준다.
    private final PostRepository postRepository;

    @Transactional // 쓰기 지연 처리까지
    public Article save(ArticleDTO dto){
        // 비즈니스 로직이 필요하다면 작성
        return postRepository.save(dto.toEntity());
    }

    // 전체 게시글 조회 기능
    public List<Article> findAll(){
       List<Article> articles =  postRepository.findAll();
       return articles;
    } 

}

 

 

 

 

공통 응답 DTO 만들기 - 2
package com.example.demo.common;

import lombok.Data;

@Data
public class ApiUtil<T> {

    private Integer status; // 응답 상태 코드 저장 (200, 400, 500)
    private String msg; // 응답 메시지 저장 (성공, 실패 문자열)
    private T body; // 응답의 실제 데이터 저장 (제네릭 활용)

    // 성공적인 응답을 반환할 때 사용하는 생성자
    public ApiUtil(T body){
        this.status = 200; // 통신 성공
        this.msg = "성공";
        this.body = body;
    }

    // 커스텀 상태코드와 메시지를 반환 시킬 때 사용하는 생성자 (예 : 에러 응답)
    public ApiUtil(Integer status, String msg){
        this.status = status;
        this.msg = msg;
        this.body = null;
    }

}

 

 

 

BlogController 코드 추가 - 3
package com.example.demo._domain.blog.controller;

import java.util.*;

import org.apache.tomcat.util.http.parser.MediaType;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import com.example.demo._domain.blog.dto.ArticleDTO;
import com.example.demo._domain.blog.entity.Article;
import com.example.demo._domain.blog.service.BlogService;
import com.example.demo.common.ApiUtil;

import lombok.RequiredArgsConstructor;

@RequiredArgsConstructor // final을 사용했기 때문에 초기화 자동 설정
@RestController // @Controller + @ResponseBody
public class BlogApiController {

    private final BlogService blogService;

    // URL 즉, 주소 설계 http://localhost:8080/api/articles
    @PostMapping("/api/articles")
    public ResponseEntity<Article> addArticle(@RequestBody ArticleDTO dto) {
        // 1. 인증검사
        // 2. 유효성 검사
        Article savedArticle = blogService.save(dto);
        return ResponseEntity.status(HttpStatus.CREATED).body(savedArticle);
    }

    // URL 즉, 주소 설계 http://localhost:8080/api/articles
    @GetMapping("/api/articles")
    public ApiUtil<List<Article>> getAllArticles() {
        List<Article> articles = blogService.findAll();
        if(articles.isEmpty()){
            return new ApiUtil<>(204, "조회된 게시글이 없습니다.");
        }

        return new ApiUtil<>(articles);
    }

}

 

 

 

 

ExceptionHandler 만들기 - 4

package com.example.demo.common.errors;

public class Exception400 extends RuntimeException{

    public Exception400(String msg){
        super(msg);
    }

}
package com.example.demo.common;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import com.example.demo.common.errors.Exception400;
import com.example.demo.common.errors.Exception401;
import com.example.demo.common.errors.Exception403;
import com.example.demo.common.errors.Exception404;
import com.example.demo.common.errors.Exception500;

// RuntimeException 터지면 해당 파일로 오류가 모인다.
@RestControllerAdvice // C.A -> 뷰 에러페이, R.C.A 데이터 반환 (에러)
public class MyExceptionHandler {

    private static final Logger logger = LoggerFactory.getLogger(MyExceptionHandler.class);

    @ExceptionHandler(Exception400.class)
    public ResponseEntity<?> ex400(Exception400 e) {
        ApiUtil<?> apiUtil = new ApiUtil<>(400, e.getMessage());
        return new ResponseEntity<>(apiUtil, HttpStatus.BAD_REQUEST);
    }

    @ExceptionHandler(Exception401.class)
    public ResponseEntity<?> ex401(Exception401 e) {
        ApiUtil<?> apiUtil = new ApiUtil<>(401, e.getMessage());
        return new ResponseEntity<>(apiUtil, HttpStatus.UNAUTHORIZED);
    }

    @ExceptionHandler(Exception403.class)
    public ResponseEntity<?> ex403(Exception403 e) {
        ApiUtil<?> apiUtil = new ApiUtil<>(403, e.getMessage());
        return new ResponseEntity<>(apiUtil, HttpStatus.FORBIDDEN);
    }

    @ExceptionHandler(Exception404.class)
    public ResponseEntity<?> ex404(Exception404 e) {
        ApiUtil<?> apiUtil = new ApiUtil<>(404, e.getMessage());
        return new ResponseEntity<>(apiUtil, HttpStatus.NOT_FOUND);
    }

    @ExceptionHandler(Exception500.class)
    public ResponseEntity<?> ex500(Exception500 e) {
        ApiUtil<?> apiUtil = new ApiUtil<>(500, e.getMessage());
        return new ResponseEntity<>(apiUtil, HttpStatus.INTERNAL_SERVER_ERROR);
    }
}

 

 

 

 

BlogApiController
package com.example.demo._domain.blog.controller;

import java.util.*;

import org.apache.tomcat.util.http.parser.MediaType;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import com.example.demo._domain.blog.dto.ArticleDTO;
import com.example.demo._domain.blog.entity.Article;
import com.example.demo._domain.blog.service.BlogService;
import com.example.demo.common.ApiUtil;
import com.example.demo.common.errors.Exception400;

import lombok.RequiredArgsConstructor;

@RequiredArgsConstructor // final을 사용했기 때문에 초기화 자동 설정
@RestController // @Controller + @ResponseBody
public class BlogApiController {

    private final BlogService blogService;

    // URL 즉, 주소 설계 http://localhost:8080/api/articles
    @PostMapping("/api/articles")
    public ResponseEntity<Article> addArticle(@RequestBody ArticleDTO dto) {
        // 1. 인증검사
        // 2. 유효성 검사
        Article savedArticle = blogService.save(dto);
        return ResponseEntity.status(HttpStatus.CREATED).body(savedArticle);
    }

    // URL 즉, 주소 설계 http://localhost:8080/api/articles
    @GetMapping("/api/articles")
    public ApiUtil<?> getAllArticles() {
        List<Article> articles = blogService.findAll();
        if (articles.isEmpty()) {
            if (articles.isEmpty()) {
                // return new ApiUtil<>(new Exception400("게시글이 없습니다."));
                throw new Exception400("게시글이 없습니다.") ;
            }
        }

        return new ApiUtil<>(articles);
    }

}

 

 

 

728x90