23.05.08

이준영·2023년 5월 8일
0

코딩 방식

hard coding(날코딩)  - base
model1    - 중심(base로 잡도록 노력하기)

mvc model2    - 향상(숙련도 필요)
	controller -> servlet으로 만듦
    					parameter
                    	url



상태(값)유지 -> 로그인 -> (후에 회원관리)

로그인

  • 회원에 대한 정보 유지
    1. 로그아웃
    2. 프로그램 종료시

상태(값) - 저장 구역
page - 한 페이지 내에서 저장
request - request(include, forward 구역까지)
session - 브라우저가 종료하거나, session 삭제까지
application - 톰캣 종료시까지(톰캣 내 전 사이트 공유)

= HashMap 구조

setAttribute("key", value) - 데이터 저장
getAttribute("key") - 데이터 가져오기



Attribute

데이터 저장(setAttribute) - 데이터 가져오기(getAttribute)
오브젝트 형식으로 가져오는 것이라 캐스팅 해줘야한다.


오브젝트 형식이므로 객체도 들어갈 수 있다. (wrapper 클래스 또한 가능)



request

include 활용 (include/ forward로 써도 form에서 사용하는 value랑 같은 request 객체 사용(공유) 가능하다)
request -> request_ok -> request_ok_sub

request

request_ok

request_ok_sub

결과


attribute는 set으로 넘겨주는 것이 있어야 값을 가져온다



session

브라우저가 다르면 다른 객체 공유

cookie / session(웹서버에 브라우저별로 저장, session id를 통하여 구별)

브라우저마다 id가 다름



브라우저를 완전히 껐다 키면 다른 id 가짐



클래스를 하나 더 만들어서 (session1 / session2 아이디를 비교하면 같음, 브라우저가 꺼지기 전까진 id가 같다.)



세션 다양한 메서드

  1. 생성시간 : 브라우저가 실행될 때 기준(브라우저를 껏다 키면 생성시간도 바뀐다)
  2. 현재시간 : 말 그대로 현재시간
  3. 유효시간 : set으로 설정해주면 그 시간만큼 유효시간이 정해짐, default값은 1800 / 정해놓고 나면 다시 정하거나, 세션이 종료 전에는 바뀌지 않음

페이지 디렉티브에서 세션 사용 여부 지정할 수 있음




session의 attribute

데이터가 session에 의해 공유 됨

setAttribute - 값 저장
getAttribute - 값 가져오기
removeAttribute - 값 삭제 (지우고 난 후에 돌아가보면 null로 바뀌어있음)


session1

session2

session3


set~getAttribute 실행 순서 - set으로 저장을 해야 get으로 받기 가능(1로 받지 않고 2를 먼저 실행하면 값 null)


removeAttribute 실행 순서 - session3에서 삭제 후 실행 -> session2로 돌아가면 data1 값 null (저장된 데이터를 전부 삭제하더라도 id 자체는 바뀌지 않는다)

'


session.invalidate() - 세션 id 완전히 지우고 만듦

실행 순서 -> session3에서 invalidate 실행 -> 2로가면 id가 바뀌고 둘 다 null로 초기화

                                    session3 실행하여 초기화  ↓↓↓↓↓



DFD

로그인폼

	(id, password, 회원등급 ... 등)
	로그인 확인
    		성공 : (세션 부여) 후 성공확인 페이지로 넘어감
            			세션검사 성공 : 페이지 내용  
                        						-> 로그아웃페이지
                        실패 - 로그인 폼
            실패 : 뒤로 돌아감

응용

로그인 폼 : login_form.jsp
로그인 확인 : login_ok.jsp
성공확인 : login_complete.jsp
로그아웃 : logout_ok.jsp


login_form.jsp


login_ok.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
login_ok.jsp
<%
	//  login_ok.jdp (로그인 처리 페이지)
	request.setCharacterEncoding("utf-8");
	
	String id = request.getParameter("id");
	String password = request.getParameter("password");
	
	//실제 아이피 / 패스워드
	// 패스워드 select 방식으로 비교, 직접 가져오기 x!
	String save_id = "tester";
	String save_password = "123456";
	
	//0 - 성공 / 1- 비밀번호 오류 2 / - 기타
	int flag = 2;
	
	if(save_id.equals(id) && save_password.equals( password )) {
		flag = 0;
	} 
	else {
		flag = 1;
	}
	

	out.println("<script type='text/javascript'>");
	if(flag == 0) {
		//정상적 부여시 session구하고 (민감한 개인정보 입력금지 ...) 컴플리트로 보냄
		session.setAttribute("sid", id);		
		session.setAttribute("sgrade", "a");		
		
		out.println("alert('로그인 성공')");
		out.println("location.href='login_complete.jsp'");
	}
	else if(flag  == 1) {
		out.println("alert('비밀번호 오류')");
		out.println("history.back()");
	}
	else if(flag == 2) {
		out.println("alert('기타 오류')");
		out.println("history.back()");
	}
	out.println("</script>");
	%>

