Crontab 설정하기

1) crontab 기본
crond 데몬 /etc/rec.d/init.d/crond 스크립트에 의해 시작, 종료,재시작될 수 있다

기본 명령의 위치 :/user/bin/crontab
=>아무곳에서나 실행 가능 함 등록,수정, 보기

사용형식
 crontab [ -u 사용자 id] 파일
 crontab [-u 사용자 id] { -l | -r | -e}

$ crontab -l
no crontab for truefeel

설정한 적이 없어 아직 비어있다

crond 실행 확인
=>ps -ef | grep crond

crond 시작
=> /etc/rc.d/init.d/crond start{restart | stop}

일반사용자에게 crontab 명령어 사용하도록 설정 허가
=> /etc/cron.allow 여기에 ID 등록

일반사용자의 crontab 명령어사용을 제한하고자 한다면
=>/etc/cron.deny  에 ID를 등록


  etc/cron.allow : 허용할 사용자 ID 목록
  /etc/cron.deny  : 거부할 사용자 ID 목록

  cron.allow 파일이 있으면 이 파일에 들어있는 ID만 사용 가능
  cron.deny  파일이 있으면 이 파일에 들어있는 ID는 사용 불가
  따라서 cron.deny에 truefeel ID를 추가해주면 됩니다.

등록 내용 설정
"분,시,일,월,요일, 실행명령" 순으로 설정

2) crontab 파일 형식

- 한 줄당 하나의 명령 (두줄로 나눠서 표시할 수 없음)
- # 으로 시작하는 줄은 실행하지 않는다.

crontab -e 을 하면 vi 에디터가 나온다.(환경변수 EDITOR에 따라 다른 에디터를 사용할 수 있다.)
 


위는 매일 4:30분과 12:30분에 rsync 명령을, 매주 일요일 1:40분에 perm_set.sh를 실행함을 의미한다.

vi 에디터를 통해 설정을 하므로 중요한 몇 가지 에디터 사용법은 익혀야 한다.

3) 설정 예
시간 설정에서 몇가지 의미있는 것들을 알아보자.

- '*'표시는 해당 필드의 모든 시간을 의미한다.
- 3,5,7 와 같이 콤마(,)로 구분하여 여러 시간대를 지정할 수 있다.
- 2-10와 같이 하이픈(-)으로 시간 범위도 지정할 수 있다.
- 2-10/3와 같이 하이픈(-)으로 시간 범위를 슬래쉬(/)로 시간 간격을 지정할 수 있다.
(2~10까지 3간격으로. 즉, 3,6,9를 의미함)



=>  > /dev/null  2>&1 의 의미

  지정한 명령어 처리 결과와 발생할지 모르는 에러메시지를 출력하지 않고 모두 버린다는(/dev/null)는
  뜻입니다. 만약 결과와 에러를 파일로 저장하려면 /dev/null 대신 파일명을 적어주면 된다.

ex)
반응형
블로그 이미지

Good Joon

IT Professionalist Since 1999

,

y <카피할 라인개수> y
p
하면 된다

블럭삭제는
d <디울 라인 개수 >d
한다
반응형
블로그 이미지

Good Joon

IT Professionalist Since 1999

,

vi 에는 set paste 기능 없다.

:set noai

하면 된다.

반응형
블로그 이미지

Good Joon

IT Professionalist Since 1999

,
prstat : Process 와 CPU Load 볼 수 있음
vmstat : 머신의 리소스 스테이터스 볼 수 있음
iostat : 내장디스크의 상태를 볼 수 있음
mpstat : 멀티프로세서의 Load 를 알 수 있음
netstat : 네트워크 상태 알 수 있음
pfiles : PID 에 해당하는 프로세스가 사용하는 리소스(네트워크 포트 정보 포함)를 알 수 있음

반응형
블로그 이미지

Good Joon

IT Professionalist Since 1999

,

Vi: Search and Replace

Change to normal mode with <ESC>.

Search (Wraped around at end of file):

  Search STRING forward :   / STRING.
  Search STRING backward:   ? STRING.

  Repeat search:   n
  Repeat search in opposite direction:  N  (SHIFT-n)

Replace: Same as with sed, Replace OLD with NEW:
 
 First occurrence on current line:      :s/OLD/NEW
  
 Globally (all) on current line:        :s/OLD/NEW/g 

 Between two lines #,#:                 :#,#s/OLD/NEW/g
  
 Every occurrence in file:              :%s/OLD/NEW/g 
반응형
블로그 이미지

Good Joon

IT Professionalist Since 1999

,

which
whereis
locate
find

Solaris 의 경우, whereis 등은, /usr/ucb 안에 보통 들어있다
반응형
블로그 이미지

Good Joon

IT Professionalist Since 1999

,

출처 : http://www.iwiz.pe.kr/bbs/zboard.php?id=webdev&page=1&sn1=&divpage=1&sn=off&ss=on&sc=on&select_arrange=headnum&desc=asc&no=4

 

