웹사이트의 로그인 성공 시 해당 사용자의 정보를 어떻게 가지고 있어야할까?

 

이는 세션쿠키를 이용해서 가지고 있을 수 있다!

 

즉 쉽게 말해서 클라이언트측에 남느냐 서버에 기록이 남느냐에 따라 쿠키(과자부스러기=흔적)이나 세션이냐

클라이언트에 흔적남기기 = 쿠키(Cookie)

서버에 흔적남기기 = 세션(Session)

 

우리는 Session에 대해 알아볼 것 이다.

 

정말 쉽게 말해보자면 클라이언트가 서버에 요청하면 해당 클라이언트에 이름표(?)를 붙여놓는다고 할 수 있다.

이제 그 이름표를 가지고 정보를 가지고 올 수 있다.

 

코드를 보면서 이해해보자!

아래의 예제는 클라이언트측의 코드(jsp)이다.

session.getAttribute(); 라는 코드가 의심스럽다.

파라미터로 값들을 구별할 수 있는 id값을 넣는 것이다. 서버측 코드를 보면 바로 이해할 수 있을 것이다.

<%@page import="admin.member.Admin"%>
<%@ page contentType="text/html;charset=utf-8"%>
<%
	//세션에서 데이터 꺼내기
	out.print("당신이 사용하고 있는 세션객체는 "+session);
	Admin admin = (Admin)session.getAttribute("ad");
	
	//만일 admin VO가 null이면? 인증을 거치지 않거나, 세션이 만료된 상황이므로, 현재
	//페이지에 대한 접근 자체를 막아야한다..
	if(admin!=null){
%>
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<%@ include file="/admin/inc/head.jsp" %>
<style>

</style>
</head>
<body>
<div><a href="#"><%=admin.getMid() %></a>님 반갑습니다.</div>
<a href="/admin/logout.jsp">로그아웃</a>
<%@include file="/admin/inc/topnavi.jsp" %>
<div style="padding-left:16px">
  <h2>Top Navigation Example</h2>
  <p>Some content..</p>
</div>

</body>
</html>
<%}else{%>
<script>
alert('올바르지 않은 접근입니다.');
history.back();
</script>
<%}%>

 

이제 서버측의 코드를 보자

단순히 서버에 저장된 id와 password랑 클라이언트측에서 파라미터로 보낸 id와 passsword가 같으면 세션에 저장을 한다.

session.setAttribute("세션ID", 저장할 객체(?)); 

<%@page import="admin.member.Admin"%>
<%@ page contentType="text/html;charset=utf-8"%>
<%@include file="/inc/lib.jsp" %>
<%
	/* 
	원래는 데이터베이스에서 조회를 해야하지만, 추후 하기로 하고
	일단은 스트링으로 비교해본다..
	*/
	String admin_id = "scott";
	String admin_pass="1234";
	
	String mid = request.getParameter("mid");
	String password = request.getParameter("password");
	
	if(admin_id.equals(mid)&&admin_pass.equals(password)){
		//로그인 성공에 대한 보상, 관리자 페이지 보여주기
		//js의 location.href와 동일한 기능의 jsp 기능 이용해보자
		Admin admin = new Admin();
		admin.setMid(mid);
		admin.setPassword(password);
		
		//jsp의 내장객체인 session객체는 클라이언트가 신규접속이라고 생각할 때, 새로운 session
		//인스턴스를 생성하고 세션 ID도 생성하여 세션에 부여한다..
		//이 세션은 클라이언트가 브라우저를 종료하지 않거나, 일정시간내에 재접속을 할 경우 계속
		//사용할 수 있다.. 따라서 웹은 stateless기반이지만, 서버측 메모리에 생성된 세션을 이용
		//하면 마치 연결이 유지된 것처럼 보여질 수 있다. 주용도) 로그인 후 회원정보를 모든 페이지에서
		//사용할 수 있는 기능, 장바구니 등에 사용..
		session.setAttribute("ad", admin);
		System.out.println("로그인 요청 시 사용중인 "+session);
		response.sendRedirect("/admin");//클라이언트로 하여금 지정한 url로 요청을 시도
	}else{
		out.print(getMsgBack("로그인 정보가 일치하지 않습니다"));
	}
