블로그 이미지
GUCCI

카테고리

전체보기 (111)
여행 (1)
기기 (2)
쇼핑 (0)
게임 (0)
etc. (6)
취업이야기 (0)
업무일지 (5)
리눅스 (38)
웹프로그래밍 (2)
네트워크 (4)
JAVA (17)
Android (0)
IOS (2)
LUA (8)
C/C++ (1)
Objective C (2)
SERVER (2)
그누보드4 (1)
MSSQL (2)
Programming (1)
자바스크립트 (4)
HTML/CSS (1)
LGNAS (0)
Total
Today
Yesterday
weblogic10X 의 DataSource 의  Inactive Connection Timeout 옵션

*위치 
웹로직콘솔 -> Services -> JDBC -> DataSources 의 만들어진 것 하나 선택

-> Configuration -> Connection Pool 에서 'Advanced' 클릭 -> "Inactive Connection Timeout" 옵션  

디폴트는 0 으로 되어있음.
가령 300 으로 입력하면, 
5분후 정상적으로 DB 자원이 회수되지 않는것이 있다면 웹로직이 강제적으로 회수를 합니다.

요즘은 DB 관련한 Framework를 사용하기 때문에 이런 옵션을 사용하게 될 경우가 많이 없어졌지만,
예전 JDBC 프로그램시 JAVA, JSP 에서 connection 가져오고 release 하는 모든것을 코딩해줬는데...
이때 실수로 release 하는것을 빼먹으면....(자원 반납하지 않게 되면..)
WAS 가 죽어버리는 사태가 발생을 합니다.
이때 이 옵션을 사용하면 임시조치와 오류내용으로 소스 수정할수 있는 힌트를 얻게 됩니다.

웹로직 log 에는 .
"forcibly....." 어쪄고 저쪄고 나오면서 강제적으로 회수한다는 Exception 이 나오는것 같더군요.
그 Exception 에 보면... 대략 오류나는 위치를 짐작할수 있습니다.


'JAVA' 카테고리의 다른 글

JDK 다운 설치  (5) 2012.02.16
java unsigned  (2) 2012.02.09
세션이 생성되고 관리되는 과정  (3) 2011.08.12
중복로그인 체크  (2) 2011.08.12
java 형변환 모음  (1) 2011.04.06
Posted by GUCCI
, |

Reached maximum capacity of pool "xxxPool", making "0" new resource instances instead of "1".


JDBC -  Control Tab 
Suspend, Resume 으로 Connection 초기화가 가능


'JAVA > exception' 카테고리의 다른 글

javax.servlet.ServletException: BeanUtils.populate  (4) 2011.03.07
Posted by GUCCI
, |

JDK 다운 설치

JAVA / 2012. 2. 16. 14:09

1. 다운로드

 

http://www.oracle.com/us/sun/index.html

 

 

Downloads 선택

  

Java SE 선택

 

 

 

Download JDK 선택

 

 

Platform을 Windows로 선택

 

 

 

 

 

jdk-6u23-windows-i586.exe 실행

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

"새로 만들기"일 경우 변수 이름에 JAVA_HOME 변수 값에 C:\jdk1.6.0_20 입력 후 "확인" 단추 선택

 

 

 

 

"새로 만들기"일 경우 변수 이름에 CLASSPATH 변수 값에 .; 입력 후 "확인" 단추 선택

"편집"일 경우 변수 값에 앞쪽에 .; 입력 후 "확인" 단추 선택

 

 

'JAVA' 카테고리의 다른 글

웹로직의 DB 자원 회수(Inactive Connection Timeout)  (0) 2013.11.19
java unsigned  (2) 2012.02.09
세션이 생성되고 관리되는 과정  (3) 2011.08.12
중복로그인 체크  (2) 2011.08.12
java 형변환 모음  (1) 2011.04.06
Posted by GUCCI
, |

java unsigned

JAVA / 2012. 2. 9. 10:57
예를 들어, int에 들어 있는 -1 이라는 숫자를, unsigned형으로 표현하면 4294967295 가 되는데, 이런 변환 작업을 자바에서 하려면 아래 예제의 unsigned32() 라는 메소드(함수)를 사용하면 됩니다. 자바에서는 unsigned형으로 형변환(Typecasting)하는 캐스트 연산자가 제공되지는 않습니다. unsigned형 자체가 없기에...

자바의 int에는 2147483647 이상의 숫자를 넣을 수 없으므로, unsigned32()는, int가 아닌 long형으로 반환합니다. (물론 자바의 long형도 unsigned형은 없지만, 64비트 정수이기에 천문학적인 정수를 대입할 수 있습니다.)
 
