* 에러발생

 

Sep  7 11:35:01 i55335 crond[7733]: Authentication token is no longer valid; new one required.

 

* 원인

계정관련 문제

 

* 해결

[root@i55335 ~]# chage -d 9999-12-31 e -1 weblog

 

 

*참고 자료

chage
(1) 설명: 사용자의 패스워드 만료에 대한 정보를 보여주거나 제한한다.
(2) 사용법
    chage [option] 사용자명
(3) option
   -l : 사용자계정에 대한 정보를 보여준다.
   -m : 패스워드 변경의 최소 날짜를 지정한다.
   -M : 패스워드 변경의 최대 날짜를 지정한다. 이 값이 지정하면 패스워드 만기일짜가 나타난다.
   -I : 패스워드 만료후에 실제 패스워드에 LOCK를 설정하기까지의 날짜를 설정한다.
   -E : 계정이 만기되는 날짜를 지정한다. MM/DD/YY 형태로 지정한다.
   -W : 패스워드 변경을 요구하는 경고날짜를 지정한다.
(4) 사용예
   1) [root@www root]# chage -l posein
      Minimum:        0
      Maximum:        99999
      Warning:        7
      Inactive:       -1
      Last Change:             4월 03, 2003
      Password Expires:       Never
      Password Inactive:      Never
      Account Expires:        Never
       => posein 사용자의 패스워드 및 계정 정보를 보여준다.
   2) [root@linux245 root]# chage -M 100 posein
       => 패스워드 만기를 최대 100일로 한다.
   3) [root@linux245 root]# chage -E 09/30/03 posein
       => 계정만기를 2003년 9월 30일로 지정한다.

Posted by '김용환'
,


스위치 (DNS 포함) 이슈로 발생할 수 있다. 특히 시스템이 문제 없다면, JVM 자체 문제일 수 있다.


The NoRouteToHostException will be thrown while attempting to connect to a remote host but the host cannot be reached for instance because of a badly configured router or a blocking firewall.

Most applications should not catch this exception; it is more robust to catch the superclass SocketException. 



아래 내용은 인프라 이슈가 아닌 JVM자체 이슈에 대해서 다룬 것이다. 


 

* 원인


JVM를 restart하면된다. DNS를 추가. 혹은 ip변경시에 java는 항상 그것을 캐쉬하고 있는 상태이기 때문에 해당 서버를 DNS정보로부터 받지 못한다.

 

 

* 증상

 


 

Server is not available * Additional Info *
qString :
http://isag.google.com:8080/common/monitor/ok.html
vhost :

 

 2007-08-29 19:18:20 [ERROR](HttpClientWrapper.java:293) No route to host : HttpClientWrapper[ encoding = MS949 establishTimeout = 12000 followRedirects = true noCache = true params = [] prepareURL = null soTimeout = 5000 statusCode = -1 SYSTEM_ENCODING = ISO8859-1 url = http://isag.google.com.com:8080/common/monitor/ok.html vhost = bodyString = null]

java.net.NoRouteToHostException: No route to host

 

모니터 java단에서 No route to host라 계속 뜬다.

 

* 해결

JVM 웹서버 재시작 또는 매번 DNS서버에서 정보를 읽어 올 수 있도록 옵션 추가해서 재시작한다. 

 -Dsun.net.inetaddr.ttl=50


 

* 이유

파일은 캐쉬되는 경향이 있다. 실제 native단에서는 한번 try한 것은 일부러 캐쉬하여 다음번 요청에 대해서 그 결과를 알려주는 경우가 있다.

네트웍도 마찬가지로 그렇게 되어 있다.

 


------


java8 소스를 보니까. NoRouteToHostException이 발생하려면 2가지 이유 중의 하나이다. 


1. EADDRNOTAVAIL

NoRouteToHostException은 소켓 연결시 EADDRNOTAVAIL이 발생하면 Exception을 던지도록 되어 있다. EADDRNOTAVAIL의 의미가 Address not available 라는 의미더라구요. DNS 이슈 문제가 아니면, 순간적으로 app server에서 특정 서버 소켓 연결을 위해 클라이언트 포트를 많이 생성(임시포트(ip_local_port_range값에서 max-min의 값)까지 생성)하면서 나는 이슈로 볼 수 있을 것 같다.  

$  cat /proc/sys/net/ipv4/ip_local_port_range

32768 65000

$  cat /proc/sys/net/ipv4/tcp_tw_reuse

0


2. EHOSTUNREACH


routing table 쪽으로 이슈가 발생해서 reach할 수 없으면 해당 에러가 발생한다. 





Posted by '김용환'
,

웹스나이퍼

web 2007. 9. 4. 02:32

웹소스 보기, html 디버깅시 유용한 툴이다.

 

 

 

http://comingsoft.com/websniper/down.html

 

 

 

 

 

 

[시스템 사양]
운영체제: Windows98,WindowsME, Windows2000, Windows2003, WindowsXP
웹브라우저: Internet Explorer 6.0 이상 버전

[설치하기]
주의! 웹스나이퍼1B 사용하시는 분은 제거 하신 후에 설치해 주십시요.
주의! 웹스나이퍼2, 2a, 3을 사용하시는 분은 websniper3a_patch.zip를 다운받아 압축을 풀고 웹스나이퍼가 설치된 경로에 덮어씌우세요.

1. 아래의 버튼을 클릭해서 websniper3a_setup.exe 웹스나이퍼 프로그램을 다운 받습니다.(다운받은 경로를 기억하세요)

2. 모든 웹브라우저를 닫습니다.
3. 위 1번항목에서 다운받은 프로그램을 클릭하면 자동으로 설치가 됩니다.
4. 설치가 완료되면 아래 그림처럼 메뉴에 등록이 됩니다(큰 빨간사각형 참고)메뉴의 "보기>탐색창>WebSniper"를 찾아 선택합니다.

< 웹스나이퍼가 설치되어 실행된 화면 그림 >

위의 그림에서 (3)번 버튼이 보이지 않는다면, 메뉴의 "보기>도구모음>사용자 지정"을 선택하여
다음 그림처럼 설정하여 위 4번항을 다시 설정하시기 바랍니다.

< 메뉴에서 websniper가 보이지 않을 경우 설정 그림>

[웹스나이퍼 프로그램 제거하기]
제거판의 "프로그램 추가/제거"를 실행합니다.
프로그램 목록에서 WebSniper 선택하여 제거합니다.
주의! WindowsXP에서 완전히 제거되지 않는 경우가 있습니다. 이때는 로그오프 한 후 다시 로그인 하여 완전히 제거하십시요.

 

 

 

Posted by '김용환'
,

한글이 깨진다. 그이유는 ZipInputStream 사용시 java는 UTF-8을 쓰도록 되어 있다.

그럴 때는 다음의 패키지를 사용한다.

http://sourceforge.net/projects/jazzlib/

Posted by '김용환'
,

 

출처: http://www.javaservice.net/

 

제목 : [Comment] 다국어 인코딩 문제의 위치 및 까발리기
  글쓴이: EB(goEB)   2002/12/02 12:42:10  조회수:2182  줄수:289
======== 2002.12.03 23:12 공지 ========
이 글의 KSC5601-1992는 잘 못되었으므로 걸러서 읽어주시기 바랍니다.
이 글과 관련된 "2부"에서 설명합니다.
=======================================



제목 : [Comment] 다국어 인코딩 문제의 위치

많은 분들이 다국어 때문에 헤메이고 있습니다.
이에 대해 저의 짧은 지식이지만 공유할 까 해서 코멘트를 달아봤습니다...


글의 영양가는 뒷부분에 있습니다.
시간 없으신 분들 장문인 만큼 뒷부분을 읽어주십시오. 다만 문자셋의 기본은 --;;


이 글에선 DB는 부분은 범위밖이기 때문에 다루지 않을 것입니다.
사실 대부분의 문제는 DB외의 곳에서 발생할 것입니다.


저는, 엔코딩에서 제일 중요한 것을 아래와 같이 분류하였습니다.
1. 각 문자셋의 종류와 이해
2. 소스 파일의 엔코딩 형태
3. 컴파일된 파일의 엔코딩 형태
4. 컴파일된 파일을 사용하는 엔코딩 형태
5. UTF-8의 필요성 인식.
6. WebBrowser의 이상한 행동(?)

"new String(str.getBytes("8859_1"), "EUC_KR");"
와 같은 문제는 별개입니다. (문자셋의 종류와 이해가 우선이지요)


<
1번에서 주의해야 할 것은. Unicode와 Unicode(UTF-8)을 동일시 여겨셔는 안된다는 것입니다.
Unicode는 코드페이지 1200이며, Unicode(UTF-8)은 65001 입니다.
그 크기 또한 다릅니다. (하늘과 땅차이 -_-)

- Unicode와 Unicode(UTF-8)을 간단 정리
Unicode는 모든 문자를 2Byte로 표시한다. - ISO-2022형태의 다국어와 차이점.
(영문이고 다국어고 필요없다. 어떤 언어든 65536가지를 표현 가능하다.
이 뜻은 2Byte가 어떤 형태로 구성되는지를 알 수 있게 하는 말.)

UTF-8은 기존 ASCII 1xx까지 유지하며 다국어는 2, 3Byte로 표시한다.
(즉, 영문은 1Byte처리 - 아래에서 다시 설명하기 때문에 매우중요)
고로, UTF-8은 프로그래밍 언어에 사용하여도 손색이 없다.

☆다국어 - 여기서 필자 맘대로 재정의한 뜻으로 기존 2Byte이상을 필요하던 언어.
 (영어등도 포함해서 말한다고 딴지 걸지 말란 뜻에서;;;)
>


<
2번을 이해하지 못하였을 경우에는 이러한 문제들이 발생합니다.

가. 만약 소스가 JSP일 경우 파일을 Include할 때 A는 정상인데 B는 깨지거나
 하는 문제 발생. (혹은 그 반대)
 ※주의! <%@ page contentType="text/html;charset=xxx"%> 와는 별개이므로 소용 없습니다.
나. *.java를 컴파일 한뒤 다국어 사용시 깨어져 나온다. --;;
 (static이나 비교문등에 미리 입력해 놓은 다국어...)
 물론 Runtime시 복구할 수 있는 경우도 겠지만 그렇게 하는 사람 있다면 따돌림 당한다는.... --;;

해결법 :
가. 소스파일을 만들어 저장할 시에 자신이 작성한 소스의 문자셋을 확인한뒤
 그 와 동일하게 저장하도록 하고, 프로젝트에 관련된 모든 파일을 동일한 문자셋으로 작업해야 한다는...
 <%@ page contentType="text/html;charset=xxx"%>의 xxx에 자신이 작성한 문자셋을 동일하게 입력.
 만약 기존에 미리 만들어둔 소스가 있을 경우라면 밑에서 다시 언급하겠습니다.
나. 소사파일을 만들어 저장할 시에 자신이 작성한 소스의 문자셋을 확인한뒤
 그 에 따라 컴파일 할 수 있도록 한다.
>


<
3, 4번의 경우는 현재로써는 가정이다. (혹은 사실 - 물론 내 자신은 아직 접한적은 없다.)

컴파일된 파일이 JVM에 의하여 로딩되는 과정과 Runtime의 과정에서 엔코딩이 서로다른 형태의
Class를 불러 들였다면? 그렇다면 이중 entrypoint가 있는 클래스가 디코딩의 기준이
되는 것일까? 그렇다면 entrypoint외의 타 클래스에서 사용된 다국어는 모두 깨어질 것이다.
아니라면 클래스간 호출시 JVM은 그 에 따른 처리를 해야한다. (느려진다.)

물론 현재의 JVM은 일반적으로 모든 소스를 Unicode 혹은 UTF-8로 불러들일 테지만 아닐 경우는
어찌 해야 할 까? (컴파일된 파일의 원본의 형태가 뭐건 Unicode 혹은 UTF-8로 변형)

이렇게 3, 4번을 넘기자 --;;
>


<
5는 2번의 경우만으로도 UTF-8의 필요성을 느끼지 않을 수 없겠습니다.

번거롭게 경우에 따라 소스를 다시 원하는 형태로 엔코딩하여 만들어야 한다는 것은
Tool과의 노가다를 감행해야한다는 것인데 말이죠.
그러므로 할 일 많(-_-)은 프로그래머로써는 UTF-8을 사용해야 한다는...

또한, UTF-8의 정렬속도 쥑입니다. --b (Unicode와의 비교를 제외한다면.)
한글이 모두 순차배열되어 있기 때문입니다. :)
그에 비해KSC5601(KSC5601-1992)는 정렬속도는 떨어진다는... (공포의 8822자)
>


<
 Application에서 프로그램 소스등(*.JSP, *.JAVA, *.TXT)의 엔코드 타입을 자동으로 인식!?!
결론은 자동 인식 가능한 문자셋이 있기도 없기도 입니다.
일반적으로 2Byte로 된 문자셋은 인식이 불가능 하지만 Unicode는 가능 합니다.
첫 시작을 16진수로 FF FE로 시작하는 문서는 Unicode를 알리는 문서입니다.
또한 Unicode(UTF-8)은 서명있는 Unicode(UTF-8) 문서일 경우는 대부분 가능합니다.
없는 경우는 가능한 툴이 있기도 하고요. (말이 자동이기 거의 강제 --)
만약 서명이 있는 경우라면 EF BB BF로 시작합니다.
이에 따라 각종 Tool에서 자동으로 읽을 수 있는 것입니다.
>



소스의 문자셋을 변경사용하기...

일반적으로 프로젝트의 모든 소스는 엔코딩 형식이 동일해야 하겠죠?
만일 기존 소스가 있는데 다르다면 현 프로젝트와 맞추어야 할 텐데...
쉽게 구할 수 있는 툴은 UltraEdit가 정도가 되겠네요 저는 v9.10을 가지고 있고
File -> Conversions에 있습니다. 이 곳에서 원하는 형태로 가능하겠습니다.

-단, 한글들의 문자셋변환 툴은 아직 보질 못했음. 혹시 보신분 손 ^^/
 한글에서 하위변환은 완벽히 안되므로 이를 염두해야함.



JSP에서 <%@ page contentType="text/html;charset=xxx"%>와
META TAG의 contentType="text/html;charset=xxx"

이둘을 사실상 모두 사용하는 경우는 웃지 못할 일입니다.
(실로 대단한 이슈입니다.)

이곳 게시물중
----------------------------------------------------------------------------------
==게시물 1========================================================================
euc-kr 이나 ksc5601 을 사용할 경우 브라우저의 한글은 잘 나온다.

대신 확장한글을 표시할 수 없어서 샾 , 햏 , 잌 같은 글자는 ? 로 깨어져 나온다.

소스보기를 해도 완전히 깨진다.
...
...
중략
...
서버쪽 한글처리는 MS949 로 정하고, 브라우저의 한글처리는 ksc5601, euc-kr 등으로
한다. 즉 서버쪽은 @page 의 contentType 속성을 charset=MS949 로 <head> 태그 내의
<meta> 태그에서 Content-type 의 값을 charset=ksc5601 로 주면 브라우저쪽의
한글처리를 마무리지을 수 있다.
==게시물 2========================================================================
NOTE: '잌'과 같은 확장한글의 경우는 추가적인 테스트가 필요합니다.
   추정컨데, 
   1) MS949(Cp949)를 DB(Oracle,DB2,..)가 지원하는가? 
   2) JVM file.encoding MS949->Cp949 에서 정상적인 동작을 하는가?
   3) default.client.encoding/client.encoding.override MS949->Cp949 에서 정상적인
    동작을 하는가? 
   4) 위 팁문서처럼 META tag에서 KSC5601을 반드시 써 주어야 하는가?
==게시물 3========================================================================
Windows에서의 JVM의 한글디폴트 인코딩 캐릭터셋 문자열은 "EUC_KR" 입니다.
Linux에선 "KSC5601"이라 나오는 군요.

그러나 "EUC_KR", "KSC5601", "EUC-KR"은 모두 동일합니다.
==================================================================================
----------------------------------------------------------------------------------
이런 내용이 있었습니다.

MS949는 엄밀히 "KSC5601-1987" 입니다. 또한 "KSC5601-1992" 입니다.
KSC5601이들의 차이점은 1992는 1987를 모두 포함하고 문자의 위치까지 호환이 되며
1987에 추가된 문자 8822(공포의)개가 있다는 것 뿐입니다.
(현재 MS OS에서는 단순한 폰트차이로 봐도 무방)
그러므로 일반적으로 KSC5601라고 통합하여 사용하는 것입니다.
(엄밀히 MS949는 META TAG에서 windows-949 혹은 ks_c_5601-1987 에 해당합니다.)

그러니 위에 언급된 게시물에 있는 MS949관련 사건들은 무효-_-가 아닐까요?

무슨 의미인고 하니 EUC-KR(Extended Unix Code-Korean)에서는 잌이 깨지지만 KSC5601은 깨지지 않습니다.
쓩, 잌, 퓩, 끁, 덁을 비교해보면 EUC-KR은 쓩만을 표현할 뿐 입니다.
KSC5601-1992는 확장을 표함합니다. (물론 UTF-8과는 비교할 것이 못되지만...)
하지만 EUC-KR은 확장을 포함하지 않습니다.
(위의 게시물 3은 2000/05/28일자로 오래되었기에
그 시절 KSC5601 = EUC-KR 라고 한 표현한 것은 그다지 문제 삼을필요는 없는듯 --;;
다만 저 게시물을 보고 아직 맞다고 생각하시는 분들을 위하여 언급하였음.)


