관리 메뉴

bright jazz music

guestbook : 07. 등록페이지와 등록처리 (1) 본문

Framework/Spring

guestbook : 07. 등록페이지와 등록처리 (1)

bright jazz music 2022. 7. 11. 09:43

**** 이 페이지를 참고하기 전에 아래의 < guestbook : 07. 등록페이지와 등록처리 (2) >를 참고할 것. ****

 

 

guestbook : 07. 등록페이지와 등록처리 (2)

부트스트랩 관련은 다운 받은 파일을 사용하고 내용물은 전부 내 파일로 채워 넣을 것.

catnails.tistory.com

 

 

 

1. 컨트롤러에 등록을 위한 경로 추가

 

//GuestbookController.java

package com.example.guestbook.controller;

import com.example.guestbook.dto.GuestbookDTO;
import com.example.guestbook.dto.PageRequestDTO;
import com.example.guestbook.service.GuestbookService;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

@Controller
@RequestMapping("/guestbook")
@Log4j2
@RequiredArgsConstructor //자동 주입을 위한 어노테이션
public class GuestbookController {

    private final GuestbookService service; // final로 선언

    @GetMapping("/")
    public String index(){
        return "redirect:/guestbook/list";
    }

    @GetMapping("/list")
    public String list(PageRequestDTO pageRequestDTO, Model model){

        log.info("list...................." + pageRequestDTO);

        // model에 result를 key로 담아서 list 페이지에 뿌려준다.
        model.addAttribute("result", service.getList(pageRequestDTO));

        return "/guestbook/list";
    }

    /*
        SpringDAta JPA를 이용하는 경우 @Pageable 어노테이션으로 Pageable 타입을 이용할 수도 있고,
        application.properties에 0이 아닌 1부터 페이지 번호를 시작하도록 받을 수 있도록 처리할 수도 있다.
        예제에서는 그냥 0부터 받는 방식을 사용하였다. 추후 검색조건 등과 같이 추가로 전달되어야 하는 데이터가
        많을 경우 더욱 복잡해질 수 있기 때문이다.
     */

	//register

    @GetMapping("/register")
    public void register(){
        log.info("register get...");
    }

    @PostMapping("/register")
    public String registerPost(GuestbookDTO dto, RedirectAttributes redirectAttributes){
        log.info("dto..." + dto);

        //새로 추가된 엔티티의 번호
        Long gno = service.register(dto);

        redirectAttributes.addFlashAttribute("msg", gno);
        return "redirect:/guestbook/list";
        /*
        * 등록 작업은 GET 방식에서는  화면을 보여주고 POST 방식에서는 처리 후에 목록페이지로 이동하도록 설계.
        * 이 때 RedirectAttributes를 이용해서 한 번만 화면에서 'msg'라는 이름의 변수를 사용할 수 있도록 처리.
        * addFlashAttribute()는 단 한 번만 데이터를 전달하는 용도로 사용함.
        * --> 브라우저에 전달되는 'msg'를 이용해서 화면 창에 모달 창을 보여주는 용도로 사용.
        * */
    }


}

 

2. 등록 페이지 생성(register.html)

 

templates - guestbook - register.html

 

<!-- register.html -->

<!DOCTYPE html>
<html lang="en" xmlns="http://www.thymeleaf.org">
<th:block th:replace="~{/layout/basic :: setContent(~{this::content})}">
    <th:block th:fragment="content">
        <h1 class="mt-4">GuestBook Register Page</h1>

        <form th:action="@{/guestbook/register}" th:method="post">
            <div class="form-group">
                <label>Title</label>
                <input type="text" class="form-control" name="title" placeholder="Enter Title">
            </div>
            <div class="form-group">
                <label>Content</label>
                <textarea class="form-control" rows="5" name="content"></textarea>
            </div>
            <div class="form-group">
                <label>Writer</label>
                <input type="text" class="form-control" name="writer" placeholder="Enter Writer">
            </div>

            <button type="submit" class="btn btn-primary">Submit</button>
        </form>
    </th:block>
</th:block>