public class Example {
  public static void main(String[] args) {

    System.out.println( unsigned32(-1) );   // 4294967295
    System.out.println( unsigned32(-2) );   // 4294967294
    System.out.println( unsigned32(1) );    // 1
    System.out.println( unsigned32(0));     // 0

    System.out.println( unsigned32(0xFFFFFFFF) );  // 4294967295 (부호 없는 32비트 int형의 최대값)
    System.out.println( unsigned32(0x7FFFFFFF) );  // 2147483647 (부호 있는 32비트 int형의 최대값)

    System.out.println( unsigned32(0x7FFFFFFF - 1) );  // 2147483646
    System.out.println( unsigned32(0x7FFFFFFF + 1) );  // 2147483648
  }


  // int를, unsigned형 long으로 변환 메서드
  public static long unsigned32(int n) {
    return n & 0xFFFFFFFFL;
  }


}




일단 JAVA가 C/C++의 unsigned 를 지원하지 않는건 맞구요,
그런 문제가 발생한다면 아래와 같은 식으로 해주시면 됩니다.

int val = myByte < 0 ? ( Byte.MAX_VALUE + 1 ) * 2 + myByte : myByte;

코드를 보시면 왜 저렇게 써야하는지는 이해를 할 수 있으리라 보네요.
log 의 경우에도 이런식으로 하시면 될것 같구요, 그리고 특별히 
Byte, Integer, Long 등의 래퍼클래스의 MAX_VALUE나 MIN_VALUE를 넘지 않는 한은
특별히 신경쓸 이유도 없습니다.(당연하겠지만...)

저도 정확히는 알 수 없습니다만, 자바에서는 자체적으로 BigDecimal 등을 이용해서
C보다 더 큰 숫자를 표현할 수 있는 방법을 제공해 주기 때문에 굳이 C처럼
unsigned 를 지원할 필요가 없다고 생각한게 아닐까요? 라는 생각을 해봤습니다.  

'JAVA' 카테고리의 다른 글

웹로직의 DB 자원 회수(Inactive Connection Timeout)  (0) 2013.11.19
JDK 다운 설치  (5) 2012.02.16
세션이 생성되고 관리되는 과정  (3) 2011.08.12
중복로그인 체크  (2) 2011.08.12
java 형변환 모음  (1) 2011.04.06
Posted by GUCCI
, |
HTTP는 stateless다.
어떤 넘이 수백 번을 요청을 보내더라도 얘가 걘지 걔가 얘인지 알 수가 없다.
한 마디로 메멘토다. 장기 기억력을 상실했다.
요청에 대한 처리가 끝나면 갑자기 지금까지 했던 모든 것을 잊어버린다.

근데 분명히 웹에서 state는 필요하다. 안 그러면 장바구니 구현 어떻게 하는데?
그 것을 위하여 세션이라는 것이 HTTP를 보완해준다.

세션은 무언가?
한 마디로 말해서 클라이언트마다 주어지는 객체들이다.
클라이언트 하나당 세션 객체 하나가 주어진다.

그럼 클라이언트는 무엇인가? 특정 아이디? 특정 IP?
다 아니다. 클라이언트는 바로 브라우저 창 그 자체다.
인터넷 익스플로러를 더블 클릭을 두 번 눌러서 키면 니는 지금
클라이언트를 두 개나 생성한 것이다.
(아 물론 ctrl+n을 눌러서 만드는 건 같은 클라이언트임... 좀 다르더라구..)

이제 클라이언트가 뭔지 이해가 갔다.
클라이언트는 서버에 HTTP Request를 보낼 때마다
어느 것이 자기 세션인지 서버에 말을 해줘야 한다.
서버는 띨하니까!

그럼 세션 객체마다 구별해야 하는 정보가 있어야 한다.
이 것이 바로 session id다.
서로 다른 클라이언트는 서로 다른 session id를 이용하여,
서로 다른 session 객체에 접근하게 된다.

근데 아무 것도 없는 無의 상태에서 사용자의 브라우저가 갑자기 신내림을 받아서
session id를 지가 만들어낼 리가 만무하다.


세션은 서버 쪽에서 만들어진다.
원리는 이렇다.

< 세션 사용을 필요로 하는 사용자의 첫 요청 >
서버의 생각///// 어라, HTTP Request의 헤더에세션 id가 없네?
이 넘은 처음 요청한 넘이다. 세션 객체를 하나 새로 만들고
그 객체의 key를 HTTP Response의 헤더로 넘겨주자.
그 HTTP Response를 받은 클라이언트의 생각/////
어 이넘이 세션 ID를 줬어. 쿠키에 설정해놓자.

< 그 다음 요청들 >
클라이언트의 생각///// HTTP Request 헤더에 session id를 넣어서 보내자.
그 걸 받은 서버의 생각///// 이 넘은 예전에 보내줬나보네... 기억이 안나. 객체 만들필요 없겠군. 있던거 쓰자!


일련의 작업은 어디서 이루어지는감?

     HttpSession session = request.getSession();

