본문 바로가기
ToyProject

스프링 게시판 만들기 - 3 (화면 생성 / HTML , CSS with BootStrap 사용법)

by 완두완두콩 2022. 1. 14.

파일 경로


현재 디렉토리 구조

 

※ static 아래 index.html(파일명 동일) 을 두는 경우 , spring boot 에서는 자동으로 welcomePage 로 인식해서

localhost:8080 을 띄우는 경우 , 첫 화면으로 생성된다.

static 하위에 정적 리소스들인 css , js 폴더를 생성하고 , templates 하위에는 동적 리소스들(HTML 에서 Thymeleaf 를 쓴다거나.. 로직이 들어가서 화면이 렌더링 되는 부분) 을 넣는다.

 

이왕 만드는 프로젝트 , css 도 없이 그냥 하는 것보다는 이쁜 UI 로 꾸며서 하는게 좋지만 

프론트에 많은 힘을 들이고 싶지 않으신 분들은 저처럼 부트스트랩을 이용하는 것을 추천드립니다.

(힘들이지 않으려 했는데 혼자 몇 시간을 삽질했는지는 비밀.....)

 

초심자를 위한 부트스트랩 사용법


https://getbootstrap.com/docs/5.1/getting-started/download/   (부트스트랩 링크)

 

다운로드 링크
다운로드 파일

 

상단의 URL 에 접속하셔서 다운로드 받으시면 위와 같은 파일이 다운 됩니다.

 

압축을 푸시면 css, js 파일이 나오는데 해당 파일을 전부 복사 -> resources / static  에 복사 해주면 됩니다. 

(최상단 디렉토리 경로 이미지 확인)

 

여기까지가 부트 스트랩을 사용하기 위한 기본 세팅입니다.

이제부터는 header 를 적용해보겠습니다.

 

https://getbootstrap.com/docs/5.1/examples/ (부트스트랩 기본 템플릿 링크)

 

Examples

Quickly get a project started with any of our examples ranging from using parts of the framework to custom components and layouts.

getbootstrap.com

 

위 링크를 타고 들어가면 다음과 같은 snippets 를 볼 수 있습니다. 부트스트랩에서 제공하는 기본적인 화면 틀이라고 생각하면 될 것 같습니다.

Header 를 만들어 볼 것이기 때문에 Headers 를 클릭하고 F12 를 통해 개발자 모드를 띄우면

다음과 같은 화면이 뜨게 됩니다. 개발자 모드에서 요소(elements) 클릭 후 , main 을 눌러주면

 

다음과 같이 각각의 <div class ="container">가 보이고 그 위 아래로 b-example-divider 가 보이는 것을 확인할 수 있습니다.

각 div 에 마우스를 올리면 해당 div 가 어떤 디자인인지 확인이 가능하고 , 원하는 디자인을 선택하셨으면

 다음과 같이 복사해서 paste 하면 코드가 그대로 복사됩니다.

저는 게시판으로 이동하기 위한 버튼과 로그인 , 회원 가입 그리고 추후 검색을 위해 해당 디자인으로 선택했습니다.

HTML


 

Index.html

<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="description" content="">
    <meta name="author" content="Mark Otto, Jacob Thornton, and Bootstrap contributors">
    <meta name="generator" content="Hugo 0.88.1">
    <title>Index</title>
    <link rel="canonical" href="https://getbootstrap.com/docs/5.1/examples/headers/">



    <!-- Bootstrap core CSS -->
    <link href="css/bootstrap.min.css" rel="stylesheet">
    <link href="css/headers.css" rel="stylesheet">
    <style>
        .bd-placeholder-img {
            font-size: 1.125rem;
            text-anchor: middle;
            -webkit-user-select: none;
            -moz-user-select: none;
            user-select: none;
        }

        @media (min-width: 768px) {
            .bd-placeholder-img-lg {
                font-size: 3.5rem;
            }
        }
    </style>
    <!-- Custom styles for this template -->

</head>
<body>