%>

 

실행결과

 

위 코드를 이해한다면 DB와 연결하고 위와 비슷하게 세션을 저장하면 끝~

'프로그래밍 > JSP' 카테고리의 다른 글

JSP | MVC패턴에 대한 이해  (0) 2020.12.16
JSP | 서블릿(Servlet) 이해  (0) 2020.12.16
JSP | 커넥션풀(Connection Pool)  (0) 2020.12.11
JSP | MyBatis 사용해보기  (0) 2020.12.10
JSP - 페이징 이해  (0) 2020.12.08

싱글톤패턴(Singleton Pattern)

 

GoF의 디자인 패턴 중 하나인 싱글톤 패턴은 인스턴스를 오직 하나만 생성해서 메모리를 절약?할 수 있다.

 

package common.db;

import java.sql.SQLException;

import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;

public class PoolManager2 {
	InitialContext context;
	DataSource ds;
	private static PoolManager2 instance;
	private PoolManager2() {
		try {
			context = new InitialContext();
			ds = (DataSource)context.lookup("java:comp/env/jdbc/myoracle");
		} catch (NamingException e) {
			e.printStackTrace();
		}
	}
	public static PoolManager2 getInstance() {
		if(instance==null) {
			return instance = new PoolManager2();
		}
		return instance;
	}
}
  • 위 코드는 커넥션풀 관리하도록 만든 객체 중 일부이다.
  • 생성자의 접근지정자를 private
  • 클래스 내에 private인 현재 클래스의 객체를 멤버변수로 둔다
  • 해당변수의 get메서드static으로 만들어서 외부에서 이 클래스에 대한 인스턴스를 만들고 싶을 때는 오직 get메서드로만 생성할 수 있고 만약 아직 생성되지 않았다면 생성, 생성되어 있으면 그냥 반환만 받는 구조
  • static의 메서드에서는 static변수만 사용할 수 있으니 변수를 static으로!

실행결과

package common.db;

public class text {
	public static void main(String[] args) {
		for(int i=1;i<=10;i++) {
			System.out.println(i+" : "+PoolManager2.getInstance());
		}
	}
}

하나의 객체만 생성하게 되는 것을 볼 수 있다!

'프로그래밍 > Java' 카테고리의 다른 글

java - 암호화  (0) 2021.01.06
java - mail 보내기  (0) 2021.01.06
JavaFX - 개발환경 구축 및 생명주기  (0) 2020.11.23
Java - JSON & XML 파싱  (0) 2020.11.17
Java - 소켓프로그래밍 기초 Echo System  (0) 2020.11.09

지금까지 DAO를 쓸 때마다 Connection객체를 생성하고 해당 메서드가 끝나면 자원을 해제하고를 반복했다.

//접속 개체 얻기 
	public Connection getConnection(){
		Connection con=null;//return 시키기 위해..
		try{
		Class.forName(driver);
		System.out.println("드라이버 로드 성공");

		con = DriverManager.getConnection(url, user,password);
	
		}catch(ClassNotFoundException e){
			e.printStackTrace();
			System.out.println("드라이버 로드 실패");
		}catch(SQLException e){
			e.printStackTrace();	
		}
		return con;
	}

	//자원해제
	public void release(Connection con){//쿼리문 수행 안했을 때..
		if(con!=null){
			try{
				con.close();	
			}catch(SQLException e){
				e.printStackTrace();
			}
		}
	}

 

웹페이지를 만들어서 많은 사람들이 사용한다고 생각해보면 많은 사람들이 페이지에 접속하고 사용할 때마다
Connection을 받고 바로 해제하고 이러한 과정이 반복된다.
DB로부터 Connection을 얻는 행동은 엄청난 자원을 필요로 하는데 (쿼리, 유저맞어?, 권한?...)
우리는 지금까지 그런 소중한 자원을 썻다 바로 버리고 있었다....;;; 

 

이런 고충을 해결하기 위해 Connection Pool을 이용해보자

 

나는 Tomcat에서 지원하는 Connection Pool을 사용했다.

