웹과 잘 연결이 되었는지 확인을 했으니, 이제 진짜 웹에서 기능을 구현할 차례다~!
웹의 요청과 연결되는 부분은 Controller이다.
웹에 board/write.do 주소로 들어가면 게시글을 작성한다.
@GetMapping(value = "/board/write.do")
public String openBoardWrite(@RequestParam(value = "idx", required = false) Long idx, Model model) {
if (idx == null) {
model.addAttribute("board", new BoardDTO());
} else {
BoardDTO board = boardService.getBoardDetail(idx);
if (board == null) {
return "redirect:/board/list.do";
}
model.addAttribute("board", board);
}
// String title = "제목";
// model.addAttribute("t", title);
return "board/write";
}
이전에는 주석처리처럼 직접 넣었던 것을, 웹의 폼에 입력한 값을 전달한다.
/board/wirte.do 엔드포인트에 대한 GET 요청을 처리한다.
@RequestParam
: idx 파라미터를 쿼리 스트링에서 가져온다.
required가 false면 이 값이 필수가 아니고, 값이 없으면 null 처리된다.
if(idx==null) : 인덱스를 전달받지 않았다면, 새로운 BoardDTO 객체를 생성하여 board라는 이름으로 모델에 추가한다.
else : 해당 idx를 가진 게시글의 상세정보를 가져온다. 만약 해당하는 게시글이 없다면 (삭제되었다거나) board가 null이니까, list.do로 리다이렉트 된다.
모든 처리가 완료되면 게시글의 폼을 보여주는 뷰 (board/write)를 반환한다.
앤드포인트(endpoint)
클라이언트가 서버와 상호작용할 때, 서버에서 제공하는 특정한 URL 주소
= 목적지 주소
ex) /home, /about 등
그럼 게시글 작성 폼을 html로 만들어보자.
메인/리소스의 templates.board에 만들었던 write.html을 다음과 같이 수정한다.
<!DOCTYPE html>
<html lang="ko" xmlns:th="http://www.thymeleaf.org" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" layout:decorate="board/layout/basic">
<th:block layout:fragment="title">
<title>This page is a write page</title>
</th:block>
<th:block layout:fragment="content">
<div class="card-content">
<form class="form-horizontal" th:action="@{/board/register.do}" th:object="${board}" method="post" onsubmit="return registerBoard(this)">
<input type="hidden" th:if="*{idx != null and idx > 0}" th:field="*{idx}" />
<div class="form-group">
<label for="noticeYn" class="col-sm-2 control-label">공지글 설정</label>
<div class="col-sm-10" style="margin-top: 10px">
<input type="checkbox" th:value="*{noticeYn}" id="noticeYn" name="noticeYn" th:checked="*{#strings.equals(noticeYn, 'Y')}" />
</div>
</div>
<div class="form-group">
<label for="secretYn" class="col-sm-2 control-label">비밀글 설정</label>
<div class="col-sm-10" style="margin-top: 10px">
<input type="checkbox" th:value="*{secretYn}" id="secretYn" name="secretYn" th:checked="*{#strings.equals(secretYn, 'Y')}" />
</div>
</div>
<div class="form-group">
<label for="title" class="col-sm-2 control-label">제목</label>
<div class="col-sm-10">
<input type="text" th:field="*{title}" class="form-control" placeholder="제목을 입력해 주세요." />
</div>
</div>
<div class="form-group">
<label for="writer" class="col-sm-2 control-label">이름</label>
<div class="col-sm-10">
<input type="text" th:field="*{writer}" class="form-control" placeholder="이름을 입력해 주세요." />
</div>
</div>
<div class="form-group">
<label for="content" class="col-sm-2 control-label">내용</label>
<div class="col-sm-10">
<textarea th:field="*{content}" class="form-control" placeholder="내용을 입력해 주세요."></textarea>
</div>
</div>
<div class="btn_wrap text-center">
<a th:href="@{/board/list.do}" class="btn btn-default waves-effect waves-light">뒤로가기</a>
<button type="submit" class="btn btn-primary waves-effect waves-light">저장하기</button>
</div>
</form>
</div>
</th:block>
<th:block layout:fragment="script">
<script th:inline="javascript">
/*<![CDATA[*/
function registerBoard(form) {
form.noticeYn.value = form.noticeYn.checked == false ? 'N' : 'Y';
form.secretYn.value = form.secretYn.checked == false ? 'N' : 'Y';
var result = (
isValid(form.title, "제목", null, null)
&& isValid(form.writer, "이름", null, null)
&& isValid(form.content, "내용", null, null)
);
if (result == false) {
return false;
}
}
/*[- end of function -]*/
/*]]>*/
</script>
</th:block>
</html>
<th:block layout:fragment="title"> : 타이틀을 정의하는 부분
<th:block layout:fragment="content"> : 실제 작성 폼이 있는 부분
<form> 폼 데이터(parameter)를 전달하기 위해
내부에는 게시글의 정보를 입력받는 input fields들 o.
onsubmit : 폼 데이터의 유효성 검증 위한 이벤트
return : 자바스크립트는 기본적으로 return true여서, 선언하지 않으면 바로 컨트롤러 호출함
~> 함수를 실행하기 위해 return 선언
th:action
: 폼이 제출될 때 데이터가 전송되는 엔드포인트를 지정 -> register.do로 데이터 전송
th:object
: 폼 안에서 사용될 객체 지정 -> BoardDTO 객체 필드와 바인딩
th:field="*{idx}"
: <input name="idx">와 같음 -> BoardDTO의 idx 필드와 연결
th:check : true면 checked 속성 부여
@{ }
: 타임리프의 URL 링크 표현식
th:if : 조건에 따라 해당 태그가 렌더링 or 제거
th:inline="javascript" : 자바스크립트 사용
<![CDATA[]]> : 자바스크립트 함수 사용 위해 CDATA로 묶어 특수문자를 문자열로 처리
registerBoard 함수 : 공지글/비밀글 체크 여부에 따라 값 지정 & isVaild : 필수 입력 필드의 유효성 검사
@PostMapping(value ="/board/register.do")
public String registerBoard(final BoardDTO params) {
try {
boolean isRegistered = boardService.registerBoard(params);
if (isRegistered == false) {
// return showMessageWithRedirect("게시글 등록에 실패하였습니다.", "/board/list.do", Method.GET, null, model);
}
} catch (DataAccessException e) {
// e.printStackTrace();
// return showMessageWithRedirect("데이터베이스 처리 과정에 문제가 발생하였습니다.", "/board/list.do", Method.GET, null, model);
} catch (Exception e) {
// return showMessageWithRedirect("시스템에 문제가 발생하였습니다.", "/board/list.do", Method.GET, null, model);
}
// return showMessageWithRedirect("게시글 등록이 완료되었습니다.", "/board/list.do", Method.GET, null, model);
return "redirect:/board/list.do"
}
POST 요청이 register.do로 들어올 때, 이 메서드가 실행된다.
게시글 데이터(params 객체)를 boardService를 이용하여 게시글을 등록한다.
게시글 등록이 완료되면 list로 리다이렉트하여 게시글 목록을 보여준다.
Post 요청
클라이언트가 서버로 데이터를 전송하는 데 사용
body(본문)에 데이터를 담아서 전송
웹 애플리케이션에서 어떤 정보를 생성/수정하기 위해
아직 구현을 안 했으므로, 저장하기를 누르면 에러가 뜰 것이다.
그러나 데이터베이스에는 잘 입력이 됐을 것이다~!
'백엔드(Back-End) > Spring Boot' 카테고리의 다른 글
[스프링부트] IoC, Di, 컨테이너 (0) | 2023.12.05 |
---|---|
[sts4-Spring Boot] 08. List - 게시글 목록 보여주기 (0) | 2023.12.04 |
[sts4-Spring Boot] 갑자기 sql database 에러날 때 (1) | 2023.12.04 |
[sts4-Spring Boot] 06. Layout (Presentation Layer - 컨트롤러 처리) (0) | 2023.11.30 |
[sts4-Spring Boot] 05. Layout (Business Layer - 서비스 영역 처리) (0) | 2023.11.29 |