어쨌든 어떠한 환경이던 WebBrowser간엔 어떤 문자셋이건 쌍통합니다.
(이점이 중요합니다. 왜 깨어져야할 확장 글씨가 정상 표시되는지를 이제 설명합니다.
-MS Win XP에서 IE 6.0과 Nescape Navigator 7.0을 테스트 해봄. Linux, Unix에서 안해봄)

제가 위에서 언급한 확장글씨가 왜 이곳 게시판이 EUC-KR임에도 불구하고 깨지지 않고 정상으로 보일까요?


WebBrowser는(어쩌면 OS레벨) HTML 소스의 문자셋이 뭐건 Unicode (단, UTF-8 문자셋은 제외)로 변환시킵니다.
그리고 화면에 출력합니다. 이 때 필드(INPUT TAG, TEXTAREA TAG등)에 입력한 값 역시
당연 Unicode(UTF-8인지는 정확히 확인하지 않았음. 하지만 UTF-8문자셋은 그대로 UTF-8) 데이터 입니다.
(눈으로는 구분 못하죠.)
그래서 입력할 당시에는 모든 문자를 입력할 수가 있는 것입니다.
허나 값을 서버로 보내면 HTTP Header (혹은 META TAG)에 정의된 문자셋으로 컨버팅 합니다.
(Server로 전송되는 TCP/IP 데이터를 보면 증명 가능)
이 때 컨버팅 불가능한 문자는 &# + Unicode값 으로 변경됩니다. 그렇게 서버로 날라가는 것입니다.
(이 값만으로도 알 수 있겠지만 EUC-KR은 KSC5601에 비해 확장한글이 부족하단것을 알 수 있습니다.)

만약 서버에 날라간 엔코딩 타입이 KSC5601이였지만 깨지는 문자가 있었다면, 그 깨지는 문자는
&# + Unicode 형태로 계속 보존되게 되는 것입니다. DB에 역시 그렇게 입력됩니다.
그렇다고 한다면 눈치빠른 분들은 벌써 한가지 이상의 문제를 지적하실 것입니다.

첫째. &# + Unicode 로 표현된 문자는 특수처리를 하지 않는다면 영원히 그렇게 되어 있다는 것을...
(많은 문자셋을 보시면 알겠지만 ACSII는 유지되기 때문입니다.)
고로, WebBrowser 이외의 곳에서는 문제가 --;;
-이 때문에 DB에서 검색할 경우에 문제가 있다.

둘째. 기존 &# + Unicode를 추후 Unicode, UTF-8등에 마이그레이션 할 때 따로 작업 해야 할 것입니다.
(제가 아직 자동변경해주는 툴은 못 봤습니다. --;;
뭐 그리 어려운건 아니지만 양이 크면 큰일인 것 만은 확실합니다.)

셋째. DB의 필드의 길이가 개발자가 원했던 길이를 벗어날 수도 있는 문제.
&# + Unicode는 최대 7자의 길이를 가집니다. (MAX : &#65536) 그럼 EUC-KR이나 KSC5601로 DB용량 아끼려다
필드깨지고 필드길이 제한 없으면 오히려 Unicode혹은 UTF-8보다 용량만 증가하고 --;;

넷째. 간혹 게시물등 내용을 보면 &# + Unicode값이 그 대로 보이는 경우가 있습니다.
이유는 제가 일전에 올린 게시물 내용에도 언급했듯 & 을 &amp;로 변형하였기 때문입니다.
즉, &amp;를 &로 원래대로 놓으면 첨에 입력했을 당시의 문자가 보이는 것입니다.

다섯째. 어쩌면 MS외의 OS환경은 그 문자를 표현할 방법은 특수처리를 하지 않는 이상
현재로써는 없을 수도 있습니다. (제가 Linux, Unix에선 안해본지라 --;;)

참고.
'葶' <- 이 문자는 Unicode와 UTF-8문자셋이 아니면 깨집니다.
WebBrowser에서 보는 데는 지장 없습니다. 지금도 보이시죠?
이 '葶'는 서버에 전달 될 때 &#33910; 이렇게 변형되어 전달 됩니다.
(지금 이 게시판에서 WebBrowser의 소스보기를 해도 알 수 있습니다.)




정리하자면
1. 정말이지 UTF-8은 꼭 필요하며 (한글만 사용한다 할 지라도) 필요한 시기는 지금입니다.
2. MS949 와 KSC5601은 같으니 위에서 언급한 MS949사건(?)은 정확성을 위해
 여러 환경에서 (JAVA의 각 버젼별 등등) 재 테스팅이 필요할 것으로 사료됩니다.
 - 실제 제가 MS949로 서버에서 처리라는 곳에 가서 HTTP프로토콜로 전송되는 값을 확인한 결과
 KSC5601과의 차이를 못 봤습니다.
 Servlet, JSP, HTML페이지 = ksc5601로 해서 다시 한번 테스트 해보셨으면 함.
3. WebBrowser가 버젼과 OS별로 어떠한 형태로 서버에 값을 전달하는지 정확히 알아야 합니다.
 또한 이 때문에 JSP등 WebBrowser와 통신하는 처리는 DB의 특성을 안탄다고 봐도 무방.
 (대부분 DB의 엔코딩을 EUC-KR, KSC5601로 하고 프로그램 역시 그렇게 짜기에)
4. JAVA에서 EUC-KR을 사용하실 거라면 KSC5601을 추천합니다.
 (단, 정렬시 속도저하 혹은 엉뚱한 순서 우려)
5. EUC-KR과 KSC5601의 상호변환을 허용하지 말자. (특히 KSC5601-1992에 문제가 있음)


※ 문자는 bits와 Font의 장난이란걸 잊지 마세요. 
(Font의 장난에 특별히 주의하십시오.
bits값은 정상인데 OS따라 표시되지 않는 경우도 있고 Tools에 따라 표시되지 않는 경우도...
그러므로 문제가 되는 곳에서는 항상 bits값을 확인하는 습관을...)



지금껏 정리가 안되었다면 안된 장문 읽어주신것 감사드립니다.
잘못된점 있으면 지적하여 주시구요

건승하십시오.


==================================================================================
이 글은 EmotionalBrain이 작성하였으며 처음 게시된 곳은 www.javaservice.net 입니다.

이 글을 어디에 사용하든 작성자와 원 출처는 지울 수 없습니다.

2002.12.01
==================================================================================





P.S
위에 "게시물 1" 에서 언급된 내용을 잠깐 말하자면
JSP에서 <%@ page contentType="text/html;charset=XXX"%> 라고하면 아시겠지만
XXX가 META TAG보다 HTTP Header에 Context-Type이 먼저 날라갑니다.
이 때 JSP에서 MS949라고 하면 HTTP Header에서도 MS949라 날라가는데 WebBrowser에 그런게
없다는 걸 감안하면 JAVA의 황당함이 --;;
MS949는 엄밀히 말하면 META TAG에서 "windows-949" 혹은 "ks_c_5601-1987" 에 해당하는데
그대로 "MS949"가 -_-;;
그덕에 META TAG에 따로 windows-949나 "ks_c_5601-1987"를 무조건 넣어야 한다는...
어찌됐건 MS949는 KSC5601이기 때문에 KSC5601로만 모두 처리하면 MS949는 필요 없습니다.


P.S 2
이거 작성할라구 이것과 관련된 윈도우 창만 지금 30개가 떠 있네요 --;;
무려 5시간 허비 --;; (확실하게 쓰려구 많은 노력을 했기에...)
Navigator두 MS OS에 첨 깔아보고 --;;
(근데 제 컴이 빨라서인지 Navigator가 예전에 비해 실행속도 무지 빨라졌네요!)
제목 : Re: encoding 관련 url
  글쓴이: 허광남(heogn)   2002/12/04 01:42:33  조회수:478  줄수:36
게시물1 의 저자입니다. 
EB 님의 명성은 익히 보아온 바라 제 글을 토대로 연구결과를 공유해주셔서 감사드립니다.
(사실 좀 뜨끔했습니다. ^^;)
MS949 는 CP949 와 같다는 것
iana 에는 빠져있는 문자셋이며 윈도우즈와 java 진영에서 공유하는 OS 기반의 문자셋
라는 것
제가 이해하고 있는 것이었고, EB님의 글처럼 한글의 한계상황을 넘어가는데는 UTF-8 
문자셋을 해야된다는 것에 공감합니다.

Hangul and Internet in Korea FAQ 신정식님 8번글 참고
http://jshin.net/faq/index.html

iana 에 등록된 문자셋에 관한 링크
http://www.iana.org/assignments/character-sets

cp949 의 unicode mapping table
http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP949.TXT

Extended Encoding Set (contained in i18n.jar)
http://www.mobilejava.co.kr/bbs/temp/lecture/personal/encoding.html

윤경구님과 김필호님의 Cp949 에 관한 글
http://java.freehosting.co.kr/java/messages/1297.html

사실 아직 정리가 완전히 안된 상태입니다.
EB님의 글을 저 또한 참고하고 두가지 인코딩을 표시해야되는 우스꽝스런 jsp 
코딩스타일을 빨리 벗어나야겠습니다.(^^; 언제가 될지는 저도... )

행복하세요.
---------------------------------
jakarta-seoul project 
jakarta 문서 한글화 사이트
http://www.apache-korea.org

---------------------------------
http://okjsp.pe.kr
제목 : [Comment] 다국어 인코딩 문제 2부 - 2002.12.04 13:20
  글쓴이: EB(goEB)   2002/12/04 12:28:11  조회수:1132  줄수:269
제목 : [Comment] 다국어 인코딩 문제 까발리기 2부

먼저, 첫글을 작성시 짧은 시간에 많은 것을 하려다 보니 본의아니게 큰 실 수를 저질렀다는 것
사과드립니다. (이런 실수는 해서는 안돼는데... 쩝)

대신 이 글에서 만회합니다. ^^;;

뿌리가 흔들리는 부분입니다. (쿠..쿨럭)
KSC5601-1992 는 KSC5601-1987 과 혼환 안된다고 보셔두 무방합니다. --;;
제가 가지고 있는 자료를 제가 잘 못 본 탓입니다... (변명이란 이런것 --;;)
완성형과 조합형의 차이는 아실겁니다.
KSC5601-1987는 KS완성형이라고도 합니다. KSC5601-1992 는 표준(상용이 아님) 조합형입니다.

헉헉 --;;

제가 저 부분 하나를 잘 못 읽었습니다;;;
그러한 이유로 뿌리가 안 흔들릴 수 없습니다.


KSC5601 = ks_c_5601-1987 = MS949 입니다.


KSC5601-1987는 확장이 아니라 제가 말씀드렸습니다. - 잌 등의 문자.

그럼 확장을 포함하는 것은 무엇일까요?
(기존엔 저의 글에서 KSC5601-1992라는 짜가가 이를 대신 했었습니다만... --;;)



제가 MS949 = KSC5601 = KSC5601 + 확장한글 이라고(확장이 KSC5601의 배열과 100% 호환) 하였는데 그렇다면?
(KSC5601 = KSC5061 + 확장한글이라는 정보는 예전 1998.11년 에도 마이크로 소프트웨어 잡지에 실렸음.
이 내용을 틀렸을 것이라 생각하지 않음. 이유는 테스트과정에서 밝혀낼 것. - 첨부자료참고)

바로 MS949 이였습니다.

제가 첨 게시물을 올리기 전에 어떤 아이러니한 점이 있었는데 그게 JAVA의 버그인줄만 알았으나
KSC5601-1992와 MS949가 별개라른 점을 알자 드디어 원인을 알게 되었습니다.
(또한 그당시 KSC5601-1992 도 문제가 있다고 봤습니다. -_ㅜ)

먼저 MS949으로 JAVA소스에 확장을 포함하여 작성하고 JAVAC -ENCODING옵션을 KSC5601로 하면
소스작성시 넣은 확장 한글이 깨지지 않습니다.

하지만 MS949의 확장한글을 Runtime환경에서 KSC5601로 하면 확장한글이 깨집니다.
(KSC5601로 변환할 때 변환기에서 확장한글영역은 ?로 바꾼다는 얘기)

즉, KSC5601 <> MS949는 호환이 되지만 안돼는 것입니다.

풀어서 말하면 MS949를 KSC5601으로 변경시에 MS949디코더기는 정확히 풀었으나 KSC5601엔코더기는
KSC5601표준정의에 의하여 MS949의 확장영역을 처리할 필요가 없어도 KSC5601의
디코더/엔코더가 정상 인증이 된다는 것입니다.
그러므로 표준정의에 의한 KSC5601밖의 DBCS영역은 ?로 처리해도 문제가 없는 것이 되겠습니다.
(KSC5601이 MS949의 확장영역을 ?로 변경하지 않으면 완존 MS949 De/Endcoder 라는 것입니다. -_-;;
이러한 경우가 실무에 존재하는데 그 예는 모르는 사람이 없을 정도로 유명한
JSP에서의 @Page와 HTML의 META에 각기 다르게 적용하는 경우와 제가 위에서 방금말한
JAVA소스는 MS949로 JAVA -ENCODING 은 KSC5601로 주었을 경우가 되겠습니다.
- 이곳에서 MS949가 확장을 포함하는 장본인이라는게 또 다시 증명되네요 --;;)

※ 참고. 확장완성형은 MS 독단으로 만든것입니다. - MS에게만 표준 = 국민의 표준 -_-;;


정리하자면 그리하여 JAVA에서 KSC5601외에 MS949를 따로 보유하고 있는 것이 되겠습니다.





많은 분들이 MS949 = CP949로 알고 있습니다. 여기서 CP는 CodePage를 말합니다.

하지만... 과연 그럴까요? 한번 까발려 보도록 하겠습니다.

---------------------------
첨부 소스 설명...

-첨부파일의 Class는 ISO8859-1 로 Encoding하여 컴파일 하였음.-

어떤한 OS이건 어떤한 형태로 Compile하건 특성을 없애기 위하여
한글은 Bytes(Source 변수에 해당)로 입력하였습니다.

그러므로 100% JAVA의 Runtime환경의 특성만을 탑니다.

입력된 한글의 내용은
가잌덁
이렇게 MS949를 기반으로한 Byte값 3글자입니다.

테스팅시 주의 사항은 문자를 출력할 때 OS에 따라 한글의 표현이 안될터이니
반드시 Byte[] 값을 확인해 보시기 바랍니다. Byte[] 값이야 말로 어떠한 상황이든
JAVA에서 처리한 처리 결과를 정확히 확인할 수 있기 때문입니다.