저 코드에서 모든 것이 이루어진다. 컨테이너가 알아서한다.
개발자는 세션이 어떻게 생성되고, id는 어떻게 주고받아지는지 전혀 신경 쓸 필요 없다.
참고할 메소드들 알아보자.

(1) boolean b = session.isNew()   
//방금 전에 생성된 세션일 경우 true 리턴

(2) HttpSession session = request.getSession(false);   
//기존 세션 객체가 있으면 그 걸 리턴하고, 없으면 걍 null을 리턴해. 세션을 새로 만들지 말고...
//참고로 request.getSession(true)는 request.getSession()과 동일한 코드...



좋다. 근데 또 문제가 생겼다.
쿠키를 사용하지 않는 브라우저가 있다.
그런 넘에게는 URL을 통하여 session_id를 주고받는 방법밖에 없다.
이 것을 URL재작성이라고 부른다.
URL재작성은 서블릿 내에서 다음과 같은 코드로 이루어진다.

     out.println("<a href = \"" + response.encodeURL("/BeerTest.do") + "\">click me</a>");

URL뒤에 세션 ID를 추가하게 된다.
/BeerTest.do;jsessionid=0AAB6C7DE415 이런 식으로...
아 참고로 정적인 페이지(걍 html)는 쿠키를 사용하지 않는 브라우저에겐 방법이 없다.
위의 방법을 쓰려면 무조건 동적으로 생성되는 페이지여야함 -ㅅ-
(컨테이너의 지능에 따라서 재작성을 안할수도! 아래 참고!)



컨테이너는 다음과 같이 동작한다.

< HTTP Request header의 Cookie헤더 또는 URL에 session id가 없을 때 >
이 사용자는 처음 접속한 사용자다.
일단은 이 사용자가 쿠키를 사용할 수 잇는지 없는지 모른다.
그러므로 세션 id를 
HTTP 헤더와 URL 재작성, 두 가지 통로로 모두 보내본다.

< HTTP Request header의 Cookie헤더 또는 URL에 session id가 있을 때 >
이 사용자는 두 번째 이상 접속한 사용자다.
일단은 이 사용자가 쿠키를 사용할 수 있는지 없는지는
어디에 세션 id가 적혀있는지 보면 알 수 있다.
세션 id가 URL에 적혀있는 경우, request.encodeURL메소드는 URL을 세션id를 추가하여 재작성하게 된다.
세션 id가 HTTP Req 헤더에 적혀있는 경우, request.encodeURL메소드는 URL을 세션id를 추가하여 재작성하지 않는다. 그냥 안보내고 고고씽 해도 그 클라이언트는 세션 id 지가 알아서 저장한거기 때문.


그! 래! 서!
요청 파라미터의 jsessionid, JSESSIONID로 파라미터를 보내는
ㅄ짓은 하지 말자. 이미 예약되어있다. (RESERVED)

'JAVA' 카테고리의 다른 글

JDK 다운 설치  (5) 2012.02.16
java unsigned  (2) 2012.02.09
중복로그인 체크  (2) 2011.08.12
java 형변환 모음  (1) 2011.04.06
자바 iBATIS 결과를 XML 리턴받기 : xmlResultName , java , xml  (1) 2011.04.06
Posted by GUCCI
, |

중복로그인 체크

JAVA / 2011. 8. 12. 17:35
/* 
* 로그인 중복체크
* 이미 로그인한 사용자가 있을경우 기존의 사용자 세션을 종료후 자신이 로그인.
* 해시테이블에 세션과 접속자 아이디를 저장해 둔다.
* 세션 Object를 저장하는 이유는 동일한 아이디로 재접속 했을경우 
* 아이디로 세션Object를 찾아내어 기존의 접속을 끊기위해서다.(invalidate)
*/ 


============== WEB-INF\src\test\LoginManager.java ===============
package test; 

import java.util.*;
import javax.servlet.http.*;
/*
* session이 끊어졌을때를 처리하기 위해 사용
* static메소드에서는 static만사용 하므로static으로 선언한다.
*/
public class LoginManager implements HttpSessionBindingListener{

    private static LoginManager loginManager = null;
    
    //로그인한 접속자를 담기위한 해시테이블
    private static Hashtable loginUsers = new Hashtable();
    