<main>


    <header class="p-3 bg-dark text-white">
        <div class="container">
            <div class="d-flex flex-wrap align-items-center justify-content-center justify-content-lg-start">
                <a href="/" class="d-flex align-items-center mb-2 mb-lg-0 text-white text-decoration-none">
                    <svg class="bi me-2" width="40" height="32" role="img" aria-label="Bootstrap"><use xlink:href="#bootstrap"/></svg>
                </a>

                <ul class="nav col-12 col-lg-auto me-lg-auto mb-2 justify-content-center mb-md-0">
                    <li><a href="#" class="nav-link px-2 text-secondary">Home</a></li>
                    <li><a href="#" class="nav-link px-2 text-white">Board</a></li>
                    <li><a href="#" class="nav-link px-2 text-white">Pricing</a></li>
                    <li><a href="#" class="nav-link px-2 text-white">FAQs</a></li>
                    <li><a href="#" class="nav-link px-2 text-white">About</a></li>
                </ul>

                <form class="col-12 col-lg-auto mb-3 mb-lg-0 me-lg-3">
                    <input type="search" class="form-control form-control-dark" placeholder="Search..." aria-label="Search">
                </form>

                <div class="text-end">
                    <button type="button" class="btn btn-outline-light me-2" onclick="location.href='/member/memberLoginForm'">Login</button>
                    <button type="button" class="btn btn-warning" onclick="location.href='/member/memberJoinForm'">Sign-up</button>
                </div>
            </div>
        </div>
    </header>

</main>


<script src="js/bootstrap.bundle.min.js"></script>


</body>
</html>

 

Header 만 적용한 index.html 입니다. 로직이 잘 생성됐는지 확인하고 , DB 에 값을 입력해보기 위해 간단하게

welcomePage 를 만들었습니다.

 

/member/memberJoinForm.html

<!doctype html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="description" content="">
    <meta name="author" content="Mark Otto, Jacob Thornton, and Bootstrap contributors">
    <meta name="generator" content="Hugo 0.88.1">
    <title>Sing In</title>
    <link rel="canonical" href="https://getbootstrap.com/docs/5.1/examples/sign-in/">



    <!-- Bootstrap core CSS -->
    <link href="/static/css/bootstrap.min.css"
          th:href="@{/css/bootstrap.min.css}"rel="stylesheet">
    <link href="/static/css/signin.css"
          th:href="@{/css/signin.css}"rel="stylesheet">
    <link href="/static/css/headers.css"
          th:href="@{/css/headers.css}" rel="stylesheet">
    <style>
        .bd-placeholder-img {
            font-size: 1.125rem;
            text-anchor: middle;
            -webkit-user-select: none;
            -moz-user-select: none;
            user-select: none;
        }

        @media (min-width: 768px) {
            .bd-placeholder-img-lg {
                font-size: 3.5rem;
            }
        }
    </style>


    <!-- Custom styles for this template -->
</head>
<body class="text-center">

<main class="form-signin">
    <form action="memberJoinForm.html" th:action method="post">

        <!--    <img class="mb-4" src="../assets/brand/bootstrap-logo.svg" alt="" width="72" height="57">-->
        <h1 class="h3 mb-3 fw-normal">Please sign in</h1>

        <div class="form-floating">
            <input type="text" class="form-control" id="username" name="username" placeholder="Username">
            <label for="username">username</label>
        </div>
        <div class="form-floating">
            <input type="password" class="form-control" id="password" name="password" placeholder="Password">
            <label for="password">Password</label>
        </div>
        <div class="form-floating">
            <input type="text" class="form-control" id="email" name="email" placeholder="name@example.com">
            <label for="email">Email</label>
        </div>
        <div class="checkbox mb-3">
            <label>
                <input type="checkbox" value="remember-me"> Remember me
            </label>
        </div>
        <button class="w-100 btn btn-lg btn-primary" type="submit">Sign in</button>
        <button class="w-100 btn btn-secondary btn-lg"
                onclick="location.href='memberList.html'"
                th:onclick="|location.href='@{/member/memberList}'|"
                type="button">취소</button>
        <p class="mt-5 mb-3 text-muted">&copy; 2017–2021</p>

    </form>
</main>



</body>
</html>

 

/member/memberSaved.html