아래, 제가 테스팅한 결과를 올려보겠습니다. (JDK v1.3.1

============================================================
System.getProperty      : MS949

Source Output...
Source                  : -80, -95, -97, -27, -120, -28

String Output...
strMS949                : 가잌덁
strCP949                :
strCP949fix             : 가쌧
strKSC5601              : 가??
strKSC56011992          : 쌰?걳
strEUCKR                : 가??

Byte[] Output...
byteMS949               : -80, -95, -97, -27, -120, -28
byteCP949               :
byteCP949fix            : -80, -95, -101, 81
byteKSC5601             : -80, -95, 63, 63
byteKSC56011992         : -101, 88, 63, -127, -102
byteEUCKR               : -80, -95, 63, 63
============================================================

위의 값을 보시면 여지껏 제가 말씀드렸던 것들이 무엇인지 결과를 보고난뒤니 감이 잘 올 것입니다.

※ 보는 방법
- Source 변수 : 원본 데이터 이며 OS의 (Encoding문제) 특성을 없애기 위하여
 Byte[]로 구성되었다.
- strXXX 변수 : Source를 기준으로 각 문자셋으로 변환하여 화면에 출력해본다.
- byteXXX 변수 : strXXX로는 OS에 따라 보이는 문자가 있고 없고 하므로 정확성을 위하여
 strXXX를 Byte[] 로 변환하여 출력한 결과이다.
 이 값이 만약 저의 결과와 다르다면 제 시스템 혹은 결과가 다른 시스템 혹은 둘다 이상있는 겁니다. -_-;;
 (OS가 아닌 JAVA만 이상있다.)
- CP949와 CP949fix의 차이점은 CP949는 Source의 3글자를 표현하도록 했던 것이고
 CP949fix는 2글자까지만 표현하도록 했던 것의 차이입니다.
 이유는 제 시스템에선 3글자를 전혀 출력하지 못했기 때문입니다.
 (Byte[]가 안나왔으므로 엔코딩/디코딩 자체 문제.)
- Byte에서의 숫자 '63' 은 문자 '?'에 해당하는 것으로써 OS의 폰트문제로 글씨가 깨지는 것이 아닌
 엔코딩/디코딩 자체에서 처리할 수 없다는 뜻입니다.

※ 위의 Byte 코드에서 63이라고 나온 곳이 제일 중요한 곳이 되겠습니다.
63은 압축으로 비유하자면 손실 압축기법입니다.
무슨 뜻인고 하니 63이 아닌 다른 값들로 변환되었다면 실제 그 문자셋을 표현해주는 시스템
(위에서 저는 MS949였기 때문에 MS949만 모두 정상처리 된 것 입니다.)
에서는 글씨가 정상으로 출력된다는 얘기입니다.
(또한, 원래 문자셋으로 복원해도 정상으로 된다는 얘깁니다.)
위의 "byteKSC56011992" 결과를 본다면 그 시스템에서(표준 조합형)는 "기?덁"으로 보이는 것입니다.
그러니 문자셋 상호변환시 63으로 되는 곳이 있다면 그들간 변환은 절대 금물~!

위의 결과를 보시면 아시겠지만 JAVA에서는 MS949와 CP949는 100% 호환되지 못합니다.

그러므로 많은 분들이 알고계신 MS949 = CP949는 JAVA에선 딴 얘기로 통합니다. --;;





정리하면

가. 여전히 JAVA에서 EUC-KR(KS_C_5861-1992)은 사용하지 말아야할 존재 입니다.
- 메일 때문에 사용해야한 다면 차라리 KSC5601-1987과 ISO-2022-KR을 이용하여 처리하십시오.
 오직 MS949때문입니다. - Client가 MS환경이 많으니...
(얄미운 MS지만 UTF-8정의할 때 우리나라가 세계에서 두번째로 많은 코드를 사용할 수 있게 해주었습니다.)

나. Oracle에서 KO16KSC5601를 사용할 때 KSC5601 디코딩/엔코딩이 MS949를 무시 하는지 확인해야 할 것입니다.
 또한, KO16KSC5601이 EUC-KR을 100% 지원해주는가 의문이 들지 않을 수 없습니다.
 적어도 KSC5601에 MS949의 확장문자가 포함되었을 경우에
 EUC-KR로 컨버팅하여보면 특정문자가 깨지기 때문입니다.
 - Oracle에서도 Unicode 있지 않나요? (UTF-8 말고) 그럼 그거 쓰면 될텐데 --;;
   (UTF-8 쓰기 싫은 사람들에겐... 혹은 UTF-8사용하면 안되는 이들에겐 - 이런 경우가 있다;;)

다. Client가 WebBrowser이고 문서의 문자셋이 Unicode, UTF-8이 아닐경우
 WebBrowser가(어쩌면 OS레벨) HTTP header나 HTML의 META에 정의된 문자셋이 지원하지 않는
 문자가 있을 경우 이를 자동으로 &# + Unicode(Int16)로 변경한다는 것에 주의하셔야 하며
 이에 따른 문제는
 1. WebBrowser외의 곳에서는 한글 변환이 어려우며 100% 처리하기 위해서는 Unicode나 UTF-8를 이용하여
    직접제작한 처리기를 통해야만 표현할 수 있다.
 2. &# + Unicode로 입력된 내용을 검색시 부작용이 많이 있다.
    (이곳두 제가 '덁' 이라고 입력한거 검색 안됨... 제가 이곳 소스를 보진 않았지만
    모두 EUC-KR루 처리했으니 서버에 항상 &# + Unicode로 갔을 것이고 검색어 역시
    그렇게 처리되어 쿼리를 날릴 텐데두 안되는거 보면 이곳 소스한번 보구잡따. --;;
    더욱 재밌는 것은 파일명을 '덁'으루 하면 EUC-KR인 이곳에서 본문은 &# + Unicode로 가지만
    파일명은 제대로 간다. --;; 역쉬 %xx 로 전달되는게 짱이얌 -0-;; %xx 형태 원츄 --b
    - JAVA에서 직접 EUC-KR 스트링의 Byte를 편집할 수 있다면 이것이 쉽게 가능하게 한다.
     문제는 Byte를 편집하였기 때문에 표준에 어긋나는 일이라는거 --;; 그래서 무효 --;;
     또한, 눈에 보이는 '덁'이 실제 '덁'이 아닌 OS가 꺼벙해서 보이는 경우 있다. - 어렵지만 중요한 말)

라. Red Hat Linux 7.1 에서 UTF-8.
 - RedHat Linux v7.1 한글판 OS에서 (WebBrowser는 Navigator v7 한글판) '잌'
   등의 문자는 '이ㅋ' 이렇게 표현되었었다. --;;
   확장문자 입력은 아예 되지도 않는다. --;;
   Linux에서 JAVA코딩시 이들을 주의하자. (또한 실제적으로 정상인데 Font문제로 표시되지
   않을 수 있으므로 Byte값을 확인하자. 특히 Linux에서 "아햏햏"이 출력되지 않는 다고 하신분 -_-+
 - UTF-8관련 자료
    영문
    (인증문제가 걸린다면 상위디렉토리부터 접근해본다. --;;)
    한글

마. MS OS에서 Win NT 2000부터는 파일 시스템의 기본이 UTF-8이지만 Win98은 잘 모르겠다.
 이 것을 언급한 이유는 제가 올린 "UTF-8로 URL 요청할 시 한글 처리 가능케" 바꾸는 게시물에 올린
 *.htc의 소스를 보면 URL이 "file:///"이면 KSC5601(MS949)로 바꾸지 말라는 부분이 있는데 이 때문이다.

바. JAVAC -ENCODING   옵션을 잊지 말자. (이거 아직도 모르고 계시는 분이 있다는 -_-+)
 이 때, -ENCODING은 소스파일과 동일하게 해주어야 한답니다. ^^
 JSP에서는 @PAGE contentType의 charset 셋이 이 역할을 합니다.
 (또한, Application, Session Scope를 지닌 변수에도 적용됨, 그러므로 프로젝트의 모든
  ENCODING타입이 같아야 득이됨.)
 "JAVA -Dfile.encoding=" 이 옵션은 기본으로 통한다. ㅡㅡ;;

사. JSP에서 @PAGE 를 사용할 시 반드시 INCLUDE되는 파일이 아닌 불러들인 파일에 넣어주어야 한다.

아. MS949와 CP949는 다르다. (적어도 JAVA에선 다르다.)

자. JSP에서 MS949를 HTTP header로 보낼 땐 "KS_C_5601-1987" 로 보내게 만들어 달라구 항의 하자;;;
 아니면 우리 프로그래머가 그렇게 되도록 직접 뜯어 고치자;;



결론, 테스트고 모고 귀찮으니 그냥 UTF-8 사용하자 -0-;;



그럼 즐프~~~



p.s 글이 너무 길어 더는 못 쓰겠습니다. --;;
또한 글만 길었지 여러분께 많이 도움이 되는지도 모르겠음. ㅠㅠ (쿠..쿨럭;;)


첫 글에서 KSC5601-1992 를 잘 못 말씀드린것 다시한번 죄송합니다.



이 글에 도움을 주신분.
1. 허광남(heogn)
2. 기타 인터넷 사이트에서 참고자료 제공자...
끝 --;;


============================================================
작성자 : EmotionalBrain
처음 게시된 곳 : www.JavaService.net
============================================================






Update 2002.12.04 13:20

위에서
--------------
먼저 MS949으로 JAVA소스에 확장을 포함하여 작성하고 JAVAC -ENCODING옵션을 KSC5601로 하면
소스작성시 넣은 확장 한글이 깨지지 않습니다.

...
...

JAVA소스는 MS949로 JAVA -ENCODING 은 KSC5601로 주었을 경우가 되겠습니다.
--------------

은 제가 그 당시 만들었던 소스가 없어서 그걸 다시 테스팅 할 수 없지만 "심민우(smwpower)"
님 말씀대로 첨부된 소스로 재 테스팅 해보니 제 테스팅이 잘 못 되었던것 같습니다.

그럼 -encoding을 KSC5601로 하고 String(KSC5601) Byte[]를 편집해서 만들어 놓거나
컴파일된 Class파일에 확장문자를 찾아서 Byte[]를 변경하면 되겠습니다.
- 목적은 KSC5601에 Byte를 수정해서 확장을 넣는 것입니다. -




Update 2002.12.06 19:29
--------------------------

위의 업데이트 사항에서 EUC_KR 상태의 문자를 Byte(CharCode)가 편집된 경우는
3번째 [Comment]에서의 JSP와 DB "EUC_KR"에 관련된 내용에서도 있습니다. ^^;;

Download TTT.java (2331 Bytes) TTT.java (2331 Bytes)
Download TTT.class (2074 Bytes) TTT.class (2074 Bytes)
제목 : Re: mizi linux 에서의 한글
  글쓴이: 허광남(heogn)   2002/12/04 15:05:12  조회수:196  줄수:33
EB 님의 글 잘 읽었습니다. 
재밌는 글이 있어서 퍼옵니다. 
--------------------------------------------------------
1 cp949 또는 uhc(unified hangul code 통합완성형)
1995년 윈도95의 등장과 함께 나타났다.
처음에는 각계각층의 반대에 의해 입력만 막아놨지만 윈도98부터는 자연스럽게 포함이
되면서 일반적으로 쓰이는 글자셋이 되어버렸다.
이전부터 쓰이던 euc-kr이나 완성형에서 쓰이지 못했던 글자들을 마음대로 입/출력 할
수 있게 된것은 환영할 만한 일이나 다른 운영체제나 환경을 전혀 고려하지 않은
것이라 문제의 소지가 컸다.
지금 모질라에서는 euc-kr 글자셋 환경이라도 uhc글자를 읽을 수 있게 바뀌어졌다.
(지금 uhc가 컴퓨터바닥에서 얼마나 큰 영향을 끼치는지 알 수 있는 하나의 예라 할
수 있다)

2 MiziLinux에서 cp949 또는 uhc에 대한 대비
제일 근본적으로 처리할 수 있는 것은 유니코드 글자셋이라 볼 수 있을것이다. See
ko_KR.UTF-8 ( http://linux.mizi.com/wim/ko_5fKR_2eUTF_2d8 )
하지만 우리가 할 일이 너무 많아진다.
glibc의 gconv(iconv)에서도 cp949가 지원이 된다.
전에 농담조로 나온 말이지만 ko_KR.cp949라는 새로운 로케일을 만드는 것도 그럴듯
만한 대안이 될 수 있을것이다.
리눅스환경에서 한글입력기의 표준이다시피 한 아미는 아직 euc-kr밖에 지원을 하지
않는다.
from:
http://linux.mizi.com/wim/_ed_95_9c_ea_b8_80_ed_99_98_ea_b2_bd

---------------------------------
jakarta-seoul project 
jakarta 문서 한글화 사이트
http://www.apache-korea.org

---------------------------------
http://okjsp.pe.kr
제목 : Re: EB(goEB)님에 대한 테스트중 이상한점..
  글쓴이: 심민우(smwpower)   2002/12/05 00:42:16  조회수:197  줄수:60
주신 소스를 가지고 
javac TTT.java 와
javac -encoding ksc5601 TTT.java
로 컴파일 했을 경우 이상이 없었읍니돠..

그런대..
byte[] Source = new byte[] {-80, -95, -97, -27, -120, -28}; 을
byte[] Source = "가잌덁".getBytes(); 로 수정하거나..

strMS949		=	new String(Source,"MS949"); 을
strMS949		=	new String("가잌덁".getBytes(),"MS949"); 로
수정해서 테스트 할땐..

javac TTT.java로 컴파일 하면 출력결과에 이상이 없었읍니돠.

그런대
javac -encoding ksc5601 TTT.java 로 하면
출력결과가 아래와 같읍니돠..

System.getProperty      : MS949

Source Output...
Source                  : -80, -95, 63, 63

String Output...
strMS949                : 가??
strCP949                : 가??
strCP949fix             : 가쌧
strKSC5601              : 가??
strKSC56011992          : 쌰??
strEUCKR                : 가??

Byte[] Output...
byteMS949               : -80, -95, 63, 63
byteCP949               : -80, -95, 63, 63
byteCP949fix            : -80, -95, -101, 81
byteKSC5601             : -80, -95, 63, 63
byteKSC56011992         : -101, 88, 63, 63
byteEUCKR               : -80, -95, 63, 63

또한 
javac -encoding MS949 TTT.java 로 컴파일 하면
이상이 없읍니돠..

설명중 
/******
먼저 MS949으로 JAVA소스에 확장을 포함하여 작성하고 JAVAC -ENCODING옵션을 KSC5601로 하면
소스작성시 넣은 확장 한글이 깨지지 않습니다
********/
이부분이 바뀌지 않았나 싶어서여..
아님 제가 잘못 했나 싶기도 하구여...

참고로 UTF-8은 코드상에서 어떻게 구현 되남여?
혹  strUTF	 = new String(Source, "UTF-8"); 이렇게 하는 게 맞나여?





제목 : Re: Win95와 Win98에서의 문자셋
  글쓴이: EB(goEB)   2002/12/05 03:13:07  조회수:222  줄수:48
"허광남(heogn)" 님께...

제가 아는 정보는 Win95는 MS949가 맞지만(확장통합완성형), Win98은 Unicode 인데요
(KSC5700 표준 한글코드)

그리고 그 때문에 대부분의 글씨가 입력가능한 건데, (아시겠지만 확장통합완성형은
글씨 입력 시스템 제작시 두려움을 안겨줍니다. - 순서 엉망. 그래서 리눅스에서
EUC-KR말고 확장통합완성은 입력기를 만들기 어렵기에 아직 없음)

단지 확장문자는 원시스템인 Unicode에서 MS949(KSC5601)의 확장 영역에 넣어서
표현해줄 수 있는 것이기 때문에 Win98이 MS949인 것 처럼 보일 뿐이지요.

- 여기서 중요한 점은 한글만으로는 Unicode와 MS949의 비교가 안된다는 것입니다.
왜냐면 양쪽모두 한글 "11172"자를 지원하기 때문이죠.
그러므로 한글외의 것으로 비교를 해야 합니다.

MS949는 완전 Unicode안에 포함됩니다. 그래서 제가 Oracle에서 Unicode를
권장하였습니다. Oracle이 Unicode일 때 JAVA에서는 MS949라면 제한 문자가 MS949이기
때문에 사용시 전혀 지장이 없기 때문입니다.

그리고 MS에서 처리하는 방식이 표준에 의거한 것인지 (OS 버젼에 따라.)

또한 JAVA에서의 MS949와 CP949는 현재 차이를 보이는데 그 원인은?

MS측에서도 MS949와 CP949는 다릅니다... ...

CP949는 MS IDE 툴에서는 기본적으로 KS_C_5601-1987로 처리되게 되어 있더군요.
MS949와 CP949를 표준에 정의된 대로인지 문자셋 전체를 까봐야 할 것입니다.
(겉으로 확인할 수 없는 이유는 MS949가 CP949와 다르다 하더라도
CP949가 MS949시스템에서 같은 코드만 같구 있으면 정상인것 처럼 보이기 때문이죠.
그래서 많은 CP949의 디코더, 엔코더를 검증해야하며 관련 자료를 찾아
어떤 것이 진실인지 밝혀야 합니다.)


- 실제 차이가 있다면 Linux등의 시스템에서 MS949도 지원해주었으면 하네요...
그래야 지금 사용할 JAVA에서 MS949가 계속 문제 없이 돌아가죠 --;;


==================================================================================
"심민우(smwpower)" 님께...

o.O?

정말 그러네요? JAVAC 에서 엔코딩을 정상 처리는 군요! 그 당시 제가 테스팅 했던
파일을 지웠는데 (넘 지저분해서) 그럼 그 때 제가 잘 못 했었던것 같습니다.
그럼 String(KSC5601)을 Runtime환경에서 Byte[]를 편집해서 만들어 놓는 방법 밖에 없겠군요.
아니면 KSC5601로 컴파일된 Class파일에 KSC5601문자를 찾아서 Byte[]를 변경하거나요. ^^
시간 나면 이부분 다시 해보도록 하겠습니다.
제목 : Re: [Comment] 이 곳 사이트의 검색이 제대로 이루어 지지 않는 이유
  글쓴이: EB(goEB)   2002/12/07 02:13:20  조회수:1820  줄수:230
---------------------------------------------------------------------------------------------------
저희 나라에서 프로그래머 개인이 알고 있는 지식의 공유가 활발하지 않다고 느끼는 것은 건 저 뿐일까요?

어쩌면 저의 시각이 좁아서 그런 것일 수도 있겠습니다만 -ㅁ-;;
---------------------------------------------------------------------------------------------------



제가 2부의 글에서 말씀 드렸듯 제가 입력한 글이 검색되지 않았었습니다.
그것을 파헤처본 결과를 이 곳에서 다룹니다.

이 글은 여러분에게 Server Page개발/코딩시 주의해야할 점이 무엇이며 가짜 문자를 다룹니다.

이 본문의 주된 내용은 2부의 "결론"
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
나. Oracle에서 KO16KSC5601를 사용할 때 KSC5601 디코딩/엔코딩이 MS949를 무시 하는지 확인해야
 할 것입니다.
 또한, KO16KSC5601이 EUC-KR을 100% 지원해주는가 의문이 들지 않을 수 없습니다.
 적어도 KSC5601에 MS949의 확장문자가 포함되었을 경우에
 EUC-KR로 컨버팅하여보면 특정문자가 깨지기 때문입니다.
 

다. Client가 WebBrowser이고 문서의 문자셋이 Unicode, UTF-8이 아닐경우
 WebBrowser가(어쩌면 OS레벨) HTTP header나 HTML의 META에 정의된 문자셋이 지원하지 않는
 문자가 있을 경우 이를 자동으로 &# + Unicode(Int16)로 변경한다는 것에 주의하셔야 하며
 이에 따른 문제는
 1. WebBrowser외의 곳에서는 한글 변환이 어려우며 100% 처리하기 위해서는 Unicode나 UTF-8를 이용하여
    직접제작한 처리기를 통해야만 표현할 수 있다.
 2. &# + Unicode로 입력된 내용을 검색시 부작용이 많이 있다.
    (이곳두 제가 '덁' 이라고 입력한거 검색 안됨... 제가 이곳 소스를 보진 않았지만
    모두 EUC-KR루 처리했으니 서버에 항상 &# + Unicode로 갔을 것이고 검색어 역시
    그렇게 처리되어 쿼리를 날릴 텐데두 안되는거 보면 이곳 소스한번 보구잡따. --;;
    더욱 재밌는 것은 파일명을 '덁'으루 하면 EUC-KR인 이곳에서 본문은 &# + Unicode로 가지만
    파일명은 제대로 간다. --;; 역쉬 %xx 로 전달되는게 짱이얌 -0-;; %xx 형태 원츄 --b
    - JAVA에서 직접 EUC-KR 스트링의 Byte를 편집할 수 있다면 이것이 쉽게 가능하게 한다.
     문제는 Byte를 편집하였기 때문에 표준에 어긋나는 일이라는거 --;; 그래서 무효 --;;
     또한, 눈에 보이는 '덁'이 실제 '덁'이 아닌 OS가 꺼벙해서 보이는 경우 있다. 
     - 어렵지만 중요한 말)
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
에 해당합니다.

이곳의 게시판의 문자셋은 EUC-KR이니 Form과 QueryString의 내용을 전송할 때
서버에 MS949에 포함된 문자(확장통합완성형)는 (eg. 덁, 횽, 햏)
&# + Unicode(Int16)의 형식으로 날라갑니다. (KSC5601은 문자그대로)

그럼 DB에 역시 그렇게 입력됩니다.
- 어떤한 문자셋으로 변경하건 ASCII문자들(7bit)이기 때문에 깨지지 않을 것입니다.


이제 제가 이곳에서 글을 올리는 과정과 검색하는 과정을 설명해보겠습니다.
(기본이라 다 알고 계신다구요? 그래도 보세요.)

1. 본문에 확장문자인 "아햏햏"을 입력하고 글을 작성합니다.
2. "아햏햏"을 검색합니다.
3. 결과를 지켜 봅니다. -_-;;
 결과는 성공적으로 "아햏햏"을 검색하였습니다.

히~ 검색이 정상으로 되어서 기쁘군요. ^^ 아이 저아 ^.~

그렇게 장난좀 치고 심심해서 "덁"을 검색했습니다.
왜... 왠걸? 제가 1부의 글과 2부의 글에 "덁"을 입력했는데 그 게시물은 검색이 안되고
타인이 올린 "덁"은 검색이 되는 것입니다. @.@ 화... 황당 --;;

이런 --;; 제가 작성해서 올린글은 '왕따'를 당한 것이였습니다. 쩌..쩝...
거..검색이 안 이루어지다뉘 --;;

다음날 이 문제를 까발리기루 했습니다.... 하나부터 열까정 많은 테스팅을 했던것...

이들간의 차이를 분석하니 "덁"은 &# + Unicode로 입력되었었고
"햏"'은 EUC-KR이 아닌대두 "햏" 으로 입력되었던 것입니다.

화...황당;;;
아시는 분도 있으시겠지만 EUC-KR에서의 "햏"은 존재하지 않습니다.
즉, "햏"이 보이긴 하지만 실제 EUC-KR에서의 "햏"은 가짜입니다.
그 가짜를 만드는 방법은 제가 2부에서 언급했듯 현재 문자셋 상태에서 문자셋간 변환하지 않고
직접 Byte(혹은 CharCode)를 수정하면 가능케 합니다.

2부의
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
"다". 의 내용중
    더욱 재밌는 것은 파일명을 '덁'으루 하면 EUC-KR인 이곳에서 본문은 &# + Unicode로 가지만
    파일명은 제대로 간다. --;; 역쉬 %xx 로 전달되는게 짱이얌 -0-;; %xx 형태 원츄 --b
    - JAVA에서 직접 EUC-KR 스트링의 Byte를 편집할 수 있다면 이것이 쉽게 가능하게 한다.
     문제는 Byte를 편집하였기 때문에 표준에 어긋나는 일이라는거 --;; 그래서 무효 --;;
     또한, 눈에 보이는 '덁'이 실제 '덁'이 아닌 OS가 꺼벙해서 보이는 경우 있다. 
     - 어렵지만 중요한 말)
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
내용에 해당합니다.

그럼 이제 원인을 알게 되었습니다. 서버에 전송될 때 EUC-KR형태이지만 어떤 문제로 인하여
&# + Unicode형태로 전달 되지 않는 다는 것!

하지만 여기서 이상한 점이 있습니다. 제가 작성했던 "덁"은 EUC-KR형태라 &# + Unicode형태로
서버로 갔는데 왜 "햏"은 처리되지 않고 가는 것일까? (--?)

그래서 게시물을 또 다시 작성하였는데 본문에 "덁", "햏" 모두 입력했습니다.
근데 역시 &# + Unicode 형태가 처리 되지 않는 것입니다.

이런 말도 안돼는 --;; 아까 "덁"으로 검색됐던 타인의 게시물을 봐도 &# + Unicode 형태가
아니였습니다.

타 사이트에서 EUC-KR로 처리된 것은 어떻게 처리될까아?
그래서 그곳에 가서 테스팅 했더니 "덁", "햏" 모두 &# + Unicode 처리로 되어 정상으로
동작하더란 것입니다.

그럼 이제 남은것은 웹브라워의 버그와, 이곳 사이트의 HTML Source의 이상 문제 였는데...

일단 제가 이곳에 입력했던 "덁" 처리가 "&# + Unicode" 로 처리된 게시물과
"덁"이 짜가 "덁"으로 처리된 게시물의 차이를 (아시겠지만 엄청난 분량임;;;) 확인시작후

10초만에 제가 입력한 글들의 차이를 발견하였습니다. (의외로 빨리 찾음 --v)

그 차이는 바로 1부에서 설명했던
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
참고.
'葶' <- 이 문자는 Unicode와 UTF-8문자셋이 아니면 깨집니다.
WebBrowser에서 보는 데는 지장 없습니다. 지금도 보이시죠?
이 '葶'는 서버에 전달 될 때 &#33910; 이렇게 변형되어 전달 됩니다.
(지금 이 게시판에서 WebBrowser의 소스보기를 해도 알 수 있습니다.)
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
"葶" 요 문자였습니다.

즉, 본문에 "葶"과 "덁", "햏"등의 확장문자를 포함하면 확장문자는 "&# + Unicode"
로써 정상처리된다는 것이였습니다. (어..엄청 황당;;)
(본문에 "葶"만 딸랑 하나 넣으면 이 것도 정상처리 되지 않습니다.)
그러니 저의 글에 있던 "덁"은 검색되지 않을 수밖에 --;;
본문엔 "&# + Unicode"이렇게 입력되고 검색어는 "%88%E4"(짜가 "덁") 로 전달되었으니...

그렇담 왜 이 곳 사이트에서만 그런일이 발생할 까?

그래서 이곳 사이트의 HTML Source를 분석하니...

이곳, 웹페이지는 HTML의 META TAG에 CharSet을 포함하지 않았습니다.
다만, Server에서 Header에 "Content-Type: text/html; charset=euc-kr" 를 보냅니다.
이 때문에 IE(WebBrowser)는 인코딩을 "한국어(EUC)"라고 인식하게 되는 것입니다만...

이 때, IE에서도 인코딩을 "한국어(EUC)"라고 표시하고,
또 Jscript를 이용하여 현재 보여지는 화면의 인코딩을 확인하여도 "euc-kr"이라고 인식을 하지만

IE의 버그 때문에 정상처리 되지 않았던 것이였습니다.


결론.
***************************************************************************************************
가. META TAG에 반드시 CharSet을 포함해야한다.
    - Unicode, UTF-8형태의 CharSet에서는 있어도 그만 없어도 그만인지는 확인하지 않았음;;;

	EUC-KR환경은 당연포함해야하지만
	
	KSC5601환경의 경우 당연 서버에서 모두 확장문자는 정상처리 하니 문제가 없겠지만
	위에서 언급한 "葶"는 META TAG에도 KSC5601을 포함하여야만 정상처리 되었고
	그렇지 않을 시엔 "匪" 이 문자가 이를 대신하였다. (짜가가 판치는 세상;;)
	그러므로 META TAG는 필수적으로 처리되어야 하며
	또한 META TAG앞에 다른 어떠한 화면에 출력되는 문자는 있어서는 안되었다.
	
	예로써 다음과 같은 환경엔 META TAG가 있으나 마나였다.
	---------------------------------------------------
	먼저 출력해본다.
	<html>
	<head>
	<meta http-equiv="Content-Type" content="text/html; charset=EUC-KR">
	...
	---------------------------------------------------
	즉, 위의 환경엔 확장문자도 EUC-KR기준이 아닌 KSC5601(MS949)기준으로 처리된다.

***************************************************************************************************
나. DB의 "KO16KSC5601" 과 JAVA EUC-KR의 궁합.

 2부에선 언급했던 "나"의 내용

『나. Oracle에서 KO16KSC5601를 사용할 때 KSC5601 디코딩/엔코딩이 MS949를 무시 하는지 확인해야
 할 것입니다.
 또한, KO16KSC5601이 EUC-KR을 100% 지원해주는가 의문이 들지 않을 수 없습니다.
 적어도 KSC5601에 MS949의 확장문자가 포함되었을 경우에
 EUC-KR로 컨버팅하여보면 특정문자가 깨지기 때문입니다.』

 은 이곳 JAVAservice.net DB의 환경이 "KO16KSC5601" 이라면 이곳 본문에서 실험해봐서
 알겠지만 EUC-KR의 잘 못 된 내용까지도 DB에 모두 넣을 수 있다는 결론이기 때문에
 MS949를 "KO16KSC5601"에 넣어도 된다는 것이다.(이원형님이 우려하시던 내용)
 
 다만, EUC-KR에서 확장문자는 실질적으로 지원하지 않는 것이기 때문에
 String strNEW = new String(EUCKRsource.getBytes("EUC_KR"), "Some...");
 으로 변형해서는 절대로 그 확장문자는 보존할 수 없음에 주의하고 트릭을 사용하고 싶다면
 비록 현 문자가 EUC_KR (혹은 JSP의 @Page에서 EUC_KR이지만) 이긴해도
 String strNEW = new String(EUCKRsource.getBytes("MS949"), "Some...");
 라고 뻥을 처주는 트릭을 사용하여야만 EUC_KR에 입력된 가짜 확장문자도 복구할 수 있다.
 ※ 주의! 이 트릭은 반드시 IE WebBrowser에서 넘겨받은 값만 100% 오류없이 처리할 수 있습니다.
***************************************************************************************************
다. Navigator는 확장어 처리가 완전 엉뚱하게 된다.
 (다양한 셋팅으로 시도 하였으나, 본좌는 방법이 없다는 결론을 내었다. --)
***************************************************************************************************



테스팅 환경. WinXP, IE6, Navigator 7.0



이글의 모든 내용은 많은 테스팅을 거쳤으며 많은 증거들이 있으니 믿으셔도 됩니다. --;;



이 곳에 언급된 검색의 문제점은 이 내용 파헤치기 전 자체테스팅한 

검색 엔진의 문제 20% 정도에 해당하는 내용이 되네요...

그 테스팅 결과가 어마마해서뤼.. 어떻게 글을 작성해야할 지 --;;



---------------------------------------------------------------------------------------------------
미약한 저의 글 읽어 주셔서 감사드리며, 지식 공유하고 서로 부족한점 매꾸워 줍시다. ^_^

EmotionalBrain...
---------------------------------------------------------------------------------------------------




---------------------------------------------------------------------------------------------------
Update - 2002.12.06 19:42

기존
"가. META TAG에 반드시 CharSet을 포함해야한다. - Unicode, UTF-8은 있어도 그만 없어도 그만;;;"
을
"가. META TAG에 반드시 CharSet을 포함해야한다.
    - Unicode, UTF-8형태의 CharSet에서는 있어도 그만 없어도 그만인지는 확인하지 않았음;;;"
로 변경.
(죄송합니다. 문서를 몇번이고 읽어본뒤 올려야 했었는데)
---------------------------------------------------------------------------------------------------
제목 : Re: 그러면 "나"의 결론 DB부분은 꼭 검증해야...
  글쓴이: EB(goEB)   2002/12/07 21:50:52  조회수:234  줄수:66
전 확장자만 cgi 인줄 알았는데...

실질적으로 JSP 이거......


***************************************************************************************************
나. DB의 "KO16KSC5601" 과 JAVA EUC-KR의 궁합.

 2부에선 언급했던 "나"의 내용

『나. Oracle에서 KO16KSC5601를 사용할 때 KSC5601 디코딩/엔코딩이 MS949를 무시 하는지
 확인해야 할 것입니다.
 또한, KO16KSC5601이 EUC-KR을 100% 지원해주는가 의문이 들지 않을 수 없습니다.
 적어도 KSC5601에 MS949의 확장문자가 포함되었을 경우에
 EUC-KR로 컨버팅하여보면 특정문자가 깨지기 때문입니다.』

 은 이곳 JAVAservice.net DB의 환경이 "KO16KSC5601" 이라면 이곳 본문에서 실험해봐서
 알겠지만 EUC-KR의 잘 못 된 내용까지도 DB에 모두 넣을 수 있다는 결론이기 때문에
 MS949를 "KO16KSC5601"에 넣어도 된다는 것이다.(이원형님이 우려하시던 내용)
***************************************************************************************************

라는 부분이 이곳 DB환경이 "KO16KSC5601" 두 아니구 JSP 두 실제 아니니

이것은 검증해야 되겠네요....

(다른 내용은 모두 Client 부분이니까 이미 검증 되었고...
Socket상으로 전달되는 값도 확인했고...)


단순히 폼값만 받아서 DB에 저장해보면 돼는데...


아햏햏 으로 --;;


환경이 안되니 원...

오라클을 --;;


제가

"이곳 JAVAservice.net DB의 환경이 "KO16KSC5601" 이라면"

이라하였으니 다행히 제가 문법을 정확히 썼네요.... (글들에서 오타두 많은 편이였는데..)


테스팅 환경 돼시는분 부탁드립니다. ㅠㅠ



p.s 전 cgi(CGI 말고), php엔 관심이 없는지라 ... 분석할 의향이 --;;
굳이 분석할 필요도...

META TAG의 CHARSET 넣구 이미 만들어진 파일(DB)의 내용을 전부 바꾸시면 되니깐... ^^
(문자셋을 뭐로 하건간에 변경해야 함)

EUC-KR로 했지만 KSC5601을 흡수 하는걸 봐서 KSC5601로 해도 돼겠습니다.
다만 Unicode, UTF-8을 cgi에서 처리할 수 있는지는... 안해봐서..


p.s 2 여러분 META TAG 꼭 쓰세요.... --;; 안그럼 먼 훗날 후회해요 --;;
기회가 된다면 검색엔진에서 META TAG의 문자셋의 중요성을 (반다시!!)
언급할 까 합니다만.... 언제가 될지..

세상 이렇게 바쁘게 살아서야 원.. --;;
제목 : Re: 메타태그
  글쓴이: 서민구(4baf)   2002/12/08 06:09:42  조회수:244  줄수:46
캐릭터셋에 대해서 너무나 모른상태라서 이해가 안가는 것 몇가지를
질문드리겠습니다.

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

는 있으나 마나라고 하셨는데

그렇다면, 

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

이런 방식으로 해야한다는 말씀이신가요?

두번째로 

이곳, 웹페이지는 HTML의 META TAG에 CharSet을 포함하지 않았습니다.
다만, Server에서 Header에 "Content-Type: text/html; charset=euc-kr" 를 보냅니다.
이 때문에 IE(WebBrowser)는 인코딩을 "한국어(EUC)"라고 인식하게 되는 것입니다만...

라고 말씀하셨는데,

이 얘기는 jsp의 @page태그에서 contentType을 지정해야하고 동시에
meta 태그를 지정해야한다는 말씀으로 이해하면 될런지요...

세번째로 utf-8을 쓰라고 하셨는데 정작 리눅스에서 LANG을 utf-8로
지정할 수 있는건가요? 자바에서 컴파일 및 실행을 utf-8로 하면 되기야
하겠지만 리눅스에서 텔넷으로 들어가서 utf-8인코딩으로 문자를 입력하려면
어떤 환경을 써야하나요? 울트라 에디트로 편집하고 ftp로 올리는건
힘든것 같은데요..

마지막으로
전체적으로 내용을 정리했으면 하는데...

제가 했으면 좋겠지만 , 제가 요즘 시간이 안나서 저는 여력이 없군요... 
이달말이 되야 시간이 나는 관계로 이렇게 직접 해보지도 않고 질문을
드립니다.. 죄송하네요.

-----------------------------------------------
서민구 (NO---SPAM4baf@orgio.net)
제게 메일을 보내시려면 이메일 주소의 'NO---SPAM'을
제거하시고 메일을 보내주세요.
제목 : Re: 서민구님께~
  글쓴이: EB(goEB)   2002/12/08 12:09:14  조회수:239  줄수:174
제가 말씀 드린 것은
*--------------------------------------------------------------------------------------------------
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=EUC-KR">
--------------------------------------------------------------------------------------------------*
이 아니구요.

위에서 말씀 드렸듯
*--------------------------------------------------------------------------------------------------
먼저 출력해본다.
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=EUC-KR">
...
--------------------------------------------------------------------------------------------------*
요겁니다.
위에 EUC-KR 앞에 출력된 문자 보이시죠? "먼저 출력해본다." 라는 글귀
그걸 가르킨 겁니다.

다시 한번 말씀드리자면 CharSet 정의 앞에 어떠한 것도 화면에 출력되어서는 안된다는 것입니다.

즉,
*--------------------------------------------------------------------------------------------------
<input type=button>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=EUC-KR">
...
--------------------------------------------------------------------------------------------------*
은 정상처리 되지 않으며

*--------------------------------------------------------------------------------------------------
<input type=hidden>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=EUC-KR">
...
--------------------------------------------------------------------------------------------------*
은 정상처리 된다는 것이죠.

간혹 CharSet 앞에 먼저 출력하시는 분이 있어서 설명드린 거구요.

왜 CGI들을 디버깅 할 때도 그런경우가 있짜나요.. 괜히 입력받은값 확인 한답시구.
*--------------------------------------------------------------------------------------------------
<%폼이나 쿼리스트링값 디버깅을 위해 출력하기%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=EUC-KR">
...
--------------------------------------------------------------------------------------------------*
라는 형식 말입니다.

이런 경우를 조심하잔 것이죠.

그러므로 CharSet을 설정하기전엔 어떠한 것도 화면에 출력해서는 안됩니다.
(Client측의 버그 때문에 --;;)




그리고 JSP의(엄밀히 이런류의 CGI 모두해당. eg. ASP, ASP.NET)
@page에도 넣어야 하는게 맞습니다.

그래야 소스를 제대로 읽을 수 있습니다. (javac -encoding과 같은 맥락입니다.)


*--------------------------------------------------------------------------------------------------
세번째로 utf-8을 쓰라고 하셨는데 정작 리눅스에서 LANG을 utf-8로
지정할 수 있는건가요? 자바에서 컴파일 및 실행을 utf-8로 하면 되기야
하겠지만 리눅스에서 텔넷으로 들어가서 utf-8인코딩으로 문자를 입력하려면
어떤 환경을 써야하나요? 울트라 에디트로 편집하고 ftp로 올리는건
힘든것 같은데요..
--------------------------------------------------------------------------------------------------*
라는 질문에 대한 답변은 불행히도...

UTF-8관련부분은 한글환경에선 리눅스에서는 어떠한 것도 해당하지 못합니다.

제가 아는 바로는 리눅스에서 UTF-8한글 입력도 안되고...
그렇다고 EUC-KR이나 KSC5601이나 MS949등등을 UTF-8로 변경해주는 툴도 없으니까요..
UTF-8로된 한글을 출력해주는 환경은 몇가지 제공된다지만 전혀 쓸모 없는 기능이라는;;;
(입력두 안되는데 어케 코딩을 해요 --;; 글타구 변환기두 없꽁)


그러니 JAVA를 이용해서 제작하심이 ^^;;
 - 그냥 간단히 InputStream과 OutputStream으로만으로도 할 수 있떠여

그리구 제가 언급한
*--------------------------------------------------------------------------------------------------
일반적으로 프로젝트의 모든 소스는 엔코딩 형식이 동일해야 하겠죠?
만일 기존 소스가 있는데 다르다면 현 프로젝트와 맞추어야 할 텐데...
쉽게 구할 수 있는 툴은 UltraEdit가 정도가 되겠네요 저는 v9.10을 가지고 있고
File -> Conversions에 있습니다. 이 곳에서 원하는 형태로 가능하겠습니다.

-단, 한글들의 문자셋변환 툴은 아직 보질 못했음. 혹시 보신분 손 ^^/
 한글에서 하위변환은 완벽히 안되므로 이를 염두해야함.
--------------------------------------------------------------------------------------------------*
라고 했듯

한글 변환은 제대로 처리되지 않더라구요.
(특히 왜 자꾸 UTF-8과는 어쩌다가 되는지 ㅠㅠ)

좋은 플그램 구하는 것보다 JAVA로 자작하는 것이 더 빠를 겁니다.
(그냥 작성한 내용 자동으로 UTF-8로 변환해주는 거)

-JBuilder로 작업하신다면 좋은 결과가 있을 수도 있겠네요
 * 참고. JBuilder의 프로젝트 옵션에 있습니다.




그리구 저...정리 라구요? --?

여기에 올린 내용은 문자셋 문제의 40% 정도 밖엔 해당 되지 않는데요 --;;
(많은 시간을 소비하였지만 애석하게도 아직 이것 밖엔 정리되지 않았기 때문에
완전한 모습이 나오기 전엔 현재 정리가 어렵습니다.)


제가 UTF-8 형식을 추구하는 진정한 이유와, 목적은 여지껏 설명했던 부분 속에 있어요!
겉에 드러나 있는 단순한 문제가 아니구요.

(현실적으로 가능만 하다면야 UTF-8이상의 것을 써야 하지만)

제가 첨부터 자세한 설명과 이곳 사이트의 검색 문제를 올린 이유는 왜 UTF-8이여야만 하는지를
내면적으로 나타내려 했기에 그런건데~
(내면을 직설적으로 표현 해봐야 그냥 결론만 날 뿐이겠네요
항상 그렇듯 그냥 그렇게 하라구 알려주고 이유는 설명않고 --;;)


굳이 표면적으로 말하자면
검색을 한다고 했을 때

"내가 입력한 검색어가 과연 검색어 일까?" <= 무지 어렵지만 상당히 의미있는말...

수수께끼라여기시는 분들은 문자셋 이해를 아직 못하신 것일 테고
아시는 분들이라면 이것은 상당한 의미를 지닌말로 해석하시겠네요.


요 수수께끼를 정확히 이해하셨다면 전세계에 있는 웹 검색엔진은 (Yahxx, Emxx, Hanxxx, 등등)
새롭게 만들어져야 한다는 걸 아실 겁니다. ^^
(최소한 수정은 불가피 합니다.
특히 몇몇 서버는 DB내용 자체를 바꿔야 한다는... 쩌비... <- 증거 있습니다. --;;
Yahxx도 DB를 바꿔야 --;;)

하지만 딱 한군데는 꼭(UTF-8초과 필요시만 아니라면. 현재 필요한 곳이 있던가요? 어느나라였더라?)
그럴 염려는 없겠더군요 ^^ 어딜까요? ^.~
(역시 그 곳은 세계 최고라 하여도 손색이 없습니다. 유명한.. GxxGxx)

흥미롭지 않나요? ㅡㅡ;;


저 역시 언능 정리는 하고 싶지만
전 아마 1개월 이후에나 가능할 것 같습니다.
지금 하는 작업이 저에게 중요하기 때문에

이 문제 저를 흥분시키지만 여지껏 테스팅한거 대충 메모만 한뒤 잠시 접으렵니다.


p.s
현재의 검색엔진에는 EUC-KR이나 KSC5601이 더 났지만 어디까지나 아주짧은 미래까지만
해당합니다.


p.s 2
나머지 60%를 언제 쯤 정리 하게 될런지.. ㅠㅠ


p.s 3
제가 테스팅 환경이 되지 않는 부분은 서로 해주었으면 합니다.
그래야 추후 정리할 때 깔끔히 할 수 있지 않겠어요?
어떤 사람이 정리할 진 모르지만


즐프 하십시오. ^^

'web' 카테고리의 다른 글

java.net.NoRouteToHostException: No route to host 해결  (0) 2007.09.04
웹스나이퍼  (0) 2007.09.04
Sitemesh에서 여러개의 configuration 파일을 읽게 하기  (0) 2007.08.24
Sitemesh 참조자료  (0) 2007.08.24
Sitemesh #4 Sitemesh 팁  (0) 2007.08.24
Posted by '김용환'
,

 

이클립스에서 Team Sync with Repository를 사용할때, 스페이스를 무시할 수 있다.

 

general 에서 compare/patch를 메뉴를 선택하여 ignore white space를 선택하면 된다.

Posted by '김용환'
,

 

퍼포먼스 정보를 얻기 위해서는 다음의 정보가 필요하다..


1. 전체 디스크 사용량 : 테이타 (*.MYD)+ 인덱스(*.MYI)
2. 테이블 개수 : show tables
3. 데이터 사용량 : *.MYD 혹은 show table status 에서 DATA size
4. 인덱스 사용량 : *.MYI 혹은 show table status 에서 INDEX size
5. 아카이브 사용량 : 데이터 디렉토리에서 binlog 사이즈(hostname-bin.000???)
6. 주간 데이터 증가량 : 전체 디스크 사용량의 차이
7. 테이블 증가수 : show table status 에서 create_time 확인
8. 평균 초당 트랜잭션 수 : mysqladmin 에서 status 값 확인
9. 평균 초당 커넥션 수 : mysqladmin 에서 status 값 확인 

 

mysqladmin status에 대해서 잘 몰랐는데, 많이 배우고 싶다

 

출처:

http://linux-sarang.net/board2/bbs_read.php?bbs=study&page=4&nownum=72&num=727

 

▶ 작성자 : 운비(unbinara@dreamwiz.com)
▶ 작성완료일 : 2001년 12월 8일(토)
▶ 배포권한 : 상관없음(작성자만 표시해 주기 바람 <-- 예의상..^^;)
▶ 참고사항 : 번역시 100% 완벽하지는 않음
[mysqladmin]
▷mysqladmin -u root -p proc stat(=processlist) --> 서버에 현재 활동중인 threads상태보기
Enter password:
+------+------+-----------+----+---------+------+-------+------------------+
| Id | User | Host | db | Command | Time | State | Info |
+------+------+-----------+----+---------+------+-------+------------------+
| 3704 | root | localhost | | Query | 0 | | show processlist |
+------+------+-----------+----+---------+------+-------+------------------+
Uptime: 281302 Threads: 1 Questions: 27330 Slow queries: 0 Opens: 1771 Flush tables: 1 Open tables: 64 Queries per second avg: 0.097

▷mysqladmin status

Uptime : the MySQL server 시작된 후 현재까지 시간 (초)
Threads : 현재 디비서버에 연결된 유저수
Questions : 서버시작후 지금까지 요청된 쿼리수
Slow queries : --log-slow-queries[=file_name] option로 시작된 서버가 variables에 지정된
long_query_time seconds시간보다 큰 쿼리시간을 가진 요청수
Opens : 서버가 시작된 후 현재까지 열렸던 테이블 수
Flush tables : flush ..., refresh, and reload commands된 수
Open tables : 현재 열려 있는 테이블 수
Queries per second avg : 평균 초당 쿼리수

Memory in use :the mysqld code에 의해 직접 할당된 메모리 (only available when MySQL is compiled with --with-debug=full).
Max memory used : the mysqld code에 의해 직접 할당된 최대메모리 (only available when MySQL is compiled with --with-debug=full).





▷mysqladmin -u root -p ping -->디비서버가 살아있는지 확인
Enter password:
mysqld is alive





▷mysqladmin -u root -p extended-status(※mysql>show stauts)
+--------------------------+-----------+
| Variable_name | Value |
+--------------------------+-----------+
| Aborted_clients | 0 |
| Aborted_connects | 7 |
| Bytes_received | 1273369 |
| Bytes_sent | 334385278 |
| Connections | 3656 |
| Created_tmp_disk_tables | 0 |
| Created_tmp_tables | 0 |
| Created_tmp_files | 0 |
| Delayed_insert_threads | 0 |
| Delayed_writes | 0 |
| Delayed_errors | 0 |
| Flush_commands | 1 |
| Handler_delete | 4 |
| Handler_read_first | 1766 |
| Handler_read_key | 3525 |
| Handler_read_next | 2052 |
| Handler_read_prev | 1859 |
| Handler_read_rnd | 757854 |
| Handler_read_rnd_next | 1975607 |
| Handler_update | 3190 |
| Handler_write | 36 |
| Key_blocks_used | 245 |
| Key_read_requests | 7473 |
| Key_reads | 245 |
| Key_write_requests | 386 |
| Key_writes | 209 |
| Max_used_connections | 1 |
| Not_flushed_key_blocks | 0 |
| Not_flushed_delayed_rows | 0 |
| Open_tables | 64 |
| Open_files | 128 |
| Open_streams | 0 |
| Opened_tables | 1768 |
| Questions | 27128 |
| Select_full_join | 0 |
| Select_full_range_join | 0 |
| Select_range | 22 |
| Select_range_check | 0 |
| Select_scan | 7694 |
| Slave_running | OFF |
| Slave_open_temp_tables | 0 |
| Slow_launch_threads | 0 |
| Slow_queries | 0 |
| Sort_merge_passes | 0 |
| Sort_range | 38 |
| Sort_rows | 757848 |
| Sort_scan | 5121 |
| Threads_cached | 0 |
| Threads_created | 3655 |
| Threads_connected | 1 |
| Threads_running | 1 |
| Uptime | 279770 |
+--------------------------+-----------+


▷mysqladmin -u root -p variables(※mysql>show valiables)
+-------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Variable_name | Value |
+-------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ansi_mode | OFF |
| back_log | 50 |
| basedir | /usr/local/mysql/ |
| binlog_cache_size | 32768 |
| character_set | euc_kr |
| character_sets | euc_kr dec8 dos german1 hp8 koi8_ru latin1 latin2 swe7 usa7 cp1251 danish hebrew win1251 estonia hungarian koi8_ukr win1251ukr greek win1250 croat cp1257 latin5 |
| concurrent_insert | ON |
| connect_timeout | 5 |
| datadir | /usr/local/mysql/data/ |
| delay_key_write | ON |
| delayed_insert_limit | 100 |
| delayed_insert_timeout | 300 |
| delayed_queue_size | 1000 |
| flush | OFF |
| flush_time | 0 |
| have_bdb | NO |
| have_gemini | NO |
| have_innobase | NO |
| have_isam | YES |
| have_raid | NO |
| have_ssl | NO |
| init_file | |
| interactive_timeout | 28800 |
| join_buffer_size | 131072 |
| key_buffer_size | 8388600 |
| language | /usr/local/mysql/share/mysql/korean/ |
| large_files_support | ON |
| locked_in_memory | OFF |
| log | OFF |
| log_update | OFF |
| log_bin | OFF |
| log_slave_updates | OFF |
| long_query_time | 10 |
| low_priority_updates | OFF |
| lower_case_table_names | 0 |
| max_allowed_packet | 1048576 |
| max_binlog_cache_size | 4294967295 |
| max_connections | 100 |
| max_connect_errors | 10 |
| max_delayed_threads | 20 |
| max_heap_table_size | 16777216 |
| max_join_size | 4294967295 |
| max_sort_length | 1024 |
| max_tmp_tables | 32 |
| max_write_lock_count | 4294967295 |
| myisam_recover_options | OFF |
| myisam_sort_buffer_size | 8388608 |
| net_buffer_length | 16384 |
| net_read_timeout | 30 |
| net_retry_count | 10 |
| net_write_timeout | 60 |
| open_files_limit | 0 |
| pid_file | /usr/local/mysql/data/3egg.com.pid |
| port | 3306 |
| protocol_version | 10 |
| record_buffer | 131072 |
| query_buffer_size | 0 |
| safe_show_database | OFF |
| server_id | 0 |
| skip_locking | ON |
| skip_networking | OFF |
| skip_show_database | OFF |
| slow_launch_time | 2 |
| socket | /tmp/mysql.sock |
| sort_buffer | 2097144 |
| table_cache | 64 |
| table_type | MYISAM |
| thread_cache_size | 0 |
| thread_stack | 65536 |
| timezone | KST |
| tmp_table_size | 1048576 |
| tmpdir | /tmp/ |
| version | 3.23.32 |
| wait_timeout | 28800 |
+-------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+


[그외]
mysqladmin create [databasename] : Create a new database.
mysqladmin drop [databasename] : Delete a database and all its tables.
mysqladmin flush-hosts : Flush all cached hosts.
mysqladmin flush-logs : Flush all logs.
mysqladmin flush-tables : Flush all tables.
mysqladmin flush-privileges : Reload grant tables (same as reload).
mysqladmin kill [id(,id,...)]: Kill mysql threads.
mysqladmin password : Set a new password. Change old password to new-password.
mysqladmin reload : Reload grant tables.
mysqladmin refresh : Flush all tables and close and open logfiles.
mysqladmin shutdown : Take server down.
mysqladmin slave-start : Start slave replication thread.
mysqladmin slave-stop : Stop slave replication thread.
mysqladmin version : Get version info from server.







▷ mysqladmin -u root -p variables(※mysql>show valiables)
------------------------------------------------------------------------------------------------------------------------------
ansi_mode
on으로 되어있으면 --ansi로 시작된 것이다(Running MySQL in ANSI Mode를 참조하고,설명은 다음에)

back_log
mysql이 가지는 현저한 커넥션요청수
메인 mysql 스레드가 짧은시간에 매우 많은 커넥션이 일어났을때 생기며, 이때 그러한 커넥션을 체크하고
새로운 스레드를 생성시키기위해 생기지만 이러한 현상은 극히 적게 발생하는 것이다.
back_log는 mysql이 순간적으로 새로운 요청에 답변하는 것을 멈추기전 짧은 시간동안 얼마나 많은 요청들이
쌓일 수있는지 알려준다. 만약, 짧은 시간동안 많은 수의 커넥션이 생길것을 예상한다면 back_log를 증가시켜주어야 한다
back_log를 다른말로 표현하면 들어오는 TCP/IP커넥션에 대해서 귀기울이는 큐의 수이다.
사용자OS마다 이러한 큐의 사이즈에 한계가 있다. 따라서, 자신들이 가지고 있는 OS의 메뉴얼을 참고하여
최대치가 얼마인지 확인하여야 한다. 또한, 자신의 OS시스템이 가지는 한계치보다 높게 back_log를 가지면 효가가 없다.

basedir
mysql이 설치된 기본 디렉토리

--------------------------------------------------------------------------------------------------------------
bdb_cache_size
bdb테이블에 대한 rows와 인데스 케쉬에 할당된 버퍼
bdb테이블을 사용하지않는다면 시작할 때 --skip-dbd로 시작해야 이러한 케쉬에 대해 메모리를 낭비하지 않는다

bdb_log_buffer_size
dbd테이블의 인덱스와 rows를 케쉬하는데 할당된 버퍼
bdb테이블을 사용하지않는다면 시작할 때 --skip-dbd로 시작해야 이러한 케쉬에 대해 메모리를 낭비하지 않는다

bdb_home
--dbd-home옵션으로 설치했을대 나타나는 버클리디비 홈디렉토리

bdb_max_lock
긴 트랙잭션이나 mysql이 쿼리계산시에 많은 rows를 검사해야만 할때, lock테이블이 12개의 에러혹은 lock이 가능하지 않는
dbd타입의 에러가 발생되면 bdb_max_lock를 증가시켜야한다. 디폴트는 1000이며 bdb테이블을 활성화시킬수있다

bdb_logdir
--bdb-logdir 옵션을 주었을때 나타난다

bdb_shared_data
--bdb-shared-data을 사용하면 on된다

bdb_tmpdir
--bdb-tmpdir옵션을 주었을 때

※ 위는 버클리디비를 사용하였을 때 나타나는 values이다
--------------------------------------------------------------------------------------------------------------

binlog_cache_size.
트랜젝션동안 binary log에 대해 sql문을 잡고있는 케쉬사이즈
큰 다중문 트랜젝션을 빈번히 사용한다면, 이 사이즈를 높게잡아 퍼포먼스를 증가시킬수있다
자세한 것은 BEGIN/COMMIT/ROLLBACK Syntax를 참조하라

character_set
디폴트 문자셋(현재 세팅한)

character_sets
지원하는 모든 문자셋

concurrent_inserts
디폴트로 on되어있으면 mysql은 select하는 동안에 동시에 myisam테이블에 insert를 사용할 수있도록한다
시작시 off로 하려면 --safe or --skip-new로 해주어야 한다

connect_timeout
mysqld server가 Bad handshake에 반응하기전 연결된 패킷에 대해 기다리는 시간(초)

datadir
mysql 데이타가 들어있는 홈디렉토리

delay_key_write
(디폴트로 )on되어있으면 mysql은 delay_key_write option을 테이블생성에 honor(??)한다
이 옵션과 함께 테이블에 대한 key buffer는 모든 인덱스 update시에 flush하지 않고 테이블이 잠겨질때만 flush한다
이것은 key가 많을때 쓰기 속도를 높일 수있으나, 이를 사용하려면 myisamchk --fast --force함께 모든 테이블에 자동 체크를
추가하여야 한다. mysqld를 --delay-key-write-for-all-tables option으로 시작하면, 모든 테이블들이 마치 the delay_key_write option
으로 생성된 것으로 취급된다.
mysqld를 --skip-new or --safe-mode로 시작함으로써 이런 flag를 없앨수 있다.


delayed_insert_limit
delayed_insert_limit rows를 삽입한 후에 INSERT DELAYED handler는 어떠한 select문들이 해결되지 않았는지 체크한다
만약 해결되지않은 select문들이 있다면 실행한다.

delayed_insert_timeout
INSERT DELAYED thread는 얼마나 오래동안 종료되기전 insert문들을 기다려야 하는지를 나타낸다.

delayed_queue_size
INSERT DELAYED를 처리하는데 할당된 rows의 queue사이즈
queue가 풀되면 INSERT DELAYED를 행하는 클라이언트는 queue에 다시 여유가 생길때까지 기다릴 것이다.

flush
--flush option으로 시작된 mysql은 on으로 표시된다

flush_time
non-zero value로 세팅되면 매번 flush_time시 모든 테이블이 닫히는 것을 기다린다.(디스크에 resources and sync things를 비우기 위해)
작은 리소스를 가지는 Win95, Win98에서 이러한 옵션을 사용하기를 추천한다.

ft_min_word_len
FULLTEXT index에 포함된 최소문자길이
이 값을 바꾼후에는 FULLTEXT index를 재생성해야만 한다

ft_max_word_len
FULLTEXT index에 포함된 최대문자길이
이 값을 바꾼후에는 FULLTEXT index를 재생성해야만 한다

ft_max_word_len_sort
REPAIR, CREATE INDEX, or ALTER TABLE에서 빠른 인데스 재생성에 사용되는 FULLTEXT index의 최대문자길이
문자길이가 길면 길수록 늦게 insert된다.
thumb규칙은 다음과 같다.
ft_max_word_len_sort를 증가시킬때 mysql은 temporary files을 더크게 생성하고(따라서, disk I/O로 인해 프로세스가 줄어든다)
one sort block에 더적은 keys를 둘것이다(이것은 효율성을 저하시킨다)
ft_max_word_len_sort가 너무 작을 때, 대신 mysql은 인덱스에 많은 단어들을 천천히 insert하지만, 짧은 단어들은 매우 빠르게 입력한다.
이것은 단지 EPAIR, CREATE INDEX, or ALTER TABLE동안 인덱스를 재성시 적용된다

ft_boolean_syntax
List of operators는 MATCH ... AGAINST(... IN BOOLEAN MODE)의해 지원된다. MySQL Full-text Search참조

have_innodb
InnoDB tables을 지원할 시에 YES가 되고, --skip-innodb사용하면 disalbed된다

have_bdb
Berkeley DB tables을 지원할 시에 YES가 되고, --skip-bdb사용하면 disalbed된다

have_raid
mysqld가 RAID option을 지원하면 YES

have_openssl
mysql이 the client/server protocol상에서 SSL (encryption:암호화)를 지원하면 YES로 나타난다

init_file
서버를 시작할때 --init-file option를 지정할 때 나타는 파일 이름
서버가 시작시에 이파일을 실행하기를 원하는 sql문 파일이다

interactive_timeout
서버가 close전에 상호작용할 커넥션에 activity를 기다리는 시간(초)
상호작용하는 클라이언트는 mysql_real_connect()에 CLIENT_INTERACTIVE option를 사용하는 클라이언트로 정의된다
wait_timeout를 참조하라

join_buffer_size
인덱스를 사용하지않는 full 조인에 사용되는 버퍼사이즈
이 버퍼는 두개의 테이블사이에 각각의 full조인에 대한 유일한 시간이 할당된다
인덱스를 추가하는 것이 불가능할때 더 빠른 full조인을 하기위해 증가시켜라
보통 빠른 조인을 수행하는 최상의 방법은 인덱스를 추가하는 것이다

key_buffer_size
인덱스 블럭은 모든 쓰레드에의해 완화되어지고 공유되어진다.
key_buffer_size는 인덱스블럭에 사용되어지는 버퍼사이즈이다.
인덱스를 더 잘 다루기위해 허용된 만큼 많이 이것을 증가시켜라.
256M에 64M를 할당하는 것이 주로 mysql에서 일반화 되어있다.
하지만,당신의 시스템의 50% 이상 커진다면, 시스템이 페이징하면서 굉장히 느려진다.
mysql이 데이타를 읽는데 케쉬하지 않기 때문에 show status와 show varibles를 사용하여
Key_read_requests, Key_reads, Key_write_requests, Key_writes를 검사하고 key buffer의 퍼포먼스를 체크하는 것을 명심하라.
Key_reads/Key_read_request율은 보통 0.01보다 작아야한다.
updates/deletes를 대부분 사용한다면 Key_write/Key_write_requests가 1에 가까워지는게 일반적이고,
동시에 update를 많이하거나 delay_key_write를 사용한다면 Key_write/Key_write_requests는 작아진다.
※기본은 16M이다.
Key_buffer_used*1024(byte)에 2~3배면 충분하다(투덜이님)

SHOW Syntax를 참조하라
동시에 많은 rows를 쓰게하려면 LOCK TABLES를 사용하라
LOCK TABLES/UNLOCK TABLES Syntax를 참조하라

language
에러메세지에 사용되는 언어

large_file_support
big file support로 mysql이 컴파일되을때

locked_in_memory
mysqld는 --memlock로 메모리에 lock된다면 on

log
시작시 --log로 모든 쿼리를 logging하면 on

log_update
시작시 --update-log하면 on

log_bin
시작시 binary log를 하면

log_slave_updates
If the updates from the slave should be logged.

long_query_time
하나의 쿼리가 long_query_time(초)보다 길면, Slow_queries counter가 증가될 것이다
시작시 --log-slow-queries를 사용하면, 쿼리는 slow query logfile에 쌓인다
The Slow Query Log를 참조하라

lower_case_table_names
테이블이름에 1로 세팅되면, 디스크에 lowercase(인쇄)되어 쌓이며, 테이블이름은 case-insensitive될 것이다
Case Sensitivity in Names를 참조하라

max_allowed_packet
패킷의 최대사이즈
이 message버퍼는 net_buffer_length bytes에 최기화된다.
하지만, 필요시 max_allowed_packet bytes까지 증가한다.

가능한 잘못된 큰 패킷을 잡기위해 디폴트는 작다
biggest BLOB를 사용하기를 원하면 이것을 증가시켜야 하며, 당신이 사용하기 원하는 만큼 커진다.
The protocol limits for max_allowed_packet은 MySQL 3.23에서는 16M이고, MySQL 4.0에서는 4G이다

max_binlog_cache_size
multi-statement transaction가 max_binlog_cache_size의 메모리양보다 큰 메모리를 요청하면
에러가 발생


max_binlog_size
3.23.33이후에서 가능하며, 주어진 값보다 초과되어 binary (replication) log에 쓰는 것은 log가 rotate된다
1024bytes보다 작거나 1Gbytes보다 크게 할 수없으며, 디폴트는 1Gbytes이다

max_connections
동시유저 수
이 값이 mysqld에서 요구하는 file descriptors의 수를 증가하면 이 값을 증가시켜라
file descriptor limits와 Too many connections Error를 참조하라

※기본 값은 100이다. 투덜이님에 의하면 max_userd_connections의 두배정도가 적정하다고 한다


max_connect_errors
호스트로 부터 interrupted connections수가 많아지면, 이 호스트는 많아진 수부터 block될 것이다.
FLUSH HOSTS를 사용하여 unblock할 수있다.

max_delayed_threads
INSERT DELAYED statements를 다루기 위해 쓰레드수들보다 더 많이 시작시키지 마라.
모든 INSERT DELAYED threads가 사용되어진 이후 새로운 테이블에 데이타를 입력시키면,
그 row는 마치 DELAYED attribute이 지정되지 않은것처럼 입력될 것이다.

max_heap_table_size
Don't allow creation of heap tables bigger than this.
여기에서 정의 되어진 것보다 더큰 테이블을 heap에 만들지 못한다

max_join_size
max_join_size 레코드들보다 더 큰것들을 읽으려 조인을 사용하는 것은 에러를 발생시킨다.
where절이 없고, 오래걸리는 조인과 많은(수백만)rows를 반환하려는 유저가 있으면 이것을 세팅하라


max_sort_length
BLOB or TEXT values를 정렬할때 사용되는 수(bytes)
(only the first max_sort_length bytes of each value are used; the rest are ignored).

max_user_connections
하나의 유저당 활성화된 커넥션수(0 = no limit).

max_tmp_tables
(This option doesn't yet do anything.)
클라이언트가 동시에 열수있는 임시테이블의 최대수

max_write_lock_count
After this many write locks, allow some read locks to run in between.


myisam_bulk_insert_tree_size
MySQL은 bulk inserts를 하기위해 특별한 트리구조의 케쉬를 사용한다
(예: INSERT ... SELECT, INSERT ... VALUES (...), (...), ..., and LOAD DATA INFILE)
이것은 쓰레드당 bytes에 케쉬 트리 사이즈를 제한한다.
0으로 세팅하면 이 최적화는 disable된다
디폴트는 8MB이다

myisam_recover_options
--myisam-recover option를 사용하였을때

myisam_sort_buffer_size
REPAIR를 사용하는 인덱스를 정력하거나 CREATE INDEX or ALTER TABLE과 함께 인덱스를 만들때 할당되는 버퍼사이즈

myisam_max_extra_sort_file_size
fast index creation를 위해 temporary file를 생성하는 것이 key cache보다 더 커진다면 key cache method가 우선한다
이것은 인덱스를 생성하기위해 slower key cache method를 사용하는 large tables에서 long character keys에 주로 사용된다
이 parameter는 Mbytes이다

myisam_max_sort_file_size
temporary file은 최대사이즈는 인덱스(mysql이 REPAIR, ALTER TABLE or LOAD DATA INFILE동안)를
재생성하는 동안 사용되도록 허락한다.
파일사이즈는 이것보다 더 클것이며, 인덱스는 slower key cache를 통해 생성될 것이다.
이 parameter는 Mbytes이다

net_buffer_length
communication buffer는 쿼리사이에 이 사이즈를 다시 세팅하여야 한다
net_buffer_length가 보통 바뀌지는 않지만, 당신이 매우 작은 메모리를 가지고 있다면
이것을 기대된 쿼리사이즈를 세팅할 수있다.
(클라이언트에 의해 보내진 sql문의 기대된 길이이다. sql문이 이 길이를 초과한다면,
버퍼는 max_allowed_packet까지 자동적으로 커진다)

net_read_timeout
읽기가 안되기전 커넥션으로 부터 더 많은 데이타를 기다리는 시간(초)
커넥션으로부터 데이타를 기대하지 않을때는 이 타임아웃은 rite_timeout으로 정의된다
lave_read_timeout참조하라


net_retry_count
communication port에 읽기가 방해된다면, 이것은 포기하기전에 많은 수를 재시도한다.
이것은 internal interrupts가 모든 쓰레드에 보내짐으로써 FreeBSD에서 꽤 높게 나타난다


net_write_timeout
block이 쓰기를 회피하기전에 커넥션에 쓰여지기를 기다리는 시간(초)

open_files_limit
이 값이 '0'이면 mysqld는 max_connections*5
또는 max_connections + table_cache*2 (whichever is larger) number of files이 필요하다
mysqld가 'Too many open files'에러를 나타내면 이 값을 증가시켜야 한다.
open_files_limit '0'이 아니면 mysqld는 file descriptors가 setrlimit()를 사용하도록 바꾸기위해 이것을 사용한다
open_files_limit '0'이면, mysqld는 max_connections*5

pid_file
--pid-file pid 파일위치

port
mysql포트넘버 (디폴트 3306)

protocol_version
The protocol version used by the MySQL server.

record_buffer
일련의 연속적인 스캔을 하는 각각의 쓰레드는 쓰레드가 스캔하는 버퍼사이즈를 할당한다
많은 연속적인 스캔을 할경우 이값을 증가시키기를 원할 수있다.

record_rnd_buffer
정렬된 순서대로 rows를 읽을때 rows는 디스크찾기를 하지않고 이 버퍼를 통해 읽는다
세팅해놓지않으면 record buffer에서 세팅된값이다

query_buffer_size
쿼리버퍼의 초기 할당
대부분의 쿼리가 (like when inserting blobs) 길다면 이값을 증가시켜야만 한다


safe_show_databases
유저가 어떤 데이타베이스권한도 테이블의 권한도 가지지 않는 데이타베이스를 보여주지 마라
이것은 만약 당신이 다른 유저들이 가지고 있는 데이타베이스를 볼 수있는 사람들에 대해 걱정한다면 보안을 향상시킬수있다
skip_show_databases를 참조하라

server_id
--server-id option의 값

skip_locking
만약 mysqld가 외부 lock을 사용한다면 off이다

skip_networking
local(socket)커넥션만을 허락한다면 on이다

skip_show_databases
PROCESS_PRIV권한을 가지지 않는 사람들이 SHOW DATABASES를 못하게 한다
만약 사람들이 다른 유저들이 가지고있는 데이타베이스를 보는 것을 걱정한다면 이것은 보안을 향상시킨다
safe_show_databases참조

slave_read_timeout
읽기가 실패하기전 master/slave연결로 부터 더 많은 데이터를 기다릴 수있는 시간(초)

slow_launch_time
쓰레드 생성이 이 값보다 더 길다면(초당), Slow_launch_threads counter는 증가될 것이다


socket
서버에 의해 사용되는 Unix socket /[절대경로]/이름

sort_buffer
정렬을 필요로 하는 각 쓰레드는 버퍼사이즈를 할당한다.
더 빠른 ORDER BY or GROUP BY operations를 위해서 이 값을 증가시켜라.
section A.4.4 Where MySQL Stores Temporary Files를 참조하라

※sort_buffer와 record_buffer
sort_buffer와 record_buffer의 합이 8M가 넘지 않도록 주의한다
(sort_buffer+record_buffer)*max_connections가 자신의 램보다 크지 않도록해야 한다.

table_cache
모든 쓰레드들에 대한 오픈할 수있는 테이블 수
이 값을 증가시키면 mysqld가 필요로 하는 파일 descriptors의 수를 증가시킨다.
Opened_tables variable를 체크함으로서 테이블케쉬를 증가시키것이 필요한지 체크할 수있다.
SHOW Syntax를 참조하라
이 값이 크고 FLUSH TABLES가 많지않다면(모든 테이블들을 닫고 재오픈하도록 강요하는 것) 그때, 이값을 증가시켜야 한다
테이블케쉬에 더 많은 정보를 얻으려면 How MySQL Opens and Closes Tables를 참조하라

※이것은 투덜이님에 의하면 mysql서버가 한번에 열수있는 테이블 수라고 한다
기본값은 64인데, max_connections의 1.5배정도 크기로 하는것이 좋다고 한다.


table_type
디폴트 테이블 타입(myisam)

thread_cache_size
케쉬를 재사용하기위해 얼마나 많은 쓰래드를 유지해야하는가
클라이언트가 연결이 끊겼을 때, 그 클라이언트의 쓰래드는 이전보다 더 많은 thread_cache_size 쓰레드가 존재하지 않는다면
케쉬에 놓여진다.
모든 새로운 쓰레드들은 먼저 케쉬에서 나오며, 단지 케쉬가 비어있을대 새로운 쓰레드를 생성한다.
이 값은 새로운 연결이 많을 경우 성능향상을 위해 증가시키게 된다.
보통 이것은 좋은 쓰레드수행을 가진다면 현저한 성능향상을 주지는 않는다.
connection과 threds_created사이에 차이를 알기위해서는 현재의 쓰레드 케쉬가 당신에게 얼마나 효과적인지 알 수있다.

thread_concurrency
솔라리스에서, mysqld는 이 값과 thr_setconcurrency()를 호출할 것이다.
thr_setconcurrency()는 application에게 쓰레드시스템에게 동시에 실행되도록 원하는 쓰레드수에 대한 힌트를 준다



thread_stack
각 쓰레드에 대한 스택사이즈
the crash-me test에 의해 발견된 한계치
디폴트는 normal operation에 대해 충분히 크다.
MySQL Benchmark Suite를 참조하라

timezone
디비서버 타임 존

tmp_table_size
메모리안에 temporary table이 이 사이즈를 초과하면 mysql은 자동적으로 temporary table을 디스크에 MyISAM table으로
변환할 것이다. 당신이 많은 advanced GROUP BY queries과 많은 메모리를 가지고 있다면 이 값을 증가시켜라


tmpdir
temporary files 과 temporary tables를 사용할 수있는 디렉토리

version
mysql서버 버젼

wait_timeout
서버를 닫히기전에 연결을 활성화하는데 서버가 기다리는 시간(초)
interactive_timeout를 참조하라
----------------------------------------------------------------------------------------------------------------------------------------







▷ mysqladmin -u root -p extended-status(※mysql>show stauts)
----------------------------------------------------------------------------------------------------------------------------------------
Aborted_clients
클라이언트가 연결을 적절히 닫지않아서 죽었기때문에 끊어진 연결수
Communication Errors / Aborted Connection를 참조

Aborted_connects
연결실패된 mysql서버에 연결시도 수
Communication Errors / Aborted Connection참조

Bytes_received
모든 클라이언트로 부터 받은 바이트 수

Bytes_sent
모든 클라이언트에게 보낸 바이트수

Connections
mysql서버에 연결시도한 수

Created_tmp_disk_tables
sql문을 실행하는 동안 생성된 디스크에 존재하는 임시테이블 수

Created_tmp_tables
sql문을 실행하는 동안 생성된 메모리에 존재하는 임시테이블 수

Created_tmp_files
얼마나 많은 임시파일을 mysqld가 생성했는가

Delayed_insert_threads
사용중인 insert handler threads가 지연되고 있는 수

Delayed_writes
INSERT DELAYED로 쓰여진 rows수

Delayed_errors
어떤 에러(duplicate key로인한 때문에 INSERT DELAYED로 쓰여진 rows수

Flush_commands
초과 flush명령수

Handler_delete
테이블로 부터 지워진 rows수

Handler_read_first
인덱스로 부터 읽혀진 처음 entry수
이것이 높으면 서버는 많은 full index scans를 하고 있다는 것을 의미한다
예를 들어 SELECT col1 FROM foo는 col1은 인덱스되었다는 것을 추정한다.

Handler_read_key
키가 존재하는 row를 읽는 요청수
이것이 높으면 당신의 쿼리와 테이블이 적절히 인덱스화되었다는 좋은 지적이된다.

Handler_read_next
키순서대로 다음 row를 읽는 요청수
이것은 만약 range constraint와 함께 인덱스컬럼을 쿼리할 경우 높아질 것이다.
이것은 또한 인덱스 스캔하면 높아질 것이다

Handler_read_rnd
고정된 위치에 존재하는 row를 읽는 요청수
이것은 결과를 정렬하기를 요하는 많은 쿼리를 한다면 높아질 것이다

Handler_read_rnd_next
데이타파일에서 다음 row를 읽기를 요청수
이것은 많은 테이블 스캔을 하면 높아질 것이다
일반적으로 이것은 당신의 테이블들이 적절하게 인덱스되지 않았거나 당신의 쿼리들이
당신이 가지고 있는 인덱스들의 이점을 활용하지 못하고 있다는 것을 의미한다

Handler_update
Number of requests to update a row in a table.
한테이블에 한 row를 업데이트를 요청하는 수

Handler_write
Number of requests to insert a row in a table.
한테이블에 한 row를 insert요청하는 수

Key_blocks_used
The number of used blocks in the key cache.
key케쉬에서 블럭을 사용하는 수

Key_read_requests
케쉬에서 키블럭을 읽기를 요청하는 수

Key_reads
디스크로부터 키블럭을 물리적으로 읽는 수

Key_write_requests
The number of requests to write a key block to the cache.
케쉬에서 키블럭을 쓰기위해 요청하는 수

Key_writes
The number of physical writes of a key block to disk.
디스크에 키블럭을 물리적으로 쓰는 수

Max_used_connections
동시사용 연결 최대수

Not_flushed_key_blocks
키케쉬에서 키블럭이 바뀌지만 디스크에는 아직 flush되지 않는다

Not_flushed_delayed_rows
Number of rows waiting to be written in INSERT DELAY queues.
INSERT DELAY queue에서 쓰여지기를 기다리는 row수

Open_tables
현재 오픈된 테이블수

Open_files
현재 오픈된 파일수

Open_streams
주로 logging에 사용되는 현재 오픈된 stream수

Opened_tables
지금까지 오픈된 테이블 수

Select_full_join
키없이 조인된 수(0이 되어야만 한다)

Select_full_range_join
reference table에서 range search를 사용한 조인수

Select_range
첫번째 테이블에 range를 사용했던 조인수
보통 이것이 크더라도 위험하진 않다

Select_scan
첫번째 테이블을 스캔했던 조인수

Select_range_check
각 row후에 key usage를 체크한 키없이 조인한 수(0이어야만 한다)

Questions
서버에서 보낸 쿼리수


Slave_open_temp_tables
현재 slave thread에 의해 오픈된 임시 테이블 수

Slow_launch_threads
연결된 slow_launch_time보다 더 많은 수를 갖는 쓰레드수

Slow_queries
long_query_time보다 더 많은 시간이 걸리는 쿼리 수
Slow Query Log참고

Sort_merge_passes
정렬해야만 하는 merge수
이 값이 크면 sort_buffer를 증가하는것에 대해 고려해야한다

Sort_range
Number of sorts that where done with ranges.

Sort_rows
정렬된 row수

Sort_scan
테이블 스캔에 의해 행해진 정렬수

Table_locks_immediate
즉시 획득된 테이블 lock 시간 (3.23.33부터 추가된 항목)

Table_locks_waited
즉시 획득되지 않고 기다림이 필요한 테이블 lock 시간
이것이 높아지면 성능에 문제가 있으므로, 먼저 쿼리를 최적화 시키고, 테이블을 분산시키거나 복제를 사용해야한다
(3.23.33부터 추가된 항목)

Threads_cached
스레드 캐쉬에서 쓰레드 수

Threads_connected
현재 오픈된 연결수

Threads_created
연결을 다루기위해 생성된 쓰레드 수

Threads_running
sleeping하지 않는 쓰레드 수

Uptime
서버가 스타트된 후로 지금까지의 시간

[참고]
1. Opened_tables가 크면 table_cache variable의 값이 너무 작은것일지도 모른다
2. key_reads가 크면 key_cach의 값이 너무 작은것일지도 모른다
3. cache hit rate은 key_reads/key_read_requests이다
4. Handler_read_rnd가 크면 MySQL의 모든 테이블을 스캔하는 많은 쿼리가 있다거나
key를 적절히 사용하지 않는 조인들이 있을지 모른다
5. Threads_created가 크면 thread_cache_size값을 증가시키기를 바랄수도 있다
6. Created_tmp_disk_tables이 크면 디스크대신 임시테이블메모리를 얻기위해
tmp_table_size값을 증가시키기를 원할 수있다
----------------------------------------------------------------------------------------------------------------------------------------


[튜닝참조 1]
※ 기본적으로 support-files밑에 `my-huge.cnf', `my-large.cnf', `my-medium.cnf', `my-small.출
를 기본으로 my.cnf 로 바꾸어 사용하면서 조정한다.

1. memory (>=256M)이고
많은 테이블이 있으며, 적당한 클라이언트수에서 최고 성능을 유지하기 위해
shell> safe_mysqld -O key_buffer=64M -O table_cache=256 \
-O sort_buffer=4M -O record_buffer=1M &
이러한 옵션으로 서버를 실행하는데, my-cnf에서 이를 수정하여 사용하면 될 것이다.

2. 128M메모리에 테이블이 적지만, 정렬이 많을 때
shell> safe_mysqld -O key_buffer=16M -O sort_buffer=1M

3. 메모리는 적지만 많은 연결이 있을 때
shell> safe_mysqld -O key_buffer=512k -O sort_buffer=100k \
-O record_buffer=100k &
또는

shell> safe_mysqld -O key_buffer=512k -O sort_buffer=16k \
-O table_cache=32 -O record_buffer=8k -O net_buffer=1K &

[튜닝 참조2]
※group by와 order by작업이 가지고 있는 메모리보다 훨씬 클 경우, 정렬 후 row 읽는 것을 빠르게
하기위해 record_rnd_buffer값을 증가시켜라

※많은 연결로 인한 swapping problems는 메모리를 올려야 되는 것은 당연하다

※만약 튜닝을 위해 parameter를 바꾸고 그 효과에 대해 알아볼려면
shell> mysqld -O key_buffer=32m --help
를 사용하면된다. 주의할점은 --help를 나중에 붙여야 한다는 것이다.

※mysqladmin -u root -p -i5 -r extended-status | grep -v "0"
Enter password:
+--------------------------+-------+
| Variable_name | Value |
+--------------------------+-------+
| Bytes_received | 38 |
| Bytes_sent | 55 |
| Connections | 2 |
| Flush_commands | 1 |
| Handler_read_first | 1 |
| Handler_read_rnd_next | 13 |
| Open_files | 1 |
| Opened_tables | 6 |
| Questions | 1 |
| Table_locks_immediate | 5 |
| Threads_created | 1 |
| Threads_connected | 1 |
| Threads_running | 1 |
| Uptime | 5 |
+--------------------------+-------+

▶Bytes_received:
모든 클라이언트로 부터 받은 바이트 수
▶Bytes_sent:
모든 클라이언트에게 보낸 바이트수
▶Connections:
mysql서버에 연결시도한 수
▶Flush_commands:
초과 flush명령수
▶Handler_read_first:
인덱스로 부터 읽혀진 처음 entry수
이것이 높으면 서버는 많은 full index scans를 하고 있다는 것을 의미한다
예를 들어 SELECT col1 FROM foo는 col1은 인덱스되었다는 것을 추정한다.
▶Handler_read_rnd_next:
데이타파일에서 다음 row를 읽기를 요청수
이것은 많은 테이블 스캔을 하면 높아질 것이다
일반적으로 이것은 당신의 테이블들이 적절하게 인덱스되지 않았거나 당신의 쿼리들이
당신이 가지고 있는 인덱스들의 이점을 활용하지 못하고 있다는 것을 의미한다
▶Open_files:
현재 오픈된 파일수
▶Opened_tables:
현재 오픈된 테이블수
▶Questions:
서버시작후 지금까지 요청된 쿼리수
▶Table_locks_immediate:
즉시 획득된 테이블 lock 시간 (3.23.33부터 추가된 항목)
▶Threads_created:
연결을 다루기위해 생성된 쓰레드 수
▶Threads_connected:
현재 오픈된 연결수
▶Threads_running:
sleeping하지 않는 쓰레드 수
▶Uptime :
서버가 스타트된 후로 지금까지의 시간

Posted by '김용환'
,

Sitemesh에서 기본적으로 제공하는 ConfigDecoratorMapper는 파일 하나만 달랑 읽게 하고 있다.

좀 당황스럽게 왜 하나만 읽게 하냐는 말이지. 여러개 파일을 읽고, 다양하게 나눠서 읽는 마당에..

 

  <mapper class="com.opensymphony.module.sitemesh.mapper.ConfigDecoratorMapper">
   <param name="config" value="${decorators-file}" />
  </mapper>

 

여러개의 파일을 다음과 같이 사용한다.

 

         <mapper class="com.google.common.sitemesh.mapper.MultipleConfigDecoratorMapper">
                <param name="config1" value="/common/decorators/decorators.xml" />
                <param name="config2" value="/WEB-INF/decorators.xml" />
         </mapper>

 

ConfigDecoratorMapper를 수정한 소스는 다음과 같다.

 

package com.google.common.sitemesh.mapper;

import java.util.Arrays;
import java.util.List;
import java.util.ArrayList;
import java.util.Properties;
import java.util.SortedSet;
import java.util.TreeSet;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.opensymphony.module.sitemesh.Config;
import com.opensymphony.module.sitemesh.Decorator;
import com.opensymphony.module.sitemesh.DecoratorMapper;
import com.opensymphony.module.sitemesh.Page;
import com.opensymphony.module.sitemesh.mapper.AbstractDecoratorMapper;
import com.opensymphony.module.sitemesh.mapper.ConfigLoader;

/**
 * Reads decorators and mapping from the <code>param</code> property.
 * If param is not given, read default file('WEB-INF/decorators.xml')
 * <br>
 * It is extended for multiple config file for ConfigDecoratorMapper<br>
 * <br>
 * Example below <br>
 * <mapper class="com.google.common.sitemesh.mapper.MultipleConfigDecoratorMapper"> <br>
 *  <param name="config2" value="/WEB-INF/common-decorators.xml" /> <br>
 *  <param name="config1" value="/WEB-INF/decorators.xml" /> <br>
 * </mapper> <br>
 *
 * @author knight76
 *
 */
public class MultipleConfigDecoratorMapper extends AbstractDecoratorMapper {
 private static Log log = LogFactory.getLog(MultipleConfigDecoratorMapper.class);

 private List<ConfigLoader> configLoaderList = null;

 /** Create new ConfigLoader using '/WEB-INF/decorators.xml' file. */
 public void init(Config config, Properties properties, DecoratorMapper parent) throws InstantiationException {
         super.init(config, properties, parent);
         configLoaderList = new ArrayList<ConfigLoader>();
         try {
          // property의 모든 데이터 키값을 오름차순으로 받아  configLoader에 저장한다.
          String[] props = properties.keySet().toArray(new String[0]);
          Arrays.sort(props);
          for (Object propertyName : props) {
           String fileName = properties.getProperty((String)propertyName, "/WEB-INF/decorators.xml");
           ConfigLoader configLoader = new ConfigLoader(fileName, config);
           configLoaderList.add(configLoader);
          }
         }
         catch (Exception e) {
             log.error(e);
         }
     }

 /**
  * Retrieve {@link com.opensymphony.module.sitemesh.Decorator} based on
  * 'pattern' tag.
  */
 public Decorator getDecorator(HttpServletRequest request, Page page) {
  String thisPath = request.getServletPath();

  // getServletPath() returns null unless the mapping corresponds to a
  // servlet
  if (thisPath == null) {
   String requestURI = request.getRequestURI();
   if (request.getPathInfo() != null) {
    // strip the pathInfo from the requestURI
    thisPath = requestURI.substring(0, requestURI.indexOf(request
      .getPathInfo()));
   } else {
    thisPath = requestURI;
   }
  }

  String name = null;
  try {
   name = getMappedName(thisPath);
  } catch (ServletException e) {
   log.warn(e);
  }

  Decorator result = getNamedDecorator(request, name);
  return result == null ? super.getDecorator(request, page) : result;
 }

 /**
  * 주어진 thispath를 받아 해당 thispath에 매핑된 decorator 이름을 가져온다.
  * @param thisPath
  * @return
  * @throws ServletException
  */
 private String getMappedName(String thisPath) throws ServletException {
  String name = null;
  for (ConfigLoader loader : configLoaderList) {
   name = loader.getMappedName(thisPath);
   if (name != null) {
    return name;
   }
  }
  return name;
 }

 /**
  * Retrieve Decorator named in 'name' attribute. Checks the role if
  * specified.
  */
 public Decorator getNamedDecorator(HttpServletRequest request, String name) {
  Decorator result = null;
  try {
   result = getDecoratorByName(name);
  } catch (ServletException e) {
   log.warn(e);
  }

  if (result == null
    || (result.getRole() != null && !request.isUserInRole(result
      .getRole()))) {
   // if the result is null or the user is not in the role
   return super.getNamedDecorator(request, name);
  } else {
   return result;
  }
 }

 /**
  * 주어진 name을 받아 decorator를 얻어온다.
  * @param name
  * @return
  * @throws ServletException
  */
 private Decorator getDecoratorByName(String name) throws ServletException {
  Decorator result = null;
  for (ConfigLoader configLoader : configLoaderList) {
   result = configLoader.getDecoratorByName(name);
   if (result != null) {
    return result;
   }
  }
  return result;
 }
}

Posted by '김용환'
,

Sitemesh 참조자료

web 2007. 8. 24. 05:31

이 세 군데 외엔 쓸만한데 없더먼...

그 다음엔 내 블로그??!!! ㅋㅋ

 

http://opensymphony.com/sitemesh
http://blog.naver.com/paradozz?Redirect=Log&logNo=15918519

Posted by '김용환'
,

Sitemesh #4 Sitemesh 팁

web 2007. 8. 24. 05:29

당연하겠지만, 이 글은 그저 간단한 팁이라 생각하면 되겠당.. 더 좋은 방법이 있으면 더욱 많이 생겨나면 좋겠다.

샘플의 특정회사는 당근 가명이다...^^

 

특정 패턴을 빼거나 적용하기

특정 디렉토리에 모든 웹 컴포넌트(jsp, action, html등등)을 하나의 decoration으로 적용이 가능하다. 하지만, 때에 따라서는 그 폴더안에 특정 웹 컴포넌트등은 그 decoration을 적용시키지 않을 수도 있고, 다른 decoration을 적용시킬 수 있다.
즉, context상 같은 디렉토리에 있지만, UI상에서 다르게 decoration이 적용될 수 있는데, 이런 예외상황을 처리할 수 있는 방법을 Sitemesh는 가지고 있다.
exclude 패턴, jsp상에서의 meta 태그, decorator 패턴 지정등을 통해서 여러 패턴으로 지정이 가능하다.

Decoration의 exlclude 패턴 사용하기

특정 패턴의 action 혹은 html, jsp등에 지정된 pattern을 아예 적용하지 않고 싶을 때에 exclude를 사용할 수 있다. 이 때, 주의할 점은 decorators.xml에 exclude 패턴을 사용했다 해서 적용되지 않는다.

decorators.xml
...
<excludes> 
    <pattern>/exclude.gl</pattern> 
    <pattern>/alert.gl</pattern>
</excludes> 
...

그 이유는 sitemesh.xml 에서 exclude할 패턴을 적용할 파일을 지정해야 한다. sitemesh.xml 파일에서 exlcude할 파일 리스트가 적힌 xml파일을 지정한다.
decorator-mapper 태그안에 mapper class를 ConfigDecoratorMapper안에 해당 config파일을 적용했다 하더라도 이는 exclude 파일 리스트와는 무관하다.

<excludes file="/WEB-INF/decorators.xml"/>

다음은 exclude를 적용한 실제 예제이다.

sitemesh.xml
<sitemesh>
	<page-parsers>
		<parser default="true" class="com.opensymphony.module.sitemesh.parser.DefaultPageParser" />
		<parser content-type="text/html" class="com.opensymphony.module.sitemesh.parser.FastPageParser" />
	</page-parsers>

	<excludes file="/WEB-INF/d1.xml"/>
	<decorator-mappers>
		<mapper class="com.opensymphony.module.sitemesh.mapper.ConfigDecoratorMapper">
			<param name="config" value="/WEB-INF/decorators.xml" />
		</mapper>
	</decorator-mappers>
</sitemesh>
d1.xml
<decorators>
    <excludes>
	<pattern>/exclude.gl</pattern> 
         <pattern>/alert.gl</pattern>
    </excludes>
</decorators>
decorators.xml
<decorators defaultdir="/WEB-INF/decorators">
    <decorator name="indexLayout" page="indexLayout.jsp">
        <pattern>/index.gl</pattern>
    </decorator>
 
    <decorator name="defaultHeader" page="defaultHeader.jsp"/>
    <decorator name="defaultFooter" page="defaultFooter.jsp"/>


    <decorator name="default" page="default.jsp">
        <pattern>/*</pattern>
    </decorator>
</decorators>

decorator 설정 파일에서 null decorator 지정

위의 예처럼 exclude 패턴를 사용하여 지정된 패턴에서 일부 파일을 예외화할 수 있다. 또한 이 방법 외엔 다른 방법이 있다. decorator를 null로 지정하여 decoration이 적용안되게 할 수 있다. 또는 다른 특정 decoration을 지정할 수 있다.

decorators.xml
<decorator name="null">
    <pattern>/test.gl</pattern>
</decorator>

jsp, html파일에 meta 태그 사용

decorators.xml에 특정 decorator을 지정하였지만 해당 패턴에 속하지 않았지만, jsp의 파일에 decorator를 지정하여 사용이 가능하다. 이를 위해서는 sitemesh.xml에서 반드시 PageDecoratorMap 클래스가 decorator mapper로 바인딩되어야 한다. (순서는 com.opensymphony.module.sitemesh.mapper.ConfigDecoratorMapper 보다는 상위에서 정의해야 한다. 그 이유에 대해서는 자세한 내용은 다음장에서 언급한다.)

siemesh.xml
<mapper class="com.opensymphony.module.sitemesh.mapper.PageDecoratorMapper">
    <param name="property.1" value="meta.decorator" />
    <param name="property.2" value="decorator" />
</mapper>

decorators 설정파일에서 tv라고 하는 decorator와 아무 decoration도 적용되지 않는 null decorator를 적용한다.

decorators.xml
<decorator name="tv" page="tv.jsp">
</decorator>

<decorator name="null">
</decorator>

google.jsp파일에서 tv라고 하는 decorator를 지하여, tv.jsp의 decorator page를 UI에서 쓸 수 있도록 할 수 있다.

google.jsp
<meta name="decorator" content="tv" />
<%@ page language="java" pageEncoding="MS949" %>
<html>
<head>
<title> Google Test</title>
</head>
<body onload="http://~~~">
google6
</body>
</html>

만약, 아무 decoration도 적용하지 않겠다면, 다음의 코드를 jsp 상단에 지정하면 된다.

<meta name="decorator" content="null" />

Decorator 체인

sitemesh.xml에서 정의된 mapper들의 순서가 chain으로 연결되어 있다. 순서에 유의를 해야 하는데, 순서에 따라서 완젼 다른 결과가 나올 수 있다. 왜 순서에 주의해야 하는지를 예제를 통해서 알아본다.

sitemesh.xml은 PageDecoratorMapper와 ConfigDecoratorMapper를 가지고 있다.

sitemesh.xml
<sitemesh>
	<page-parsers>
		<parser default="true" class="com.opensymphony.module.sitemesh.parser.DefaultPageParser" />
		<parser content-type="text/html" class="com.opensymphony.module.sitemesh.parser.FastPageParser" />
	</page-parsers>

	<!-- <excludes file="/WEB-INF/d1.xml"/>  -->

	<decorator-mappers>

		<mapper class="com.opensymphony.module.sitemesh.mapper.PageDecoratorMapper">
			<param name="property.1" value="meta.decorator" />
			<param name="property.2" value="decorator" />
		</mapper>

		<mapper class="com.opensymphony.module.sitemesh.mapper.ConfigDecoratorMapper">
			<param name="config" value="/WEB-INF/decorators.xml" />
		</mapper>
	</decorator-mappers>
</sitemesh>

decorators.xml은 여러 decorator를 가지고 있다.

decorators.xml
<decorators defaultdir="/WEB-INF/decorators">
    <decorator name="defaultHeader" page="defaultHeader.jsp"/>
    <decorator name="defaultFooter" page="defaultFooter.jsp"/>

    <decorator name="default" page="default.jsp">
        <pattern>/*</pattern>
    </decorator>
    
    <decorator name="tv" page="tv.jsp">
    </decorator>

    <decorator name="null">
    </decorator>
</decorators>

위에서 사용된 google.jsp를 사용한다.

google.jsp
<meta name="decorator" content="tv" />
<%@ page language="java" pageEncoding="MS949" %>
<html>
<head>
<title> Google Test</title>
</head>
<body onload="http://~~~">
google6
</body>
</html>

실행을 해보면, tv decorator가 적용된 결과값이 나온다. (당연하다.)

Header
tv앞 google6 tv뒤 
Footer

만약 sitemesh.xml에서 PageDecoratorMapper, ConfigDecoratorMapper의 연결자 순서를 바꾸어 본다.

sitemesh.xml
<sitemesh>
	<page-parsers>
		<parser default="true" class="com.opensymphony.module.sitemesh.parser.DefaultPageParser" />
		<parser content-type="text/html" class="com.opensymphony.module.sitemesh.parser.FastPageParser" />
	</page-parsers>

	<!-- <excludes file="/WEB-INF/d1.xml"/>  -->

	<decorator-mappers>
		<mapper class="com.opensymphony.module.sitemesh.mapper.ConfigDecoratorMapper">
			<param name="config" value="/WEB-INF/decorators.xml" />
		</mapper>

		<mapper class="com.opensymphony.module.sitemesh.mapper.PageDecoratorMapper">
			<param name="property.1" value="meta.decorator" />
			<param name="property.2" value="decorator" />
		</mapper>
	</decorator-mappers>
</sitemesh>

결과는?? tv decorator가 적용되지 않는다. 기본 디폴트 decorator로 적용된다.
그 이유는 ConfigDecoratorMapper에서 처리되어 default decorator로 decoration된다.

<decorator name="default" page="default.jsp">
        <pattern>/*</pattern>
    </decorator>

즉, decoration mapper는 chain으로 구성되어 있고 (사실은 Filter Chain이다. ) 순서에 맞게 서비스를 처리하고 바로 리턴하도록 되어 있다는 점이다. 이 내용은 Site Mesh 매뉴얼 1(소개) 맨 마지막에서 언급되었으니, 참조하면 된다.

decoraotr page에서 특정 필드 추가하기

property 값을 두번 지정할 수 없다. 따로 따로 나눠서 decorator:getProperty를 사용한다.

아래의 예는 <decorator:getProperty/> 태그의 property 속성을 나란히 적어놓았다. 이 예제는 syntax 문제를 일으키기 때문에 동작이 되지 않아 에러를 web browser를 통해 볼 것이다.

X, layout.jsp
<body onload="<decorator:getProperty property="body.onload" property="body.bottommargin" writeEntireProperty="true" />" bgcolor=ffffff topmargin=0 marginheight=0>

아래의 예는 각각 따로 <decorator:getProperty/> 태그를 중복해서 사용한 것이다. 제대로 동작되는지 확인할 수 있다.

O, layout.jsp
<body onload="<decorator:getProperty property="body.onload" writeEntireProperty="true" />"  
body.bottommargin="<decorator:getProperty property="body.bottommargin"  writeEntireProperty="true" />"  
         bgcolor=ffffff topmargin=0 marginheight=0>

웹 페이지는 그저 onload와, bottommargin만 지정하면 해당 atribute가 적용되는지 알 수 있을 것이다.

<body onload="alert('1');" bottommargin=5>

Action과 Decoration

Action에 특정 decorator page를 지정한 상태에서 그 Action 에 여러 Request Parameter가 붙었을 때, 그 Action의 decorator page로 보여진다??

특정 Action에 decorator를 지정하고, Action의 디폴트 메소드외 다른 메소드를 호출하면, 또는 리쿼스트 파라미터가 여럿이 적용이 될까?

밑의 decorators.xml 파일의 예를 보자. google Action은 decorator page를 default.jsp로 가지고 있다. google.gl을 요청하면 default.jsp가decoration이 되어 xwork.xml에서 지정한 jsp파일을 보여줄 것이다.

decoratos.xml
<decorator name="default" page="default.jsp">
    <pattern>/google.gl</pattern>
    <pattern>/google.jsp</pattern>
</decorator>

만약 google Action에 parameter를 추가하거나, Action의 특정 메소드를 특정 메소드를 호출한다면, 적용이 안될 수 있도 있을 법하다. '*' 패턴을 추가하지 않기 때문에 아리까리할 수 있다.

/google.gl?m=register

결과는 해당 패턴에 적용된다는 것이다. Action 이름을 리쿼스트 파라미터로 받으면 파라미터가 얼마나 붙든지 간단하게 정의된 Action기반 Sitemesh 설정파일로 쉽게 처리할 수 있다.

Action의 결과(jsp)중 특정 결과 jsp만 다른 decorator를 줄 수 있다?? - 1번째 얘기

결론부터 말하면, 불행히도 이 방법을 시도했지만, 환경설정 파일만 수정해서는 할 수 없다.

다음의 예를 들어본다. 밑의 예에서 google Action의 결과중 유일하게 적용안되는 것이 있다. 바로 save.jsp 이다. 강조하지만, Sitemesh는 Request URL을 기준으로 되어 있어 dispatch할 경우 여전히 google.gl으로 남기 때문에 save.jsp에 대해서는 bean decorator가 적용되지 않는다.
하지만, redirection이 된 edit.jsp는 패턴이 제외된 채로 적용된다. 그러나 URL이 바뀌는 불상사는 감수해야 한다.

xwork.xml
<action name="google" class="com.google.publ.test.action.GoogleAction">
    <result name="register">/googleRegister.jsp</result>
    <result name="edit" type="redirect">/edit.jsp</result>
    <result name="save">/save.jsp</result>
</action>
decoratos.xml
<excludes>
    <pattern>/edit.jsp</pattern>
</excludes>

<decorator name="default" page="default.jsp">
    <pattern>/google.gl</pattern>
</decorator>

<decorator name="bean" page="beanLayout.jsp">
    <pattern>/save.jsp</pattern>
</decorator>

Action의 결과(jsp)중 특정 결과 jsp만 다른 decorator를 줄 수 있다?? - 2번째 얘기

제목을 보고 짐작했겠지만, 하나의 Action에서 나온 결과에 대해서 다른 decorator를 쓸 수 있는 방법은 존재한다. 바로 내용이 들어가는 jsp안에 특정 decorator를 설정하는 것이다.

밑의 예를 보자. 바로 google Action이 success인 경우 google.jsp로 dispatch되는데, google.jsp안에 있는 메타 태그에 지정된 content의 decoration 타입에 맞춰 브라우져에 나타나게 된다.

google.jsp
<META name="decorator" content="tv">
....
decorators.jsp
<decorator name="default" page="default.jsp">
   <pattern>/google.gl</pattern>
</decorator>

<decorator name="tv" page="tv.jsp">
</decorator>
xwork.xml
<action name="google" class="com.google.publ.test.action.GoogleAction">
    <result name="success">/google.jsp</result>
    <result name="register">/googleRegister.jsp</result>
</action>

이렇게 사용할 수 이유는 바로 sitemesh.xml 파일의 설정과 관련이 있다. sitemesh.xml 에서 ConfigDecoratorMapper보다 PageDecoratorMapper를 먼저 설정하기 때문이다.

sitemesh.xml
...
<mapper class="com.opensymphony.module.sitemesh.mapper.PageDecoratorMapper">
         <param name="property.1" value="meta.decorator" />
	<param name="property.2" value="decorator" />
</mapper>

..
<mapper class="com.opensymphony.module.sitemesh.mapper.ConfigDecoratorMapper">
	<param name="config" value="/WEB-INF/decorators.xml" />
</mapper>
..

decorator가 적용되는 순서

decorators.xml에 decorator 태그가 지정된 순서대로 decorator가 적용된다.

예를 들어보자. google.gl이라는 action이 호출될 때, 정확하게 URL과 동일한 이름을 패턴으로 갖는 tv decorator가 적용된다.

decorators.xml
<decorators defaultdir="/WEB-INF/decorators">

    <decorator name="defaultHeader" page="defaultHeader.jsp"/>
    <decorator name="defaultFooter" page="defaultFooter.jsp"/>
    <decorator name="leftMenu" page="leftMenuLayout.jsp"/>

    <decorator name="tv" page="tv.jsp">
	    <pattern>/google.gl</pattern>
    </decorator>

    <decorator name="default" page="default.jsp">
	    <pattern>/*.gl</pattern>
    </decorator>

    <decorator name="null">
    </decorator>

</decorators>

pattern이 적용되는 순서

패턴이 적용되는 순서가 다르다. Request URI를 보고 패턴이 지정된 것중에서 다음의 순서대로 해당 decorator page를 찾게된다.

  1. 정확하게 단어가 맞는 패턴 (Exact word)
  2. 'abc*'나 'abc?'와 같은 컴플렉스 패턴 (Complext)
  3. '/', '*', '/*'와 같은 디폴트 패턴 (Default)

tiles의 getAsString(또는 tiles에서 put을 이용하여 atrribute을 지정) 을 어떻게 변경시키냐?

webwork를 보면, <action> 태그 밑에 <param> 태그를 사용할 수 있다. static parameter interceptor를 이용하여 action에 필드를 넘길 수 있다. 이 때, action은 setter 메소드와 클래스 필드만을 적으면 된다.
자세한 내용은 webwork를 참조하라.

action을 기반하는 jsp중, jsp파일들이 서로 다른 Layout 템플릿을 쓰는 경우

어쩔 때는 rightmenu를 쓰고, 어쩔 때는 rightmenu를 안 쓰는 경우.

  • redirect 하기.
  • 해당 jsp파일에서 meta 태그를 이용하여 특정 decorator를 사용하게 함.
Posted by '김용환'
,