본문 바로가기
백엔드(Back-End)/Spring Boot

[sts4-Spring Boot] 07. Create - 웹에서 게시글 등록하기 구현

by 기딩 2023. 12. 4.
728x90

2023.11.30 - [백엔드(Back-End)/Spring Boot] - [sts4-Spring Boot] 06. Layout (Presentation Layer - 컨트롤러 처리)

 

[sts4-Spring Boot] 06. Layout (Presentation Layer - 컨트롤러 처리)

2023.11.29 - [백엔드(Back-End)/Spring Boot] - [sts4-Spring Boot] 05. Business Layout 서비스 영역 처리 [sts4-Spring Boot] 05. Layout (Business Layer - 서비스 영역 처리) 2023.11.28 - [백엔드(Back-End)/Spring Boot] - [sts4-Spring Boot] 04.

silvow94.tistory.com

웹과 잘 연결이 되었는지 확인을 했으니, 이제 진짜 웹에서 기능을 구현할 차례다~!

 

웹의 요청과 연결되는 부분은 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(본문)에 데이터를 담아서 전송

웹 애플리케이션에서 어떤 정보를 생성/수정하기 위해

 

아직 구현을 안 했으므로, 저장하기를 누르면 에러가 뜰 것이다.

그러나 데이터베이스에는 잘 입력이 됐을 것이다~!

728x90