본문 바로가기

Programming/SpringBoot

[SpringBoot] 간단한 게시판 만들기 #2 - Controller 구현

반응형

Controller는 View로부터 오는 API 요청들을 어떻게 처리할 것인지 정의하는 역할을 한다.

 

=> /board/list란 경로로 GET 요청이 왔을 때 어디로 보내고,

     /board/post란 경로로 GET 요청이 올 때 어디로 보내고, POST 요청이 오면 xxService로부터 Data를 받아와서

     view로 Attribute를 전달하는 등,

    /xx/xxx 경로로 요청이 올 때 PathVariables를 받아올지 등 정의를 수행한다.

 

- Controller는 @Controller 애노테이션을 붙여서 해당 Class가 Controller임을 알려줘야 한다.

 

shop.pingping2.board.controller.BaseController.java

 

/ 경로로 오는 요청을 처리하는 Controller이다.

 

package shop.pingping2.board.controller;

import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import shop.pingping2.board.config.auth.SessionUser;

import javax.servlet.http.HttpSession;

@RequiredArgsConstructor
@Controller
public class BaseController {

    private final HttpSession httpSession;

    @GetMapping("/")
    public String index(Model model){

        SessionUser user = (SessionUser) httpSession.getAttribute("user");

        if(user != null) {
            model.addAttribute("userName", user.getName());
            model.addAttribute("userImg", user.getPicture());
        }

        return "index";
    }
}

 

shop.pingping2.board.controller.BoardController.java

/board 경로로 오는 요청을 처리하는 Controller이다.

package shop.pingping2.board.controller;

import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import shop.pingping2.board.dto.BoardDto;
import shop.pingping2.board.service.BoardService;

import lombok.AllArgsConstructor;
import org.springframework.stereotype.Controller;

import java.util.List;


@Controller
@AllArgsConstructor
@RequestMapping("board")    // /board 경로로 들어오는 경우 아래의 Method들로 분기될 수 있도록 설정
public class BoardController {
    private BoardService boardService;

    // 게시판

    // 게시글 목록
    // list 경로로 GET 메서드 요청이 들어올 경우 list 메서드와 맵핑시킴
    // list 경로에 요청 파라미터가 있을 경우 (?page=1), 그에 따른 페이지네이션을 수행함.
    
    @GetMapping({"", "/list"})
    public String list(Model model, @RequestParam(value="page", defaultValue = "1") Integer pageNum) {
        List<BoardDto> boardList = boardService.getBoardlist(pageNum);
        Integer[] pageList = boardService.getPageList(pageNum);

        model.addAttribute("boardList", boardList);
        model.addAttribute("pageList", pageList);

        return "board/list";
    }

    // 글쓰는 페이지
    
    @GetMapping("/post")
    public String write() {
        return "board/write";
    }

    // 글을 쓴 뒤 POST 메서드로 글 쓴 내용을 DB에 저장
    // 그 후에는 /list 경로로 리디렉션해준다.
    
    @PostMapping("/post")
    public String write(BoardDto boardDto) {
        boardService.savePost(boardDto);
        return "redirect:/board/list";
    }

    // 게시물 상세 페이지이며, {no}로 페이지 넘버를 받는다.
    // PathVariable 애노테이션을 통해 no를 받음
    
    @GetMapping("/post/{no}")
    public String detail(@PathVariable("no") Long no, Model model) {
        BoardDto boardDTO = boardService.getPost(no);

        model.addAttribute("boardDto", boardDTO);
        return "board/detail";
    }

    // 게시물 수정 페이지이며, {no}로 페이지 넘버를 받는다.
    
    @GetMapping("/post/edit/{no}")
    public String edit(@PathVariable("no") Long no, Model model) {
        BoardDto boardDTO = boardService.getPost(no);

        model.addAttribute("boardDto", boardDTO);
        return "board/update";
    }

    // 위는 GET 메서드이며, PUT 메서드를 이용해 게시물 수정한 부분에 대해 적용

    @PutMapping("/post/edit/{no}")
    public String update(BoardDto boardDTO) {
        boardService.savePost(boardDTO);

        return "redirect:/board/list";
    }

    // 게시물 삭제는 deletePost 메서드를 사용하여 간단하게 삭제할 수 있다.
    
    @DeleteMapping("/post/{no}")
    public String delete(@PathVariable("no") Long no) {
        boardService.deletePost(no);

        return "redirect:/board/list";
    }

    // 검색
    // keyword를 view로부터 전달 받고
    // Service로부터 받은 boardDtoList를 model의 attribute로 전달해준다.
    
    @GetMapping("/board/search")
    public String search(@RequestParam(value="keyword") String keyword, Model model) {
        List<BoardDto> boardDtoList = boardService.searchPosts(keyword);
        
        model.addAttribute("boardList", boardDtoList);
        
        return "board/list";
    }
}

 

@RequestMapping("board")

Board 관련된 Controller이기 때문에 board 경로로 들어오는 요청을 하기의 Method로 분기될 수 있도록 설정

 

 