IE6에서의 개인정보보호(P3P) 구현과 쿠키 관련 문제점

1. P3P

(1) P3P의 개념

  P3P(Platform for Privacy Preferences)는 W3C에서 개발한 프라이버시 보호 관련 표준 기술이다.  P3P에 대한 상세한 설명은 뉴스&이슈란을 참고하면 되며, 그 개념을 쉽게 설명하자면 식품등에 붙어있는 일종의 "성분표시"라고 할 수 있다.  P3P를 적용한 사이트에서는 HTTP 헤더 또는 링크된 XML 파일을 통해 해당 사이트에서 취급하는 게인정보의 레벨이나 성격 등을 웹브라우져에게 알려주고 있다.  실제 사이트상에서의 P3P의 적용은 기술적으로는 별로 어렵지 않으나 "개인정보보호"라는 용어에서 느껴지듯 정책적인 측면이 매우 강하고 까다롭다.  또 계속 읽다보면 느끼겠지만 부적절한 번역 등으로 인해 각종 용어들이 무척 어렵게 느껴질 것이다.  그러나 실제로 그렇게 어려운 개념은 아니다.  단지 이해하기 힘들뿐...

  현재 우리나라에서는 회원들이나 방문객들의 개인정보를 보유하고 있는 웹사이트들은 의무적으로 "개인정보보호지침"을 기재하도록 법률로 정해져 있다.  이런 개인정보보호지침은 사람이 그 내용을 읽고 이해할 수 있도록 되어있지만, P3P는 이와는 반대로 웹브라우져 등의 소프트웨어에서 해당 사이트의 개인정보보호 지침을 인식할 수 있도록 규정되어 있다.  즉, 기계 차원에서 접속한 사이트의 개인정보 보호지침을 인식하고 현재 사용자가 설정해둔 허용값과 비교해본 후 허용, 제한, 강등, 금지 등의 조치를 자동으로 취하게 되는 것이다.

  P3P는 아직 법률과 같은 규정에 의해 강제되고 있는 사항이 아니기 때문에 모든 사이트에 적용해야할 의무는 없으나, 현재 MSIE 6.0에서 이 기능이 부분적으로 탑재되어 있기 때문에 웹프로그래머로서는 이를 무시할 수 없다.  MSIE 6.0에서부터 발생하는 쿠키 관련 문제 등의 상당 부분이 바로 이 P3P와 연관되어 있기 때문이다.

