Wednesday, September 16, 2009

자바스크립트 단축키 사용 [Key Binding]



자바스크립트 단축키 사용 [Key Binding]

Scripter/JAVASCRIPT 2008/08/19 10:20

가끔씩 Ajax 웹어플리케이션을 만들다 보면 단축키를 요구하는 고객들이 많다.
그러한 이유로 단축키 관련 스크립트를 찾아보던중에 prototype el.observe() (extjs에서는 el.on())를 이용한 keycode를 바인딩해주는
스크립트를 찾았다.

얼마전에 ajaxian post에 올라왔던 글이였는데 잊고 있었던거.. ㅡ.,ㅡ;
잠시 꼬불쳐 두다... 키값 참조할때도 좋겠다.

참조URL , 샘플URL


<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/prototype/1.6.0.2/prototype.js"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/scriptaculous/1.8.1/scriptaculous.js"></script>
<script type="text/javascript" >
var Key = {

// -- Alphabet
A: 65,
B: 66,
C: 67,
D: 68,
E: 69,
F: 70,
G: 71,
H: 72,
I: 73,
J: 74,
K: 75,
L: 76,
M: 77,
N: 78,
O: 79,
P: 80,
Q: 81,
R: 82,
S: 83,
T: 84,
U: 85,
V: 86,
W: 87,
X: 88,
Y: 89,
Z: 90,

a: 97,
b: 98,
c: 99,
d: 100,
e: 101,
f: 102,
g: 103,
h: 104,
i: 105,
j: 106,
k: 107,
l: 108,
m: 109,
n: 110,
o: 111,
p: 112,
q: 113,
r: 114,
s: 115,
t: 116,
u: 117,
v: 118,
w: 119,
x: 120,
y: 121,
z: 122,

// -- Special Keys
BACKSPACE: 8,
TAB: 9,
ENTER: 13,
ESCAPE: 27,
END: 35,
HOME: 36,
ARROW_LEFT: 37,
ARROW_UP: 38,
ARROW_RIGHT: 39,
ARROW_DOWN: 40,
DELETE: 46,
QUESTION_MARK: 63

};

/*
* Tie into ? and ESCAPE
*/
document.onkeypress = function(e) {
if (e.charCode == Key.QUESTION_MARK) {
KeyBindingsHUD.toggle();
} else if (e.keyCode == Key.ESCAPE) {
KeyBindingsHUD.hide();
} else {
KeyBindings.actionForKey(e);
}
}

var KeyBindings = (function() {
var bindings = {};

var findNumber = function(key) { // get the name of the key from the charCode
for (var name in Key) {
if (Key[name] == key) {
return name;
}
}
}

return {
add: function(binding) {
if (typeof binding.keys == "string") { // short circuit for non-arrays
binding.keys = [ binding.keys ];
}
bindings[binding.eventname] = binding;
},

remove: function(eventname) {
bindings[eventname] = undefined;
},

html: function() {
var html = [];

for (var key in bindings) {
if (bindings.hasOwnProperty(key)) {
var binding = bindings[key];
var keys = binding.keys.collect(function(key) {
return Object.isNumber(key) ? findNumber(key) : key;
});
html.push(keys.join(', ') + ': ' + binding.description);
}
}

return html.join('<br/>');
},

actionForKey: function(e) {
for (var action in bindings) {
if (bindings.hasOwnProperty(action)) {
var keys = bindings[action].keys;
keys.each(function(key) {
if (e.charCode == 0) {
if (e.keyCode == key) {
document.fire(action, e);
throw $break;
}
}
if (String.fromCharCode(e.charCode) == key) {
document.fire(action, e);
throw $break;
}
});
}
}
},

caseInsensitive: function(keys) {
if (typeof keys == "string") keys = [ keys ]; // array wrap
var newArray = [];
keys.each(function(c) {
newArray.push(c, c.toUpperCase());
});
return newArray;
}
}
})();