1) server.xml

    <!--톰캣서버의 server.xml 파일을 열어서 GlobalNamingResources태그 안에 넣어준다-->
    <!--myoracle은 개발자 마음대로 선언해주면 된다.-->
    <Resource name="jdbc/myoracle"
		auth="Container"
		type="javax.sql.DataSource"
        <!--driver의 위치-->
		driverClassName="oracle.jdbc.driver.OracleDriver"
        <!--사용하는 DB의 url-->
		url="jdbc:oracle:thin:@localhost:1521:XE"
        <!--유저의 id-->
		username="lastuser"
        <!--유저의 비밀번호-->
		password="lastuser"
		maxActive="20"
		maxIdle="10"
		maxWait="3000"/>

2) web.xml

	<resource-ref>
	<res-ref-name>jdbc/myoracle</res-ref-name><!--server.xml에서 썼던 이름와 동일하게!-->
	<res-type>javax.sql.DataSource</res-type>
	<res-auth>Container</res-auth>
	</resource-ref>

3) tomcat/context.xml

<ResourceLink type="javax.sql.DataSource"
                      name="jdbc/myoracle"
                      global="jdbc/myoracle" />
                      <!--여기도 이름을 동일하게!!-->

4) 사용방법 (테스트)

<html>
<head>
<%@ page
import="java.sql.*,
javax.sql.*,
java.io.*,
javax.naming.InitialContext,
javax.naming.Context" %>
</head>
<body>
<h1>JDBC JNDI Resource Test</h1>

<%
/*
JNDI란? 
JAVA Naming Directory interface : 어떤 정보를 프로그래밍 언어인 자바코드에 넣지 말고, 외부의 xml과 같은 자원으로 관리하는 방법 
(즉, 자바코드 안에 설정정보를 넣지 말고, 코드 밖으로 빼서 유지관리하자!)  server.xml
*/

InitialContext initCtx = new InitialContext(); //검색 객체
DataSource ds = (DataSource) initCtx.lookup("java:comp/env/jdbc/myoracle"); //검색객체가 안에 내용을 찾는다. server.xml의 datasource를 찾아나선다
//새로운 접속이 아니라, 이미 풀에 존재하는 접속 객체를 대여하는 것!
Connection conn = ds.getConnection();//커넥션풀로부터 하나의 커넥션을 얻는 작업!! 

Statement stmt = conn.createStatement();
ResultSet rset = stmt.executeQuery("select * from board");
while (rset.next()) {
out.println("title=="+rset.getString("title")+"<br>");
}
rset.close();
stmt.close();
conn.close();
initCtx.close();
%>
</body>
</html>

 

JNDI란?

JAVA Naming Directory Interface : 어떤 정보를 프로그래밍 언어인 자바코드에 넣지 않고 외부의 xml과 같은 자원으로 관리하는 방법  (즉, 자바코드 안에 설정정보를 넣지 말고, 코드 밖으로 빼서 유지관리하자!) 

ex) server.xml, web.xml ..?

 

DataSource?

  • Connetion Pool을 관리하기 위한 객체!!!
  • Connection 획득과 반환 등의 작업을 한다! 
<Resource name="jdbc/myoracle"
		auth="Container"
		type="javax.sql.DataSource"
        <!--driver의 위치-->
		driverClassName="oracle.jdbc.driver.OracleDriver"
        <!--사용하는 DB의 url-->
		url="jdbc:oracle:thin:@localhost:1521:XE"
        <!--유저의 id-->
		username="lastuser"
        <!--유저의 비밀번호-->
		password="lastuser"
		maxActive="20"
		maxIdle="10"
		maxWait="3000"/>
  • 위의 server.xml에서 넣어줬던 코드는 DataSource를 의미! (type="javax.sql.DataSource")

'프로그래밍 > JSP' 카테고리의 다른 글

JSP | 서블릿(Servlet) 이해  (0) 2020.12.16
JSP | session  (0) 2020.12.16
JSP | MyBatis 사용해보기  (0) 2020.12.10
JSP - 페이징 이해  (0) 2020.12.08
JSP - 이미지 업로드  (0) 2020.12.04

+ Recent posts