    /*
     * 싱글톤 패턴 사용
     */
    public static synchronized LoginManager getInstance(){
        if(loginManager == null){
            loginManager = new LoginManager();
        }
        return loginManager;
    }
     
    
    /*
     * 이 메소드는 세션이 연결되을때 호출된다.(session.setAttribute("login", this))
     * Hashtable에 세션과 접속자 아이디를 저장한다.
     */
    public void valueBound(HttpSessionBindingEvent event) {
        //session값을 put한다.
        loginUsers.put(event.getSession(), event.getName());
        System.out.println(event.getName() + "님이 로그인 하셨습니다.");
        System.out.println("현재 접속자 수 : " +  getUserCount());
     }
    
    
     /*
      * 이 메소드는 세션이 끊겼을때 호출된다.(invalidate)
      * Hashtable에 저장된 로그인한 정보를 제거해 준다.
      */
     public void valueUnbound(HttpSessionBindingEvent event) {
         //session값을 찾아서 없애준다.
         loginUsers.remove(event.getSession());
         System.out.println("  " + event.getName() + "님이 로그아웃 하셨습니다.");
         System.out.println("현재 접속자 수 : " +  getUserCount());
     }
     
     
     /*
      * 입력받은 아이디를 해시테이블에서 삭제. 
      * @param userID 사용자 아이디
      * @return void
      */ 
     public void removeSession(String userId){
          Enumeration e = loginUsers.keys();
          HttpSession session = null;
          while(e.hasMoreElements()){
               session = (HttpSession)e.nextElement();
               if(loginUsers.get(session).equals(userId)){
                   //세션이 invalidate될때 HttpSessionBindingListener를 
                   //구현하는 클레스의 valueUnbound()함수가 호출된다.
                   session.invalidate();
               }
          }
     }
     
     
     /*
      * 사용자가 입력한 ID, PW가 맞는지 확인하는 메소드
      * @param userID 사용자 아이디
      * @param userPW 사용자 패스워드
      * @return boolean ID/PW가 일치하는 지 여부
      */
     public boolean isValid(String userId, String userPw){
         
         /*
          * 이부분에 Database 로직이 들어간다.
          */
         return true;
     }


    /*
     * 해당 아이디의 동시 사용을 막기위해서 
     * 이미 사용중인 아이디인지를 확인한다.
     * @param userID 사용자 아이디
     * @return boolean 이미 사용 중인 경우 true, 사용중이 아니면 false
     */
    public boolean isUsing(String userID){
        return loginUsers.containsValue(userID);
    }
     
    
    /*
     * 로그인을 완료한 사용자의 아이디를 세션에 저장하는 메소드
     * @param session 세션 객체
     * @param userID 사용자 아이디
     */
    public void setSession(HttpSession session, String userId){
        //이순간에 Session Binding이벤트가 일어나는 시점
        //name값으로 userId, value값으로 자기자신(HttpSessionBindingListener를 구현하는 Object)
        session.setAttribute(userId, this);//login에 자기자신을 집어넣는다.
    }
     
     
    /*
      * 입력받은 세션Object로 아이디를 리턴한다.
      * @param session : 접속한 사용자의 session Object
      * @return String : 접속자 아이디
     */
    public String getUserID(HttpSession session){
        return (String)loginUsers.get(session);
    }
     
     
    /*
     * 현재 접속한 총 사용자 수
     * @return int  현재 접속자 수
     */
    public int getUserCount(){
        return loginUsers.size();
    }
     
     
    /*
     * 현재 접속중인 모든 사용자 아이디를 출력
     * @return void
     */
    public void printloginUsers(){
        Enumeration e = loginUsers.keys();
        HttpSession session = null;
        System.out.println("===========================================");
        int i = 0;
        while(e.hasMoreElements()){
            session = (HttpSession)e.nextElement();
            System.out.println((++i) + ". 접속자 : " +  loginUsers.get(session));
        }
        System.out.println("===========================================");
     }
     
    /*
     * 현재 접속중인 모든 사용자리스트를 리턴
     * @return list
     */
    public Collection getUsers(){
        Collection collection = loginUsers.values();
        return collection;
    }
}

/*
* 거의 대부분의 웹사이트를 보면 브라우저를 열고 로그인후
* 또다시 다른브라우저를 열고 로그인을 하면 로그인이 되는것을 확인하실수
* 있습니다. 이는 즉... 여러곳에서 동일한 아이디로 접속을 할수있다는 예입 
* 니다. 이와 반대로 메신저같은경우는 이미 로그인이 되어있을시 다른곳에서
* 로그인을 하면 접속을 끊을지를 물어보는 기능도 보셨을 겁니다. 이를 웹에
* 서 구현하여 보았습니다. 
* 본 예제소스는 우리가 구현하려고 예제에서 가장 핵심적인 부분을 맡고있
* 는 소스입니다.
* 여기서 HttpSessionBindingListener는 서블릿 컨테이너에서 세션이 끊길때
* (valueUnBound)와 이를 구현하는 오브젝트가 해당 세션에 setAttribute될
* 때(valueBound) 호출합니다. 굳이 이를 구현하는이유는 세션이 끊기는 시
* 점을 정확히 잡아내기 위함입니다. 사용자가 로그아웃버튼을 누를시도 있지
* 만 세션이 타임아웃되는경우도 세션이 끊겨야 하기 때문입니다. 그리고 
* 브라우저의 닫기버튼, Alt+F4, Ctrl+E버튼 을 누를시 이벤트를 잡는방법도 
* 차근차근 알아보도록 합시다.

=============================== login.jsp ============================
<%
    /*
     * 로그인 페이지, 로그인전 현재 로그인된 이용자수를 출력한다.
     */