/*
*
*/
var KeyBindingsHUD = (function() {
var isShown = false;
var headerId = '_keybindings_header';

return {
toggle: function() {
(isShown) ? this.hide() : this.show();
},
show: function() {
if (!isShown) {
var header = $(headerId);
if (!header) {
header = this.createElement();
}
header.innerHTML = KeyBindings.html();
header.blindDown({duration: 0.2});
isShown = true;
}
},
hide: function() {
if (isShown) {
$(headerId).blindUp({duration: 0.2});
isShown = false;
}
},
createElement: function() {
var header = document.createElement('div');
header.id = headerId;
header.align = 'center';
header.style.display = 'none';
header.style.width = '100%';
header.style.backgroundColor = '#111111';
header.style.color = '#eeeeee';
header.style.fontSize = '10pt';
header.style.paddingTop = '4px';
header.style.paddingBottom = '4px';
header.style.borderBottom = '1px solid #333';

var body = document.body;
body.insertBefore(header, body.firstChild);

return $(headerId);
}
}
})();




KeyBindings.add({
eventname: 'action:move-up',
keys: ['p', Key.ARROW_UP ],
description: "Move up the stack"
});

KeyBindings.add({
eventname: 'action:move-down',
keys: ['n', Key.ARROW_DOWN ],
description: "Move down the stack"
});

document.observe('action:move-up', function(e) {
alert(1)
});

document.observe('action:move-down', function(e) {
alert(2);
});

</script>

**************************************

F5키를 막는 방법은 아래와 같습니다.

마우스 오른쪽 클릭으로 새로고침하는 것을 방지

* 메뉴와 도구모음에서 새로고침하는 것은 원천적으로는 막을 수 없습니다. (물론 없애버릴 수는 있다지만...)







소스다운로드 :

















Tuesday, September 15, 2009

mysql 외부접속 허용 질문 //

mysql 외부접속 허용 질문 //
mup5050 2006.04.05 22:49
답변 1| 조회 6,214


라그 프리서버를 구축하면서 sql 로 하려고 하는데,

저희집은 포맷을 자주 할 수 밖에 없는 개구장이~구닥다리 컴인지라

컴에 APM 을 깔아서 사용하기는 조금 그렇더라구요. 제가 자주 잊는 탓에

중요한 자료도 잘 백업해두질 않기 때문에 -_-;



웹호스팅의 mysql DB 에다가 라그 프리서버 구축을 sql 로 연동해서

사용하려면 mysql 의 외부접속 허용이 가능해야 된다, 라고 하던데요,



제가 계속~ 나오지도 않는 것 끝까지 검색하니까

DB 아이디 생성시 host 부분을 localhost 가 아닌 % 로 해주면

외부의 모든 접속을 허용한다는 내용을 봤었습니다.



뭐, 그래서 외부접속 허용이 가능하다는 리얼마인드 호스팅을 해봤지만

외부접속허용 으로 만들어놔도 연결이 자꾸자꾸 끊어진다는 에러만

줄창 나와대고 -,.-





자, 이제 본 질문을 -ㅂ -;;





1. mysql 외부접속을 허용하게 하려면 host 부분을 localhost 가 아닌 %로 해주는것,

그 이외에 특정 대역만 허용하는 방법이 있을까요? 외부 여러 다양한 IP에서

접속할겁니다, 아마 ;ㅂ; mysql 에는 계정 아이디와 비번, 케릭터의 정보같은것이

저장될거라서요......





2. mysql 외부접속 허용을 하려면 phpmyadmin 에서 어떤 작업들을 거쳐야 하는지…?





3. 뭐, 있을거라 생각하지는 않지만 라그 프리서버같은 '외부의 프로그램을

mysql DB 와 연결해서 저장이 되게 하는것' 을 가능하게 해주는 계정을 발급하는

곳이 있을까요? 너무 비싸지 않은 수준에서는 가능해서요 ''; 계정 아이디와 비번,

케릭의 정보 등등만 저장되기 때문에 용량도 트래픽도 적어도 되는 ;;







최대한 답변 부탁드립니다 ^^;

신고