<!--form 태그에는 action 속성값을 /guestbook/register로 지정하고 POST 방식으로 전송할 수 있도록 처리한다.
input 태그에는 적절한 name 값을 지정해야 하는데 GuestbookDTO로 수집될 테이터이므로 동일하게 맞춰주면 자동 수집된다.
-->

 

 

 

 

3. 등록 처리와 목록 페이지의 모달창

 

현재는 등록처리가 이루어 진 후 '/guestbook/list'로 이동한다.

처리 된 후에는 처리 되었다는 결과를 보여줄 필요가 있다. 이를 위해 모달창을 사용한다.

 

3-1 자바스크립트를 이용해서 데이터를 등록한 후에 전달되는 msg 값을 확인하기.

 

<!--list.html-->

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">

<th:block th:replace="~{/layout/basic :: setContent(~{this::content})}">

    <th:block th:fragment="content">
        <h1>GuestBook List Page!!!!</h1>

        <table class="table table-striped"> <!--테이블이 줄무늬로 나옴. table-hover 하면 커서가 올라가면 색 바뀜  -->
            <thead>
            <tr>
                <th scope="col">#</th>
<!--                <th scope="col">Gno</th>-->
                <th scope="col">Title</th>
                <th scope="col">Writer</th>
                <th scope="col">Regdate</th>
            </tr>
            </thead>
            <tbody>
            <tr th:each="dto : ${result.dtoList}"> <!--PageResultDTO안에 들어있는 dtoList 반복처리-->
                <th scope="row">[[${dto.gno}]]</th>
                <td>[[${dto.title}]]</td>
                <td>[[${dto.writer}]]</td>
<!--                <td>[[${dto.regDate}]]</td>-->
                <td>[[${#temporals.format(dto.regDate, 'yyyy/MM/dd')}]]</td><!--등록일자를 포맷으로 출력-->
            </tr>
            </tbody>
        </table>

        <!-- 페이지 이동을 위한 태그-->
        <ul class="pagination h-100 justify-content-center align-items-center"> <!-- ul 태그 안에는 전부 적용 -->
            <!--h-100: 가로로 표시, justify-content-center: 페이지의 중앙에 표시 왼쪽은 start 오른쪽은 end-->

            <li class="page-item" th:if="${result.prev}">
                <a class="page-link" th:href="@{/guestbook/list(page= ${result.start -1 })}"
                   tabindex="-1">Previous!</a>
                <!-- pageSize가 10이기 떄문에 11페이지 이상부터 Previous! 버튼이 나타난다.-->
            </li>

            <li th:class=" 'page-item ' + ${result.page == page?'active':''} "th:each="page: ${result.pageList}">
                <a class="page-link" th:href="@{/guestbook/list(page= ${page})}">
                    [[${page}]]
                </a>
            </li>

            <li class="page-item" th:if="${result.next}">
                <a class="page-link" th:href="@{/guestbook/list(page= ${result.end + 1})}">Next!</a>
            </li>
        </ul>
        <!-- 추가 태그 끝
            '이전(previous)'과 '다음(next)' 부분은 Thymeleaf의 if를 이용해서 처리.
            페이지 중간에 현재 페이지 여부를 체크해서 'active'라는 이름의 클래스가 출력되도록 작성

        -->
    <!-- 모달창 관련 -->
    <div class="modal" tabindex="-1" role="dialog">
        <div class="modal-dialog" role="document">
            <div class="modal-header">
                <h5 class="modal-title">Modal title!</h5>
                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                    <span aria-hidden="true">&times;</span>
                </button>
            </div>
            <div class="modal-body">
                <p>Modal body text goes here.</p>
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
                <button type="button" class="btn btn-primary">Save changes</button>
            </div>
        </div>
    </div>    
        
        
    <script th:inline="javascript">
        //여기에 자바스크립트 추가됨.
        var msg = [[${msg}}]]
        console.log(msg)
        //Thymeleaf의 inline 속성을 이용해 처리하면 별도의 타입처리가 필요치 않다.
    </script>

    </th:block>

</th:block>

아래의 모달창 관련 내용과 자바스크립트가 추가되었다.

 

 

 

Comments