(2) P3P의 구현

  실제 웹사이트에서 P3P를 구현하기 위해서는 개인정보 보호정책이 담긴 XML 파일을 페이지에 링크하거나, 또는 압축된(Compact) 개인정보보호정책이라 불리는 HTTP 헤더값을 이용하는 방법이 있다.  XML의 경우에는 다음과 같은 방법으로 XML 파일의 URL을 지정하면 P3P를 지원하는 브라우져에서 해당 파일을 읽어와 사이트의 개인정보보호정책을 이식하게 된다. (XML파일의 스펙은  http://www.w3.org/TR/P3P 참고)

  • HTTP 헤더 이용 방법 : P3P: policyref="http://test.com/p3p.xml"
  • 태그 이용법1 : <meta http-equiv="P3P" content='policyref="http://w.about.com/w3c/p3p.xml"'>
  • 태그 이용법2 : <link rel="P3Pv1" href="http://w.about.com/w3c/p3p.xml" type="text/xml"> 

  그리고 압축된 정책은 HTTP 헤더값에 한줄로 간략하게 넣는 형태로서 헤더값은 [P3P: CP='CAO PSA CONi OTR OUR DEM ONL'] 과 같은 형식으로 구성되어 있다.  실제로 우리가 사용하고자 하는 것도 바로 이 압축된 정책이다.  지금 IE에서 [도구]-[인터넷 옵션]-[개인정보] 메뉴를 보라.  개인정보 설정이 디폴트값인 보통으로 되어 있다면 "압축된 개인정보 보호정책이 없는 제3사 쿠키를 차단합니다"라는 문구를 볼 수 있을 것이다.  이제 "압축된 개인정보 보호정책"이란 무엇인지 이해가 되는가? (굵은 글자는 꼭 외워야 한다.)

  우리의 목적은 P3P를 실제 사이트에 적용하는 것이 아니라 P3P의 개념을 이해하여 웹프로그램상의 쿠키 적용 등에 있어 IE6에서 발생하는 문제를 막고자하는데 있으므로 굳이 P3P의 스펙을 이해할 필요는 없다. (그러기엔 너무 난해하고 까다롭다. 고로 나도 모른다.)  따라서 개인적으로 개인정보보호에 각별한 관심이 있다면 이쯤에서 이 글을 읽는 것을 중단하고 MSDN이나 W3C의 P3P 공식 사이트를 뒤져보기 바란다.

2.  MSIE 6에서의 P3P 구현

  마이크로스프트에서는 IE6에서 구현된 개인정보 보호기능과 관련해 공식적으로 다음과 같이 밝히고 있다.  (귀찮으면 읽지 않아도 된다.  한마디로 요약하자면 IE6로 쿠키를 보내려면 P3P 압축 정책을 사용하라는 말이다.)

"Internet Explorer 6의 개인 정보 기능에서 쿠키를 성공적으로 사용하려면 웹 서비스는 W3C(World Wide Web Consortium)에서 개발한 개인 정보 기본 설정용 플랫폼(P3P: Platform for Privacy Preferences) 프로젝트에 정의된 대로 압축 정책을 구축해야 합니다. Internet Explorer 6 개인 정보 기능은 이러한 압축 정책과 사용자의 개인 정보 설정에 기초하여 쿠키를 필터링합니다. 이 문서는 해당 사이트와 연관된 쿠키의 개인 정보 요구 사항 및 Internet Explorer 6에서 구현되는 쿠키 필터링에 대해 설명합니다. 일부 쿠키에는 압축 정책이 필요하지 않을 수도 있지만, 모든 쿠키에서 정책을 구현하는 것이 바람직합니다."

  IE6에서는 P3P를 이용해 개인정보 보호기능을 구현하고 있으며, 이에 따라 압축정책이 없는 쿠키들은 경우에 따라 거부될 수도 있다.  IE 6 발표 후 기존 사이트에서 빈번한 쿠키 관련 문제들이 바로 여기에 기인하고 있다.  IE6의 개인정보 보호기능은 [도구]-[인터넷 옵션]-[개인정보]를 통해 그 레벨을 조절할 수 있는데, 레벨별 제한 수준은 다음과 같다.

선택 지정
모든 쿠키 차단 - 모든 웹 사이트의 쿠키를 차단합니다.
- 사용자 시스템에 있는 쿠키는 웹 사이트에서 읽을 수 없습니다.
높음 - 압축 정책(컴퓨터가 읽을 수 있는 압축된 개인 정보 보호 정책)을 갖고 있지 않은 모든 웹 사이트의 쿠키를 차단합니다.
- 사용자의 명시적 동의 없이 개인 식별 정보를 사용하는 모든 웹 사이트의 쿠키를 차단합니다.
보통 높음 - 압축 정책(컴퓨터가 읽을 수 있는 압축된 개인 정보 보호 정책)을 갖고 있지 않은 제 3 사 웹 사이트의 쿠키를 차단합니다.
- 사용자의 명시적 동의 없이 개인 식별 정보를 사용하는 제 3 사 웹 사이트의 쿠키를 차단합니다.
- 사용자의 묵시적 동의 없이 개인 식별 정보를 사용하는 제 1 사 웹 사이트의 쿠키를 차단합니다.
보통 - 압축 정책(컴퓨터가 읽을 수 있는 압축된 개인 정보 보호 정책)을 갖고 있지 않은 제 3 사 웹 사이트의 쿠키를 차단합니다.
- 사용자의 명시적 동의 없이 개인 식별 정보를 사용하는 제 3 사 웹 사이트의 쿠키를 차단합니다.
- 사용자의 묵시적 동의 없이 개인 식별 정보를 사용하는 제 1 사 웹 사이트의 쿠키를 Internet Explorer를 닫을 때 사용자 시스템에서 삭제합니다.
낮음 - 압축 정책(컴퓨터가 읽을 수 있는 압축된 개인 정보 보호 정책)을 갖고 있지 않은 제 3 사 웹 사이트의 쿠키를 차단합니다.
- 사용자의 묵시적 동의 없이 개인 식별 정보를 사용하는 제 3 사 웹 사이트의 쿠키를 Internet Explorer를 닫을 때 사용자 시스템에서 삭제합니다
모든 쿠키 허용 - 모든 쿠키를 사용자 시스템에 저장합니다.
- 사용자 시스템에 있는 쿠키는 이 쿠키를 만든 웹 사이트에서 볼 수 있습니다.

  여기에서 배경색이 다른 "보통" 레벨이 바로 대부분의 IE6 이용자들의 설정이다. (이유는 단지 디폴트값이므로...)  여기에서 MS식 번역으로 쿠키의 종류를 알아볼 필요가 있다.

  • 제1사 쿠키 : 현재 보고 있는 사이트에서 제공하는 쿠키이다.  즉 현재 sme.or.kr을 보고 있다면 sme.or.kr에서 보내온 쿠키가 바로 제1사 쿠키이다.
  • 제3사 쿠키 : 현재 보고 있는 사이트가 아닌 다른 사이트에서 보내온 쿠키이다.  이것은 img 태그나 frame 또는 iframe 등을 통해 다른 사이트의 컨텐츠를 링크해왔을 경우 해당 컨텐츠에서 쿠키를 보내오면 제3사 쿠키로 취급된다. (제2사 쿠키가 없는 이유는 제3사 라는 용어가 바로 third-party의 번역이기 때문이다 -_-)
  • 영구쿠키(지속성쿠키) : 쿠키의 만료일자가 지정되어 임시파일 디렉토리에 텍스트 파일 형태로 남게되는 쿠키로서 브라우져가 닫혀도 삭제되지 않는다. (그러나 만료일자가 되면 삭제되므로 엄밀히 따지면 영구히 존재하지는 않는다.  이 세상에 영원한 것은 없는 법...)
  • 임시쿠키(세션쿠키) : 쿠키의 만료일자가 지정되지 않아 브라우저가 닫히면 자동으로 삭제되는 쿠키로 메모리상에만 존재한다.
Internet Explorer 6은 제1 컨텐트를 호스트 도메인과 연관된 것으로 정의합니다. 제3 컨텐트는 호스트 도메인 이외의 도메인에서 만들어집니다. 예를 들어, 주소 표시줄에 www.wideworldimporters.com을 입력하여 이동했더니 이 사이트에 www.wingtiptoys.com의 배너 광고가 떠있다고 가정해 보십시오. 이 두 사이트에 쿠키를 설정할 경우, www.wideworldimporters.com의 쿠키가 제1 컨텍스트 쿠키이고 www.wingtiptoys.com의 쿠키가 제3 컨텍스트 쿠키가 됩니다.

이따금 상업용 웹 페이지에는 제1 컨텐트와 제3 컨텐트가 혼재해 있습니다. Internet Explorer 6 개인 정보 기능은 제1 컨텐트와 제3 컨텐트를 구별합니다. 이 때 근간이 되는 가정은 사용자의 제1 및 제3과의 관계가 서로 다르다는 것입니다. 실제로 사용자는 제3을 알지 못할 수도 있고 제3과 새로운 관계를 설정할 것인지 선택할 수도 있습니다. 이러한 이유 때문에 제3 컨텐트에 대한 기본 개인 정보 설정은 제1에 대한 설정보다 엄격합니다.

참고 www.wideworldimporters.com 및 toys.wideworldimporters.com은 둘 다 wideworldimporters.com이라는 동일한 최소 도메인을 갖고 있습니다. 동일한 최소 도메인을 호스트 도메인으로 공유하는 컨텐트를 제1 컨텐트로 간주하며, 마찬가지로 이러한 도메인에서 설정된 쿠키는 제1 쿠키로 간주합니다. 최소 도메인은 동일한 최상위 도메인(TLD)을 가져야 합니다. .com, .net, .org 등을 일반적인 TLD의 예로 들 수 있습니다.

참고 사용자가 HTTPS(Secure Hypertext Transfer Protocol)을 사용하여 보안 연결을 통해 www.wideworldimporters.com을 방문할 경우, HTTPS를 사용하지 않는 이 페이지의 컨텐트를 제3 컨텐트로 간주합니다.

  이제 용어가 정리되었으면 다시 보통 수준의 개인정보 보호 레벨을 보자.  "압축 정책을 갖고 있지 않은 제 3 사 웹 사이트의 쿠키를 차단합니다."라는 말이 무슨 뜻인지 이해가 되는가?  이게 도대체 우리와 무슨 관계가 있을까?  매우 중요한 관계가 있다.

  이 P3P를 처음으로 들여다보게 된 계기는 수록업체 홈페이지들의 게시판에 글을 쓸때 에러가 나는 문제로 인해 정대리님의 지시를 받아 조사에 착수했었다.  현재 업체 게시판의 경우에는 게시판 자동등록기를 막기 위해 글 입력 폼에 들어가면 쿠키를 하나 보내고, 이후 폼이 submit 되면 해당 쿠키가 존재하는지 여부를 확인해 실제로 글을 등록하게 되어 있다.  따라서 글쓰기 폼을 거치지 않고 자동등록기 등을 통해 바로 submit 하게 되면 차단이 되게 만들어져 있다.  그러나 IE6 이용자의 경우에는 개인정보 보호기능 때문에 쿠키가 차단되어 정상적으로 글쓰기 폼을 거쳐와도 쿠키가 없기 때문에 에러가 난다.  바로 "압축 정책을 갖고 있지 않은 제 3 사 웹 사이트의 쿠키"이기 때문이다.  홈페이지 URL은 업체명을 딴 aaa.co.kr이지만 게시판 부분은 sme.or.kr에서 링크해오기 때문에 제3사 쿠키가 되버리기 때문이다.

  비단 게시판 문제뿐 아니라 아직 리포트되진 않았지만 sme.or.kr, smipc.or.kr, koreasme.org 등 여러가지 도메인이 혼용되어 서로 링크를 걸어가며 사용하는 사이트의 성격상 어느곳에서 이와 유사한 문제가 나타날지는 알 수 없다.  따라서 쿠키를 보낼때는 반드시 "압축된 정책"을 사용하는 것이 문제를 피할 수 있다.  이것은 매우 간단하게 프로그램 앞 줄에 다음과 같은 한줄만 추가시켜 주면 된다.

[PHP] header ("P3P: CP='ALL IND DSP COR ADM CONo CUR CUSo IVAo IVDo PSA PSD TAI TELo OUR SAMo CNT COM INT NAV ONL PHY PRE PUR UNI'");

  다른 언어도 이와 유사하게 HTTP 헤더값을 추가시켜주면 된다.  그런데 문제는 PHP에서 이 코드를 넣고 헤더분석 프로그램으로 테스트해본 결과 이 헤더값이 실제로 브라우져로 날아가지 않았다. (이유는 모른다... -_-)   더군다나 중기관의 수많은 프로그램 코드중 어떤 프로그램 소스에서 쿠키를 발급하는지 찾는것도 쉬운 일이 아니다.  따라서 가장 확실한 방법은 웹서버 차원에서 이 헤더를 뿌려주는 방법이다.  웹서버에서 뿌려주면 기존 프로그램 소스 수정없이 모든 프로그램에 적용될 것이다.   Apache에서는 httpd.conf에 다음과 같은 라인을 추가시켜 주면 된다.  (현재 SME 서버에 적용되어 있다)

<IfModule mod_headers.c>
Header add P3P "CP='ALL IND DSP COR ADM CONo CUR CUSo IVAo IVDo PSA PSD TAI TELo OUR SAMo CNT COM INT NAV ONL PHY PRE PUR UNI'"
</IfModule>

  Header add 라인은 한 줄로 주욱 써야 하며, 물론 사전에 apache_root/libexec/mod_headers.so 파일이 존재하고 LoadModule과 AddModule을 통해 모듈이 정상적으로 로드되어 있어야 한다.  (mod_headers.so는 아파치 기본 컴파일 옵션으로는 설치되지 않는다.)

  이제 마지막 남은 한가지 의문은 암호문같이 길게 나열된 코드가 도대체 무엇이냐는 것이다.  바로 이것이 압축된 개인정보 정책인데, 그 의미는 솔직히 본인도 모른다.

  P3P Spec을 보고 본인 나름대로 정책을 구성해가며 계속 시도해 보았으나 무심한 IE6는 배가 불렀는지 상태바에 빨간아이콘을 내보이며 계속 쿠키 받기를 한사코 거부했다.  그래서 '이런 괴물을 만든 MS 사이트에서는 어떤 정책을 사용하나?'라는 의문이 들어 헤더분석기를 이용해 MS 사이트의 압축정책을 조사해본 결과 상기와 같은 정책이 들어있길래 Copy해서 그대로 헤더로 뿌려봤더니 드디어 빨간아이콘이 나타나지 않아서 채택한 것일 뿐이다. (무려 25개나 되는 압축된 정책들의 의미를 찾아볼 엄두가 나지 않았음... 불성실의 극치임.  -_-  본받지 맙시다!)

  압축 정책의 스펙에 대해서는 아래에서 간략히 소개할 것이며, 여기에 나와있지 않은 내용은 P3P 공식 사이트를 되져보면 된다.

3. P3P의 압축정책 Spec

개인 정보 태그 압축 토큰
<contact-and-other/> CAO
<pseudo-analysis/> PSA
<contact required="opt-in"/> CONi
<other-recipient/> OTR
<ours/> OUR
<demographic/> DEM
<online/> ONL

범주 압축 토큰 설명
<physical/> PHY 연락처 또는 위치 정보
<online/> ONL 인터넷 상의 연락처 또는 위치 정보(예: 전자 메일 주소)
<government/> GOV 정부에서 발급한 ID(예: 사회 보장 번호)
<financial/> FIN 개별 재무 정보

용도 압축 토큰 설명
<customization/> CUS 사용자에 의해 명시적으로 요청된 사이트 수정
<individual-analysis/> IVA 개별 사용자와 관련될 수 있는 분석
<individual-decision/> IVD 사용자 기록에 기초한 동작 수행
<contact/> CON 개별 사용자에게 연락하는 데 사용할 수 있는 정보
<telemarketing/> TEL 전화 판촉에 사용할 수 있는 정보
<other-purposes/> OTP 다른 P3P 용도 이외의 기타 용도

수신인 압축 토큰 설명
<same/> SAM 일관된 관례에 따라 고유한 목적에 데이터를 사용하는 정식 항목
<delivery/> DEL 주어진 용도 이외에 목적에 데이터를 사용할 수 있는 배달 서비스를 수행하는 정식 항목
<other-recipient/> OTR 공급자에게 책임이 있지만 알려지지 않은 방법으로 데이터를 사용할 수 있는 항목
<unrelated/> UNR 공급자에게 알려지지 않은 방법으로 데이터를 사용하는 항목
<public/> PUB 공개 포럼

  짧은 시간내에 P3P를 파헤치다보니 미흡한 점이나 잘못된 부분도 많으리라 봅니다.  편의상 존칭어를 생략한 점 사과드리고, 앞으로 보충설명이나 문제점 지적 부탁드립니다.

반응형
블로그 이미지

Good Joon

IT Professionalist Since 1999

,

Servlet 2.1 부터 HttpSession 의 getSessionContext() 메소드가 Deprecate 되었다.
저렇게 가져온 HttpSessionContext 에서 getSession(id) 해버리면 끝났던 것이, 이제는 직접 Map 을 만들던가 하여
getSession(id) 를 구현해 주어야 하는 불편함이 생겼다.

아래 코드 처럼, HttpSessionListener 를 implement 하여 Session 이 생성되거나 사라질 때 마다 Map 에 넣어서 관리를 해주도록 코딩을 해야 한다. 나중에 현재 접속중인 사용자와 같은 기능을 할때에도 아래를 응용하여 잘 쓰면 된다.
   
     17 public class SessionListener implements HttpSessionListener{
     18
     19     public void init(ServletConfig config){
     20     }
     21
     22     /**
     23      * Adds sessions to the context scoped HashMap when they begin.
     24      */
     25     public void sessionCreated(HttpSessionEvent event){
     26         HttpSession    session     = event.getSession();
     27         ServletContext context     = session.getServletContext();
     28         Map            activeUsers = (Map)context.getAttribute("activeUsers");
     29
     30         activeUsers.put(session.getId(), session);
     31     }
     32
     33     /**
     34      * Removes sessions from the context scoped HashMap when they expire
     35      * or are invalidated.
     36      */
     37     public void sessionDestroyed(HttpSessionEvent event){
     38         HttpSession    session     = event.getSession();
     39         ServletContext context     = session.getServletContext();
     40         Map            activeUsers = (Map)context.getAttribute("activeUsers");
     41
     42         activeUsers.remove(session.getId());
     43     }
     44 }

직접 Java 코드에서 request.getSession(true); 했을 때, Listener 가 잘 Call 되지 않는다라는 글도 있었는데, 이점을 잘 테스트 하며 사용해보도록 한다.

그리고, Clustered 환경에서 혹시나 문제 소지가 있을 수도 있으니, 테스트 해가면서 사용한다.
반응형
블로그 이미지

Good Joon

IT Professionalist Since 1999

,


--------------------------------------------------------------
request.getRequestedSessionId()는 지금 만들어진 세션Id을 보기 위함이 아니라,
이전에 만들어진세션의 Id를 보기 위함입니다
--------------------------------------------------------------
세션은 보통 세션만 쓰지는 않습니다. 요것이 life타임이 얻는것이나 셋팅하는 값으로 잘 안되기 때문입니다.
디폴트가 30분인데 30분이 되기 전에 사라지는 일이 종종발생하기 때문입니다.
세션에 대한 메소드를 추가 해서 소스를 올렸습니다.
getCreateTime : 생성된 시간을 반환해주는 메소드입니다.
getLastAccessedTime : 마지막으로 세션을 access한 시간을 반환해줍니다.
getMaxInactiveInterval  : 마지막 acceess로 부터 살아남을 수 있는 시간입니다.
하지만 전 그전에 사라지는 경우를 종종 봐왔기때문에 오히려 살아남을 수 있는 최대한의 시간이라고 말하고 싶습니다.
getId : 서버가 클라이언트별루 주는 세션ID입니다. 인식자인 셈이죠..


아래 소스를 실행하면 아이디를 넣어 달라는 말이 나올겁니다. 거기서 아이디를 넣으면 그 아이디를 세션에 넣습니다.
그리고는 소스 하단부분의 if문장을 실행하게 되죠.


 


<%@ page contentType="text/html; charset=euc-kr"   session="true" %>
<%@ page import="java.io.*,java.util.*"%>
<html>
<body>
<%
if(session.getValue("id") == null  ){
%>
  아이디를 입력하세요.<br>
  아이디가 없으신 분은 guest를 입력하세요.<br>
  <form  >
      아이디 <input type="text" name="id"><br>
              <input type="submit" value="login">
  </form>           
<%
}
%>


<%
String user="";
if(request.getParameter("id") != null){
  user=request.getParameter("id");
  session.putValue("id",user);
          java.util.Enumeration st = session.getAttributeNames();
%>
  <br>
  <table border="1" align="center">
              <tr>
                          <td>getCreationTime()</td>
                          <td><%=(new Date(session.getCreationTime()))%></td>
              </tr>
              <tr>
                          <td>getID</td>
                          <td><%=session.getId()%></td>
              </tr>
              <tr>
                          <td>getMaxInactiveInterval</td>
                          <td><%=(session.getMaxInactiveInterval()/60)%>min</td>
              <tr>
              <tr>
                          <td>getLastAccessedTime()</td>
                          <td><%=(new Date(session.getLastAccessedTime()))%></td>
              </tr>
  </table>


<%
}
%>
</body>
</html>


--------------------------------------------------------------
일정한 시간이 지나서, 이미 해당 HttpSession 이 invalidate 되었군요...
이미 invalidate 된 session을 다시 invalidate 시키려고 하면 IllegalStateException이
발생합니다. 이 경우에 발생하는 IllegalStateException은 무시하시면 되겠습니다.


아래처럼 고치세요..


>    String mem_id = req.getParameter("mem_id");
>    HttpSession session = SessionPool.get(mem_id);
>
>    if(session!=null) {
>       session.invalidate(); // <--- !!!
>       SessionPool.remove(mem_id);
>    }


==>


>    String mem_id = req.getParameter("mem_id");
>    HttpSession session = SessionPool.get(mem_id);
>
>    if(session!=null) {
>       try{session.invalidate();}catch(Exception e){} // <-- !!!
>       SessionPool.remove(mem_id);
>    }
--------------------------------------------------------------


1. 현재 로긴되어 있는 사용자들의 id 와 세션카운트를 하는 방법


 


package session;


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


public class SessionDisplay extends HttpServlet {


 public void doGet(HttpServletRequest req, HttpServletResponse res)
 throws ServletException, IOException {


  res.setContentType("text/plain");
  PrintWriter out = res.getWriter();


  HttpSession dummySession = req.getSession(true);
  dummySession.putValue("userID", "Watcher");
  HttpSessionContext context = dummySession.getSessionContext();


  int i = 0;
  Enumeration ids = context.getIds();
  out.println("========================================");   
  out.println("No  SessionID  UserID");   
  out.println("========================================");   
  while (ids.hasMoreElements()) {
   i++;
   String id = (String) ids.nextElement();
   HttpSession session = context.getSession(id);
   String user_id = (String)session.getValue("userID");
   out.print("(" + i + ")" + id );
   out.println("  userID = [" + user_id + "]");   
  }
  out.println("========================================");   
  out.println("Total Connect User : " + i );
  out.println("========================================");   
  out.flush();
 }
}
--------------------------------------------------------------


1. user들이 로그인시 각각의 session에 아이디등이 저장됩니다.
    관리자입장에서 모든 유저들의 로그인상태를 알고자 하는데요,
    모든 유저들의 session에 저장된 값을 읽을수 있는지요...


 


   int k = 0;
   int j = 0;
   HttpSessionContext context = session.getSessionContext();
   Enumeration ids = context.getIds();
   while(ids.hasMoreElements())
   {
      String id = (String) ids.nextElement();
      out.println("<tr><td>");
      out.println(id);
      HttpSession foreignSession = context.getSession(id);
      String foreignUser = (String) foreignSession.getValue("LoginUser");
      String foreignName = (String) foreignSession.getValue("LoginUserName");
      out.println("<td>"+foreignUser);
      out.println("<td>"+foreignName);
      out.println("<td>"+request.getHeader("REMOTE_ADDR"));
      out.println("<td>"+new Date(foreignSession.getCreationTime()));
      out.println("<td>"+new Date(foreignSession.getLastAccessedTime()));
      out.println("</tr>");
   }
  
   위와 같이 하였더니 되더군요...
   근데요 브라우저 기준 세션을 보여주더군요...
   세션이 null로 나온것은 세션저장안된 브라우저랍니다. 
--------------------------------------------------------------


1. 세션 ID획득하는 방법임다.
  
   // 이건 세션의 컨텍스트를 얻기위한겁니다..(컨텍스터를 이용해서 세션의 ID를 알려고...)
   HttpSessionContext context = session.getSessionContext();
  
   // 위의 컨텍스트를 이용해서...
   Enumeration ids = context.getIds();
  
   // 최신의 상태가 아닌 세션을 검색하기위해 세션ID를 살펴봄..
   while (ids.hasMoreElements()) {
      String id = (String)ids.nextElement();
      out.println("Checking " + id + "...."); // 세션의 ID가 나오겠죠...
      HttpSession session = context.getSession(id);
      . . .
      String foreignUser = (String)foreignSession.getValue("user_id");
   }
--------------------------------------------------------------


1. jsp에서 회원로그인에서 session을 받아 처리하는 부분하고 이 session을 가지고
   정보수정이랑 하고 싶은데 어떻게 처리를 해 줘야 하나요?
  
   로그인할때 회원아이디값을 넘겨줍니다.
   값을 받은 페이지에서는 그 값을 세션에 넣습니다.
   이렇게요..
   session.putValue("id",userid);
   여기서 userid는 회원아이디값을 받은 String입니다.
   그러면 세션에 id가 들어가겠지요.
   다음으로 정보수정하는 페이지에 세션을 가져오는 문장을 넣지요.
   session.getValue("id");
   그리고 그 값을 String형으로 변환해서 임의의 변수에 넣습니다.
   그리고 그 임의의 변수를 이용해서 해당회원의 정보를 수정하면 되겠지요...
--------------------------------------------------------------


1. >client별 세션객체를 얻어서 client들의 세션 저장내용을 지우는 부분입니다...
   >근데 맨날도 아니구 가끔 아주 가끔 foreignSession객체에서 NullPointerException이
   >발생하는데요... 왜 그런에러가 나는지 모르겠네요...


   > HttpSessionContext context = session.getSessionContext();
   > Enumeration ids = context.getIds();
   > while(ids.hasMoreElements())
   > {
   > id = (String) ids.nextElement();
   > HttpSession foreignSession = context.getSession(id);
   > String[] session_valuenames = foreignSession.getValueNames();
   > for(int i=0; i<session_valuenames.length; i++)
   > {
   > foreignSession.removeValue(session_valuenames[i]);
   > }
   > }
  
   일종의..동기화 문제로 보여집니다.
   세션목록을 가져온 후,
   그리고 세션저장내용을 지우기 전에
   세션타임아웃 등의 이유로 세션이 없어지면
   해당 id값이 없으니 null이 들어갈것이구..
   모 일단 그렇게 보여지네요 ^^



또한 참고하세요..


 


☞ 로그인하고 로그아웃할때 데이터베이스 테이블에 값을 설정해서 비교하는 방법이 있습니다.


☞ 세션정보에 로그인한 사용자의 데이터도 넣을수 있을수 있다면,
세션을 체크해서 주기적으로 데이터베이스를 체크한다면 가능할거 같기두 한데요...


☞ javax.servlet.http.* 패키지에 보면 HttpSessionBindingListener 인터페이스가 있습니다.


이 인터페이스에는 몇개의 메소드가 있는데 그 중 한개가 아래에 있는것입니다.


 


// HttpSessionBindingListener 구현
public void valueUnbound(HttpSessionBindingEvent http) {
        logout();
}


 


위 메소드는 서블릿에서 사용자의 세션이 끊어졌을때 생기는 이벤트입니다.
그러니깐 사용자가 로그인 했을때 데이타 베이스에 세션 정보가 있다면 중복 로그인한 사용자이고, 없다면 세션 정보를 넣어두고, 위 메소드에서 세션 종료시 DB에 저장된 세션정보를 지우던지 필드를 ™V팅하던지 작업을 하시면 될것같습니다.


 


? 관련 메소드 정리


Object getAttribute(String name)
 - 주어진 이름으로 세션에 저장된 객체를 리턴한다. ※ Object getValue(String name)


Enumeration getAttributeNames()
 - 세션에 저장된 모든 객체들의 이름을 Enumeration 타입으로 리턴한다. ※ String


 


getValueNames()
long getCreationTime()
 - 1970년 1월 1일 0시 0분 0초를 기준으로 세션이 생성된 시간을 리턴한다.(단위 ms)


String getId()
 - 세션의 ID를 리턴한다.


long getLastAccessedTime()
 - 1970년 1월 1일 0시 0분 0초를 기준으로 클라이언트가 이 세션에서 요청을 보낸 마지막 시간을 리턴한다.


int getMaxInactiveInterval()
 - 서버가 클라이언트의 요청없이 세션을 유지하는 최대 시간을 리턴한다. (단위 초)


void invalidate()
 - 세션을 종료한다.


boolean isNew()
 - 세션이 만들어지고 클라이언트가 아직 세션에 조인되지 않았으면 true를 리턴한다.


void setAttribute(String name, Object value)
 - 세션에 이름을 이용해서 객체를 저장시킨다. ※ void putValue(String name, Object value)


void removeAttribute(String name)
 - 주어진 이름의 객체를 세션에서 삭제한다. ※ void removeValue(String name)


void setMaxInactiveInterval(int interval)
 - 클라이언트의 요청없이 세션을 유지할 수 있는 최대 시간을 설정한다. (단위 초)

반응형
블로그 이미지

Good Joon

IT Professionalist Since 1999

,

HP UX

11.xx 일 경우
# getconf KERNEL_BITS
64

10.xx 일 경우
# getconf LONG_MAX
2147483647
(64비트임)로 확인할 수 있습니다

AIX

현재 load된 kernel 이 32-bit 혹은 64-bit 인지 확인하는 명령어
# bootinfo -K
32

사용중인 machine이 32-bit 혹은 64-bit 인지 확인하는 명령어
# bootinfo -y
32


SOLARIS

# isainfo -kv
64-bit sparcv9 kernel modules
현재 이 시스템은 64bit 커널을 가지고 운영을 하는 시스템 이다.

# isainfo -kv
32-bit sparcv kernel modules
이 시스템은 32bit 커널을 가지고 운영을 하는 시스템이다.

# isainfo -v
64-bit sparcv9 applications 32-bit sparc applications
"-v"만 했을 경우 이 시스템에서는 32bit / 64bit 체계의 프로그램을 사용할 수 있다.

# isainfo -v
32-bit sparc applications
이 시스템은 32bit 체계의 프로그램만 구성하여 사용할 수 있다.
반응형
블로그 이미지

Good Joon

IT Professionalist Since 1999

,