%>
<%@ page language="java" contentType="text/html; charset=EUC-KR"%>
<%@ page import="test.LoginManager"%>
<%!
    //싱글톤 패턴을 사용하였기 때문에 생생되어있는 인스턴스를 얻어온다.
    LoginManager loginManager = LoginManager.getInstance(); 
%>
<%
    //login_try에서 로그인을 하지 않을경우 세션에 남아있는 userId를 제거한다.
    session.removeAttribute("userId");
%>
<html>
<head>
    <title>로그인 중복방지 Test</title>
</head>
<body>
    <h3 align="center">현재 접속자 수 : <%=loginManager.getUserCount() %>명</h3>
    <form action="login_try.jsp" name="login">
        <div align="center">
            아이디  :   <input type="text" name="userId"><br>
            비밀번호    :   <input type="passward" name="userPw"><br>
            <input type="submit" value="로그인">
        </div>
    </form>
</body>
</html>




============================= login_try.jsp ============================
<%
    /*
     * 로그인 시도페이지, id, pw유무를 체크하고, 올바르다면 
     * 이미 접속한 아이디인지 체크한다. 이미 접속한 아이디라면
     * 기존 접속을 유지할것인지, 기존접속을 kill시키고 로그인할것인지를 
     * 확인한다.
     */
%>
<%@ page language="java" contentType="text/html; charset=EUC-KR" %>
<%@ page import="test.LoginManager"%>
<%!
    //싱글톤 패턴을 사용하였기 때문에 생생되어있는 인스턴스를 얻어온다.
    LoginManager loginManager = LoginManager.getInstance(); 
%>
<html>
<head>
    <title>로그인 중복방지 Test</title>
</head>
<body align="center" valign="center">
<%
    String userId = request.getParameter("userId");
    String userPw = request.getParameter("userPw");
    
    //아이디 패스워드 체크
    if(loginManager.isValid(userId, userPw)){
        
        //접속자 아이디를 세션에 담는다.
        session.setAttribute("userId", userId);
        
        //이미 접속한 아이디인지 체크한다.
        //out.println(userId);
        //out.println(loginManager.isUsing(userId));
        loginManager.printloginUsers();
        if(loginManager.isUsing(userId)){
%>
            이미 접속중입니다. 기존의 접속을 종료하시겠습니까?<P>
            <a href="disconnect.jsp">예 </a>
            <a href="login.jsp">아니오</a>
<%
        }else{
            loginManager.setSession(session, userId);
            response.sendRedirect("login_ok.jsp");
        }
%>
<%
    }else{
%>
        <script>
            alert("로그인후 이용해 주세요.");
            location.href = "login.jsp";
        </script>
<% 
    }
%>
</body>
</html>




========================== disconnect.jsp ============================
<%
    /*
     * login_try.jsp에서 로그인 중복시 무시하고 로그인할경우 호출.
     * 기존의 session을 끊고 hashTable에 저장후 login_ok.jsp를 호출.
     */
%>
<%@ page language="java" contentType="text/html; charset=EUC-KR" %>
<%@ page import="test.LoginManager"%>
<%!
    //싱글톤 패턴을 사용하였기 때문에 생생되어있는 인스턴스를 얻어온다.
    LoginManager loginManager = LoginManager.getInstance(); 
%>
<html>
<head>
    <title>로그인 중복방지 Test</title>
</head>
<body>
<%
    String userId = (String)session.getAttribute("userId");
    if(userId != null){
        //기존의 접속(세션)을 끊는다.
        loginManager.removeSession(userId);
        
        //새로운 세션을 등록한다. setSession함수를 수행하면 valueBound()함수가 호출된다.
        loginManager.setSession(session, userId);
        response.sendRedirect("login_ok.jsp");
    }
%>
</body>
</html>




============================= login_ok.jsp ============================
<%
    /*
     * 정상적으로 로그인되었을경우 호출
     * 접속자 아이디를 보여주고 현재 접속중인 모든 사용자를 뿌려준다.
     */
%>
<%@ page language="java" contentType="text/html; charset=EUC-KR" %>
<%@ page import="java.util.*, test.LoginManager"%>

<%!
    //싱글톤 패턴을 사용하였기 때문에 생생되어있는 인스턴스를 얻어온다.
    LoginManager loginManager = LoginManager.getInstance(); 
%>
<html>
<head>
    <title>로그인 중복방지 Test</title>