login_complete.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
	int flag = 1;
	if(session.getAttribute("sid") != null || session.getAttribute("sgrade") != null) {
		//로그인 성공
		flag  = 0 ;
	}
	
	if(flag ==0) {
%>	

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
login_complete.jsp<br>
<a href="logout_ok.jsp">로그아웃 </a>
</body>
</html>
<%
	} 
	
	else if (flag == 1) {
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<script type="text/javascript">
	alert('로그인해야합니다.')
	location.href = 'login_form.jsp';
	</script>
</body>
</html>
<%		
	}
%>	

logout_ok.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>

<%
	//logout_ok.jsp
	
	session.invalidate();
%>    
    
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<script type="text/javascript">
		alert('로그아웃 되었습니다.');
		location.href="login_form.jsp";
	</script>
</body>
</html>

실행



db화하기

테이블 만들기 : member1

번호			seq			int				not null		primary key auto.increment
아이디			id			varchar(12)		not null
비밀번호			password	varchar(12)		not null
이름			name		varchar(12)		not null
이메일			mail		varchar(50)
등급			grade		char(1)			not null
등록일			wdate		datetime		not null

insert into member1 values (0, 'tester' ,'1234', '이름', 'test@test.com', 'A', now());

login_ok에 db 연동해서 select 작업하여 가져오기

  1. context.xml, api 통하여 db 연동

  2. login_ok.jsp 작업

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@page import="javax.naming.Context"%>
<%@page import="javax.naming.InitialContext"%>
<%@page import="javax.naming.NamingException"%>

<%@page import="javax.sql.DataSource"%>

<%@page import="java.sql.Connection"%>
<%@page import="java.sql.PreparedStatement"%>
<%@page import="java.sql.ResultSet"%>
<%@page import="java.sql.SQLException"%>
login_ok.jsp
<%
	//  login_ok.jdp (로그인 처리 페이지)
	request.setCharacterEncoding("utf-8");


	
	String id = request.getParameter("id");
	String password = request.getParameter("password");
	
	Connection conn = null;
	PreparedStatement pstmt = null;
	ResultSet rs = null;
	
	int flag = 2;
	
	try { 
		Context initCtx = new InitialContext();
		Context envCtx = (Context) initCtx.lookup("java:comp/env");
		
		DataSource dataSource = (DataSource) envCtx.lookup("jdbc/mariadb5");
		
		conn = dataSource.getConnection();
		
		//select 어떻게 하냐에 따라 활용 경우가 달라짐
		//ex> count(*) (회원 수 조사, 아이디 중복 검사 등)
		//ex> name, grade, mail 정보 가져와서 활용 => session
		//비밀번호는 암호화해서 넣기
		//아이디 중복검사,  아이디/비밀번호찾기-> 이메일 통하기
		String sql = "select name, mail, grade from member1 where id = ? and password = ?";
		
		pstmt = conn.prepareStatement(sql);
		
		pstmt.setString(1, id);
		pstmt.setString(2, password);

		rs = pstmt.executeQuery();
		
		if(rs.next()) {
			flag = 0;	
			
			session.setAttribute("sid", id);
			session.setAttribute("sname", rs.getString("name"));
			session.setAttribute("sgrade", rs.getString("grade"));
		} 
		else {
			flag = 1;
		}
		
	}  catch( NamingException e ) {
		System.out.println( "[에러] " + e.getMessage() );
	} catch( SQLException e ) {
		System.out.println( "[에러] " + e.getMessage() );
	} finally {
		if( pstmt != null ) try { pstmt.close(); } catch(SQLException e) {}
		if( conn != null ) try { conn.close(); } catch(SQLException e) {}
	}
	
	

	out.println("<script type='text/javascript'>");
	if(flag == 0) {
		out.println("alert('로그인 성공')");
		out.println("location.href='login_complete.jsp'");
	}
	else if(flag  == 1) {
		out.println("alert('비밀번호 오류')");
		out.println("history.back()");
	}
	else if(flag == 2) {
		out.println("alert('기타 오류')");
		out.println("history.back()");
	}
	out.println("</script>");
	%>

