Jumbo96 2023. 10. 4. 17:23
728x90
반응형

연휴가 지나갔다.. ㅠoㅠ

# 잡담코너

 GNB

 Global Navigation Bar

 내가  어느 위치에 있든 고정적으로 보여지는 메뉴 바

LNB

 Local Navigation Bar

 

★복습

1. Controller를 만드는 기준

  + 개발자의 암묵적인? 약속?..  GNB에 있는 바에 있는 대분류 Controller를 두고 그 안에 들어갈 하위 컨트롤러를 만든다..?

2. 로그인 주소는 동일하게 맞추고

  +Get 과 Post를 만들어준다. Get으로만 맞춰도 괜찮긴한데 Post로만 맞추는 건 X

     +Get은 조회를 하고 싶을 때 그 외 CRUD 중 R 빼고 Post로 한다. 

     +주소를 아껴야 좋음!

     +로그인시 마지막으로 접속한 날자를 남길때 Post를 사용할 수 도있음 입력이니까!

 

    public String signupPost(@ModelAttribute Owner owner) {
        System.out.println(owner);
        ownerRepository.save(owner);

@ModelAttribute  에 쓰는 명과 save명을 같게

return "redirect:/auth/signup";

Post방식으로 요청을 마무리하면 로그인을 다시하게 됨 들어온게 Post이기에 나온 답도 Post라 Get방식으로 요청을 마무리

# 템플릿을 써서 마무리한게 포워드 라고 함

 

★학습목표

1. 게시글쓰기

2. 조회, 수정

  + 댓글 작성 및 조회

3. AOP

4. Filter / interceptor

 

★ 학습

게시글 기능을 구현할 때 필요한 사항

사람마다 다름!!

1. 디자인 - 사용자가 쓸 수 있는 모습을 보여줘야 함!

                   + imput , textarea 

2. 데이터 베이스 - 작성된 게시글이 저장이 되어야 함! JPA 

                               + Entity (@Entity, @id)

                               + Repository

# JPA를 안쓸경우 create 작성하고 어쩌구 저쩌구 많음

3. Controller - 사용자 요청 -> 응답 (json , redirect, templates)

 

1. 만들기

html 파일을 만들어준다!

<form action="/board/write" method="post">
    <!-- 제목, 내용, ....  -->
    <!-- name이 제대로 작성이 되어야 백엔드에서 편함 -->
<input type="text" name="title">
<textarea name="content" cols="30" rows="10"></textarea>
<button>작성 완료</button>
</form>

Board.java 만들기

package com.example.basic.model;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

import lombok.Data;

@Entity
@Data
public class Board {
    @Id @GeneratedValue
    // id 없으면 프라이머리 키가 없어서 작동안하고
    // @GeneratedValue 순서
    int id;
    String title;
    String content;
}

이렇게 만들어주면  나는 h2를 사용중이기에

h2에 BOARD 파일이 생성!!

작성자칸을 만들면

<th:block th:if="${session.name} == null">
    <input type="text" name="write" placeholder="입력해주세요.">
</th:block>
<th:block th:unless="${session.name} == null">
    <input type="text" name="write" th:value="${session.name}">
</th:block>

HTML에 작성해주고 Board.java에 String wirte 써주면

이렇게 나오는데 이러면 로그인을 안해도 누구나 다쓰게되니까

세션을 이용해서 로그인을 안 했을 경우 작성을 하지 못하게 튕겨내기

    @Autowired
    HttpSession session;

    @GetMapping("/writer")
    public String write() {
        String name = (String) session.getAttribute("name");
    //                          trim 앞뒤 공백제거
        if(name == null || name.trim().equals("")) {
            return "redirect:/auth/signin";
        }
        return "board/write";

이렇게 작성하면 양식화면에서 튕겨낸다.

이후 로그인 화면으로 이동하게되고 로그인을 하고 들어가면

작성자에 name이 찍혀나온다.

보안조치를 더 해줘야 함... 

 

2. title 리스트 만들기

    @GetMapping({"/list","/"}) // 이렇게 하면 board/list써도 되고 board만 해도 이 페이지가 보여지게 됨
    public String list(Model model) {
        List<Board> boardList = boardRepository.findAll(); //model을 안쓰면 boardList 가 html로 전달 x 그래서 model씀
        model.addAttribute("boardList", boardList);
        // model을 씀으로써 연결해줌
        return "board/list";
    }
<ul th:each="board : ${boardList}">
    <li th:text="${board}"></li>
</ul>

 

/ 까지만 써도 보여지게 됨

 

PageRequest 이용해서 페이지 만들어서 보여주기

   @GetMapping({"/list","/"}) // 이렇게 하면 board/list써도 되고 board만 해도 이 페이지가 보여지게 됨
    public String list(Model model,
    @RequestParam(defaultValue = "1") int p) {
        PageRequest page = PageRequest.of(p - 1,2);

        Page<Board> boardList = boardRepository.findAll(page); //model을 안쓰면 boardList 가 html로 전달 x 그래서 model씀
       
        model.addAttribute("boardList", boardList);
        // model을 씀으로써 연결해줌
        return "board/list";
    }

이렇게 3페이지에 애들이 나오게됨 여기서 내림차순으로 만든다면 

        Direction dic = Direction.DESC; //내림차순
        Sort sort = Sort.by(dic, "id");

이렇게 작성해주면 

내림차순으로 나옴..!

목록에서 상세보기로 가게 만들기

<ul th:each="board : ${boardList}">
    <li>
        <a href="">
            [[ ${board.id} ]] / [[ ${board.title} ]]
        </a>
    </li>
</ul>

작성해주면

id와 타이틀만 찍혀나옴

 

3. 상세보기

이제 목록을 클릭시 내용이 보이게 만들면

<ul th:each="board : ${boardList}">
    <li>
        <!-- th:href !! 꼭 th: 를 입력해야 오류가 없음 -->
        <a th:href="@{/board/detail(id=${board.id})}">
            [[ ${board.id} ]] / [[ ${board.title} ]]
        </a>
    </li>
</ul>

list 수정하고 detail이란 HTML 을 만들어준다

<p>번호 : [[${board.id}]]</p>
<p>제목 : [[${board.title}]]</p>
<p>내용 : [[${board.content}]]</p>
<p>작성자 : [[${board.writer}]]</p>
    @GetMapping("/detail")
    public String detail(
        @RequestParam int id, Model model) {
        Optional<Board> opt = boardRepository.findById(id);
        model.addAttribute("board", opt.get());
   
        return "board/detail";
    }

그리고 Controller를 만들어주면 클릭

이렇게 나오게 된다

 

4. 수정하기

수정을 만들려면 html 을 새로만들고 Controller 을 조금만져주면 된다.

우선 detail.html에서 수정버튼을 만든다 여러 예시가 있음

            <!-- 내가 몇번 게시글(id)을 수정할 것인지만 알려주면 됨 -->
            <!-- 세션에 id를 담아놨다가 꺼내써도 좋음 -->
            <!--board.id 가 없으면 데이터를 뿌려줄? 수 없음  -->

    <button th:text="수정" th:onclick="'location=\'/board/update?id=' + ${board.id} '\'' "></button>
                                <!--   '              1묶음         ' + 2묶음        ' ' << 3묶음                  
                                                 ' '; 문법으로 나타내게 되면  ' 를 못쓰니까 \ 로  ' 를 나타냄  -->
    <!-- 접두어/사 namespace // 000: < 이녀석 -->
    <a  th:href="@{/board/update(id=${board.id})}">수정</a>

    <button onclick="update()">수정</button>

    <script>
        function update() {
            location= '/board/update?id=[[${board.id}]]';
        }
    </script>

이런 코드말고도 여러가지가 있을 수 있음!! 

다음 Controller 

     @GetMapping("/update")
    public String update(
        @RequestParam int id, Model model) {
        Optional<Board> opt = boardRepository.findById(id);
        model.addAttribute("board", opt.get());
        return "board/update";
    }
   
    @PostMapping("/update")
        public String updatePost(@ModelAttribute Board board){
        boardRepository.save(board);
        return "redirect:/board/update";
    }
<form action="/board/update" method="post">
    <input type="text" name="title" th:value="${board.title}">
    <textarea name="content" cols="30" rows="10"> [[${board.content}]]</textarea>
    <input type="text" name="writer" th:value="${board.writer}">
    <input type="hidden" name="id" th:value="${board.id}">
<button>수정 완료</button>
</form>

update.html 을 만들어주면

이렇게 내용을 가져와서 수정할 수 있게된다.

수정이다아아 

※ 지금은 PostMapping update에 return 주소를 안바꿔서 오류가 뜨지만 수정은 됨

※ 게시글 수정이나 회원정보 수정이나 똑같은 맥락

 

5.삭제하기

detail.html 에 작성

    <button onclick="remove()">삭제</button>
 
        function remove() {
            const isOk = confirm('삭제하시겠습니까?');
            if(isOk) {
            location= '/board/remove?id=[[${board.id}]]';
            }
        }

Controller에 작성

    @GetMapping("/remove")
    public String remove(@RequestParam int id) {
    Board board = new Board();
    board.setId(id);
    boardRepository.delete(board);
        return "redirect:/board/list";
    }

지저분.. 하지만 이렇게 삭제가 된당.

 

+ 작성자만 삭제하기 코드

    @GetMapping("/remove")
    public String remove(@RequestParam int id) {
        //로그인된 이름
    String loggedName = (String) session.getAttribute("name");
    Optional<Board> dbboard = boardRepository.findById(id);
    // 현재 게시글 작성자 이름
    String savedName = dbboard.get().getWriter();

    //자바의 문자열 비교 주의사항 - equals()
    if(savedName.equals(loggedName)) {
        Board board = new Board();
        board.setId(id);
        boardRepository.delete(board);
    } else{
        return "redirect:/board/detail?id=" + id;
    }
        return "redirect:/board/list";
    }

이러면 session에 저장된 로그인 name과 writer가 일치해야 삭제 가능

 

※연습용이라 데이터베이스 컬럼이랑 게시글이랑 맞추지도 않았음.. 실제로는 컬럼명을 통일해서 프라이머리키와 외래키를 신경써서 만들어야함

 

 

728x90
반응형