목차 (클릭시 해당 목차로 이동)
이제는 View 계층 설계 및 구현의 차례이다.
index.html 제작
설계
- body header와 footer는 모든 곳에서 쓰기 때문에 여기서 미리 제작해놓는다.
- 점보트론으로 CLASS FLIX를 표시한다.
- NetFlix의 뷰 아이디어를 따왔다. 홈화면에서 category별 인터넷 강의를 바로 볼 수 있도록 한다.
구현
header
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head th:fragment="header">
<title>CLASS FLIX</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="viewport" content="width=device-width" initial-scale="1">
<link rel="stylesheet" href="/css/bootstrap.css">
<link rel="stylesheet" href="/css/classflix.css">
</head>
bodyHeader
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<nav th:fragment="bodyHeader" class="navbar navbar-default">
<div class="container-fluid">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse"
data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
<span class="sr-only"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="/">CLASS FLIX</a>
</div>
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav navbar-right">
<li><a href="/members/new">회원가입<span class="sr-only"></span></a></li>
<li><a href="#">강의등록</a></li>
</ul>
</div>
</div>
</nav>
footer
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<footer th:fragment="footer" style="background-color: #000000; color: #ffffff">
<div class="container">
<br>
<div calss="row">
<div class="col-sm-4" style="text-align: center;"><h5>Copyright © 2021</h5><h5>김동호(Dongho Kim)</h5></div>
<div class="col-sm-4"><h4>대표자 소개</h4><p>저는 CLASS FLIX의 대표 김동호입니다. 홍익대학교 컴퓨터공학과에 재학중입니다.</p></div>
<div class="col-sm-4"><h4 style="text-align: center;">SNS</h4>
<div class="list-group">
<a href="https://www.youtube.com/channel/UCzPBLnZ88905X61WRQy9EpQ" class="list-group-item">유투브</a>
<a href="https://www.github.com/dongho108" class="list-group-item">깃허브</a>
<a href="https://ksabs.tistory.com/" class="list-group-item">블로그</a>
</div>
</div>
</div>
</div>
</footer>
home (index.html)
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head th:replace="fragments/header :: header">
</head>
<body>
<style type="text/css">
.jumbotron {
text-shadow: black 0.2em 0.2em 0.2em;
color: red;
}
.lecture-images {
width: 128px;
height: 83px;
}
.panel-heading {
font-weight: bold;
background-color: white;
}
.lecture-title {
font-weight: bold;
}
.star_rating {font-size:0; letter-spacing:-4px;}
.star_rating a {
font-size:22px;
letter-spacing:0;
display:inline-block;
margin-left:5px;
color:#ccc;
text-decoration:none;
}
.star_rating a:first-child {margin-left:0;}
.star_rating a.on {color:#E1BC3F;}
</style>
<div th:replace="fragments/bodyHeader :: bodyHeader" />
<div class="container">
<div class="jumbotron">
<h1 class="text-center"> CLASS FLIX</h1>
<p class="text-center" style="text-shadow: none"> 인강 추천좀 </p>
</div>
<div class="row">
<div class="panel panel-default">
<div class="panel-heading">IT 분야 인기 강의</div>
<div class="panel-body">
<div class="col-md-3">
<img class="lecture-images" src="/images/springInstroduction.png" alt="스프링입문">
<h5 class="lecture-title">스프링입문</h5>
<p class="star_rating">
<a href="#" class="on">★</a>
<a href="#" class="on">★</a>
<a href="#" class="on">★</a>
<a href="#" class="on">★</a>
<a href="#" class="on">★</a>
</p>
</div>
<div class="col-md-3">
<img class="lecture-images" src="/images/springCore.jpeg" alt="스프링코어">
<h5 class="lecture-title" >스프링코어</h5>
<p class="star_rating">
<a href="#" class="on">★</a>
<a href="#" class="on">★</a>
<a href="#" class="on">★</a>
<a href="#" class="on">★</a>
<a href="#">★</a>
</p>
</div>
<div class="col-md-3">
<img class="lecture-images" src="/images/jpa.png" alt="jpa기초">
<h5 class="lecture-title" >JPA기초</h5>
<p class="star_rating">
<a href="#" class="on">★</a>
<a href="#" class="on">★</a>
<a href="#" class="on">★</a>
<a href="#">★</a>
<a href="#">★</a>
</p>
</div>
<div class="col-md-3">
<img class="lecture-images" src="/images/jpaPrac1.png" alt="jpa활용1">
<h5 class="lecture-title" >JPA활용1</h5>
<p class="star_rating">
<a href="#" class="on">★</a>
<a href="#" class="on">★</a>
<a href="#" class="on">★</a>
<a href="#" class="on">★</a>
<a href="#" class="on">★</a>
</p>
</div>
</div>
</div>
<div class="panel panel-default">
<div class="panel-heading">요리 분야 인기 강의</div>
<div class="panel-body">
<div class="col-md-3">
<img class="lecture-images" src="/images/springInstroduction.png" alt="스프링입문">
<h5 class="lecture-title">스프링입문</h5>
<p class="star_rating">
<a href="#" class="on">★</a>
<a href="#" class="on">★</a>
<a href="#" class="on">★</a>
<a href="#" class="on">★</a>
<a href="#" class="on">★</a>
</p>
</div>
<div class="col-md-3">
<img class="lecture-images" src="/images/springCore.jpeg" alt="스프링코어">
<h5 class="lecture-title" >스프링코어</h5>
<p class="star_rating">
<a href="#" class="on">★</a>
<a href="#" class="on">★</a>
<a href="#" class="on">★</a>
<a href="#" class="on">★</a>
<a href="#">★</a>
</p>
</div>
<div class="col-md-3">
<img class="lecture-images" src="/images/jpa.png" alt="jpa기초">
<h5 class="lecture-title" >JPA기초</h5>
<p class="star_rating">
<a href="#" class="on">★</a>
<a href="#" class="on">★</a>
<a href="#" class="on">★</a>
<a href="#">★</a>
<a href="#">★</a>
</p>
</div>
<div class="col-md-3">
<img class="lecture-images" src="/images/jpaPrac1.png" alt="jpa활용1">
<h5 class="lecture-title" >JPA활용1</h5>
<p class="star_rating">
<a href="#" class="on">★</a>
<a href="#" class="on">★</a>
<a href="#" class="on">★</a>
<a href="#" class="on">★</a>
<a href="#" class="on">★</a>
</p>
</div>
</div>
</div>
</div>
</div>
<div th:replace="fragments/footer :: footer" />
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
</body>
</html>
결과
* 강의부분은 어떻게 구성되어야할지 미리 테스트 이미지와 데이터를 html 상에서 넣어놓았다.
MemberForm 제작
설계
- Member에 대한 정보 (이름, 나이, 성별, 직업)을 등록할 수 있게한다.
- 내비게이션의 회원가입을 누르면 연결될 수 있도록 한다.
구현
memberForm
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head th:replace="fragments/header :: header" />
<style>
.fieldError {
border-color: #bd2130;
}
</style>
<body>
<div th:replace="fragments/bodyHeader :: bodyHeader"/>
<div class="container">
<div class="page-header">
<h1 class="text-center">회원가입</h1>
</div>
<form role="form" action="/members/new" th:object="${memberForm}"
method="post">
<div class="form-group">
<label th:for="name">이름</label>
<input type="text" th:field="*{name}" class="form-control" placeholder="이름을 입력하세요"
th:class="${#fields.hasErrors('name')}? 'form-control fieldError' : 'form-control'">
<p th:if="${#fields.hasErrors('name')}" th:errors="*{name}">Incorrect date</p>
</div>
<div class="form-group">
<label th:for="age">나이</label>
<input type="text" th:field="*{age}" class="form-control"placeholder="나이를 입력하세요">
</div>
<div class="form-group">
<label th:for="gender">성별</label>
<input type="text" th:field="*{gender}" class="form-control"
placeholder="성별을 입력하세요">
</div>
<div class="form-group">
<label th:for="career">직업</label>
<input type="text" th:field="*{career}" class="form-control"
placeholder="직업을 입력하세요">
</div>
<div class="text-center">
<button type="submit" class="btn btn-primary">등록하기</button>
</div>
</form>
<br/>
</div> <!-- /container -->
<div th:replace="fragments/footer :: footer" />
</body>
</html>
컨트롤러
설계
- HomeController 에서 첫 화면 (홈화면)을 연결한다.
- MemberController에서 memberForm을 연결한다. (정보는 DTO로 전달)
- memberForm dto에서는 이름을 필수로 적게 @NotEmpty를 건다.
구현
HomeController
package dongho.classflix.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class HomeController {
@RequestMapping("/")
public String home() {
return "home";
}
}
MemberController
package dongho.classflix.controller;
import dongho.classflix.service.MemberService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
@RequiredArgsConstructor
public class MemberController {
private final MemberService memberService;
@GetMapping("/members/new")
public String createForm(Model model) {
model.addAttribute("memberForm", new MemberForm());
return "members/memberForm";
}
}
MemberForm (dto)
package dongho.classflix.controller;
import dongho.classflix.domain.Gender;
import lombok.Getter;
import lombok.Setter;
import javax.validation.constraints.NotEmpty;
@Getter
@Setter
public class MemberForm {
@NotEmpty(message = "회원 이름은 필수 입니다")
private String name;
private int age;
private Gender gender;
private String career;
}
memberForm.html
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head th:replace="fragments/header :: header" />
<style>
.fieldError {
border-color: #bd2130;
}
</style>
<body>
<div th:replace="fragments/bodyHeader :: bodyHeader"/>
<div class="container">
<div class="page-header">
<h1 class="text-center">회원가입</h1>
</div>
<form role="form" action="/members/new" th:object="${memberForm}"
method="post">
<div class="form-group">
<label th:for="name">이름</label>
<input type="text" th:field="*{name}" class="form-control" placeholder="이름을 입력하세요"
th:class="${#fields.hasErrors('name')}? 'form-control fieldError' : 'form-control'">
<p th:if="${#fields.hasErrors('name')}" th:errors="*{name}">Incorrect date</p>
</div>
<div class="form-group">
<label th:for="age">나이</label>
<input type="text" th:field="*{age}" class="form-control"placeholder="나이를 입력하세요">
</div>
<div class="form-group">
<label th:for="gender">성별</label>
<input type="text" th:field="*{gender}" class="form-control"
placeholder="성별을 입력하세요">
</div>
<div class="form-group">
<label th:for="career">직업</label>
<input type="text" th:field="*{career}" class="form-control"
placeholder="직업을 입력하세요">
</div>
<div class="text-center">
<button type="submit" class="btn btn-primary">등록하기</button>
</div>
</form>
<br/>
</div> <!-- /container -->
<div th:replace="fragments/footer :: footer" />
</body>
</html>
'Project > ClassFlix' 카테고리의 다른 글
[ClassFlix] EP 7. view 페이지 제작과 컨트롤러 연결 - 3 (0) | 2021.04.30 |
---|---|
[ClassFlix] EP 6. view 페이지 제작과 컨트롤러 연결 - 2 (0) | 2021.04.29 |
[ClassFlix] EP 4. domain, repository, service 계층별 설계 및 구현 (0) | 2021.04.26 |
[ClassFlix] EP 3. 도메인 설계와 테이블 생성 (0) | 2021.04.21 |
[ClassFlix] EP 2. 개발환경 세팅 (0) | 2021.04.21 |