id/password 입력 -> db에서 조회해서 저장되어 있는 값이면 로그인 성공(아니면 실패)



쿠키(cookie)

저장위치 - 클라이언트(브라우저 내부)
로그인 같은 민감한 문제(세션), 광고 하루동안 안띄우기 같은 것(쿠키)
클라이언트와의 연결 끊어져도 만료기간 설정하면 그때까지 끊어지지 않는다.

쿠키 세션 차이점

						 쿠키										 세션
	저장위치		클라이언트(브라우저 내부)								웹 서버
	소멸시기		쿠키 저장시 만료기간 설정							브라우저 종료시
           	(만료시점 지나지 않으면 자동 삭제 x)				(만료기간에 상관없이 삭제)
   	저장타입			파일											객체
	속도				쿠키						>				세션
    보안				쿠키						<				세션
    저장정보		지워도 별 상관 없고, 						  사용자나 다른 누군가에게 
    			큰 영향없는 정보들							노출되면 안되는 중요한 정보들
    													

쿠키 값 저장하기 (add)

<%
	Cookie cookie1 = new Cookie("data1", "value1");
    //유효시간 설정
	cookie1.setMaxAge(30 * 60);
	//클라이언트 브라우저에 저장해줘!
	response.addCookie(cookie1);

	Cookie cookie2 = new Cookie("data2", "value2");
	cookie2.setMaxAge(30 * 60);
	//클라이언트 브라우저에 저장해줘!
	response.addCookie(cookie2);
%>

저장된 쿠키 값 얻기 가능( get )


<% 
	Cookie[] cookies = request.getCookies();
	if(cookies != null && cookies.length > 0) {
		for(int i = 0; i< cookies.length; i++ ) {
			out.println(cookies[i].getName() + " : ");
			out.println(cookies[i].getValue() + "<br>");
		}
	}
%>



setMaxAge(0) / (-1) : 쿠키 삭제

<% 
	Cookie[] cookies = request.getCookies();
	if(cookies != null && cookies.length > 0) {
		for(int i = 0; i< cookies.length; i++ ) {
			out.println(cookies[i].getName() + " : ");
			out.println(cookies[i].getValue() + "<br>");
		}
	}
	
	Cookie cookie = new Cookie("data1", "");
    //유효시간을 일부러 0으로 만들어 끝내버림 
	cookie.setMaxAge(0); //0이나 -1
	response.addCookie(cookie);
%>

새로고침 후 다시 실행하면 쿠키가 삭제됨



쿠키를 이용한 로그인

login_form 동일

login_ok 작업

	out.println("<script type='text/javascript'>");
	if(flag == 0) {
		Cookie cookie1 = new Cookie("login_id", id);
		Cookie cookie2 = new Cookie("login_grade", "A");
		
		response.addCookie(cookie1);
		response.addCookie(cookie2);
		
		
		out.println("alert('로그인 성공')");
		out.println("location.href='login_complete.jsp'");
	}
	else if(flag  == 1) {
		out.println("alert('비밀번호 오류')");
		out.println("history.back()");
	}
	else if(flag == 2) {
		out.println("alert('기타 오류')");
		out.println("history.back()");
	}
	out.println("</script>");
    
    이 부분에 flag == 0 에다가 쿠키 추가

login_complete

Cookie[] cookies = request.getCookies();
	if(cookies != null && cookies.length > 0) {
		for(int i = 0;  i <cookies.length; i++) {
			if(cookies[i].getName().equals("login_id") 
					&& !cookies[i].getName().equals("")) {
				flag = 0;
				break; //포문 빠져 나가기
			}
		}
	}
    
    맨 위에다 추가

logout_ok

<%
	//logout_ok.jsp
	Cookie cookie1 = new Cookie("login_id", "");
	Cookie cookie2 = new Cookie("login_grade", "");
	cookie1.setMaxAge(0);
	cookie2.setMaxAge(0);
	response.addCookie(cookie1);
	response.addCookie(cookie2);
	
	session.invalidate();