</head>
<body align="center" valign="center">
<%
    //jsp내장객체 session을 이용하여 접속자 아이디를 얻어온다.
    String userId = (String)session.getAttribute("userId");

    if(userId != null){
%>
        <%=userId%>님 환영합니다.
        <a href="logout.jsp">로그아웃</a>
        <p>
        현재 접속자 : <br>
<%
        Collection collection = loginManager.getUsers();
        Iterator iterator = collection.iterator();
        int i=0;
        while(iterator.hasNext()){
            out.print((++i)+". "+iterator.next()+"<br>");
        }
    }else{
%>
        <script>
            alert("로그인후 이용해 주세요.");
            location.href = "login.jsp";
        </script>
<% 
    }
%>
</body>
</html>



============================= logout.jsp ==============================
<%
    /*
     * 로그아웃을 클릭했을때 호출된다.
     */
%>
<%@ page language="java" contentType="text/html; charset=EUC-KR" %>
<%
//session을 확~~~끊어 버린다. 이시점에 LoginManager의 valueUnbound()가 호출된다.
session.invalidate();
response.sendRedirect("login.jsp");
%>

지금까지 중복로그인 체크를 막기위한 테스트를 해 보았다.

처음 강좌에서 얘기했던 윈도우 닫기버튼, 

윈도우 닫기 단축키인 Alt+F4, Ctrl+E를 수행했을때 세션을 끊는방법을 

알아보겠다. 우리가 아래 예제를 수행했던 이유를 먼저 알아보자.

특정 사용자가 로그인을 시도한다고 생각해보자. 

일반 웹사이트에서는 로그인을하고 다른쪽에서 

로그인을 시도할경우 아무런 대책없이 로그인을 허용하였다.

우리가 많이 사용하는 메신저의 예를 들어보자.

메신저의 경우 로그인을 했을시 이미 접속중이라는 메시지가 뜨게된다.

만약 위와같은 메시지가 수시로 뜬다면 

자신의 id가 누군가가 도용해서 사용중이라는 사실을 알수있을것이다...

그런 느낌이 온다면 우리는 id, password를 변경하여 정보누출을 

어느정도 막을수 있을것이다. 

그리고 또하나 자신의 계정으로 접속중에 제 3자의 누군가가 로그인을 했다면

누군가가 다른곳에서 접속중이라는 메시지를 뿌려줄수 있다면 훨씬 더 좋을

것이다.

우리가 만든 예제에서는 몇가지 문제점이 있다.

위기능을 사용하기 위해서는 로그인시 누군가가 자신의 id로 

이미 로그인 중인지를 알아내는것이 중요하다. 

그리고 이미 로그인된것이 확인 되었다면 자신이 로그인하기를 원한다면 

이미 로그인한 세션을 끊고 자신의 세션을 등록해야한다.. 

그러기 위해서 우리는 해시테이블을 사용하였으며..

기존의 세션을 끊기위해서 세션 오브젝트를 직접 담았다.

문제점은 누군가가 자신의 id로 이미 로그인중인지 알아내는것이다.

우리가 로그인을 하고 무조건 로그아웃버튼을 클릭했다면 그당시 세션을 끊어

다른곳에서의 로그인을 바로 허용하면 되지만 닫기버튼을 누를때나 

Alt+F4, Ctrl+E를 누를때 이벤트를 잡지못하면 안된다는것이다.

그렇지 못하면 그 세션은 서버의 메모리에 계속 살아서 세션이 타임아웃되기

까지는 계속 살아있을것이다.(이때는 HttpSessionBindingListener의 valueUnbound함수가 서블릿 컨테이너에서 호출한다.)

정상적으로 로그아웃버튼을 누르고 브라우저를 닫는사람이 어디있겠는가?

대게의 사용자들은 로그아웃을 하지 않고 바로 닫아버릴것이다.

여기서 위의 방법으로 닫았을때 이벤트를 잡을수 있는 방법을 설명하겠다.

예제는 간단하다.




============================== main.jsp ==============================
<frameset rows="0,*" border="0">
    <frame name="duplChkFrame" scrolling=no frameborder=0 marginwidth="0" marginheight="0" src='frame.html' noresize>
    <frame name="topFrame" scrolling="no" frameborder=0 marginwidth="0" marginheight="0" target="mainFrame" src="mainFrame.jsp" noresize>
</frameset>


============================== frame.html' ============================
<html>
<head>
<script>
    /**
    * logout()
    * 작 성 자 : 권홍재
    * 작 성 일 : 2006-12-18
    * 개    요  : 브라우저가 닫길시 호출
    * return값 : void
    */
    function logout(){
        location.href = 'logout.jsp';
    }
</script>

</head>
<body OnUnload="logout()">
</body>
</html>






위처럼 onUnLoad이벤트를 사용하면 된다.

프레임으로 나눈 이유는 브라우저가 하나의 프레임만으로 되어있다면..

페이지 이동시마다 onUnLoad이벤트가 발생한다는것이다..

