[SpringBoot] TIL 074 - 23.11.08

유진·2023년 11월 8일
0

SpringBoot

Thymeleaf


바꾸고 싶을 경우 앞, 뒤 값 변경하면 됨.

main.html

<!DOCTYPE html>
		<!-- 현재 HTML 문서에 타임리프 문법을 사용한다고 선언 -->
<html xmlns:th="http://www.thymeleaf.org">
<head>
	<meta charset="UTF-8">
	<title>프로젝트</title>
	
</head>
<body>
	<main>
		
		<!-- th:block
			- html 태그가 아닌 단순히 타임리프를 쓰기 위한 태그가 필요할 때 사용
			- 타임리프 해석 시 다른 타임리프 수행 후 사라짐
		-->
        <th:block th:replace="~{common/header}"></th:block>

        <section class="content">
            <section class="content-1">
            	<h3>로그인된 회원 정보</h3>
             	${sessionScope.loginMember}
             	
             	
             	<h3>닉네임이 일치하는 회원의 전화번호 조회</h3>
            	
            	<input type="text" id="inputNickname">
            	<button id="btn1">조회</button>
            	<h4 id="result1"></h4>
            	
            	<hr>
            	
            	<h3>이메일을 입력받아 일치하는 회원의 정보를 조회</h3>
            	<input id="inputEmail">
            	<button id="btn2">조회</button>
            	<ul id="result2">
            	</ul>



				<h3>삼항 연산자</h3> <!-- 타임리프에서 쓸 수 있는 연산자 -->
				<!-- ${name} 값이 있으면 true, 없으면 false -->
				<p th:text="${name} ? ${name} : '이름 없음'"></p>
				<!--          조건   ?   true  :   false   -->
				<p th:text="${name2} ? ${name2} : '이름 없음'"></p>


				<h3>Elvis 연산자</h3> <!-- 삼항 연산자보다 간단하게 쓸 수 있는 연산자 -->
				<p th:text="${name} ?: '이름 없음'"></p>
				<p th:text="${name2} ?: '이름 없음'"></p>


				<h3>No-Operation</h3> <!-- 타임리프에서 만든 연산자 -->
				<p th:text="${name} ?:_">(태그에작성)이름 없음</p>
				<p th:text="${name2} ?:_">(태그에작성)이름 없음</p>

				

            </section>
            

            <!-- 아이디/비밀번호/로그인버튼 영역 -->
            <section class="content-2">

				<!-- 로그인 X -->
				<th:block th:unless="${session.loginMember}">

					<form th:action="@{/member/login}" method="post" name="login-form" id="loginFrm">

						<fieldset class="id-pw-area">
							<section>
								<input type="text" name="memberEmail" placeholder="이메일"
									autocomplete="off"
									value=""
									>
								<input type="password" name="memberPw" placeholder="비밀번호">
							</section>

							<section>
								<button>로그인</button>
							</section>
						</fieldset>

						<label>
							<input type="checkbox" name="saveId"> 아이디 저장     
						</label>

						<!-- 회원가입/ Id/pw 찾기 영역 -->
						<section class="signup-find-area">
							<a th:href="@{/member/signUp}">회원가입</a>
							<span>|</span>
							<a th:href="@{#}">ID/PW 찾기</a>
						</section>

					</form>

				</th:block>

				<!-- 로그인 O -->
				<!-- request Scope는 그냥 써도 인식함.
					session Scope는 session.loginMember 이런식으로 session.을 꼭 붙여야한다.
				-->
				<th:block th:if="${session.loginMember}">

					<article class="login-area">
						<a th:href="@{/myPage/profile}">
							<img th:src="@{/images/user.png}" id="memberProfile">
						</a>
						
						<div class="my-info">
							<div>
								<a th:href="@{/myPage/info}" id="nickname">[[${session.loginMember.memberNickname}]]</a>
								<!-- <th:block th:text="${session.loginMember.memberNickname}">로그인 회원의 닉네임</th:block> 
									너무 길기 때문에 위의 방법으로 사용 가능!
								-->
								<a th:href="@{/member/logout}" id="logoutBtn">로그아웃</a>
							</div>
							
							<p></p>
						</div>
					</article>

				</th:block>
            			

            </section>

        </section>
       
    </main>
    
    <th:block th:replace="~{common/footer}"></th:block>

	<!-- SockJS 추가 -->
    <!-- <script src="https://cdn.jsdelivr.net/npm/sockjs-client@1/dist/sockjs.min.js"></script> -->


	<!-- main.js 추가 -->
	<script th:src="@{/js/main.js}"></script>

</body>
</html>

header.html


fragment = 태그 일부분만 가져오는 것 가능

<link rel="stylesheet" th:href="@{/css/main-style.css}">
                        <!-- 경로나 주소 작성할 때 쓰는 타임리프 표기법 : 
                            타임리프 사용 시, 하나로 통일하는 것이 좋아서 이렇게 작성하는 것! -->