<!doctype html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="description" content="">
    <meta name="author" content="Mark Otto, Jacob Thornton, and Bootstrap contributors">
    <meta name="generator" content="Hugo 0.88.1">
    <title>Signin Template · Bootstrap v5.1</title>
    <link rel="canonical" href="https://getbootstrap.com/docs/5.1/examples/sign-in/">



    <!-- Bootstrap core CSS -->
    <link href="/static/css/bootstrap.min.css"
          th:href="@{/css/bootstrap.min.css}"rel="stylesheet">
    <link href="/static/css/signin.css"
          th:href="@{/css/signin.css}"rel="stylesheet">
    <link href="/static/css/headers.css"
          th:href="@{/css/headers.css}" rel="stylesheet">
    <style>
        .bd-placeholder-img {
            font-size: 1.125rem;
            text-anchor: middle;
            -webkit-user-select: none;
            -moz-user-select: none;
            user-select: none;
        }

        @media (min-width: 768px) {
            .bd-placeholder-img-lg {
                font-size: 3.5rem;
            }
        }
    </style>


    <!-- Custom styles for this template -->
</head>
<body>
<div class="container">

    <div class="py-5 text-center">
        <h2>회원가입 결과</h2>
    </div>
<!-- 추가 -->
<!--<h2 th:if="${param.status}" th:text="'저장 완료!'"></h2>-->
    <div>
    <label for="memberId">식별 ID</label>
    <input type="text" id="memberId" name="memberId" class="form-control" value="1" th:value="${member.id}"readonly>
</div>
<div>
    <label for="username">회원 아이디</label>
    <input type="text" id="username" name="username" class="form-control" value="상품A" th:value="${member.username}"readonly>
</div>
<div>
    <label for="password">비밀번호</label>
    <input type="text" id="password" name="password" class="form-control" value="10000" th:value="${member.password}" readonly>
</div>
<div>
    <label for="email">이메일</label>
    <input type="text" id="email" name="email" class="form-control" value="10" th:value="${member.email}" readonly>
</div>

<hr class="my-4">

<div class="row">
    <div class="col">
        <button class="w-100 btn btn-primary btn-lg"
                onclick="location.href='editForm.html'"
                th:onclick="|location.href='@{/member/memberList/{memberId}/memberEditForm(memberId=${member.id})}'|"
                type="button">회원 정보 수정</button>
    </div>
    <div class="col">
        <button class="w-100 btn btn-secondary btn-lg"
                onclick="location.href='index.html'"
                th:onclick="|location.href='@{/index.html}'|"
                type="button">메인으로</button>
    </div>
</div>

</div> <!-- /container -->
</div>
</body>
</html>

 

메인화면 - index.html  / 회원 가입을 위한 폼 화면 - memberJoinForm.html /

회원 가입 결과 = memberSaved.html

memberJoinForm.html
memberSaved.html

 

 

※ 참고 : html 파일의 경로를 templates 가  아닌 static 에 두게 되면 , 일반 사용자 누구든 url 을 통해 접근할 수 있기 때문에 static 에는 웬만하면 html 을 넣어놓지 말 것 !

 

※ 참고 : html 파일을 보면 th:onclick 등의 Thymeleaf 문법이 사용된 것을 알 수 있다. 

onclick="location.href='index.html'"
th:onclick="|location.href='@{/index.html}'|"

기존 onclick 은 무시되고 th:onclick 이 불려지게 되므로 onclick 은 삭제해도 무방.

그 외에도 th:value 등 여러 문법이 사용됐으니 참고.

 

※ 참고 : button 등 경로 설정에 주의 바랍니다. (저와 똑같은 디렉토리 구조로 생성한다면 문제 없을 것 같습니다.)

 

다음편!

https://dodokong.tistory.com/22?category=1249752

 

스프링 게시판 만들기 - 4 (회원 가입 & Controller 만들기)

스프링 게시판 만들기 - 2 에서 도메인 생성 & 회원 가입 로직 & 테스트 케이스를 작성해보았고 , 스프링 게시판 만들기 - 3 에서 프론트 화면을 만들어 보았다. https://dodokong.tistory.com/entry/%EC%8A%A4%ED

dodokong.tistory.com

 

댓글