곧 페이지가 이동시마다 로그아웃이 발생한다는뜻이며 

고로 세션이 끊겨서 페이지를 이동할수 없다는 말이 된다.

이를 방지하기 위해서 프레임으로 나누어서 메인 프레임에는

일반적인 페이지를 호출을 하고 로그아웃 페이지를 호출하는부분은

페이지가 변경되지 않는 frame.html에서 로그아웃 처리를 하는것이다.

페이지가 닫길때 frame.html에서 onUnLoad이벤트가 발생하여

logout.jsp를 호출하는것이다.

참... 그리고 한가지 새로고침버튼이나 F5번버튼 마우스 오른쪽 버튼을 

클릭하고 새로고침을 할경우는 어쩔수 없다는 것이다..

페이지를 다시 부르는것이기때문에 페이지를 부르기전 기존페이지가 

죽기전에 onUnload이벤트가 발생한다는 것이다. 이를 해결하기 위해서는 

마우스 오른쪽버튼 상단의 메누 보이지 않기, 키업이벤트에서 F5번키를

막는수밖에는 없다.^^;

이것으로 중복로그인체크 강좌를 마치겠다...^^*

'JAVA' 카테고리의 다른 글

java unsigned  (2) 2012.02.09
세션이 생성되고 관리되는 과정  (3) 2011.08.12
java 형변환 모음  (1) 2011.04.06
자바 iBATIS 결과를 XML 리턴받기 : xmlResultName , java , xml  (1) 2011.04.06
태그 제거 정규식  (2) 2011.03.16
Posted by GUCCI
, |

java 형변환 모음

JAVA / 2011. 4. 6. 13:33
[TextView to Double]
TextView  xDoubleA = Double.parseDouble(xViewA.getText());

** xViewA 값은 무조건 숫자형식이여야함. 아닌경우 Exception이 발생.

[int to String]
String str = Integer.toString(i);String str = "" + i;

[String to Int]
int i = Integer.parseInt(str);int i = Integer.valueOf(str).intValue();

[Double to String]
String str = Double.toString(d);

[Long to String]
String str = Long.toString(l);

[Float to String]
String str = Float.toString(f);

[String to Double]
double d = Double.valueOf(str).doubleValue();

[String to Long]

long l = Long.valueOf(str).longValue();long l = Long.parseLong(str);

[String to Float]
float f = Float.valueOf(str).floatValue();

[Decimal to Binary]

String binstr = Integer.toBinaryString(i);

[Decimal to Hexadecimal]
String hexstr = Integer.toString(i, 16);String hexstr = Integer.toHexString(i);Integer.toHexString( 0x10000 | i).substring(1).toUpperCase());
hexadecimal(String) to int
int i = Integer.valueOf("B8DA3", 16).intValue();int i = Integer.parseInt("B8DA3", 16);

[ASCII Code to String]
String char = new Character((char)i).toString();

[Integer to ASCII Code]
int i = (int) c;

[Integer to Boolean]
boolean b = (i != 0);

[Boolean to Integer]
int i = (b)? 1 : 0;

[Boolean to string]
       boolean theValue = true;
       
        //boolean to String conversion
        String theValueAsString = new Boolean(theValue).toString();
       
        System.out.println(theValueAsString);
Posted by GUCCI
, |
IBATIS 는 결과 값을 xml 로 리턴해주는 아주 좋은 기능이 있다. 다만 List 로 받을 경우 따로 파싱해줘야 하는 점이 걸릴뿐이다.

<%=sqlMap.queryForList("select-user-xml", null)%>

위 소스를 브라우저에서 확인하면 각 row 마다 하나의 xml형식으로 완성시켜 배열로 리턴해주게 된다.

++ 참고사이트 : http://naingyo.springnote.com/pages/1495674 iBATIS 가 xml 로 반환해준 값이 라는 부분을 참조하자.
위 결과를 xml 데이터로 사용할 수 없기에 한번더 파싱과정을 거쳐야 한다. 위 사이트도 해결책이 되겠지만, 유동적이지 못한 부분이 걸리는 것 같다. 각 데이터마다 모델에 맞는 처리를 해줘야한다는 것. 그래서 하루종일 이것을 어떻게 하면 간편하게 사용할 수 있을 까? 고민끝에 결과가 나와 소스를 공개한다.

본 소스는 2010/01/05 - [개발센터/JAVA] - 자바 XML 제어 라이브러리 JDOM : JAVA 의 확장 버전이다.


* Xml.java