<!-- fontaswesom 아이콘 사용할 수 있는 스크립트 연결-->
<script th:src="@{https://kit.fontawesome.com/f821b57119.js}" crossorigin="anonymous"></script>

<header>

    <!-- 클릭 시 메인페이지로 이동하는 로고 -->
    <section>
        <a th:href="@{/}">
            <img th:src="@{/images/logo.jpg}" id="homeLogo">
        </a>
    </section>

    <!-- 검색창 부분 -->
    <section>
        <section class="search-area">
            <!-- form 내부 input 태그 값을 서버 또는 페이지로 전달 -->
            <form th:action="@{/search}" method="GET" name="search-form">

                <!-- fieldset : form 내부에서 input을 종류별로 묶는 용도로 자주 사용 -->
                <fieldset>

                    <!-- search : 텍스트 타입과 기능적으로는 똑같으나,
                        브라우저에 의해 다르게 표현될 수 있음. -->
                    <!-- autocomplete : HTML 기본 자동완성 사용 X -->
                    <input type="search" id="query" name="query"
                        autocomplete="off" placeholder="회원을 닉네임으로 검색해주세요."
                    >

                    <button id="searchBtn" class="fa-solid fa-magnifying-glass"></button>
                </fieldset>

            </form>

        </section>
    </section>

    <section></section>
</header>

<!-- 보통은 header안에 작성하나 사이드에 nav가 있는 경우도 있기 때문에 따로 작성해본다! -->
<nav>
    <ul>
        <li><a href="#">공지사항</a></li>
        <li><a href="#">자유게시판</a></li>
        <li><a href="#">질문게시판</a></li>
        <li><a href="#">FAQ</a></li>
        <li><a href="#">1:1문의</a></li>
    </ul>
</nav>

참고

-> 타임리프에 대한 문법들은 개발자 도구에서 보이지 않음

footer.html

<footer>
   <p>Copyright &copy; KH Information Educational Institute E-Class</p>

   <section>
       <a href="#">프로젝트 소개</a>
       <span>|</span>
       <a href="#">이용약관</a>
       <span>|</span>
       <a href="#">개인정보처리방침</a>
       <span>|</span>
       <a href="#">고객센터</a>
   </section>
</footer>

<!-- javascript 영역에서 타임리프를 적용/ 해석 함 -->
<!-- html 안에 있는 script 태그 안에서만 사용 가능! 확장자가 .js인 곳에서는 사용 불가능 -->
<script th:inline="javascript"> 
	
	/* Natural Template */
	const message = /*[[${message}]]*/ "전달 받은 메세지";
	// 타임리프 해석    값(자료형 알아서 해석)   사라짐(설명)
	//                 문자, 숫자 구분

	if(message != null) alert(message);

</script>

MemberController.java

package edu.kh.project.member.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.bind.support.SessionStatus;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import edu.kh.project.member.model.dto.Member;
import jakarta.servlet.http.HttpSession;

@RequestMapping("/member")
@Controller
@SessionAttributes({"loginMember"})
public class MemberController {

	// 로그인
	@PostMapping("/login")
	public String login(Member inputMember, Model model, RedirectAttributes ra) {
		
		if(inputMember.getMemberEmail().equals("user01") &&
			inputMember.getMemberPw().equals("pass01!")) {
			
			Member loginMember = new Member();
			loginMember.setMemberEmail("user01");
			loginMember.setMemberNickname("유저일");
			loginMember.setMemberNo(1);
			
			model.addAttribute("loginMember", loginMember);
			
		} else {
			// 로그인 실패 시 테스트
			ra.addFlashAttribute("message", "아이디 또는 비밀번호 일치하지 않음");
		}
		
		return "redirect:/";
	}
	
	
	// 로그아웃
	@GetMapping("/logout")
	public String logout(SessionStatus status, HttpSession session) {
		status.setComplete();
		return "redirect:/";
	}
	
}

Member.java

package edu.kh.project.member.model.dto;

import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;

@NoArgsConstructor
@Getter
@Setter
@ToString
public class Member {
	private int memberNo;
	private String memberEmail;
	private String memberPw;
	private String memberNickname;
	private String memberTel;
	private String memberAddress;
	private String profileImage;
	private String enrollDate;
	private String memberDeleteFlag;
	private int authority; // 회원권한(1:일반, 2:관리자)
}

mainController.java

package edu.kh.project.main.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class MainController {
	
	@RequestMapping("/")
	public String mainForward(Model model) {
		
		model.addAttribute("name", "홍길동");
		
		// Spring MVC : /webapp/WEB-INF/views/common/main.jsp
		
		// Spring Boot (+ thymeleaf 템플릿 엔진)
		// src/main/resources/templates/common/main.html
		
		return "common/main";
	}

}

[ 구현 화면 ]

아이디 user01 비밀번호 pass01! 입력 후 로그인 버튼 클릭 시,
잘못된 아이디, 비밀번호 입력 후 로그인 버튼 클릭 시,
해당 alert창 뜸

0개의 댓글