20211128 금요일 수업 정리

DUUUPPAAN·2021년 11월 28일
0

20211122 WAS(TOMCAT), JSP

목록 보기
5/10

·목요일에 이은 jsp 수업

-개인적으로 금요일과 토요일에 금요일 수업을 정리할 수 없어서 일요일인 오늘 정리를 하게 되었다. 아직도 이해가 안되는 부분이 많아서 정리를 미룰까 하다가 그래도 이 시점에서는 정리를 해야할 것 같아서 정리를 한다.

-목요일의 로그인 페이지에 이은 회원가입과 관련된 페이지를 만들었다. 특히 이번엔 쿠키와 관련된 공통모듈과 String과 관련된 공통 모듈을 교수님께서 제공해주셔서 해당 모듈을 사용해서 여러 로직을 처리했다. 물론 해당 공통모듈을 전부 알 수 있으면 좋겠지만 그 부분을 일일이 설명하면 수업이 너무 길어지고 프로젝트를 시작도 못 할 것이라고 틈틈히 보라고 하셨다. 실제로 회사를 가도 아직은 만들어진 모듈을 사용하게 될 것이라고 하셨고 나중에 정말 코딩 실력이 늘어서 공통모듈을 만들 수 있는 수준까지 가라고 격려해주셨다.

·회원가입 페이지 전 쿠키와 log4j

-기존에는 로그를 system.out.println();의 방식으로 콘솔에 직접 찍어주었다. 문제는, 이런 식으로 콘솔에 찍게되면 모든 오류에 대해 기록이 남게 되고, 만약 이런 사이트의 이용자가 수백 수천명이 된다면, 그 이용자 전부의 기록이 out.println으로 찍힌다. 그리고 그렇게 찍힌 부분은 역시 메모리의 부하를 주게 된다. 심지어, 이렇게 찍힌 로그는 선택해서 지우기도 쉽지 않다고 한다. 그래서 log4j라는 외부 모듈을 사용해서 로그를 단계별, 레벨별로 관리할 수 있다고 하셔서 log4j과 관련된 소스를 받았다. 물론, 아직 환경변수를 설정하지 않아서 정확하게 어떻게 기능하는지는 못 봤지만 월요일에는 확인이 가능할 것 같다.

-회원가입과 관련된 부분에서 쿠키를 제외할 수는 없다고 하셨다. 쿠키는 예전에도 많이 봐왔다. 인터넷 옵션에 인터넷 방문 기록 및 쿠키 제거란 말이 항상 있었다. 그래서 따로 무슨 기능을 하는지는 몰라도 뭔가 나의 기록이 저장되어 있는 것이겠구나란 생각은 했었다.

-HTTP 프로토콜은 request를 보내면 연결 상태가 끊어진다. 그래서 다른 페이지를 가거나 돌아왔을 때, 다시 연결해야 하는 경우가 생길 수 있다. 그래서 쿠키라는 것에 아이디와 비밀번호를 저장하여 또 다른 로그인 절차를 줄여준다. 예를 들어 내가 로그인을 하고 다른 페이지에 갔다가 다시 돌아와도 로그인이 되어있는 상태인 것이다. 만약 쿠키가 없다면 내가 방문 시마다 로그인 정보를 입력해야하는 경우가 생긴다. 물론, 요즘은 쿠키보다는 서버에서 '세션'이라는 것으로 쿠키의 기능을 서버쪽에서 수행한다고 하지만, 당장 수업에서는 사용할 수 없기 때문에 쿠키의 기능을 사용한다고 하셨다.
단점: 보안상의 이유로 웹브라우저 자체에 쿠키 거부 기능이 추가되었다. 그래서 만약 거부설정이 있으면 연결을 지속시킬 수 없게 된다.
이 단점을 보완하기 위해서 세션이란 기능을 사용해서 페이지를 구축한다. 세션은 서버가 가지고 있는 정보이며 HTTP 프로토콜 헤더정보에 정보를 가지고 있다.

-쿠키사용
Javax.servlet.http 패키지에 있는 Cookie 클래스의 객체를 생성해야 한다. 서버가 웹 브라우저에 응답할 때 response객체에 담아서 사용자의 웹 브라우저에 저장시킨다. 사용자가 다시 웹서버에 요청할 때 request 객체에 실려서 다시 서버에 전달된다.

·우선 회원가입을 위한 insert문

