아래 글은 스프링 프레임 워크 첫걸음 책을 기반하여 작성한 글입니다.
드디어!! 이 책의 마지막 챕터이다!
12-1 애플리케이션 레이어
(1) 작성할 내용 확인
No | 레이어 | 컴포턴트 | 이름 | 비고 |
1 | 애플리케이션 레이어 | View | - | 화면 표시 |
2 | 애플리케이션 레이어 | Controller | Quizcontroller | 제어 역할 담당 |
3 | 애플리케이션 레이어 | Form | QuizForm | 화면의 게임 폼을 표현 |
4 | 도메인 레이어 | Service | QuizService | 인터페이스로 생성 |
5 | 도메인 레이어 | ServiceImpl | QuizServiceImpl | Service를 구현 |
6 | 도메인 레이어 | 도메인 객체 | Quiz | 엔티티 역할 |
7 | 도메인 레이어 | Repository | QuizRepository | 인터페이스로 생성 |
8 | 인프라스트럭처 레이어 | RepositoryImpl | - | O/R Mapper로 자동 생성 |
9 | 인프라스트럭처 레이어 | O/R Mapper | - | 스프링 데이터 JDBC를 사용 |
위의 표는 chapter09에서 작성한 이 프로젝트에서 필요한 컴포넌트 목록이다.
이번 장에서는 1-3 컴포넌트를 만들어보겠다.
View에서는 아래처럼 세 개의 HTML파일을 만들겠다.
- crud.html: 등록/변경/삭제/참조 화면
- play.html: 퀴즈를 랜덤으로 표시하는 화면
- answer.html: 해답 화
12-2 애플리케이션 레이어 만들기(목록 표시)
(1) Form 생성
quiz아래에 form 패키지를 만들고, 그 안에 Form 클래스를 아래와 같이 작성한다.
package com.example.quiz.form;
import jakarta.validation.constraints.NotBlank;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/** Form */
@Data
@NoArgsConstructor
@AllArgsConstructor
public class QuizForm {
/** 식별 ID */
private Integer id;
/** 퀴즈 내용 */
@NotBlank
private String question;
/** 퀴즈 해답 */
private Boolean answer;
/** 작성자 */
@NotBlank
private String author;
/** 등록 또는 변경 판단용*/
private Boolean newQuiz;
}
@NoArgsConstructor | 파라미터가 없는 기본 생성자를 생성 |
@AllArgsConstructor | 모든 필드 값을 파라미터로 받는 생성자를 만듦 |
등록일 때는 newQuiz의 값이 true, 변경일 떄는 newQuiz의 값이 false이다.
(2) Controller 생성
controller패키지를 만들고 그 안에 quizController 클래스를 만들어 아래와 같이 코드를 채운다.
package com.example.quiz.controller;
import com.example.quiz.entity.Quiz;
import com.example.quiz.form.QuizForm;
import com.example.quiz.service.QuizService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
/** Quiz 컨트롤러 */
@Controller
@RequestMapping("/quiz")
public class QuizController {
/** DI 대상 */
@Autowired
QuizService service;
/** form-backing bean의 초기화 */
@ModelAttribute
public QuizForm setupForm(){
QuizForm form = new QuizForm();
//라디오 버튼의 초깃값 설정
form.setAnswer(true);
return form;
}
/** Quiz 목록 표시 */
@GetMapping
public String showList(QuizForm quizForm, Model model){
//신규 등록 설정
quizForm.setNewQuiz(true);
//퀴즈 목록 취득
Iterable<Quiz> List = service.selectAll();
//표사용 모델에 저장
model.addAttribute("list", "list");
model.addAttribute("title", "등록 폼");
return "crud";
}
}
@ModelAttribute: 사용자가 요청시 전달하는 값을 오브젝트 형태로 매핑해주는 어노테이션
quizForm.setNewQuiz(true)를 설정해서 등록 화면을 표시한다.
(3) crud.html 생성
templates 폴더 안에 crud.html 파일을 만들어 아래처럼 코드를 채운다.
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>OX 퀴즈 애플리케이션:CRUD</title>
</head>
<body>
<h1>OX 퀴즈 애플리케이션:CRUD</h1>
<h3 th: text="${title}">제목</h3>
<!-- /* 등록/변경 완료 메시지 */-->
<p th:if="${complete}" th:text="${complete}" style="color:blue"></p>
<!-- /* ### Form ### */ -->
<form method="POST"
th:action="${quizForm.newQuiz}? @{/quiz/insert} : @{/quiz/update}"
th:object="${quizForm}">
<label>퀴즈 내용: </label>
<br>
<textarea rows="5" cols="50" th:field="*{question}"></textarea>
<br>
<div th:if="${#fields.hasErrors('question')}" th:errors="*{question}"
style="color:red"></div>
<label>퀴즈 정답: </label>
<br>
<input type="radio" value="true" th:field="*{answer}"> O
<input type="radio" value="false" th:field="*{answer}"> X
<br>
<div th:if="${#fields.hasErrors('answer')}" th:errors="*{answer}"
style="color:red"></div>
<label>작성자: </label>
<br>
<input type="text" th:field="*{author}">
<br>
<div th:if="${#fields.hasErrors('author')}" th:errors="*{author}"
style="color:red"></div>
<input th:if="${id}" type="hidden" th:field="*{id}">
<input type="submit" value="송신">
</form>
<!-- /* ### Form 끝 ### */-->
<br>
<!-- /* 여기까지가 상부영역 */ -->
<hr>
<!-- /* 여기부터가 하부영역 */ -->
<!-- /* ### 신규 등록할 때만 표시하는 부분 ###/-->
<div th:if="${quizForm.newQuiz}" style="margin: 10px">
<h3>등록된 퀴즈 목록 <a th:href="@{/quiz/play}">플레이</a><br></h3>
<!-- 삭제 완료 메시지 */ -->
<p th:if="${delcomplete}" th:text="${delcomplete}" style="color: blue"></p>
<p th:if="${msg}" th:text="${msg}" style="color: blue"></p>
<!-- /* ### 퀴즈 정보가 있으면 표시 ###/-->
<table border="1" th:unless="${#lists.isEmpty(list)}"
style="table-layout: fixed;">
<tr>
<th>ID</th>
<th>내용</th>
<th>해답</th>
<th>작성자</th>
<th>변경</th>
<th>삭제</th>
</tr>
<tr th:each="obj : ${list}" align="center">
<td th:text="${obj.id}"></td>
<td th:text="${obj.question}" align="left"></td>
<td th:text="${obj.answer} == true? O : X"></td>
<td th:text="${obj.author}"></td>
<!-- /* 변경 버튼 */ -->
<td>
<form method="GET" th:action="@{/quiz/{id}(id=${obj.id})}">
<input type="submit" value="변경">
</form>
</td>
<!-- /* 삭제 버튼 */ -->
<td>
<form method="post" th:action="@{/quiz/delete}">
<input type="hidden" name="id" th:value="${obj.id}">
<input type="submit" value="삭제">
</form>
</td>
</tr>
</table>
<!-- /* ### 퀴즈 정보가 없으면 표시 ###/-->
<p th:if="${#lists.isEmpty(list)}">등록된퀴즈가 없습니다.</p>
</div>
<!-- /* ### 신규 등록이 아닐 때 표시 ###/-->
<p th:unless="${quizForm.newQuiz}">
<a href="#" th:href="@{/quiz}">CRUD 화면에 돌아가기</a>
</p>
</body>
</html>
th:object="${quizForm}"은 폼이 서버로 전송될 때 사용되는 객체를 지정한다.
우왕.. 아래에서 th: text를 띄어썼더니 오류가 났다.
<h3 th: text="${title}">제목</h3>
다시 고치고 실행시켰더니 아래와 같은 결과가 나왔다.
12-3 애플리케이션 레이어 만들기(등록/변경/삭제 기능)
(1) 등록 기능 만들기
(2) 변경 기능 만들기
(3) 삭제 기능 만들기
12-4 애플리케이션 레이어 만들기(게임 기능)
(1) play.html 생성
(2) answer.html 생성
(3) 게임 기능 작성
'Back-end > Spring' 카테고리의 다른 글
[Spring] chapter11 애플리케이션 만들기(비즈니스 로직 처리) (0) | 2023.08.07 |
---|---|
[Spring] chapter10 애플리케이션 만들기(데이터베이스 조작) (0) | 2023.08.03 |
[Spring] chapter09 애플리케이션 만들기 (2) | 2023.08.02 |
[Spring] chapter08 유효성 검사 기능 알아보기 (0) | 2023.08.01 |
[Spring] chapter07 요청 파라미터 취득하기 (0) | 2023.07.30 |