01./**
02.* @class Xml
03.* @brief Xml Classes
04.*
05.* registered date 20100105
06.* programmed by Seok Kyun. Choi. 최석균
08.*/
09. 
10.package org.syaku.util;
11. 
12.import org.apache.log4j.Logger;
13. 
14.import java.util.*;
15.import java.io.*;
16. 
17.import org.jdom.*;
18.import org.jdom.input.*;
19.import org.jdom.output.*;
20. 
21.import org.syaku.util.*;
22. 
23.public class Xml {
24.private static Logger log = Logger.getLogger(Xml.class);
25. 
26.private SAXBuilder builder = new SAXBuilder();
27. 
28.private String root_node = "data";
29.private String child_node = "item";
30. 
31.// iBATIS
32.public Document iBATISForMake(List result) throws Exception {
33.Element data = new Element(root_node);
34. 
35.for (int i = 0; i < result.size(); i++ ) {
36.Element element = new Element(child_node);
37.String xml = (String)result.get(i);
38.Document document = builder.build(new StringReader(xml));
39. 
40.Element root = document.getRootElement();
41.List child = root.getChildren();
42.for (Iterator iter = child.iterator();iter.hasNext();) {
43.Element node = (Element) iter.next();
44. 
45.String name = (String) node.getName();
46.String value = (String) node.getText();
47.addElement(element,name,value);
48.}
49. 
50.data.addContent(element);
51.}
52. 
53.Document document = new Document(data);
54. 
55.return document;
56.}
57. 
58.// 엘리먼트 생성
59.public Element addElement(Element parent, String name, String value) {
60.Element element = new Element(name);
61.element.setText(value);
62.parent.addContent(element);
63.return parent;
64.}
65. 
66.// 애트리뷰트 생성
67.public void addAttribute(Element element, String name, String value){
68.Attribute attribute = new Attribute(name,value);
69.element.setAttribute(attribute);
70.}
71. 
72. 
73.}

* sqlMap
1.<!--//
2.* @id select-user-xml
3.* @brief 사용자관리 레코드 sub
4.* @return xml
5.//-->
6.<select id="select-user-xml" parameterClass="hashMap" resultClass="xml" xmlResultName="data">
7.생략
8.</select>


* Sample Source
01.<%@ page contentType="text/html; charset=euc-kr" %>
02.<%@ page import="java.util.*" %>
03.<%@ page import="org.jdom.*" %>
04.<%@ page import="org.jdom.output.*" %>
05.<%@ page import="org.syaku.util.*" %>
06. 
07.<%
08.HashMap hm = new HashMap();
09.List result = sqlMap.queryForList("select-user-xml", hm);
10. 
11.Xml xml = new Xml();
12.Document document = (Document) xml.iBATISForMake(result);
13. 
14.XMLOutputter outputter = new XMLOutputter();
15.Format format = Format.getPrettyFormat();
16.format.setEncoding("EUC-KR");
17.outputter.setFormat(format);
18. 
19.response.setContentType("application/xml");
20.outputter.output(document, response.getWriter());
21.%>

* 결과



++ 참고사항
http://www.jdom.org/pipermail/jdom-interest/2001-April/004948.html

출처
http://syaku.tistory.com/trackback/159

'JAVA' 카테고리의 다른 글

중복로그인 체크  (2) 2011.08.12
java 형변환 모음  (1) 2011.04.06
태그 제거 정규식  (2) 2011.03.16
이미지 태그 SRC 경로 추출  (3) 2011.03.16
파일명 추출  (2) 2011.03.16
Posted by GUCCI
, |

태그 제거 정규식

JAVA / 2011. 3. 16. 14:19
    public static String convertHtmlTags(String s) {
           s = s.replaceAll("<[^>]*>", ""); //정규식 태그삭제
           s = s.replaceAll("\\t", ""); //탭제거
           s = s.replaceAll(" ", "");   //공백제거
           return s;
    }

'JAVA' 카테고리의 다른 글

java 형변환 모음  (1) 2011.04.06
자바 iBATIS 결과를 XML 리턴받기 : xmlResultName , java , xml  (1) 2011.04.06
이미지 태그 SRC 경로 추출  (3) 2011.03.16
파일명 추출  (2) 2011.03.16
Thread 클래스  (3) 2011.03.08
Posted by GUCCI
, |

    public static String convertHtmlimg(String img) {
        Pattern p = Pattern.compile("<img[^>]*src=[\"']?([^>\"']+)[\"']?[^>]*>");
        Matcher m = p.matcher(img);
        String t = "";
        while (m.find()) {
            System.out.println(m.group(1));
            t = m.group(1);
        }
        return t;
    }
   
다른 태그로 쓸 경우 img 부분이나 src를 원하는 스트링으로 변경

'JAVA' 카테고리의 다른 글

자바 iBATIS 결과를 XML 리턴받기 : xmlResultName , java , xml  (1) 2011.04.06
태그 제거 정규식  (2) 2011.03.16
파일명 추출  (2) 2011.03.16
Thread 클래스  (3) 2011.03.08
HttpURLConnection 이용시 헤더값 세팅 방법  (3) 2011.03.03
Posted by GUCCI
, |

최근에 달린 댓글

글 보관함