-우선 회원가입을 하기 위한 sql문을 작성해야 한다. 물론 원래라면 회원정보에 대한 table에 해당하는 .java파일을 만들어야 하지만, 이미 로그인 페이지를 구성할 때 User.java를 만들었다. 그래서 해당 부분은 이미 작성되어 있는 부분을 사용하면 된다. 또한 sql문을 전부 Dao에 정리해서 작성하겠다고 했기 때문에 UserDao에 insert와 관련된 sql문을 넣어줬다.

	//회원정보 삽입
	public int userInsert(User user) 
	{
		int count = 0;
		
		Connection conn = null;
		PreparedStatement pstmt = null;
		StringBuilder sql = new StringBuilder();
		
		sql.append("INSERT INTO TBL_USER "); 
		sql.append(" (USER_ID, USER_PWD, USER_NAME, USER_EMAIL, STATUS, REG_DATE) "); 
		sql.append(" VALUES (? , ? , ? , ? , ? , SYSDATE) ");
		
		try 
		{
			int idx = 0; //얘는 순서를 위한 사용, 넘버링을 위한 용도.
			conn = DBManager.getConnection();
			pstmt = conn.prepareStatement(sql.toString());
			
			//0으로 했기 때문에 전치증가 연산자 ++사용
			//++idx는 먼저 0에서 1이되고, 자기에게 1의 값을 넣음.
			pstmt.setString(++idx, user.getUserId() );
			pstmt.setString(++idx, user.getUserPwd() );
			pstmt.setString(++idx, user.getUserName() );
			pstmt.setString(++idx, user.getUserEmail() );
			pstmt.setString(++idx, user.getStatus() );
			
			count = pstmt.executeUpdate();
		}
		catch(Exception e) 
		{
			//log4j의 기능
			logger.error("[UserDao] userInsert SQLException", e);
		}
		finally 
		{
			DBManager.close(pstmt, conn);
		}
		
		return count;
	}

-여기서 중요한 부분은 idx라는 변수를 사용해서 ?의 인덱스에 대응하게 했다는 것이다. 왜 이렇게 작성하냐면, table에 어떤 컬럼이 중간에 들어가도 굳이 숫자로 하드코딩하지 않고 ++idx만 사용하면 대응할 수 있게 하기 위해서이다. 또한, select의 sql문 결과에 대한 것은 ResultSet 객체로 받았지만, update delete insert에 대한 쿼리 실행 결과는 int로 리턴되고, 결과의 처리 건수만 리턴되기 때문에, count변수로 해당 결과 건수를 받았다.

	//회원가입가능여부
	boolean bSuccess = false;
	//쿠키 정보 가져오기
	//비어있으면 로그인 되어 있지 않음.
	//값이 있으면 로그인 되어 있음
	String cookieUserId = CookieUtil.getValue(request, "USER_ID");
	
	if(!StringUtil.isEmpty(cookieUserId))
	{
		//비어있지 않은 경우
		//쿠키를 삭제하고 로그인 페이지로 가게 하는 것.
		//예를 들어, 이미 로그인 했는데, 회원가입 페이지로 가는 경우
		//status가 y면 게시판으로 보내고, n이면 그냥 로그인 페이지로
		logger.debug("cookie UserId : "+cookieUserId);
		
		UserDao userDao = new UserDao();
		User user = userDao.userSelect(cookieUserId);
		
		if(user != null)
		{
			//유저정보 있음	
			//STringUtil의 공통 모듈 사용해서 equal함.
			//이런 간단한 로직을 왜 공통모듈로 빼나? 예를들어 'c##'을 빼주세요 라고 하면 
			//따로 하나하나 안바꾸고 모듈만 바꾸면 되기 때문
			if(StringUtil.equals(user.getStatus() , "Y"))
			{
				//정상 사용자인 경우, 게시판 페이지로 보냄.
				//원래라면 돌려보내거나 얼럿, 정보 수정으로 보냄
				response.sendRedirect("/board/list.jsp");
			}
			else
			{
				//정지 사용자인 경우 N인 경우
				//쿠키 삭제후 로그인 페이지로 이동
				CookieUtil.deleteCookie(request, response, "USER_ID");
				response.sendRedirect("/index.jsp");
			}
		}
		else
		{
			//유저정보 없음 쿠키 날림
			//유저정보엔 없는데, 로그인이 되어있다는것은 이상한 것이니까 날림.
			CookieUtil.deleteCookie(request, response, "USER_ID");
			//응답자에게 보내는데, 특정 페이지로 보내는 기능
			response.sendRedirect("/index.jsp");
		}
	}
	else
	{
		//쿠키가 없을 때.	
		bSuccess = true;
	}

-쿠키에 대한 수업을 진행한 이유가 바로 이 부분을 위해서이다. 쿠키 정보가 있고 없고에 따라 로직을 나눈 것이다. 물론 해당 부분은 공통모듈을 상당히 사용했는데, 이 부분은 공개를 할 수 없어서 굳이 이 곳에 올리지 않겠다. 위 부분의 쿠키를 사용한 이유는, 이미 로그인 되어 있는 상태여서 쿠키값이 있을 때의 상태이다. 즉, 로그인을 했는데, 회원가입버튼을 또 누른경우를 의미한다. bSuccess를 사용하는 이유는 쿠키가 없을 때를 이용해서 조건문으로 html 전체를 보여줄지 말지를 선택할 수 있게 하려고 하기 때문이다.