%>   
	invalidate 위쪽에 추가

로그인 성공시 쿠키가 추가되고, 로그아웃시 삭제되는 모습(data2는 유효기간이 지나지 않아서 남아있는 것임! 삭제를 안 해서 그렇지 삭제하면 삭제됨)



EL(Expression Language)

//기존 출력 방법
<%
	out.println( "2<br>" );
%>
<%="2" %><br>
<!-- EL -->
${ 2 }<br>
${"2"}<br>

${test}<br> <-- 이거는 변수 (나오지 않는다 )
${"test"}<br>
${'test'}<br> <-- 단일 따옴표 허용
\${'test'}<br> <-- EL이 아님(이 문자형식 그대로 나옴)


기본적인 사칙 연산 가능

EL은 이클립스에서 에러를 잘 잡아주지 못하기에 빨간줄이 뜸


${ "2" + 5 }<br>    <-- 자동형변환
${ "2" + "5" }<br>   <-- 자동형변환
\${ "일" + "5" }<br>  <-- 에러(연산불가)
${ "일" } ${ "5" }<br>
${ "2" } ${ "5" }<br>

  1. 문자열 연산이 안되고 자동형변환되어 사칙연산됨

  2. 문자 + 숫자 연산은 에러처리난다.

  3. 따로따로 사용하면 따로따로 처리 함




그 외 다른 연산자

<body>
${ 2 < 3 }<br>  <- 비교 연산자
${ 2 lt 3 }<br> <- 비교 연산자 ( < -> lt )
${ empty data }<br>  <--데이터가 비어있는지 물어보는 것
${ (2 < 3) ? "작다" : "크다" }<br>    <-- 삼항 연산자
</body>



변수 내용 출력하기

pageContext 이용

<body>
<%
	String name1 = "홍길동";
	pageContext.setAttribute("name2", "홍길동");
%>
<%=name1 %><br>
${ name1 }<br>  <-- 실행 x

<-- name2 출력하는 다양한 방법 -->
<%=pageContext.getAttribute("name2") %><br>
${ pageScope.name2 }<br> 
${ pageScope['name2'] }<br>   <-- 배열처럼 가져옴
${ name2 }<br>
</body>



내장 객체

(page/request/session/application)Scope 기억하기


데이터를 가져오는 순서

<%
	pageContext.setAttribute("name", "홍길동");
	request.setAttribute("name", "박문수");
	session.setAttribute("name", "성춘향");
%>

${ name }<br>
    

