프로그래밍/spring boot

[스프링부트] 실전! 스프링 부트와 JPA 활용1 #7 웹 계층 개발(1)

aSpring 2023. 11. 7. 02:59
728x90
728x90
※ 본 포스팅은 김영한 강사님의 인프런 '실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발' 강의를 들으며 작성한 수강일지 입니다.

 

| 웹 계층 개발

1. 홈 화면과 레이아웃
2. 회원 등록
3. 회원 목록 조회
4. 상품 등록
5. 상품 목록
6. 상품 수정
7. 변경 감지와 병합(merge)
8. 상품 주문
9. 주문 목록으로 검색, 취소
10. 다음으로

 

1. 홈 화면과 레이아웃

홈 컨트롤러 등록

package jpabook.jpashop.controller;

import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
@Slf4j // log
public class HomeController {

//    Logger log = LoggerFactory.getLogger(getClass()); // -> lombok annotation 써주면 됨

    @RequestMapping("/")
    public String home() {
        log.info("home controller");
        return "home"; // home.html thymeleaf 파일을 찾아가게 됨
    }
}

 

 

스프링 부트 타임리프 기본 설정 -> 강의에서는 기본적인 설정을 사용하므로 따로 해주지 않아도 된다고 함

spring:
 thymeleaf:
   prefix: classpath:/templates/
   suffix: .html
  • 스프링 부트 타임리프 viewName 매핑
    • resources:templates/ + (ViewName) + .html
    • resources:templates/home.html
    • 변환한 문자(home)과 스프링부트 설정 prefix, suffix 정보를 사용해 렌더링할 뷰(html)를 찾는다.
참고 
https://docs.spring.io/spring-boot/docs/2.1.7.RELEASE/reference/html/commonapplication-properties.html

 

타임리프 템플릿 등록

 

home.html

<!DOCTYPE HTML>
<!--th 이 네임태그를 가지고 thymeleaf의 속성을 쓸 수 있음-->
<html xmlns:th="http://www.thymeleaf.org">
<!--replace : incude처럼-->
<head th:replace="fragments/header :: header">
    <title>Hello</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<div class="container">
    <div th:replace="fragments/bodyHeader :: bodyHeader" />
    <div class="jumbotron">
        <h1>HELLO SHOP</h1>
        <p class="lead">회원 기능</p>
        <p>
            <a class="btn btn-lg btn-secondary" href="/members/new">회원 가입</a>
            <a class="btn btn-lg btn-secondary" href="/members">회원 목록</a>
        </p>
        <p class="lead">상품 기능</p>
        <p>
            <a class="btn btn-lg btn-dark" href="/items/new">상품 등록</a>
            <a class="btn btn-lg btn-dark" href="/items">상품 목록</a>
        </p>
        <p class="lead">주문 기능</p>
        <p>
            <a class="btn btn-lg btn-info" href="/order">상품 주문</a>
            <a class="btn btn-lg btn-info" href="/orders">주문 내역</a>
        </p>
    </div>
    <div th:replace="fragments/footer :: footer" />
</div> <!-- /container -->
</body>
</html>

 

fragments/bodyHeader.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<div class="header" th:fragment="bodyHeader">
    <ul class="nav nav-pills pull-right">
        <li><a href="/">Home</a></li>
    </ul>
    <a href="/"><h3 class="text-muted">HELLO SHOP</h3></a>
</div>

fragments/footer.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<div class="footer" th:fragment="footer">
    <p>&copy; Hello Shop V2</p>
</div>

 

fragments/header.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head th:fragment="header">
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrinkto-fit=no">
    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="/css/bootstrap.min.css" integrity="sha384-
ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T"
          crossorigin="anonymous">
    <!-- Custom styles for this template -->
    <link href="/css/jumbotron-narrow.css" rel="stylesheet">
    <title>Hello, world!</title>
</head>

 

실행하기

- html이 아니라 server를 실행해야 함

-> JpashopApplication 실행 (그 전에 h2도 실행하는 것 잊지말기)

 

참고: Hierarchical-style layouts
예제에서는 뷰 템플릿을 최대한 간단하게 설명하려고, header , footer 같은 템플릿 파일을 반복해서 포 함한다. 다음 링크의 Hierarchical-style layouts을 참고하면 이런 부분도 중복을 제거할 수 있다.
https://www.thymeleaf.org/doc/articles/layouts.html
참고: 뷰 템플릿 변경사항을 서버 재시작 없이 즉시 반영하기
1. spring-boot-devtools 추가
2. html 파일 build-> Recompile

 

view 리소스 등록

예쁜 디자인을 위해 부트스트랩(https://getbootstrap.com/) 사용

- 강의에서 사용한 버전 4.3.1

- 버전을 맞추기 위해서 All releases -> 4.3 -> 우측 상단 Download 버튼 -> 4.3.1 Download

- 다운로드 받은 압축파일을 압축 해제 -> css, js 전부 복사

 

  • resources/static 하위에 css , js 추가

- recompile

- 강제로 붙여넣은 것이기 때문에 적용이 안되었으면 다음과 같이 따라하기

- Synchronize한 후, Rebuild 또는 Build Project -> intelliJ가 resource를 인식함

 

  • resources/static/css/jumbotron-narrow.css 추가

jumbotron-narrow.css 파일

/* Space out content a bit */
body {
 padding-top: 20px;
 padding-bottom: 20px;
}
/* Everything but the jumbotron gets side spacing for mobile first views */
.header,
.marketing,
.footer {
 padding-left: 15px;
 padding-right: 15px;
}
/* Custom page header */
.header {
 border-bottom: 1px solid #e5e5e5;
}
/* Make the masthead heading the same height as the navigation */
.header h3 {
 margin-top: 0;
 margin-bottom: 0;
 line-height: 40px;
 padding-bottom: 19px;
}
/* Custom page footer */
.footer {
 padding-top: 19px;
 color: #777;
 border-top: 1px solid #e5e5e5;
}
/* Customize container */
@media (min-width: 768px) {
 .container {
 max-width: 730px;
 }
}
.container-narrow > hr {
 margin: 30px 0;
}
/* Main marketing message and sign up button */
.jumbotron {
 text-align: center;
 border-bottom: 1px solid #e5e5e5;
}
.jumbotron .btn {
 font-size: 21px;
 padding: 14px 24px;
}
/* Supporting marketing content */
.marketing {
 margin: 40px 0;
}
.marketing p + h4 {
 margin-top: 28px;
}
/* Responsive: Portrait tablets and up */
@media screen and (min-width: 768px) {
 /* Remove the padding we set earlier */
 .header,
 .marketing,
 .footer {
 padding-left: 0;
 padding-right: 0;
 }
 /* Space out the masthead */
 .header {
 margin-bottom: 30px;
 }
 /* Remove the bottom border on the jumbotron for visual effect */
 .jumbotron {
 border-bottom: 0;
 }
}

- 예쁘게 정렬된 모습

 

 

728x90
728x90