boardProject
package edu.kh.project.member.controller;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import edu.kh.project.member.model.dto.Member;
import edu.kh.project.member.model.service.MemberService;
@WebServlet("/member/login")
public class LoginController extends HttpServlet{
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
try {
// 인코딩 처리
req.setCharacterEncoding("UTF-8");
// 파라미터 얻어오기
String inputEmail = req.getParameter("inputEmail");
String inputPw = req.getParameter("inputPw");
// 서비스 객체 생성
MemberService service = new MemberService();
// 로그인 서비스 호출 후 결과 반환받기
Member loginMember = service.login(inputEmail, inputPw);
System.out.println(loginMember);
// Session 객체 생성
HttpSession session = req.getSession();
if(loginMember != null) { // 로그인 성공
// session에 로그인한 회원 정보를 추가
session.setAttribute("loginMember", loginMember);
// session 만료 시간 지정 (초단위 지정)
session.setMaxInactiveInterval(60*60);
// forward : 요청 처리 후 자체적인 화면이 존재하여
// 이를 이용해서 응답
// redirect : 요청 처리 후 자체적인 화면이 없어서
// 화면이 있는 다른 요청을 다시 호출(요청)
resp.sendRedirect("/"); // 메인 페이지 재요청
} else { // 실패
// 로그인 실패 메시지를 session에 추가
session.setAttribute("message", "아이디 또는 비밀번호가 일치하지 않습니다");
// 현재 요청 이전 페이지로 redirect
String referer = req.getHeader("referer");
// referer -> 각 페이지 방문시 남는 흔적을 말함
// request.getHeader() : 안에 파라미터로 referer 전달 시 이전페이지 주소값 반환.
// http://localhost:8080/
resp.sendRedirect(referer);
}
} catch(Exception e) {
e.printStackTrace();
}
}
}
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!-- footer는 주요 콘텐츠가 아니라서 보통 main 태그 안에 작성하지 않음. -->
<footer>
<p>Copyright © 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>
<%-- session에 message가 존재할 경우 --%>
<c:if test="${not empty sessionScope.message}">
<script>
// EL/JSTL 구문이 먼저 해석
// 문자열의 경우 따옴표가 없는 상태이니 옆에 붙여줘야함.
<%-- alert 안에는 문자열만 들어와야 함 --%>
alert('${message}') // ${message}
</script>
<%--
session에 message를 추가하면
브라우저 종료 또는 만료 전까지 계속 메세지가 출력된다
-> 1회 출력 후 session에서 message 삭제
--%>
<c:remove var="message" scope="session"/>
</c:if>
틀린 비밀번호 입력 후 로그인 버튼 클릭 시,
메세지 출력 -> 확인 버튼 클릭 시, 이전 페이지로 돌아감
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="stylesheet" href="/resources/css/main-style.css">
<!-- fontaswesom 아이콘 사용할 수 있는 스크립트 연결-->
<script src="https://kit.fontawesome.com/f821b57119.js" crossorigin="anonymous"></script>
</head>
<body>
<main>
<%-- header.jsp 추가 --%>
<%--
<jsp:include page="jsp파일경로" />
- jsp 파일 경로는 'webapp 폴더 기준'으로 작성
- JSP 액션 태그(jsp에 기본 내장됨)
- 다른 jsp 파일의 코드를 현재 위치에 추가
--%>
<jsp:include page="/WEB-INF/views/common/header.jsp" />
<section class="content">
<section class="content-1">
<h3>로그인된 회원 정보</h3>
</section>
<!-- 아이디/비밀번호/로그인버튼 영역 -->
<section class="content-2">
<c:choose>
<%-- 로그인이 안되었을때 --%>
<%-- EL empty : 비어있거나 null이면 true --%>
<c:when test="${empty sessionScope.loginMember}">
<form action="/member/login" method="post" name="login-form" id="loginFrm">
<fieldset class="id-pw-area">
<section>
<input type="text" name="inputEmail" placeholder="이메일">
<input type="password" name="inputPw" placeholder="비밀번호">
</section>
<section>
<button>로그인</button>
</section>
</fieldset>
<label>
<input type="checkbox" name="saveId"> 아이디 저장
</label>
<!-- 회원가입/ Id/pw 찾기 영역 -->
<section class="signup-find-area">
<a href="#">회원가입</a>
<span>|</span>
<a href="#">ID/PW 찾기</a>
</section>
</form>
</c:when>
<%-- 로그인이 되었을때 --%>
<c:otherwise>
<article class="login-area">
<a href="#">
<img src="/resources/images/user.png" id="memberProfile">
</a>
<div class="my-info">
<div>
<a href="#" id="nickname">${sessionScope.loginMember.memberNickname}</a>
<a href="/member/logout" id="logoutBtn">로그아웃</a>
</div>
<p></p>
</div>
</article>
</c:otherwise>
</c:choose>
</section>
</section>
</main>
<jsp:include page="/WEB-INF/views/common/footer.jsp" />
</body>
</html>
package edu.kh.project.member.controller;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
@WebServlet("/member/logout")
public class LogoutController extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// HttpSession을 얻어와
HttpSession session = req.getSession();
// Session을 무효화 하고
session.invalidate();
// 메인페이지를 재요청(redirect)
resp.sendRedirect("/");
}
}
로그아웃 버튼 클릭 시, 이전 페이지로 돌아감
서치 창에 닉네임으로 회원 검색 시, 하단 결과 나오게 코딩해보기
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<!-- fontaswesom 아이콘 사용할 수 있는 스크립트 연결-->
<script src="https://kit.fontawesome.com/f821b57119.js" crossorigin="anonymous"></script>
</head>
<body>
<main>
<%-- header.jsp 추가 --%>
<%--
<jsp:include page="jsp파일경로" />
- jsp 파일 경로는 'webapp 폴더 기준'으로 작성
- JSP 액션 태그(jsp에 기본 내장됨)
- 다른 jsp 파일의 코드를 현재 위치에 추가
--%>
<jsp:include page="/WEB-INF/views/common/header.jsp" />
<section class="content">
<section class="content-1">
<h3>로그인된 회원 정보</h3>
</section>
<!-- 아이디/비밀번호/로그인버튼 영역 -->
<section class="content-2">
<c:choose>
<%-- 로그인이 안되었을때 --%>
<%-- EL empty : 비어있거나 null이면 true --%>
<c:when test="${empty sessionScope.loginMember}">
<form action="/member/login" method="post" name="login-form" id="loginFrm">
<fieldset class="id-pw-area">
<section>
<input type="text" name="inputEmail" placeholder="이메일">
<input type="password" name="inputPw" placeholder="비밀번호">
</section>
<section>
<button>로그인</button>
</section>
</fieldset>
<label>
<input type="checkbox" name="saveId"> 아이디 저장
</label>
<!-- 회원가입/ Id/pw 찾기 영역 -->
<section class="signup-find-area">
<a href="#">회원가입</a>
<span>|</span>
<a href="#">ID/PW 찾기</a>
</section>
</form>
</c:when>
<%-- 로그인이 되었을때 --%>
<c:otherwise>
<article class="login-area">
<a href="#">
<img src="/resources/images/user.png" id="memberProfile">
</a>
<div class="my-info">
<div>
<a href="#" id="nickname">${sessionScope.loginMember.memberNickname}</a>
<a href="/member/logout" id="logoutBtn">로그아웃</a>
</div>
<p></p>
</div>
</article>
</c:otherwise>
</c:choose>
</section>
</section>
</main>
<jsp:include page="/WEB-INF/views/common/footer.jsp" />
</body>
</html>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<link rel="stylesheet" href="/resources/css/main-style.css">
<header>
<!-- 클릭 시 메인페이지로 이동하는 로고 -->
<section>
<a href="/">
<img src="/resources/images/logo.jpg" id="homeLogo">
</a>
</section>
<!-- 검색창 부분 -->
<section>
<section class="search-area">
<!-- form 내부 input 태그 값을 서버 또는 페이지로 전달 -->
<form 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>
package edu.kh.project.member.controller;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import edu.kh.project.member.model.dto.Member;
import edu.kh.project.member.model.service.MemberService;
@WebServlet("/search")
public class SearchController extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
try {
String query = req.getParameter("query");
MemberService service = new MemberService();
List<Member> memberList = service.searchMember(query);
req.setAttribute("memberList", memberList);
req.getRequestDispatcher("/WEB-INF/views/search/search.jsp").forward(req, resp);
} catch(Exception e) {
e.printStackTrace();
}
}
}
package edu.kh.project.member.model.service;
import static edu.kh.project.common.JDBCTemplate.*;
import java.sql.Connection;
import java.util.List;
import edu.kh.project.member.model.dao.MemberDAO;
import edu.kh.project.member.model.dto.Member;
public class MemberService {
private MemberDAO dao = new MemberDAO();
// 주석 단축키 : 메소드 커서 -> alt + shift + J
/** 로그인 서비스
* @param inputEmail
* @param inputPw
* @return
*/
public Member login(String inputEmail, String inputPw) throws Exception{
Connection conn = getConnection();
Member loginMember = dao.login(conn, inputEmail, inputPw);
close(conn);
return loginMember;
}
/** 회원 검색
* @param query
* @return
*/
public List<Member> searchMember(String query) throws Exception{
Connection conn = getConnection();
List<Member> memberList = dao.searchMember(conn, query);
close(conn);
return memberList;
}
}
package edu.kh.project.member.model.dao;
import static edu.kh.project.common.JDBCTemplate.*;
import java.io.FileInputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import edu.kh.project.member.model.dto.Member;
public class MemberDAO {
private Statement stmt;
private PreparedStatement pstmt;
private ResultSet rs;
private Properties prop;
public MemberDAO() {
try {
prop = new Properties();
String filePath
= MemberDAO.class.getResource("/edu/kh/project/sql/member-sql.xml").getPath();
prop.loadFromXML(new FileInputStream(filePath));
} catch(Exception e) {
e.printStackTrace();
}
}
/** 로그인 DAO
* @param conn
* @param inputEmail
* @param inputPw
* @return
*/
public Member login(Connection conn, String inputEmail, String inputPw) throws Exception{
Member loginMember = null;
try {
String sql = prop.getProperty("login");
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, inputEmail);
pstmt.setString(2, inputPw);
rs = pstmt.executeQuery();
if(rs.next()) {
loginMember = new Member();
loginMember.setMemberNo( rs.getInt(1) );
loginMember.setMemberEmail( rs.getString(2) );
loginMember.setMemberNickname( rs.getString(3) );
loginMember.setMemberTel( rs.getString(4) );
loginMember.setMemberAddress( rs.getString(5) );
loginMember.setProfileImage( rs.getString(6) );
loginMember.setAuthority( rs.getInt(7) );
loginMember.setEnrollDate( rs.getString(8) );
}
} finally {
close(rs);
close(pstmt);
}
return loginMember;
}
/** 회원 검색
* @param conn
* @param query
* @return
*/
public List<Member> searchMember(Connection conn, String query) throws Exception{
List<Member> memberList = new ArrayList<Member>();
try {
String sql = prop.getProperty("searchMember");
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, query);
rs = pstmt.executeQuery();
while(rs.next()) {
Member member = new Member();
member.setMemberNo( rs.getInt("MEMBER_NO") );
member.setMemberEmail( rs.getString("MEMBER_EMAIL") );
member.setMemberNickname( rs.getString("MEMBER_NICKNAME") );
member.setMemberTel( rs.getString("MEMBER_TEL") );
memberList.add(member);
}
} finally {
close(rs);
close(pstmt);
}
return memberList;
}
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
<entry key="login">
SELECT MEMBER_NO, MEMBER_EMAIL, MEMBER_NICKNAME, MEMBER_TEL, MEMBER_ADDR, PROFILE_IMG, AUTHORITY,
TO_CHAR(ENROLL_DATE, 'YYYY"년" MM"월" DD"일" HH24"시" MI"분" SS"초"') AS ENROLL_DATE
FROM "MEMBER"
WHERE MEMBER_DEL_FL = 'N'
AND MEMBER_EMAIL = ?
AND MEMBER_PW = ?
</entry>
<entry key="searchMember">
SELECT MEMBER_NO, MEMBER_EMAIL, MEMBER_NICKNAME, MEMBER_TEL
FROM "MEMBER"
WHERE MEMBER_DEL_FL = 'N'
AND MEMBER_NICKNAME LIKE '%' || ? || '%'
</entry>
</properties>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>회원 검색 결과</title>
</head>
<body>
<main>
<jsp:include page="/WEB-INF/views/common/header.jsp" />
<section class="search-page">
<h1>'${param.query}'로 검색한 결과</h1>
<c:choose>
<%-- c:choose 안에는 이 주석태그만 가능!!!! --%>
<%-- memberList가 비어있을때 --%>
<c:when test="${empty requestScope.memberList}">
<p>검색된 회원이 없습니다.</p>
</c:when>
<%-- memberList가 비어있지 않을 때 --%>
<c:otherwise>
<c:forEach var="member" items="${memberList}">
<div class="search-div">
<%-- var.필드명 --%>
<p>닉네임 : ${member.memberNickname}</p>
<p>이메일 : ${member.memberEmail}</p>
<p>전화번호 : ${member.memberTel}</p>
</div>
</c:forEach>
</c:otherwise>
</c:choose>
</section>
</main>
<jsp:include page="/WEB-INF/views/common/footer.jsp" />
</body>
</html>
검색창에 유저 검색 시, 나오는 화면