@GetMapping({"", "/list"})

/board

/board/list 경로로 들어오는 경우 모두 Mapping하기 위함

 

public String list(Model model, @RequestParam(value="page", defaultValue = "1") Integer pageNum)

list 경로에 요청 파라미터가 있을 경우 (?page=1), 그에 따른 페이지네이션을 수행함. 기본 값으로는 1페이지로 동작될 수 있도록 설정

 

List<BoardDto> boardList = boardService.getBoardlist(pageNum);
Integer[] pageList = boardService.getPageList(pageNum);

boardList는 boardService의 getBoardlist 메서드를 통해 게시판 리스트를 가져온다.

pageList는 boardService의 getPageList 메서드를 통해 페이지 리스트를 가져온다.

 

=> Controller는 Service에게 비즈니스 로직을 요청하게 된다.

 

model.addAttribute("boardList", boardList);
model.addAttribute("pageList", pageList);

받아온 값을 model 객체를 통해 Front에게 전달한다.

이는 추후에 thymeleaf 템플릿에 의해 변환되어 사용자에게 보여지게 된다.

 

 

@GetMapping("/post")
public String write() {
    return "board/write";
}

 

 

 

글쓰기 페이지이며, write.html을 리턴해줌

 

 

@PostMapping("/post")
public String write(BoardDto boardDto) {
    boardService.savePost(boardDto);
    return "redirect:/board/list";
}

글쓰기 페이지에서 글을 다 쓴 뒤에 '글쓰기' 버튼을 클릭할 경우 Mapping 되는 부분이다.

 

boardDto 객체로부터 값을 받아와 boardService의 savePost 메서드를 호출한다. 인자로는 Front로부터 받아온 boardDto 객체를 전달해준다.

 

그런 뒤에 /board/list.html 파일을 리디렉션하여 게시판 리스트를 출력한다.

 

 

@GetMapping("/post/{no}")
public String detail(@PathVariable("no") Long no, Model model) {
    BoardDto boardDTO = boardService.getPost(no);

    model.addAttribute("boardDto", boardDTO);
    return "board/detail";
}

 게시물 상세 페이지이며, @PathVariable 애노테이션을 사용하여 {no}로 Front로부터 Page Number를 전달받는다.

 

boardDTO는 boardService의 getPost 메서드로 게시물 내용을 받아오게 되며, 이를 model 객체를 통해 Front에게 전달하게 된다.

 

 

@GetMapping("/post/edit/{no}")
public String edit(@PathVariable("no") Long no, Model model) {
    BoardDto boardDTO = boardService.getPost(no);

    model.addAttribute("boardDto", boardDTO);
    return "board/update";
}

게시글 수정 페이지이며 Front view에서 '수정' 등의 버튼을 클릭하게 되면 해당 Page Number에 해당하는 내용을 Service -> DB를 통해 데이터를 가져오게 되며, 이를 boardDTO란 객체를 model의 Attribute로 전달해준다.

 

 

** PUT, DELETE : Hidden Method **

application.yml 파일을 보면 아래의 설정 값을 기입해주었다.

mvc:
  hiddenmethod:
    filter:
      enabled: true # GET, POST 뿐 만 아니라 PUT, DELETE 등의 메서드도 사용하기 위한 설정

이로 인해 PUT, DELETE 메서드를 사용할 수 있게 된다.

 

 

@PutMapping("/post/edit/{no}")
public String update(BoardDto boardDTO) {
    boardService.savePost(boardDTO);

    return "redirect:/board/list";
}

게시글 수정 페이지에서 모두 수정을 한 뒤 PUT 메서드를 이용해 수정한 부분을 적용하는 API이다.

Front로부터 boardDTO란 객체를 받아오고, 해당 객체를 인자로 savePost 메서드를 수행한 뒤 list.html 파일을 반환해준다.

 

@DeleteMapping("/post/{no}")
public String delete(@PathVariable("no") Long no) {
    boardService.deletePost(no);

    return "redirect:/board/list";
}

게시글 삭제를 하는 API이며 boardService의 deletePost 메서드를 사용하여 삭제한다.

 

 

@GetMapping("/board/search")
public String search(@RequestParam(value="keyword") String keyword, Model model) {
    List<BoardDto> boardDtoList = boardService.searchPosts(keyword);
    
    model.addAttribute("boardList", boardDtoList);
    
    return "board/list";
}

@RequestParam 애노테이션은 1개의 HTTP 요청 파라미터를 받기 위해서 사용한다.

반드시 'keyword'란 파라미터가 전송되어야 하며, 전송하지 않으면 400 Error가 유발된다.

 

고로 keyword란 파라미터를 찾아 keyword란 변수로 저장하고 boardService의 searchPosts(keyword) 메서드를 통해 boardDtoList란 리스트형 변수로 값을 저장한다.

 

이에 대한 결과를 model 객체를 통해 Attributes로 Front에게 전달한다.

 

 

 

 

다음에는 DB의 Table과 매핑되는 역할을 하는 domain 패키지를 알아볼 예정이다.

반응형