의견 1
질문자 채택된 경우, 추가 답변 등록이 불가합니다.
re: mysql 외부접속 허용 질문 //
jpriest 2006.04.06 08:56
자세한 답변이네요 감사합니다 ^^
yo`



1. host 컬럼에 % 로 되어 있으면 어느 IP에서든지 접속을 허용합니다. 특정한곳에서만도 제한 할수 있습니다. IP 클래스에 맞추어서 적용시켜주시면 가능합니다.



211.111.111.%

211.111.%

211.%



이렇게요



2. 두가지의 방법이 있는데 첫번째는 user 테이블에 직접 입력/수정 하는 방법이고 두번째는 Grant / Revoke 문을 사용하는것입니다. 단 어느 방법을 사용하던지 작업후에 MySQL 서버를 다시 시작하거나 다음과 같은 명령을 수행해야 합니다.



fulsh privileges;



직접 입력/수정 하는 방법은 insert / update /delete 문을 사용하여 직접 편집하는 것입니다. 예를 들어..



insert into user (host,user,password,.....) values ('%','test',password('test'),....);

update user set host = '%', .... where user = 'test';

delete from user where user = 'test';

insert 는 신규입력이고 update 는 기존의 레코드를 수정, delete는 삭제 하는것입니다. insert/update/delete 문의 기본 문법은 아셔야 하며, 각각의 컬럼등을 죄다 적어야 하는 불편함이...-,.ㅡ;;;



아니면 phpMyAadmin 을 사용해본지 오래됐지만, 아마 그리드형태로 데이터를 뿌려주고 각셀에서 편집 또는 추가하는게 있을껍니다. 그것을 이용하셔도 되고요.



grant / revoke 문은 위와 같이 사용자를 추가하고 삭제하고, 권한을 변경하는 동일한 작업을 합니다. grant 로 신규유저를 추가할경우



grant all privileges on *.* to 'test'@'%' identified by '패스워드';



grant 문은 문법도 복잡하고 하지만 각 옵션을 통해서 쉽게 사용자를 추가할수 있는 장점이 있습니다. 위 쿼리로 모든 호스트에서 접속을 허용하는 모든 권한을 가진 test 유저를 생성하게 됩니다.



phpMyAdmin에 쿼리를 실행하는곳이 있으니 그곳에서 해당 쿼리를 실행하시면 됩니다. (아 지금 생각해보니 메뉴중에 사용자 관리를 하는게 있을듯도 하는군요 언어를 한글로 선택하셔서 메뉴를 잘 살펴보시길 바래요...)



3. 외부접속을 허용하는 호스팅업체는 아직 본적이 없습니다. ^^ 대부분 보안상의 이유로 막아놓기 때문에...



그럼..



출처 : -0-./

Friday, September 11, 2009

[JavaScript] for in 을 써먹어보자.

//json 형식으로 키와 값으로 배열을 만들어 놓자..
var tmpObj = [{"name":"red", "code":"#FF0000"}, {"name":"blue", "code":"#0000FF"}, {"name":"green", "code":"#00FF00"}];

var result="";
for(var i = 0; i< tmpObj.length; i++){
for(var obj in tmpObj[i]){
result+=("\n key :" + obj + ", value " + tmpObj[i][obj]);
}
result+="\n";
}
alert(result);

//출력결과
---------------------------
Windows Internet Explorer
---------------------------

key :name, value red
key :code, value #FF0000

key :name, value blue
key :code, value #0000FF

key :name, value green
key :code, value #00FF00

---------------------------
확인
---------------------------

Tuesday, September 1, 2009

HttpSession 으로 사용자 카운팅 및 동시접속 차단

http://blog.naver.com/narutugi/140068419915

Staless 프로토콜


  • 세션에 대해 알아보기전에 우리는 HTTP의 프로토콜 특징에 대해 알아보고자 합니다.
  • HTTP 프로토콜을 기본적으로 클라이언트의 요청(request), 응답(response)로 구현되어 있습니다.
  • 이 말은, 서버에 요청을 하고 응답을 받으면 서버와의 통신이 끊기게 되고, 서버에는 클라이언트의 어떠한 정보도 유지하지 않는다는 뜻입니다.
  • 이것을 HTTP의 Staless특성인 즉, 비연결형 프로토콜이라고 합니다.
    • 장점
      • 프로토콜을 직관적으로 이해하기 쉽고, 구현이 단순합니다.
      • 클라이언트의 요청에 대한 처리 결과를 응답으로 전송하고 나면 접속이 종료되기 때문에, 서버측 네트워크 자원의 효율 성이 증가합니다. 즉, 더 많은 클라이언트 요청을 처리 할 수 있습니다.
    • 단점
      • 각 클라이언트 요청마다 새로운 접속이 이루어지기 때문에 서버측의 네트워크 자원의 낭비가 적지만, 새로운 접속을 맺기 위해 발생하는 오버헤드 즉, 수행속도의 감소가 지속적으로 발생할 수 있습니다.
      • 또한, 동일한 클라이언트가 접속하더라도, 이전의 정보가 남아있지 않아서 클라이언트의 정보에 대한 비교가 불가능 합니다.

세션 (HTTP Session)


▶가상의 접속 상태를 유지하기 위한 메카니즘입니다.

  • HTTP세션이 종료되는 시점은, 클라이언트 세션 아이디가 무효화 되는 시점입니다. 이 시점은 로그 아웃 등을 할 때 종료된다고 보면 됩니다.
  • 웹에서 세션을 사용하고 있다면, 반드시 세션을 종료하는(로그아웃) 방법도 제공을 해주어야 합니다.
  • 일정 시간 동안 동일한 클라이언트로부터 요청이 발생하지 않는다면, 이 또한 세션이 종료되도록 할 수 있습니다. web.xml에 설정된 경우 설정을 통해 시간 설정이 가능합니다.


    • 위의 설정대로 한다면, Session 은 30분후에 종료가 되겠다는 뜻이구요, 아파치 웹 서버를 따로 구성했을 경우에는 아파치 웹 서버의 WEB.XML을 수정해야 합니다.

쿠키


▶쿠키라는 것은 클라이언트의 상태 정보를 서버로 전송하기 위해 사용할 수 있는 방법 중의 하나로서 클라이언트에 저장되는 단순한 텍스트 입니다.

  • 쿠키는 브라우저가 종료되더라도 정보가 사라지지 않습니다.
  • 쿠키는 사용자가 컴퓨터를 켜든 끄든 하드디스크에 (상당기간) 저장되어 있습니다
  • 왜? PC에 저장하는 걸까요?
    • 그것은 HTTP 프로토콜이 'stateless' 프로토콜이기 때문입니다. 웹 브라우저가 웹 서버에 접속을 해서 어떤 문서나 파일을 요청하면 웹 서버는 요청 받은 내용을 보내준 다음 접속을 끊습니다.

      즉, 접속을 한 '상태(state)'가 지속되지 않고 요청된 것만 처리한 뒤 연결을 끊는 거죠. 그러므로 웹 서버는 일단 요청된 내용들을 클라이언트에 보내고 나면 그 뒤 사용자가 접속을 하고 있는지 어떤지 알 수가 없습니다.
    • 나아가, 예전에 접속했던 클라이언트가 또 접속을 한 것인지 아닌지 등은 더더욱 알 수 없습니다. 그런데 웹 사이트를 운용하는 측에서는 어떤 사용자가 다시 방문을 했는지 와 같은 정보가 절실히 필요했고 바로 이런 점을 해결하기 위해, 즉 stateless한 http의 특징을 커버하기 위해 등장한 아이디어가 쿠키(Cookie)입니다.
    • 쿠키의 아이디어는 간단합니다. 접속한 클라이언트의 하드디스크에 적당한 정보를 저장해 둠으로써 또 그 클라이언트가 접속한 경우 언제든지 하드디스크에 저장된 정보를 읽어 들여서 그 사용자를 인식할 수 있는 것입니다. '
    • 상태'에 관한 점검을 언제든지 할 수 있는 것이죠.
    • 쿠키에 저장되는 내용은 천차만별입니다. 간단하게는, 사용자가 어떤 페이지를 읽었고, 로그인 아이디가 뭐고, 이 메일 주소가 뭐고 등을 기록할 수도 있고, 사용자가 어떤 물품을 주문했는지, ip 주소가 뭐고, 어떤 사이트를 거쳐서 우리 사이트로 왔는지, 또는 서버에서 각 클라이언트를 식별할 특별한 정보를 기록하는 등, 거의 모든 형태의 정보를 저장할 수 있습니다.
    • 사용자 처지에서는 사실 기분 나쁠 수 있습니다. 나도 모르게 나의 행동이 하나하나 기록되어 '파일'로 저장되고 있고, 그 파일이 다른 곳도 아닌 '내' 컴퓨터에 나도 모르게 저장된다는 것은 별로 좋은 느낌은 아니죠.
    • 하지만, 쿠키 파일은 사용자가 컴퓨터를 끄든 켜든 하드디스크에 (상당 기간) 저장되어 있기 때문에, 언제든지 사용자가 다시 어떤 웹 사이트에 접속하면 쿠키에 저장해 놓은 정보를 읽어 들여서 여러 형태의 '맞춤화된' 서비스를 제공할 수 있습니다. 이를 테면, 로그인을 한 번만 하면 그 다음부터 안 해도 된다든지, 어떤 페이지를 "몇 번 보셨군요" 라고 알려준다든지 등이 가능합니다.
  • JSP에서 쿠키 설정하는 방법
    1. 헤더에 직접 지정하는 방법
      • HTTP 헤더를 이용한 쿠키 설정
      • Set-Cookie : name = value; expires = date; domain = serverDomain;
      • path = serverPath; secure(HTTPS)
    2. 쿠키를 추상화 시켜놓은 서블릿 API를 이용하는 방법
      • 이것은 보다 객체 지향적인 방법으로 클라이언트와 서버간의 쿠키 데이터 전송을 위해 Set-Cookie와 쿠키 헤더를 추상화한 javax.servlet.http.Cookie 클래스를 사용합니다.

JSP에서의 세션 관리


▶HttpSession과 세션 관리

  • HttpSession은 서블릿/JSP에서 세션을 유지하기 위해 필요한 일련의 작업을 단순화 혹은 추상화시켜 놓은 API라고 생각하면 될 것입니다.
  • 세션을 유지할 때는 다음의 방법을 사용합니다.
    1. 최초의 클라이언트에서 요청할 때 세션 유지를 위해 HttpSession 객체를 생성하고 고유한 세션 아이디를 생성합니다.
      • HttpSession session = request.getSession();
      • getSession()메소드는 create가 true일 경우 클라이언트 요청에 대해 기존에 생성된 객체가 존재할 때는 해당 객체를 리턴하고, 그렇지 않으면 새로운 객체를 생성하여 리턴합니다.
      • create가 false 인 경우에 요청에 대해 생성된 HttpSession객체가 존재할때 이를 리턴하고, 그렇지 않으면 null 을 리턴합니다.
      • 일반적으로 getSession()메소드는 getSession(true)과 동일하다고 보면 도비니다.
    2. HttpSession 객체 생성시 자동으로 생성된 세션 아이디를 이후의 클라이언트 요청부터 요청에 포함하여 전송합니다.
    3. 세션이 시작된 이후의 모든 요청이 들어올 때 마다 서버가 클라이언트에 부여한 세션 아이디를 통해 세션을 유지하도록 합니다.
  • [세션 테스트]

















차암 쉽쬬잉~~~~~~~~~♬

★만약, HttpSession을 사용하지 않고, page 속성에서 session = true로 했을 경우에는 JSP 내장 Session객체를 사용함을 의미합니다. 이 때에 HttpSession session 할 경우에는 동일한 session 이름의 객체가 생성되므로 HttpSession으로 만든 session에 오류가 날 수 있습니다. 이 때에는 HttpSession의 이름을 mySession 이나 뭐 기타 등등으로 바꾸면 됩니다.

★ 혹은, HttpSession을 쓰지 않고, JSP 내장 객체의 session을 사용하면 되겠는데, 이 때 jsp 내장객체의 session객체는 isNew()라는 메소드를 제공함으로써 세션의 존재 유무 혹은 세션이 현재 페이지에서 만들어졌는지 등을 알 수 있습니다.

HttpSessionBindingListener


jsp, 자바 빈( scope=application ) 하는 경우입니다.

굳이 db에 테이블을 생성하지 않아도 접속자 수를 실시간으로 구하실 수 있으실 겁니다.

=== SessionChecker.java ===============================

import java.io.*;
import java.util.*;
import javax.servlet.http.*;

public class SessionChecker{
public void setSession(HttpSession session){
// 리스너 객체를 생성해서 이것도 세션에 같이 담는다. 리스너 라는 이름으로...
session.setAttribute("listener", new CustomBindingListener());
}
}

// 여기서 구현했습니다..

class CustomBindingListener implements HttpSessionBindingListener {
public void valueBound(HttpSessionBindingEvent event) {
// 세션이 생겼을 할 내용
System.out.println("BOUND as " + event.getName() + " to " + event.getSession().getId());
}

public void valueUnbound(HttpSessionBindingEvent event) {
// 세션이 종료되었을때
System.out.println("UNBOUND as " + event.getName() + " to " + event.getSession().getId());
}
}


==== test.jsp =========================================


<%@ page contentType="text/html;charset=KS_C_5601-1987" %>

<%
session.setMaxInactiveInterval(60); // 걍 결과가 빨리 보고싶어서여.. 60초
sc.setSession(session);
out.println("세션 등록");
%>

test 페이지를 연 후 60초 뒤에 unbound 어쩌구의 메세지를 보실 수 있을 겁니다.

[출처 : OKJSP > http://www.okjsp.pe.kr/seq/20524]

출처 : http://blog.naver.com/korekiss/20038228350

HttpSessionBindingListener 는 웹에서 동시 사용자의 수 또는 하나의 아이디로 동시접속을 제한 할때 유용한 인터페이스 이다. HttpSessionBindingListener 는 두개의 메소드를 지니는데 valueBound() 와 valueUnbound() 메소드 이다.

valueBound() 는 HttpSessionBindingListener 클래스의 인스턴스가 세션에 attribute로
등록될떄 호출된다 session.setAttribute(플래그, 값)
valueUnbound()는 session.removeAttribute(플래그); 사용시
또는 세션종료시 session.invalidate()호출된다.
다음은 이를 이용한 동시 사용자및 중복 로그인 방지 프로그램이다.
LoginManager.java

package itexpert.chap05;

import javax.servlet.http.HttpSession;

import javax.servlet.http.HttpSessionBindingListener;

import javax.servlet.http.HttpSessionBindingEvent;

import java.util.Hashtable;

import java.util.Enumeration;

public class LoginManager implements HttpSessionBindingListener

{

private static LoginManager loginManager = null

private static Hashtable loginUsers = new Hashtable();

private LoginManager(){

super();

}

public static synchronized LoginManager getInstance(){

if(loginManager == null){

loginManager = new LoginManager();

}

return loginManager

}

//아이디가 맞는지 체크

public boolean isValid(String userID, String userPW){

return true //자세한 로직은 미구현

}

//해당 세션에 이미 로그인 되있는지 체크

public boolean isLogin(String sessionID){ //세션 ID를 받습니다.

boolean isLogin = false

Enumeration e = loginUsers.keys();

String key = ""

while(e.hasMoreElements()){ //다음 데이터의 유무를 판단합니다.

key = (String)e.nextElement();//key변수에 대입.

if(sessionID.equals(key)){ //현재 세션 ID값과 로그인한 값을 비교합니다.

isLogin = true //해당되는 세션 아이디가 이미 등록되어 있다는 것을 의미.

}

}

return isLogin; //초기는 FALSE 이지요. WHILE문에서 걸러진다면 위에서 알아서 처리되겠습니다.

}

//중복 로그인 막기 위해 아이디 사용중인지 체크

public boolean isUsing(String userID){

boolean isUsing = false

Enumeration e = loginUsers.keys();

String key = ""

while(e.hasMoreElements()){

key = (String)e.nextElement();

if(userID.equals(loginUsers.get(key))){//hashTable에 저장된 키값을 받는다는 것은

//키 값에 포함된 Value 값을 받는 것(즉, 사용자ID)

isUsing = true

}

}

return isUsing;

}

//세션 생성

public void setSession(HttpSession session, String userID){

loginUsers.put(session.getId(), userID) //[1] 세션 ID를 가져오고, [2] 사용자 ID를 가져와서 대입.

session.setAttribute("login", this.getInstance()); //세션의 속성에 로그인매니져의 정보를 설정합니다.

}

//세션 성립될 때

public void valueBound(HttpSessionBindingEvent event){ // 로그인 할때

}

//세션 끊길때

public void valueUnbound(HttpSessionBindingEvent event){ //로그아웃 할때

loginUsers.remove(event.getSession().getId());//이벤트가 발생을 시킨 세션의 ID 값을 가져와서 HashTable

//데이터를 삭제합니다.

}

//세션 ID로 로긴된 ID 구분

public String getUserID(String sessionID){

return (String)loginUsers.get(sessionID);

}

//현재 접속자수

public int getUserCount(){ //몇 명의 사용자가 로그인 하고 있는지 계산합니다.

return loginUsers.size();

}

}

Bind_login.jsp

<%@ page contentType="text/html;charset=euc-kr" import="itexpert.chap05.LoginManager"%>

<% LoginManager loginManager = LoginManager.getInstance(); %>

<html>

<body>

<center>

현재 접속자수 : <%= loginManager.getUserCount() %><p>

<hr>

<%

if(loginManager.isLogin(session.getId())){ //세션 아이디가 로그인 중이면

out.println(loginManager.getUserID(session.getId())+"님 안녕하세요
"

+"로그아웃");

}

else{ //그렇지 않으면 로그인 할 수 있도록

%>

<form name="login" action="Bind_login_ok.jsp">

아이디: <input type="text" name="userID"><br>

비밀번회: <input type="text" name="userPW"><br>

<input type="submit" value="로그인">

form>

<% }%>

center>

body>

html>

Bind_login_ok.jsp

<%@ page contentType="text/html;charset=euc-kr" import="itexpert.chap05.LoginManager"%>

<% LoginManager loginManager = LoginManager.getInstance(); %>

<%

request.setCharacterEncoding("euc-kr");

String userID = request.getParameter("userID");

String userPW = request.getParameter("userPW");

if(loginManager.isValid(userID, userPW)){ //ID와 비밀번호가 맞는지 확인합니다.

if(!loginManager.isUsing(userID)){//ID가 사용중인지 아닌지 판단합니다.

loginManager.setSession(session, userID); // 사용하지 않는다면, 현재 세션과 ID 저장

response.sendRedirect("Bind_login.jsp"); //다시 로그인 화면으로 이동합니다.

}

else{

//throw new Exception("이미 로그인중입니다.");

response.sendRedirect(request.getContextPath()+"/index.jsp");

}

}

else{

//throw new Exception("ID/PW 이상");

response.sendRedirect(request.getContextPath()+"/index.jsp");

}

%>

Bind_logout.jsp

<%@ page contentType="text/html;charset=euc-kr"%>

<%

session.invalidate();

response.sendRedirect("Bind_login.jsp");

%>

index.html

<%@ page language="java" contentType="text/html; charset=EUC-KR" import="itexpert.chap05.LoginManager"

pageEncoding="EUC-KR"%>

DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<%

LoginManager loginManager = LoginManager.getInstance();

%>

<script>

function isLoginUserForm() {

if(login.userID.value == "") {

alert ("ID를 입력하지 않았습니다.");

login.userID.focus();

return false

}

if(login.userPW.value == "") {

alert ("패스워드를 입력하지 않았습니다.");

login.userPW.focus();

return false

}

return true

}

script>

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=EUC-KR">

<title>방명록 작성 실습 예제 v0.01title>

head>

<body>

<center>

<h1> 방명록 작성 실습 예제 v0.03(JSP+JDBC + Login) h1>

center>

<hr/>

본 실습을 문서를 참고하지 않고 다시 작성할 수 있을때까지 반복하여 수행한다.

<br>

<hr/>

<a href="guestController.do?action_code=insert&mode=1"> 방명록작성(JSP를 이용하여 오라클 DB에 자료를 입력하는 실습)a>

<hr/>

<a href="guestController.do?action_code=select"> 방명록보기(JSP를 이용하여 오라클 DB를 조회하는 실습)a>

<hr/>

<h3>현재 접속자 수 : <%= loginManager.getUserCount() %> h3>

<hr>

<%

if( loginManager.isLogin(session.getId())) {

%>

<%= loginManager.getUserID(session.getId()) %> 님 안녕하세요

<br>

<a href="Bind_logout.jsp"> 로그아웃 a>

<%

} else {

%>

<form name="login" action="Bind_login_ok.jsp" onsubmit="return isLoginUserForm();" >

아이디 : <input type="text" name="userID"> 비밀번호 : <input type="password" name="userPW">

<input type="submit" value="로그인" >

form>

현재 버전에서의 아이디와 패스워드는 데이터베이스를 점검하지 않고 있음. <p>

그러나 동일한 이름의 아이디를 이용한 중복 로그인은 허용하지 않음.

<%

}

%>

body>

html>