이 상태에서 실행시 홍길동이 보여진다.( pageContext 주석하면 박문수가, request 주석하면 성춘향이 보임
-> 단순히 변수 선언하는 것이 아니라 검색을 하여 찾아주고 없으면 공백으로 둠(널포인트익셉션 개념이 없다.)

JspContext → ServletRequest →  HttpSession →   ServletContext
(pageScope)  (requestScope)   (sessionScope) (applicationScope)

위 순서대로 검색 후 가장 처음에 발견된 객체를 가져온다 (그래서 pageContext의 홍길동을 먼저 검색하여 가져온 것)



model의 to 쉽게 가져오기 (model1,2 작업 el로 쉽게 쓰기)

<body>
<%
	BoardTO to = new BoardTO();
	to.setSubject("제목");
	to.setWriter("작성자");
	
	pageContext.setAttribute("to", to);
%>
${ to.subject }<br>  <-- 필드변수 부르는 것이 아니라 메서드 안의 println 부르는 것
${ to.writer }<br>   <-- ""
</body>

배열로 표현 (ArrayList 도 똑같음)

<body>
<%
	BoardTO to = new BoardTO();
	to.setSubject("제목");
	to.setWriter("작성자");
	
	BoardTO to1 = new BoardTO();
	to1.setSubject("제목 1");
	to1.setWriter("작성자 1");
	
	BoardTO to2 = new BoardTO();
	to2.setSubject("제목 2");
	to2.setWriter("작성자 2");
	
	BoardTO[] lists = {to1, to2}; <-- (= ArrayList<BoardTO> lists = new ArrayList<>();)
	
	pageContext.setAttribute("to", to);
	
	request.setAttribute("lists", lists);
%>
${ to.subject }<br>  
${ to.writer }<br>

${ lists[0].subject }<br>
${ lists[2].subject }<br>   <-- 널포인틍익셉션 발생하지 않음( 에러 없이 공백으로 처리 )
${ lists[1].subject }<br>

</body>



복잡한 arraylist 형식(페이지 형식 el로 데이터 접근)

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="model.BoardTO" %>    
<%@ page import="model.BoardListTO" %>    
<%@ page import="java.util.ArrayList" %>      
<%
	BoardTO to1 = new BoardTO();
	to1.setSubject("제목 1");
	to1.setWriter("작성자 1");
	
	BoardTO to2 = new BoardTO();
	to2.setSubject("제목 2");
	to2.setWriter("작성자 2"); 
	
	BoardListTO listTO1	 = new BoardListTO();
	
	listTO1.setCpage("1");
	listTO1.setBoardTO(to1);
	
	BoardListTO listTO2	 = new BoardListTO();
	
	listTO2.setCpage("2");
	listTO2.setBoardTO(to2);
	
	ArrayList<BoardListTO> lists = new ArrayList();
	lists.add(listTO1);
	lists.add(listTO2);
	
	pageContext.setAttribute("lists", lists);

%>

${ lists[0].cpage }<br>
${ lists[1].cpage }<br>
${ lists[0].boardTO.subject }<br>
${ lists[1].boardTO.writer }<br>



부가적인 데이터 가져올 수 있음

<body>
<%
	//브라우저 정보 얻기
	out.println(request.getHeader("user-agent") + "<br>");
%>


EL 사용하여 쉽게 표기

<!-- EL 로 쉽게 적기 -->
${ header['host'] }<br>
${ header['user-agent'] }<br>
<br>
${ header }<br>  <-- 전체 표기

그 외 다른 정보

${ pageContext.request.requestURI }<br>  <- 경로
${ pageContext.request.remoteAddr }<br>  <-- 아이피



param

request.getParameter을 EL로 간편하게 사용할 수 있음.

String id = request.getParameter("id");
-> = ${ param.id } / ${ param["id"] }



JSTL (Java Server Pages Standard Tag Library)

jsp에서 사용하는 태그 라이브러리를 공통으로 사용하기 위해 정해진 표준 (커스텀 태그)

java를 html 처럼 사용하게 끔 만든 것

라이브러리 설치해야 다음 5가지 태그 라이브러리를 사용 가능함

태그 라이브러리

Core - 프로그램 개발 시 사용되는 기본적인 기능
Formatting - 날짜, 시간에 관한 형식 처리 기능
SQL - 데이터베이스 작업에 관한 기능
XML - XML 지원하는 기능
Functions - 여러가지 함수 기능 제공



Core


Core 사용시 디렉티브 저렇게 써주기 (core를 c라는 이름으로 사용할 것이라는 뜻)


<c:out

out.println 역할을 함

<body>
<!-- EL 출력 -->
${ "browser"}<br>

<!-- JSTL 출력 -->
<c:out value="browser"></c:out><br>
<br>
<% 
	pageContext.setAttribute("data", "browser");
%>

EL : ${ data }<br>
JSTL : <c:out value="${ data }"></c:out><br>
JSTL : <c:out value="${ data1 }"></c:out><br>   <-- 없는 데이터 출력하려고 할 시, 공백으로 처리
JSTL : <c:out value="${ data2 }" default="nobrowser"></c:out><br> <-- 없는 데이터에 디폴트값을 설정하여 
공백 대신 디폴트 값 출력할 수 있음
JSTL : <c:out value="${ data }" default="nobrowser"></c:out><br>  <-- 데이터가 있는데 디폴트값 줄 경우 
있는 데이터가 출력됨

</body>




<c:set

setAttribute 역할을 함

<c:set var="data1" value="value1" />
<c:set var="data2" value="value2" scope="page" />
<c:set var="data3">value3</c:set>
--> 저장해주고

data1 : <c:out value="${ data1 }" /><br>
data2 : <c:out value="${ data2 }" /><br>
data3 : <c:out value="${ data3 }" /><br>
--> 출력

data1 : <c:out value="data1" /><br>  <-- c:set이 아니라서 data1이 그대로 출력

<c:set var="data" value="value1" scope="page" />
<c:set var="data" value="value2" scope="request" />
<c:set var="data" value="value3" scope="session" />

-->scope로 기준을 잡아서 출력 가능
${pageScope.data }<br>
${requestScope.data }<br>
${sessionScope.data }<br>

profile
끄적끄적

0개의 댓글