<%
if(bSuccess == true)
	{
		 //쿠키값이 없을 때 화면을 보여주겠다.
%>
   html 전체 내용

<%
}
%>

-위처럼 사용하면, bSuccess의 불린타입 변수가 true인 경우가 아니면 html을 보여주지도 않는다.

<%
	//로그
	Logger logger = LogManager.getLogger("/user/userProc.jsp");
	HttpUtil.requestLogString(request, logger);
	
	String redirectUrl = "";
	String msg = "";
	
	
	String userId = HttpUtil.get(request, "userId");
	String userPwd = HttpUtil.get(request, "userPwd");
	String userName = HttpUtil.get(request, "userName");
	String userEmail = HttpUtil.get(request, "userEmail");
	
	//쿠키는 CookieUtil에서 가져와야 함.
	//왜 쿠키를 체크하는가?
	//지금처럼 회원가입으로도 쓰고, 회원정보 수정으로도 쓸 userProc이기 때문에.
	//수정하는 경우와 가입하는 경우를 나누기 위한 용도.
	String cookieUserId = CookieUtil.getValue(request, "userId");
	
	UserDao userDao = new UserDao();
	
	if(StringUtil.isEmpty(cookieUserId))
	{
		//쿠키정보가 비어있으면 회원가입
		//정보가 없으면 접근이 불가하게 서버쪽에서도 예외처리해줌. 500번 오류 안나게
		if(!StringUtil.isEmpty(userId) && !StringUtil.isEmpty(userPwd) 
			&& !StringUtil.isEmpty(userName) && !StringUtil.isEmpty(userEmail) )
		{
			
			//중복아이디 체크
			if(userDao.userIdSelectCount(userId) > 0)
			{
				//중복 아이디 존재
				msg = "사용자 아이디가 존재 합니다.";
				redirectUrl = "/user/userRegForm.jsp";
			}
			else
			{
				//회원가입
				User user = new User();
				
				user.setUserId(userId);
				user.setUserPwd(userPwd);
				user.setUserName(userName);
				user.setUserEmail(userEmail);
				//그냥 Y하드코딩
				user.setStatus("Y");
				
				if( userDao.userInsert(user) > 0)
				{
					//인서트는 처리 건수를 리턴, 0보다 크다면 인서트되었다는 뜻.
					msg = "회원가입이 완료 되었습니다.";
					redirectUrl = "/"; //루트페이지, 현재는 index.jsp
				}
				else
				{
					//쿼리나 로직이 잘못된 경우
					msg = "회원가입 중 오류가 발생했습니다.";
					//회원가입 페이지로 다시 감.
					redirectUrl = "/user/userRegForm.jsp";
				}
			}
			
		}
		else
		{
			//오류 메세지와 보낼 링크를 설정.
			msg = "회원가입 중 입력값이 잘못 되었습니다.";
			redirectUrl = "/user/userRegForm.jsp";
		}
	}
	else
	{
		//회원정보 수정, 쿠키가 비어있지 않으니까
	}
%>

<!DOCTYPE html>
<html>
<head>
<%@ include file="/include/head.jsp" %>

<script type="text/javascript">

$(document).ready(function() {

	alert("<%=msg%>");
    location.href = "<%=redirectUrl%>";
});   
</script>
</head>

-userId를 통해서 해당 아이디가 있는지 여부를 체크해서 회원가입을 해주는 .java파일이다. 여기서는 쿠키가 왜 쓰였냐 하면 회원가입과 수정에 전부 사용하기 위해서 사용하는 것이다. 추가적으로 쿠키정보 자체가 없는 해당 url로 접근 한경우에 애초에 오류조차나지 않도록 하려는 용도도 있다.

·아직은 따라가기에 급급하고 이해하는데 어려움

-정말 따라가는데 급급하고 쉬는 시간마다 주말에도 해당 로직을 한참동안 봤다. 그래도 어렵고 복잡한 것은 사실이다. 그리고 공통모듈을 사용하기 때문에 해당 모듈을 찾아서 보는데도 상당한 시간이 지났다. 굉장히 어려운 것 같다 공통모듈 자체를 이해하는 것이. 물론 그냥 이렇게 쓰면 되는구나 정도만 알아도 되겠지만 그래도 언젠가 더 많은 코딩을 하게 될 경우가 있으니 계속 보고 있느라 시간이 굉장히 많이 걸린 점도 있다. 그래도 계속 보니 어느정도는 이해가 되긴 하고 있다. 물론 굉장히 힘들지만, 앞으로는 정말 복습에 시간을 더 많이 투자해야 될 것 같다. 원래라면 내일은 비대면 수업이지만, 아무래도 내일도 수업을 들으러 가야할 것 같다.

profile
비전공자란 이름으로 새로운 길을 가려 하는 신입

0개의 댓글