'개발'에 해당되는 글 188건

  1. 2009.09.15 자바 암호화
  2. 2009.09.14 자바 정리 참고 1 1
  3. 2009.09.08 [Oracle] 부정형(NOT IN, <>, NOT EXISTS ...)의 비교
  4. 2009.09.08 Java DES/TripleDES 암호화 2
  5. 2009.07.28 [리눅스/솔라리스] 유닉스 혹은 리눅스용 커맨드 팁 모음입니다..
  6. 2009.06.25 [MySQL] Replication 환경 싱크 깨지는것 회피하기
  7. 2009.06.19 XSS(Cross Site Scripting: 크로스 사이트 스크립팅) == CSS
  8. 2009.06.11 mysql show status
  9. 2009.06.04 HTTP 에러코드와 상태 코드 정리
  10. 2009.06.02 JBoss DataSource 설정
2009. 9. 15. 13:39

자바 암호화




자바는 친절하게도 암호화 및 메시지 검증 코드를 구현해주는 클래스를 제공해준다.
JCE(Java Cryptography Extension)란 이름의 프레임워크가 바로 그놈이다.
J2SE 1.4 이후부터는 JCE 1.2.2가 기본적으로 포함되어 있어서 별다른 라이브러리를 추가해주지 않아도 사용할 수 있다.
초기 버젼인 JCE 1.2는 미국 보안법(?)인가에 걸려서 국내에서는 사용할 수가 없었다. (무기밀매와 똑같은 처벌을 한다는 소문이..)
JCE 1.2.1이 나오면서 제한이 풀어져서, 세계적으로 많이(?) 사용하게 되었다.
그런데 이 JCE 1.2.1 버전의 자체 디지털 서명이 2005년 7월 27일쯤인가 만료가 되서, 2005년도에 파란을 한번 일으킨적도 있다.
(그럼 만료기간을 어떻게 알수 있을까? 쉽게 알려면, 자신이 사용하는 파일의 정보를 보면 된다.
자신이 사용하는 자바 관련 디렉토리에서 jce.jar를 풀어보면 META-INF에 JCE_RSA.RSA 파일이 있을것이다. 이 파일을 보면 알 수 있는데, 윈도우 환경에서 이 파일의 확장자를 "p7s"로 변경하면 열어볼 수 있다.)


이 JCE를 사용하지 않아도, 자체적으로 구현해서 마음껏 암호학의 세계를 여행할 수 있지만, 시간에 쫓기는 분들을 위해서 간단히 사용법을 알아보도록 하자.

암호화에는 크게 블럭 암호화(block encryption)와 스트림 암호화(stream encryption)가 있는데, 여기서는 가장(?) 많이 쓰이는 블럭 암호화에 대해서 알아보도록 하겠다.
블럭 암호화는 말 그대로 데이터를 정해진 블럭으로 나눈후 해당 블럭을 암호화하는것이다.
대표적으로 DES/3DES/AES/SEED 등이 있다.

DES(Data Encryption Standard)는 Lucifer를 보완하여 IBM에서 개발한 블럭암호 알고리즘이다.
64비트 입력 블럭을 56비트 비밀키를 사용하여 암호화하는 알고리즘이다.
전세계적으로 널리 사용되었다가, 56비트라는 짧은 키(key)로 인해 안전하지 않다고 보는 견해가 많아져서, 요즘은  AES한테 밀리는 추세이다.

3DES(Triple Data Encryption Standard)는 DES의 단점을 보완하기 위해서 기존의 DES 방식을 3번 적용(암호화->복호화->암호화)시킨것으로 그 과정에 따라서 56비트의 배수로 암호화 복잡도가 증가한다고 한다.
이 3번의 암복호화 즉, Encryption->Decryption->Encryption을 첫글자를 따서 DESede라 명칭하기도한다.

AES(Advanced Encryption Standard)는 현재 미국 정부 표준으로 지정된 블럼 암호화 알고리즘으로서, DES를 대체하고 있다.
키(key)의 크기는 128, 160, 190, 224, 256비트를 사용할 수 있으며, 현재 미국 표준으로 인정받은 것은 128비트이다.
(JCE에서 제공하는것도 128비트밖에 안될지도...)

SEED는 한국정보보호진흥원을 중심으로 국내 암호 전문가들이 참여하여 만든, 순수 국내기술 블럭암호화 알고리즘이다.
(SEED는 다음에 한번 구현에해보기도 하고 오늘은 다루지 않겠다.)

블럭 암호화를 하기 위해서는 당연히 원문(plain text)이 있어야하고, 암화하 하기 위한 키(key)가 있어야한다.
그리고 블럭 암호화 운용모드에 따라서 IV(Initialization Vector)가 필요하기도 하다.
이 키(key)에 따라서 대칭키 암호화와 비대칭키 암호화로 나눌 수 있다.
대칭키 암호화는 암호화키와 복호화키가 동일하다. 속도가 빠른 장점이 있으니 키(key)를 분배하기 어렵다.(키가 누출되면 암호화 자체가 의미가 없어진다.)
비대칭키 암호화는 키(key) 분배 문제때문에 개발되었는데, 암호화와 복호화키가 다르다. 즉, 공개키(PublicKey), 개인키(PrivateKey)가 따로 생성된다.
간단히 설명하자면, 멀리 떨어진 시스템에서 사용할때에, 이 2가지를 결합하여 사용하고 있다.
대칭키 암호화에 사용할 키(key)를 생성한다음, 비대칭키 암호화를 이용해서 그 키를 분배한다.
키가 안전하게 분배되면 대칭키 암호화를 이용해서 서로 암호화된 문서를 주고 받고 하는것이다.
(비대칭키 암호화가 대칭키 암호화보다 느리기 때문에 키분배에만 사용한다.)
앞에 설명한 DEs/3DES/AES/SEED는 대칭키 암호화 알고리즘이다. 비대칭키 암호화 알고리즘은 RSA(Rivest Shamir Adleman)가 있다.(사람 이름 첫글자를 딴것임)

이제 한번 구현해보도록 하자.
(바이트들을 화면에 출력하기(?) 위해 ByteUtils 클래스를 사용하겠다. 첨부파일을 참조하도록 하자)

1. 암호화에 사용할 키(key) 만들기
 - 키를 만드는 방법은 랜덤하게 동적으로 만드는 방법과, 정해진 키를 읽어와서 만드는 방법이 있다. 두 기능을 하는 메소드를 만들어보자.
01.package test.cipher;
02.  
03.import java.security.InvalidKeyException;
04.import java.security.Key;
05.import java.security.NoSuchAlgorithmException;
06.import java.security.spec.InvalidKeySpecException;
07.import java.security.spec.KeySpec;
08.  
09.import javax.crypto.Cipher;
10.import javax.crypto.KeyGenerator;
11.import javax.crypto.SecretKey;
12.import javax.crypto.SecretKeyFactory;
13.import javax.crypto.spec.DESKeySpec;
14.import javax.crypto.spec.DESedeKeySpec;
15.import javax.crypto.spec.IvParameterSpec;
16.import javax.crypto.spec.SecretKeySpec;
17.  
18.import kr.kangwoo.util.ByteUtils;
19.import kr.kangwoo.util.StringUtils;
20.  
21.public class CipherTest {
22.      
23.    /**
24.     * <P>해당 알고리즘에 사용할 비밀키(SecretKey)를 생성한다.</P>
25.     
26.     * @return 비밀키(SecretKey)
27.     */
28.    public static Key generateKey(String algorithm) throws NoSuchAlgorithmException {
29.        KeyGenerator keyGenerator = KeyGenerator.getInstance(algorithm);
30.        SecretKey key = keyGenerator.generateKey();
31.        return key;
32.    }
33.      
34.    /**
35.     * <P>주어진 데이터로, 해당 알고리즘에 사용할 비밀키(SecretKey)를 생성한다.</P>
36.     
37.     * @param algorithm DES/DESede/TripleDES/AES
38.     * @param keyData
39.     * @return
40.     */
41.    public static Key generateKey(String algorithm, byte[] keyData) throws NoSuchAlgorithmException, InvalidKeyException, InvalidKeySpecException {
42.        String upper = StringUtils.toUpperCase(algorithm);
43.        if ("DES".equals(upper)) {
44.            KeySpec keySpec = new DESKeySpec(keyData);
45.            SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance(algorithm);
46.            SecretKey secretKey = secretKeyFactory.generateSecret(keySpec);
47.            return secretKey;
48.        } else if ("DESede".equals(upper) || "TripleDES".equals(upper)) {
49.            KeySpec keySpec = new DESedeKeySpec(keyData);
50.            SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance(algorithm);
51.            SecretKey secretKey = secretKeyFactory.generateSecret(keySpec);
52.            return secretKey;
53.        } else {
54.            SecretKeySpec keySpec = new SecretKeySpec(keyData, algorithm);
55.            return keySpec;
56.        }
57.    }
58.}

 위 코드는 일단 정상(?) 작동하는데, 맞게 구현하지는 아직 잘 모르겠다. (내공이 부족하여 혹시 틀린부분이 있으면 지적바란다.)

2. DES 암호화/복호화 해보기
 - DES 암호화/복화화를 하기위해선 Cipher 클래스를 사용하면 된다.
 - Cipher cipher = Cipher.getInstance("DES/ECB/NoPadding"); 이런씩으로 "암호화알고리즘/운용모드/패딩"으로 사용하면 된다.
 - DES는 암호화키가 64비트이므로 64비트 키를 생성하자
   (예리한 분은 여기서 의문을 가질것이다. 위~에서 설명할때 DES는 56비트 키라고 했는데, 왜 갑자기 여기서는 64비트라고 우기는가에 대해서...
    설명하자면, 64비트의 키(외부키) 중 56비트는 실제의 키(내부키)가 되고 나머지 8비트는 거사용(?) 비트로 사용된다고 한다.)
01.public static void main(String[] args) throws Exception {
02.    Key key = generateKey("DES", ByteUtils.toBytes("68616e6765656e61", 16));
03.    String transformation = "DES/ECB/NoPadding";
04.    Cipher cipher = Cipher.getInstance(transformation);
05.    cipher.init(Cipher.ENCRYPT_MODE, key);
06.      
07.    String str = "hello123";
08.    byte[] plain = str.getBytes();
09.    byte[] encrypt = cipher.doFinal(plain);
10.    System.out.println("원문 : " + ByteUtils.toHexString(plain));
11.    System.out.println("암호 : " + ByteUtils.toHexString(encrypt));
12.      
13.    cipher.init(Cipher.DECRYPT_MODE, key);
14.    byte[] decrypt = cipher.doFinal(encrypt);
15.    System.out.println("복호 : " + ByteUtils.toHexString(decrypt));
16.}

* 실행 결과
원문 : 68656c6c6f313233
암호 : 51d6aa8bcc176819
복호 : 68656c6c6f313233

 실행해보면 암호화/복호화가 잘되는것을 알 수 있다.
 DES는 암호화 알고리즘이고, ECB는 뭘까? 운용모드라고 했는데,  http://blog.kangwoo.kr/13 여기에 퍼온글이 있으니 참조하기 바란다.
 패딩(padding)은 말 그대로 패딩인데, 번역하면 채워넣기, 모자란만큼 채워넣는 역할을 한다. DES는 블럭 암호화 알고리즘이다.
 그래서 암호화 할라면 블럭이 필요한데, DES 경우 64비트가 한 블럭을 형성한다. 그런데 입력한 데이터가 64비트가 안된다면 어떻게 될까?
 궁금하면 "hello123" 을 "hello"으로 바꾼다음 실행해보자. 아마 다음과 같은 에러가 발생할 것이다.
 
* 실행 결과
 Exception in thread "main" javax.crypto.IllegalBlockSizeException: Input length not multiple of 8 bytes

 입력한 데이터가 8 bytes 즉, 64비트가 아니니 배째라는것이다.
 그러면 정상작동을 하기위해서는 블럭크기의 배수만큼 나머지 데이터를 채워줘야하는데 그 역할을 하는게 패딩이다.
 "DES/ECB/NoPadding"을 "DES/ECB/PKCS5Padding"을 바꾼다음 실행해보자.
 이제 데이터가 64비트가 아니어도 정상작동한다. 그래서 귀찮으면 가능한한 패딩을 해주게 하면 좋다.
 (운용 모드가 OFB/CFB일 경우 NoPadding을 사용해도 상관없다. IV를 이용해서 처리할때 필요가 없어지기때문이다. 믿거나 말거나)


3. DESede 암호화/복호화 해보기
 - DES와 별반 차이 없다. 키 크기가 64비트 * 3 = 192비트로 늘어난것밖에 없다.
01.public static void main(String[] args) throws Exception {
02.    Key key = generateKey("DESede", ByteUtils.toBytes("696d697373796f7568616e6765656e61696d697373796f75", 16));
03.    String transformation = "DESede/ECB/PKCS5Padding";
04.    Cipher cipher = Cipher.getInstance(transformation);
05.    cipher.init(Cipher.ENCRYPT_MODE, key);
06.      
07.    String str = "hello123";
08.    byte[] plain = str.getBytes();
09.    byte[] encrypt = cipher.doFinal(plain);
10.    System.out.println("원문 : " + ByteUtils.toHexString(plain));
11.    System.out.println("암호 : " + ByteUtils.toHexString(encrypt));
12.      
13.    cipher.init(Cipher.DECRYPT_MODE, key);
14.    byte[] decrypt = cipher.doFinal(encrypt);
15.    System.out.println("복호 : " + ByteUtils.toHexString(decrypt));
16.}

* 실행 결과
원문 : 68656c6c6f313233
암호 : ad44691609cb1e017378631303581279
복호 : 68656c6c6f313233

4. AES 암호화/복호화 해보기
 - DES와 별반 차이 없다. 키 크기가 128비트인것을 제외하면 말이다.
01.public static void main(String[] args) throws Exception {
02.    Key key = generateKey("AES", ByteUtils.toBytes("696d697373796f7568616e6765656e61", 16));
03.    String transformation = "AES/ECB/PKCS5Padding";
04.    Cipher cipher = Cipher.getInstance(transformation);
05.    cipher.init(Cipher.ENCRYPT_MODE, key);
06.      
07.    String str = "hello123";
08.    byte[] plain = str.getBytes();
09.    byte[] encrypt = cipher.doFinal(plain);
10.    System.out.println("원문 : " + ByteUtils.toHexString(plain));
11.    System.out.println("암호 : " + ByteUtils.toHexString(encrypt));
12.      
13.    cipher.init(Cipher.DECRYPT_MODE, key);
14.    byte[] decrypt = cipher.doFinal(encrypt);
15.    System.out.println("복호 : " + ByteUtils.toHexString(decrypt));
16.}

* 실행 결과
원문 : 68656c6c6f313233
암호 : d5c5e1ffb734b610679f36c0e535fe39
복호 : 68656c6c6f313233
5. IV 사용하기.
- 블록 암호의 운용 모드(Block engine modes of operation)가 CBC/OFB/CFB를 사용할 경우에는 Initialization Vector(IV)를 설정해줘야한다. 왜냐면 사용하기 때문이다. AES 암호화/복호화 코드에서 운용 모드가 CBC로 변경해보자.
01.public static void main(String[] args) throws Exception {
02.    Key key = generateKey("AES", ByteUtils.toBytes("696d697373796f7568616e6765656e61", 16));
03.    String transformation = "AES/CBC/PKCS5Padding";
04.    Cipher cipher = Cipher.getInstance(transformation);
05.    cipher.init(Cipher.ENCRYPT_MODE, key);
06.      
07.    String str = "hello123";
08.    byte[] plain = str.getBytes();
09.    byte[] encrypt = cipher.doFinal(plain);
10.    System.out.println("원문 : " + ByteUtils.toHexString(plain));
11.    System.out.println("암호 : " + ByteUtils.toHexString(encrypt));
12.      
13.    cipher.init(Cipher.DECRYPT_MODE, key);
14.    byte[] decrypt = cipher.doFinal(encrypt);
15.    System.out.println("복호 : " + ByteUtils.toHexString(decrypt));
16.}

* 실행 결과 원문 : 68656c6c6f313233
암호 : 92e4fa9add0d4d5a07954207890e5b5c
Exception in thread "main" java.security.InvalidAlgorithmParameterException: Parameters missing
...생략...

실행해보면 암호화는 되는데, 복호화도중 파라메터가 없다고 에러가 발생한다. 예상한데로라면 암호화할때도 에러가 나야하는데, 불행히도 암호화는 정상적으로 작동한다. 왜냐면 암호화할때는 IV를 지정해주지 않으면, 자동적으로 랜덤 IV를 만들어서 사용해버린다.
정말인지 테스트해보자.
01.public static void main(String[] args) throws Exception {
02.    Key key = generateKey("AES", ByteUtils.toBytes("696d697373796f7568616e6765656e61", 16));
03.    String transformation = "AES/CBC/PKCS5Padding";
04.    Cipher cipher = Cipher.getInstance(transformation);
05.    cipher.init(Cipher.ENCRYPT_MODE, key);
06.      
07.    String str = "hello123";
08.    byte[] plain = str.getBytes();
09.    byte[] encrypt = cipher.doFinal(plain);
10.    System.out.println("원문 : " + ByteUtils.toHexString(plain));
11.    System.out.println("암호 : " + ByteUtils.toHexString(encrypt));
12.      
13.    cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(cipher.getIV()));
14.    byte[] decrypt = cipher.doFinal(encrypt);
15.    System.out.println("복호 : " + ByteUtils.toHexString(decrypt));
16.}

* 실행 결과
원문 : 68656c6c6f313233
암호 : 26c7d1d26c142de0a3b82f7e8f90860a
복호 : 68656c6c6f313233
new IvParameterSpec(cipher.getIV())을 이용해서 자동 생성된 IV를 초기화 파라메터를 넘겨주니 정상 작동한다.
실제 사용할때는 암호화 복호화가 따로(?) 작동하니 이렇게 구현하는건 불가능할것이다. IV의 크기는 블럭크기와 동일하므로 키처럼 생성해서 잘 관리하면 되겠다.
01.public static void main(String[] args) throws Exception {
02.    Key key = generateKey("AES", ByteUtils.toBytes("696d697373796f7568616e6765656e61", 16));
03.    byte[] iv = ByteUtils.toBytes("26c7d1d26c142de0a3b82f7e8f90860a", 16);
04.    String transformation = "AES/CBC/PKCS5Padding";
05.    IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
06.    Cipher cipher = Cipher.getInstance(transformation);
07.    cipher.init(Cipher.ENCRYPT_MODE, key, ivParameterSpec);
08.      
09.    String str = "hello123";
10.    byte[] plain = str.getBytes();
11.    byte[] encrypt = cipher.doFinal(plain);
12.    System.out.println("원문 : " + ByteUtils.toHexString(plain));
13.    System.out.println("암호 : " + ByteUtils.toHexString(encrypt));
14.      
15.    cipher.init(Cipher.DECRYPT_MODE, key, ivParameterSpec);
16.    byte[] decrypt = cipher.doFinal(encrypt);
17.    System.out.println("복호 : " + ByteUtils.toHexString(decrypt));
18.}

* 실행 결과
원문 : 68656c6c6f313233
암호 : 1876c3ae98760ccf1821ea46fc9ce761
복호 : 68656c6c6f313233
6. 파일을 AES 암호화/복호화 해보기
 - 이번에 파일을 읽어와서 암호화/복호화를 해보자. JavaIO를 다룰 수 있으면 간단히 구현할 수 있을것이다.
01.public static void main(String[] args) throws Exception {
02.      
03.    Key key = generateKey("AES", ByteUtils.toBytes("696d697373796f7568616e6765656e61", 16));
04.    String transformation = "AES/ECB/PKCS5Padding";
05.    Cipher cipher = Cipher.getInstance(transformation);
06.    cipher.init(Cipher.ENCRYPT_MODE, key);
07.    File plainFile = new File("c:/plain.txt");
08.    File encryptFile = new File("c:/encrypt.txt");
09.    File decryptFile = new File("c:/decrypt.txt");
10.      
11.    BufferedInputStream input = null;
12.    BufferedOutputStream output = null;
13.    try {
14.        input = new BufferedInputStream(new FileInputStream(plainFile));
15.        output = new BufferedOutputStream(new FileOutputStream(encryptFile));
16.          
17.        int read = 0;
18.        byte[] inBuf = new byte[1024];
19.        byte[] outBuf = null;
20.        while ((read = input.read(inBuf)) != -1) {
21.            outBuf = cipher.update(inBuf, 0, read);
22.            if (outBuf != null) {
23.                output.write(outBuf);
24.            }
25.        }
26.        outBuf = cipher.doFinal();
27.        if (outBuf != null) {
28.            output.write(outBuf);
29.        }
30.    } finally {
31.        if (output != null) try {output.close();} catch(IOException ie) {}
32.        if (input != null) try {input.close();} catch(IOException ie) {}
33.    }
34.              
35.    cipher.init(Cipher.DECRYPT_MODE, key);
36.    try {
37.        input = new BufferedInputStream(new FileInputStream(encryptFile));
38.        output = new BufferedOutputStream(new FileOutputStream(decryptFile));
39.          
40.        int read = 0;
41.        byte[] inBuf = new byte[1024];
42.        byte[] outBuf = null;
43.        while ((read = input.read(inBuf)) != -1) {
44.            outBuf = cipher.update(inBuf, 0, read);
45.            if (outBuf != null) {
46.                output.write(outBuf);
47.            }
48.        }
49.        outBuf = cipher.doFinal();
50.        if (outBuf != null) {
51.            output.write(outBuf);
52.        }
53.    } finally {
54.        if (output != null) try {output.close();} catch(IOException ie) {}
55.        if (input != null) try {input.close();} catch(IOException ie) {}
56.    }
57.}

"plain.txt"란 파일을 만들어 놓고 실행하면, "encrypt.txt"와 "decrypt.txt" 파일이 생성될것이다. 제대로 암호화 복호화되었는지 비교해보자.
7. 비밀번호 암호화
 - 대부분의 사이트에서 비밀번호를 암호화한다.(불행히도 안하는곳도 많다.) 위에서 배운 블럭암호화 알고리즘으로 암호화를 한다면, 사이트 관리자들은 비밀번호를 다 알 수 있을것이다. (키를 해당 사이트에서 관리하므로, 키를 알면 복호화가 가능하다.) 정말 기분 나쁘다. 타인이 나의 비밀번호를 안다는것은... 그러면 관리자들도 모르게 암호화를 할려면 어떻게 해야할까?
아주 간단하다. 암호화에 사용하는 키 자체를 평문 즉, 비밀번호로 사용하면 된다. 아래 처럼 구현하면 본인만 알 수가 있는것이다. 암호화 할려는 비밀번호 자체가 두 역활을 동시에 하는것이다. 한번 구현해보자.
01.public static void main(String[] args) throws Exception {
02.    String password = "mypassword";
03.      
04.    byte[] passwordBytes = password.getBytes();
05.    int len = passwordBytes.length;
06.    byte[] keyBytes = new byte[16];
07.    if (len >= 16) {
08.        System.arraycopy(passwordBytes, 0, keyBytes, 0, 16);
09.    } else {
10.        System.arraycopy(passwordBytes, 0, keyBytes, 0, len);
11.        for (int i = 0; i < (16 - len); i++) {
12.            keyBytes[len + i] = passwordBytes[i % len];
13.        }
14.    }
15.      
16.    Key key = generateKey("AES", keyBytes);
17.    String transformation = "AES/ECB/PKCS5Padding";
18.    Cipher cipher = Cipher.getInstance(transformation);
19.    cipher.init(Cipher.ENCRYPT_MODE, key);
20.      
21.      
22.    byte[] plain = password.getBytes();
23.    byte[] encrypt = cipher.doFinal(plain);
24.    System.out.println("원문 : " + ByteUtils.toHexString(plain));
25.    System.out.println("암호 : " + ByteUtils.toHexString(encrypt));
26.      
27.    cipher.init(Cipher.DECRYPT_MODE, key);
28.    byte[] decrypt = cipher.doFinal(encrypt);
29.    System.out.println("복호 : " + ByteUtils.toHexString(decrypt));
30.}

  키는 패딩이 안되기 때문에 자체적으로 길이를 맞춰줘야한다. 여기서는 16바이트보다 크면 자르고, 16바이트보다 작으면 입력받는 비밀번호 문자를 반복해서 뒤에 붙여두는식으로 구현하였다.
 이런 방식이 귀찮다면 블럭 암호화 방법 대신, MD5나 SHA1으로 메시지 해쉬값을 저장해서 그 값을 비교해도 된다. (이 방식은 복호화가 안된다.) my-sql password() 함수가 SHA1을 이용하는데, 다음번에 알아보도록 하자.

2009. 9. 14. 16:51

자바 정리 참고 1




<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /> 

ResourceBundle 클래스, Properties 클래스 

ResourceBundle 클래스
Properties
클래스
 

jsp 파일에서 web.xml 의 값 읽어오기

################################################

ResourceBundle 클래스
리소스번들을 이용하여 프로퍼티 파일을 읽어오기
# Res_test.properties
SINCE_YEAR=2007
SINCE_MONTH=9
SINCE_DATE=2
SINCE_DAY=Sunday

import java.util.ResourceBundle;
import java.util.Enumeration;

public class ResourceBundleTest
{
 public static void main(String[] args)
 {
  ResourceBundle bundle = null;
  try{
   bundle = ResourceBundle.getBundle("Res_test");//test.Res_test

   Enumeration enum1 = bundle.getKeys();
   for(; enum1.hasMoreElements() ; ){
    String name = (String)enum1.nextElement();
    String value = bundle.getString(name);
    System.out.println(name+" : "+value);
   }
  }catch(Exception e){
   e.toString();
  }
 }
}


################################################
Properties
클래스
프로퍼티 파일에 입력하고 불러오는 PropertyTest .java 파일

import java.util.*;
import java.io.*;
/*
 * Can use globels.properties
 * Properties
 **/
class Property_Sub{
  
 private String PROPERTIES_FILE="C://java/exam/globals.properties";//globals.properties
 
 public String getProperty(String keyName){
  String value = null;
  try{
   Properties props =  new Properties();
   FileInputStream fis  = new FileInputStream(PROPERTIES_FILE);
   props.load(new java.io.BufferedInputStream(fis));
   value = props.getProperty(keyName).trim();
   fis.close();   
  }catch(java.lang.Exception e){
   e.printStackTrace();
  } 
  return value;
 }
 
 public void setProperty(String keyName, String value){
  try{
   Properties props = new Properties();
   FileInputStream fis  = new FileInputStream(PROPERTIES_FILE);
   props.load(new java.io.BufferedInputStream(fis));
   props.setProperty(keyName, value);
   props.store(new FileOutputStream(PROPERTIES_FILE), "");
   fis.close();
  }catch(java.lang.Exception e){
   e.printStackTrace();
  }
 }
 
}

public class PropertyTest extends Property_Sub{
 
 public static void main(String[] args){
  
  PropertyTest o = null;
  
  if(args.length == 1){
   o = new PropertyTest();
   System.out.println (args[0] + " : " + o.getProperty(args[0]) );
  }
  else if(args.length == 2){
   o = new PropertyTest();
   o.setProperty(args[0], args[1]);
   System.out.println(args[0] + " : " + o.getProperty (args[0]) );
  }
  else{
   System.out.println("wrong argument");
   
  }
  
 }
}
#
#globals.properties
db=sadong
driver=oracle
name=richard

################################################
jsp
파일에서 web.xml 의 값 읽어오기

web.xml 에는
<context-param>
  <param-name>jdf.config.file</param-name>
  <param-value>D:\eclipse\WEB-INF\jdf.properties</param-value>
</context-param>

jsp 에서는
getServletContext().getInitParameter("jdf.config.file")
 

################################################
import java.util.ResourceBundle;

ResourceBundle userxconfig = ResourceBundle.getBundle("com.aaa.bbb.userxconfig");
String CURR_HOST = (String)userxconfig.getObject("currHost");

===============

userxconfig.properties 파일에
currHost=
www.naver.com

이라는 부분이 있을 경우

CURR_HOSTwww.naver.com이 할당된다.

 

 

 

JSP 기초과정

1. JSP 개요

2. 설치와 Setting

3. JSP에서 사용하는 스크립팅 요소들

4. JSP 유용한 클래스

 

#####################################################################

1. JSP 개요

- 서블릿(Servlet) CGI 프로그래밍에 대한 자바 기술의 대안이다.

- CGI 프로그램이 비교적 빠른 수행능력을 보인다면 프로세스가 시작할 때의 오버헤드를 빠른 수행시간으로 메울 수 있지만

그렇지 못하다. 서블릿을 쓸 때는 자바 가상 머신이 떠 있는 상태에서 각 요청이 들어올 때 마다 프로세스보다 가벼운 자바

스레드가 실행된다.

- Java Server Pages (JSP)는 동적인 HTML과 정적으로 생성된 HTML을 섞어 주는 기술이다. JSP

디자인 부분과 로직 부분이 나뉘어 있어 쉽게 일을 분리할 수 있다.

 

#####################################################################

2. 설치와 Setting

- 사용환경 J2SDK1.4 / Tomcat5.0 / MySQL4.0

- CLASSPATH란 자바가 어디서 클래스를 찾을 수 있는지 명시해 놓은 변수다. 이것이 명시되어 있지 않다면 자바는 현재

디렉토리와 표준 시스템 라이브러리에서 클래스를 찾게 된다. CLASSPATH를 설정할 때 현재 디렉토리를 나타내는 '.'

빼놓지 않도록 유의한다.

 

2.1 Unix (C Shell)

setenv CLASSPATH .:servlet_dir/servlet.jar:servlet_dir/jsp.jar:$CLASSPATH

 

2.2 Windows 95/98/NT

set CLASSPATH=.;servlet_dir/servlet.jar;servlet_dir/jsp.jar;%CLASSPATH%

 

2.3 Path setting

ex1) Windows98 - 시작\실행\sysedit\AUTOEXEC.BAT

 SET PATH=%PATH&;C:\JDK1.4\BIN

 SET JAVA_HOME=C:\j2sdk1.4

 SET TOMCAT_HOME=C:\TOMCAT4

 SET CLASSPATH=.;C:\tomcat5\common\lib\servlet-api.jar

 

ex2) WindowsXP, Windows2000 - 내컴퓨터\등록정보\환경변수\시스템변수

 PATH          C:j2sdk1.4\bin

 JAVA_HOME     C:\j2sdk1.4

 CATALINA_HOME C:\Tomcat5

 

2.4 Classpath setting servlet_api.jar, rt.jar 세팅함

CLASSPATH       .;C:\tomcat5\common\lib\servlet-api.jar

               ;C:\j2sdk1.4\jre\lib\rt.jar

(JDK1.2이후는 classpath를 따로 지정하지 않아도 됨)

참고 SET CLASSPATH=%CLASSPATH%;c:\tomcat4\lib\servlet.jar;c:\jdk1.3\jdbc\mm.mysql-2.02-bin.jar

톰켓에서만 JDBC를 사용하려면 TOMCAT\LIB밑에 mm.mysql-2.0.2-bin.jar파일을 복사

 

http://mmmysql.sourceforge.net mm.mysql-2.0.1-bin.jar를 다운받는다.

http://dev.mysql.com/downloads/connector/j/3.1.html 에서

mysql-connector-java-3.1.10.zip 다운받는다

 

- 확인방법 java -version, javap org.gjt.mm.mysql.Driver로 확인

c:\mysql\bin>mysql-max-nt -install

c:\mysql\bin>net start mysql

c:\mysql\bin>net stop mysql

c:\mysql\bin>mysql -u root -p

mysql>show databases;

mysql>show tables;

mysql>use mydb;

mysql>desc tablename;

mysql>create mydb;

mysql>exit;

 

"로드하고 연결하고 실행한다"

Class.forName("org.gjt.mm.mysql.Driver");

Class.forName("oracle.jdbc.dirver.OracleDriver");

Class.forName("sun.jdbc.odbc.jdbcOdbcDriver");

Class.forName("postgresql.Driver");

 

Connection conn =

DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb","id","passwd");

Connection conn =

DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:ORCL","id","passwd");

Connection conn =

DriverManager.getConnection("jdbc:odbc:odbc원본명","id","passwd");

 

 

2.5 작업용 Context를 하나 만들기로 하자.

- c:\tomcat5\webapps\bit 라는 디렉토리를 만들자.

- c:\tomcat5\conf\server.xml에서 </host> 앞쪽에 다음을 추가하자.

 

----------------------------------------------------------------

<!-- Tomcat bit Context -->

<Context path="/bit" docBase="c:/tomcat5/webapps/bit" debug="0"

reloadable="true" />

-----------------------------------------------------------------

- c:\tomcat5\webapps\bit\WEB-INF\web.xml을 아래와 같이 만들자.

------------------------------------------------------------------

<?xml version="1.0" encoding="ISO-8859-1"?>

<!DOCTYPE web-app

PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"

"http://java.sun.com/dtd/web-app_2_3.dtd">

 

<web-app>

<servlet>

<servlet-name>HelloWorld</servlet-name>

<servlet-class>HelloWorld</servlet-class>

</servlet>

 

<servlet-mapping>

<servlet-name>HelloWorld</servlet-name>

<url-pattern>/servlet/HelloWorld</url-pattern>

</servlet-mapping>

</web-app>

------------------------------------------------------------------

Tomcat5.0 이하 버젼에서는 서블릿을 실행할때 설정하는 web.xml 내용임

<?xml version="1.0" encoding="ISO-8859-1"?>

<!DOCTYPE web-app

   PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"

   "http://java.sun.com/dtd/web-app_2_3.dtd">

<web-app>

 <display-name>Welcome to Tomcat</display-name>

 <description>

    Welcome to Tomcat

 </description>

 <servlet-mapping>

       <servlet-name>invoker</servlet-name>

       <url-pattern>/servlet/*</url-pattern>

  </servlet-mapping>

</web-app>

 

 

2.6. c:\tomcat5\webapps\bit\WEB-INF\classes 디렉토리를 만들고

C:\j2sdk1.4\bin\java.exe -jar -Duser.dir="C:\Tomcat4.1"

"C:\Tomcat4.1\bin\bootstrap.jar" start

 

HelloWorld.java 서블릿을 만들자.

 

//HelloWorld.java

import java.io.*;

import javax.servlet.*;

import javax.servlet.http.*;

 

public class HelloWorld extends HttpServlet {

       public void doGet(HttpServletRequest req, HttpServletResponse res)

throws ServletException, IOException{

       res.setContentType("text/html; charset=euc-kr");

       PrintWriter out = res.getWriter();

 

       out.println("<html>");

       out.println("<head><title>Hello World!</title></head>");

       out.println("<body>");

       out.println("<BIG>Hello World!</BIG>");

       out.println("</body></html>");

       }

}

 

#####################################################################

3. JSP에서 사용하는 스크립팅 요소들

 

- 스크립트들과 그 역할

- 스크립트렛(Scriptlet) <% %>  _jspService에 프로그램 추가

- 표현식(Expressions) <%= %>   _jspService에 프로그램 추가(out.print의 간략화)

- 선언문(Declarations) <%! %>  .java파일에 멤버필드와 멤버메서드 추가

- 지시문(Directives) <%@ %>    .java파일에 여러 가지 속성 정하기(지시문의 형태에 따라 .java파일의

적당한 장소에 추가)

 

java.io (PrintWriter 등을 위해서)

javax.servlet (HttpServlet 등을 위해서)

javax.servlet.http (HttpServletRequest HttpServletResponse를 위해서)

 

"javac directory\ServletClass.java" (윈도 사용자; 백 슬래시)

"javac directory /ServletClass.java" (유닉스 사용자; 슬래시)

 

3.1 Page 지시문과 import 사용하기

ex)

- Date.jsp, contentType="text/html;charset=ksc5601"  8859_1

 

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

 

<%@ page import="java.util.*"%>

<%

       Date date = new Date();

       out.println("오늘의 날짜는 "+date);

%>

 

 

ex) <%@ page 속성="" %>

<%@ page session="false"%> 기본값은 true, session 을 사용할 것인지 여부

<%@ page isThreadSafe="true"%> 기본값은 false, 여러클라이언트의 요청이 동시에 이루어질때 문제가

일어나는 것을 막고자할때 사용

<%@ page errorPage="error.jsp"%> 에러가 발생되었을때 이동하는 페이지

<%@ page isErrorPage="true"%> 이페이지가 에러페이지로 사용되는 페이지인지 아닌지정함

 

3.2 JSP 내장 객체 - 9

- out, request, response, session

- pageContext(javax.servlet.jsp.PageContent) - 내장객체와 page 지령문의 몇가지 속성을 초기화할때

- application(javax.servlet.ServletContent) - 애플리케이션에 대한 정보를 가져올때

- config(javax.servlet.ServletCongfig) - ServletConfig의 내장객체

- page(javax.servlet.jsp.HttpJspPage) - 페이지 자신을 참조하는 객체

- exception(java.lang.Throwable) - 에러페이지에만 사용

 

package org.apache.jsp;  import org.apache.jasper.runtime.*;

<%@ page import="javax.servlet.*, javax.servlet.http.*, javax.servlet.jsp.*"%>

 

1. out 객체

- javax.servlet.jsp.JspWriter 클래스에 대한 내장객체

 

2. request 객체 - get, post, cookie 불러오기(getCookie()), 헤더정보가저오기

- javax.servlet.http.HttpServletRequest 클래스의 내장객체

 

ex1)

- formget.html

<form method="get" action="getform.jsp">

ID: <input type="text" name="id"><br>

PASS: <input type="password" name="pass"><br>

<input type="submit" value="submit"><input type="reset" value="reset">

</form>

- getform.jsp

 

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

<%

 

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

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

       out.println("Id : "+id+"<br>");

       out.println("Password : "+pass+"<hr>");

       out.println("<a href='javascript:history.back(-1)'>Rear</a>";)

%>

ex2)

- formpost.html

<form method="post" action="postform.jsp">

ID: <input type="text" name="id"><br>

PASS: <input type="password" name="pass"><br>

<input type="submit" value="submit"><input type="reset" value="reset">

</form>

- postform.jsp

 

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

<%

 

       String id = new String(request.getParameter("id").getBytes("8859_1"),

"euc-kr");

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

       out.println("Id : "+id+"<br>");

       out.println("Password : "+pass+"<hr>");

       out.println("<a href='javascript:history.back(-1)'>Rear</a>";)

%>

 

ex3)

- headerInfo.jsp

<%

       out.println("현재문서의경로 "+request.getRequestURI());

       out.println("호스트명           "+request.getHeader("HOST"));

       out.println("브라우저       "+request.getHeader("User-Agent"));

       out.println("파일명         "+request.getServletPath());

       out.println("서버명         "+request.getServerName());

       out.println("포트명         "+request.getServerPort());

       out.println("URL

http://"+request.getServerName()+":"+request.getServerPort()+getServletPath());

%>

 

3. response 객체 - mine타입지정, 헤더정보세팅, sendRedirect(), cookie값 저장(addCookie())

 

ex1)

- minesetting.jsp

<%

       response.setContentType("application/zip");

       out.println("hi ~~~");

%>

ex2)

- setheader.jsp

<%

       response.setHeader("Cache-Control","no-store");

       response.setHeader("Pragma","no-cache");

       //response.setHeader("Refresh","5;URL=http://www.yahoo.co.kr") 지정한시간에 url로 이동

%>

 

ex3)

- sendRedirect.jsp

<%

       response.sendRedirect("http://www.google.co.kr");

%>

- javascript.html

<script language="javascript">

       document.location.href='http://www.hotmail.com';

</script>

 

4. session 객체

- javax.servlet.http.HttpSession 에 대한 내장객체

 

#####################################################################

5. JSP 유용한 클래스

 

ex1)

- date-format.jsp

 

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

 

<%@ page import="java.util.*, java.text.*"%>

<%

       try{

               Date date = new Date();

               SimpleDateFormat simpledateformat1 = new

SimpleDateFormat("yyyy-MM-dd h:mm: a");

               String style = "MM-dd-yyyy"

               SimpleDateFormat simpledateformat2 = new SimpleDateFormat(style);

               String today1 = simpledateformat1.format(date);

               String today2 = simpledateformat2.format(date);

 

               out.println("Today "+date+"<br>");

               out.println("Today Expression 1 "+today1+"<br>");

               out.println("Today Experssion 2 "+today2+"<br>");

 

       }catch(Exception e){

               out.println(e);

       }

%>

 

 

5.1 파일관련

ex1)

- fileorg.jsp

 

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

<%@ page import="java.io.*"%>

<%

       try{

 

               String filename = "c:\\tomcat4.1\webapps\\root\\test.txt";

 

               //String filename = "/usr/local/tomcat5.0/webapps/root/test.txt";

               File file = new File(filename);

               file.createNewFile();

               out.println("파일생성<br>");

               if (file != null){

                       FileWriter fw = new FileWriter(filename);

 

                       String text="나는 파일로 쓰여질 문구\n두번째 라인\n세번째 라인";

 

                       fw.write(text);

                       fw.close();

                       out.println("파일쓰기완료<br>");

               }

               FileReader fr = new FileReader(filename);

           BufferedReader br = new BufferedReader(fr);

           //out.println(br.readLine());

           String line;

           while( (line=br.readLine())!=null ){

                          out.println(line+"<br>");

           }

 

               out.println("파일절대경로 "+f.getAbsolutePath());

               out.println("파일이름 "+f.getName());

               out.println("파일디렉토리 "+f.getParent()):

               out.println("파일크기 "+f.length());

               Thread.sleep(5000);

               if (f.exists()){

                       f.delete();

                       out.println("파일삭제");

               }else{

                       out.println("파일없슴");

 

               }

 

       }catch(Exception e){

               out.println(e);

       }

%>

 

<%-- jsp 주석 --%>

<!-- html주석 -->

<%@ include file="copyrigth.jsp"%>

 

#################################################

import java.sql.*;

public class ConnectionTest{

  public static void main(String[] args){

      try{

         Class.forName("org.gjt.mm.mysql.Driver");

         Connection conn =

DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb","root","");

         System.out.println("Connection클래스의 객체 con 생성");

         con.close();

         System.out.println("데이터베이스와 연결을 끊음");

      }catch(Exception e){}

  }

}

#################################################

 

 

유틸소스

import javax.crypto.*;

import javax.crypto.spec.SecretKeySpec;

import javax.crypto.spec.DESKeySpec;

import javax.crypto.spec.IvParameterSpec;

import java.security.*;

import sun.misc.BASE64Decoder;

import sun.misc.BASE64Encoder;

 

import java.io.UnsupportedEncodingException;

import java.security.MessageDigest;

import java.text.SimpleDateFormat;

import java.util.Calendar;

import java.util.Date;

import java.util.StringTokenizer;

import java.util.Vector;

 

import org.w3c.dom.*;

import javax.xml.parsers.DocumentBuilder;

import javax.xml.parsers.DocumentBuilderFactory;

import java.io.File;

import java.util.ArrayList;

import java.util.List;

import java.util.ResourceBundle;

 

public class Util {

        static byte[] seedKeyData = new byte[24];

        public Util(){   

        seedKeyData[0] = 0x01;

        seedKeyData[1] = 0x02;

        seedKeyData[2] = 0x03;

        seedKeyData[3] = 0x04;

        seedKeyData[4] = 0x05;

        seedKeyData[5] = 0x06;

        seedKeyData[6] = 0x07;

        seedKeyData[7] = 0x08;

        seedKeyData[8] = 0x09;

        seedKeyData[9] = 0x10;

        seedKeyData[10] = 0x11;

        seedKeyData[11] = 0x12;

        seedKeyData[12] = 0x13;

        seedKeyData[13] = 0x14;

        seedKeyData[14] = 0x15;

        seedKeyData[15] = 0x16;

        seedKeyData[16] = 0x01;

        seedKeyData[17] = 0x02;

        seedKeyData[18] = 0x03;

        seedKeyData[19] = 0x04;

        seedKeyData[20] = 0x05;

        seedKeyData[21] = 0x06;

        seedKeyData[22] = 0x07;

        seedKeyData[23] = 0x08;

        }

        public static String encTripleDES(String beforeStr) {

        String afterStr = "";

        try {

            SecretKeySpec desKey = new SecretKeySpec(seedKeyData, "DESede"); //seedKeyData로 암호화

            Cipher desCipher = Cipher.getInstance("DESede/ECB/PKCS5Padding");

            byte[] cleartext = beforeStr.getBytes();

            desCipher.init(Cipher.ENCRYPT_MODE, desKey);

            byte[] ciphertext = desCipher.doFinal(cleartext);

            afterStr = (new BASE64Encoder()).encode(ciphertext);

        } catch (Exception e) {

            e.printStackTrace();

        }

        return afterStr;

    }

    public static String decTripleDES(String beforeStr) {        

        String afterStr = "";

        try {

            SecretKeySpec desKeyD = new SecretKeySpec(seedKeyData, "DESede");

            Cipher desCipherD = Cipher.getInstance("DESede/ECB/PKCS5Padding");

            desCipherD.init(Cipher.DECRYPT_MODE, desKeyD);

            byte[] decodedBytes = (new BASE64Decoder()).decodeBuffer(beforeStr);

            byte[] cleartext1 = desCipherD.doFinal(decodedBytes);

            afterStr = new String(cleartext1);

        } catch (Exception e) {

            e.printStackTrace();

        }

        return afterStr;

    }

    public static String getDate() {

        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        Date currentTime = new Date();

 

        return formatter.format(currentTime);

    }

    public static String cutRealNumber(String _real, int _cutPlace) {

        String result = _real;

        boolean isNumber = true;

        try {

            Double.parseDouble(_real);

        } catch (NumberFormatException e) {

            isNumber = false;

        }

        if (isNumber) {

            int pointIndex = _real.indexOf('.'); // 소수점 위치.

            if (pointIndex == -1) {

                // 소수점이 없을 때. 12 -> 12.000

                result += ".";

                for (int i = 0; i < _cutPlace; i++)

                    result += "0";

            } else {

                // 소수점이 있을 때.

                int decimalCount = (_real.length() - 1) - pointIndex; // 소수점 이하 개수 .

                if (_cutPlace > decimalCount) {

                    // 12.1 -> 12.100, 0.0 -> 0.000

                    for (int i = 0; i < _cutPlace - decimalCount; i++)

                        result += "0";

                } else if (_cutPlace < decimalCount) {

                    // 12.12345 -> 12.123

                    result = _real.substring(0, pointIndex + _cutPlace + 1);

                }

            }

        }

        return result;

    }

    public static String encode(String _origin) {

        String result = null;

        try {

            MessageDigest md5 = MessageDigest.getInstance("MD5");

            md5.update(_origin.getBytes());

            byte[] md5Password = md5.digest();

            BASE64Encoder enc = new BASE64Encoder();

            result = enc.encode(md5Password);

        } catch (Exception e) {

            e.printStackTrace();

        }

        return result;

    }

    public static String utfTo8859(String _str) {

        String result = "";

        try {

            if (_str != null)

                result = new String(_str.getBytes("UTF-8"), "8859_1");

        } catch (UnsupportedEncodingException e) {

            e.printStackTrace();

        }

        return result;

    }

    public static String kscTo8859(String _str) {

        String result = "";

        try {

            if (_str != null)

                result = new String(_str.getBytes("KSC5601"), "8859_1");

        } catch (UnsupportedEncodingException e) {

            e.printStackTrace();

        }

        return result;

    }

    public static String toKSC(String _str) {

        String result = "";

        try {

            if (_str != null)

                result = new String(_str.getBytes("8859_1"), "KSC5601");

        } catch (UnsupportedEncodingException e) {

            e.printStackTrace();

        }

        return result;

    }

    public static String toUTF(String _str) {

        String result = "";

        try {

            if (_str != null)

                result = new String(_str.getBytes("8859_1"), "UTF-8");

        } catch (UnsupportedEncodingException e) {

            e.printStackTrace();

        }

        return result;

    }

    // Unicode 2.0 -> Unicode 1.2

    public static String toUni12(String uni20) {

        int len = uni20.length();

        char[] out = new char[len];

        for (int i = 0; i < len; i++) {

            char c = uni20.charAt(i);

            if (c < 0xac00 || 0xd7a3 < c) {

                out[i] = c;

            } else  // 유니코드 2.0 한글 영역

            {

                try {

                    byte[] ksc = String.valueOf(c).getBytes("KSC5601");

                    if (ksc.length != 2) {

                        out[i] = '\ufffd';

                        System.err.println("Warning: Some of Unicode 2.0 hangul character was ignored.");

                    } else {

                        out[i] = (char) (0x3400 +

                                ((ksc[0] & 0xff) - 0xb0) * 94 +

                                (ksc[1] & 0xff) - 0xa1);

                    }

                } catch (UnsupportedEncodingException ex) {

                    throw new InternalError("Fatal Error: KSC5601 encoding is not supported.");

                }

            }

        }

        return new String(out);

    }

    // Unicode 1.2 -> Unicode 2.0

    public static String fromUni12(String uni12) {

        if (uni12 == null)

            uni12 = "";

        int len = uni12.length();

        char[] out = new char[len];

        byte[] ksc = new byte[2];

        for (int i = 0; i < len; i++) {

            char c = uni12.charAt(i);

            if (c < 0x3400 || 0x4dff < c) {

                out[i] = c;

            } else if (0x3d2e <= c) // 유니코드 1.2 한글 보충 영역 A, B

            {

                System.err.println("Warning: Some of Unicode 1.2 hangul character was ignored.");

                out[i] = '\ufffd';

            } else // 유니코드 1.2 KSC5601 대응 한글 영역

            {

                try {

                    ksc[0] = (byte) ((c - 0x3400) / 94 + 0xb0);

                    ksc[1] = (byte) ((c - 0x3400) % 94 + 0xa1);

                    out[i] = new String(ksc, "KSC5601").charAt(0);

                } catch (UnsupportedEncodingException ex) {

                    throw new InternalError("Fatal Error: KSC5601 encoding is not supported.");

                }

            }

        }

        return new String(out);

    }

    public String removeSpecialChar(String str) throws Exception {

        if (str == null || str.trim().length() == 0) return "";

        StringBuffer data = new StringBuffer(str);

        StringBuffer buf = new StringBuffer();

        for (int i = 0; i < data.length(); i++) {

            char c = data.charAt(i);

            if (((int) c > 47 && (int) c < 58)

                    || ((int) c > 64 && (int) c < 91)

                    || ((int) c > 96 && (int) c < 123))

                buf.append(c);

        }

 

        return buf.toString();

    }

    public static int cpMapping(int cpNum) {

        if (cpNum == 99)

            cpNum = 0;

        else if (cpNum == 20)

            cpNum = 15;

        else if (cpNum < 1 || cpNum > 15) cpNum = 0;

        return cpNum;

    }

    public static long diffDate(Calendar cal1, Calendar cal2) {

        long cal1sec = cal1.getTime().getTime();

        long cal2sec = cal2.getTime().getTime();

 

        long gap = cal1sec - cal2sec;

 

        long gapday = (gap / 86400) / 1000;

 

        return gapday;

    }

    public static String sqlInsectionProctect(String str) {

        if (str == null) return "";

        str = str.replace('\'', '\\');

        return str;

    }

    public static String removeSlush(String str) throws Exception {

        if (str == null || str.trim().length() == 0) return "";

        int i;

        while ((i = str.indexOf("/")) > -1) {

            str = str.substring(0, i) + str.substring(i + 1);

        }

 

        return str;

    }

    public static String removeDot(String str) throws Exception {

        if (str == null)

            return "";

        else {

            int i = -1;

            if ((i = str.indexOf(".")) > -1) {

                str = str.substring(0, i);

            }

            return str;

        }

    }

    public static String change_Code(String line, String oldString, String newString) {

        for (int index = 0; (index = line.indexOf(oldString, index)) >= 0; index += newString.length())

            line = line.substring(0, index) + newString + line.substring(index + oldString.length());

        return line;

    }

    public static String convertDate(String dateValue, String dateFormat, String gubun) {

        if (dateFormat == null || dateValue == null || dateValue.length() != 10) {

            return dateValue;

        } else if (dateFormat.equals("yyyy-MM-dd")) {

            return dateValue;

        } else {

            StringBuffer transDate = new StringBuffer(15);

            if (dateFormat.equals("dd-MM-yyyy"))

                return transDate.append(dateValue.substring(8, 10)).append(gubun).append(dateValue.substring(5, 7)).append(gubun).append(dateValue.substring(0, 4)).toString();

            else if (dateFormat.equals("MM-dd-yyyy"))

                return transDate.append(dateValue.substring(5, 7)).append(gubun).append(dateValue.substring(8, 10)).append(gubun).append(dateValue.substring(0, 4)).toString();

        }

        return "";

    }

    public static String[] splitString(String inputValue, String deli) {

        StringTokenizer st = null;

        String[] returnValue = null;

        try {

            st = new StringTokenizer(inputValue, deli);

            returnValue = new String[st.countTokens()];

            int i = 0;

            while (st.hasMoreTokens())

                returnValue[i++] = (st.nextToken());

        } catch (Exception ex) {

            returnValue = null;

        }

        return returnValue;

    }

    public static String[] splitStringIncludeNull(String inputValue, String deli) {

        StringTokenizer st = null;

        String[] returnValue = null;

        try {

            Vector returnVec = new Vector();

            st = new StringTokenizer(inputValue, deli, true);

            int count = st.countTokens();

            String previousValue = new String(deli);

            for (int i = 0; i < count; i++) {

                String currentValue = st.nextToken();

                if (previousValue.equals(currentValue)) {

                    returnVec.add("");

                } else {

                    if (!currentValue.equals(deli)) {

                        returnVec.add(currentValue);

                    }

                }

                previousValue = currentValue;

            }

            if (inputValue.substring((inputValue.length() - 1), (inputValue.length())).equals(deli))

                returnVec.add("");

            returnValue = new String[returnVec.size()];

            for (int i = 0; i < returnVec.size(); i++)

                returnValue[i] = (String) returnVec.get(i);

        } catch (Exception ex) {

            ex.printStackTrace();

            returnValue = null;

        }

        return returnValue;

    }

        public static String toEng (String ko)  {

               if (ko == null) {

                       return null;

               }             

               try {

                       return new String(ko.getBytes("KSC5601"),"8859_1");

               } catch(Exception e) {

                       return ko;

               }

        }

        public static String toKor (String en) {

               if (en == null) {

                       return null;

               }

               try {

                       return new String (en.getBytes("8859_1"), "KSC5601");

               } catch(Exception e) {

                       return en;

               }

        }

        /**

     * @param sDATE   : 입력 날짜 ==> 2000/03/09

     * @param sFORMAT : 날짜 형식(대소문자 구분없음) ==> YYYY/MM/DD

     *                ex) validDate("20040429", "yyyymmdd");

     *                validDate("2004-04-29", "yyyy-mm-dd");

     *                validDate("2004/04/29", "yyyy/mm/dd");

     */

    public static boolean validDate(String sDATE, String sFORMAT) {

        boolean bRET = false;

        sFORMAT = sFORMAT.toUpperCase();

        int iYYYY = Integer.parseInt(sDATE.substring(sFORMAT.indexOf("YYYY"), sFORMAT.indexOf("YYYY") + 4));

        int iMM = Integer.parseInt(sDATE.substring(sFORMAT.indexOf("MM"), sFORMAT.indexOf("MM") + 2));

        int iDD = Integer.parseInt(sDATE.substring(sFORMAT.indexOf("DD"), sFORMAT.indexOf("DD") + 2));

        bRET = iYYYY >= 0 && iYYYY < 10000 && iMM > 0 && iMM < 13 && iDD > 0 && iDD < 32;

        return bRET;

    }

  

        public static String checkDate(String input){

               String reVal = null;

               try

               {

                       if (input==null||input.length()!=8)

                       {

                              return input;

                       }else if (input.equals("00000000"))

                       {                     

                              return "99991231";

                       }      

                       Calendar ca = Calendar.getInstance();

                       int year = Integer.parseInt(input.substring(0,4));

                       int month = Integer.parseInt(input.substring(4,6));

                       int date = Integer.parseInt(input.substring(6));

                       ca.set(year, month-1, date);

                       String simple = "yyyyMMdd";

                       SimpleDateFormat simpledateformat = new SimpleDateFormat(simple);

                       reVal = simpledateformat.format(ca.getTime());

               }

               catch (Exception e)

               {

                       e.printStackTrace();

                       return input;

               }

               return reVal;

        }

        /**

        * 파라메터(data)의 스트링을 파라메터(before)인 문자열을 파라메터(after)로 대치한다.

        */

        public static String replaceAll(String data, String before, String after) throws Exception {

               // 쓰기전에 이스케이프 문자 처리

               if (data.length() < before.length())

                       return data;

               StringBuffer buf_data = new StringBuffer(data);

               StringBuffer buf_before = new StringBuffer(before);

               StringBuffer buffer = new StringBuffer();

               for (int i = 0; i < buf_data.length(); i++) {

                       if (buf_data.charAt(i) == buf_before.charAt(0)) {

                              if (i + before.length() <= buf_data.length() && buf_data.substring(i, i + before.length()).equals(before)) {

                                      buffer.append(after);

                                      i += buf_before.length() - 1;

                                      continue;

                              }

                       }

                       buffer.append(buf_data.charAt(i));

               }

               return buffer.toString();

        }

 

        public static String nvl(String str, String str2) {

               String retVal = null;

               if (str == null) {

                       retVal = str2;

               } else {

                       retVal = str;

               }

               return retVal;

        }

 

        public static void main(String[] args){

               try{

                       if (args.length > 0) {

                              for (int i = 0; i < args.length; i++) {

                                      String s = Util.encTripleDES(args[i]);

                                      String s1 = Util.decTripleDES(s);

                                      System.out.println("Original     ["+args[i]+"]");

                                      System.out.println("encTripleDES ["+s+"]");

                                      System.out.println("decTripleDES ["+s1+"]");

                              }      

                       }      

               } catch (Exception e) {

                       e.printStackTrace();

               }             

        }

}

 

 

 

자바소스 정리

01. ServerSocket Socket 간의 채팅 소스

02. Swing에서 이미지 아이콘 삽입 및 종료

03. RMI 정상적인 예제

04. RMI registry 등록하지 않고 사용

05. RMI 통신법

06. Directory 찾아서 리스트 만들기

07. IO 관련 소스

08. 파일을 읽는 소스

09. 입력받은 파일을 읽는 소스

10. 스트링을 파일로 저장하는 소스

11. 파일을 저장하는 소스

12. 에디터에는 볼 수 없으나 도스에서는 보임

13. Properties 파일에 관련된 소스

14. 파일과 관련해서 Properties 에서 읽어 오는 소스

15. 읽은 파일입력 후 내용확인하는 소스

16. 입력파일과 저장할 파일을 쓰는 소스

17. 파일을 읽어서 보여주는 소스

18. 2초마다 출력하는 쓰레드 소스

19. 배열과 관련하여

20. 배열로 합계 평균을 내는 소스

21. 프로그램 인수를 받아 평균과 총계를 보여주는 소스

22. 실행되지 않으나 참고해야 할 소스

23. 데이터베이스 커넷션하고 로그파일을 만듬

24. 엔터키를 두르면 검색하는 소스

25. 날짜 포맷 바꾸는 방법

26. Random 클래스로 가져온 값을 중복체크하기

27. TripleDES 을 이용한 암호화 알고리즘

28. MD5로 암호화 하는 알고리즘 (Base64 필요)

29. 버블 소트로 데이타 정렬

30. Random 함수로 받은 값을 중복 체크하는 소소

31. 날짜 관련 함수 이용

32. 특수문자 제거 메소드

33. 암호와 알고리즘을 사용후 복호화 하는 소스와 적용예

34. 특정 폴더에 쌓이는 파일을 없애는 소스

35. 원도우 배치 프로그램 실행하기

36. 메일을 발송하는 프로그램 소스

37. 세션관련 정리 소스

38. 로긴 및 서블릿 관련 소스(한글처리)

39. 쿠키 셋팅에 관한 예제

40. 클래스를 이용하는 샘플예제 소스

41. 버블 소트와 중복체크 예제

42. 날짜 체크하는 메소드 만들기

43. 조건에 맞게 메일을 보내는 소스

44. 로그를 만드는 소스

 

 

#####################################################################

44. 로그를 만드는 소스

#####################################################################

 

import java.io.*;

import java.text.SimpleDateFormat;

import java.util.Date;

 

public class LogMaker{

        static SimpleDateFormat simpledateformat = new SimpleDateFormat("HH:mm:ss");

       

        public static void println(String filename, String log){

               try{

                       Date date = new Date();

                       String pid = simpledateformat.format(date);

                       //System.out.println("LogMaker String pid->/"+pid+"/");

                       FileWriter fw = new FileWriter(filename+".log",true);

                       fw.write(pid + " : "+log+"\n");

                       fw.flush();

                       fw.close();

               } catch(Exception ex){

               }

        }

}

#####################################################################

 

#####################################################################

43. 조건에 맞게 메일을 보내는 소스

#####################################################################

 

import java.sql.*;

import java.util.*;

import java.io.*;

import javax.mail.*;

import javax.mail.internet.*;

import java.util.StringTokenizer;

import java.text.SimpleDateFormat;

import java.util.Date;

 

public class AirforwarderMailNCC extends Thread

{

        public static void main(String[] args) throws MessagingException

        {

                       Connection  conn_0 = null;

                       PreparedStatement pstmt_0 = null;

                       ResultSet rs_0 = null;

                      

                       String sDB_URL = "jdbc:oracle:thin:@165.213.251.202:1521:itts";

                       String sDB_USER = "itts";

                       String sDB_PASSWORD = "skan00";

              

                             

                       String name ="PTS_AirforwarderNCC";

                       String from = "pts.sec@samsung.com";

                       String to = null;

                       String title = "Notice from PTS";

                       String contents = null;

                       String host = "203.254.221.26"; 

                      

                       String logDir = "log";

                       SimpleDateFormat simpledateformat = new SimpleDateFormat("yyyy-MM-dd");

                       Calendar c = Calendar.getInstance();

                       Date d = c.getTime();

                       String fid = simpledateformat.format(d);

                       File resultFile = new File(logDir, fid);

                       if(resultFile.exists()== false)

                              resultFile.mkdir();

                       logDir = logDir + File.separator + fid;

                      

                       boolean ok1 = false, ok2 = false, ok3 = false;

 

                       try{

                              Class.forName("oracle.jdbc.driver.OracleDriver");                       

                             

                              StringBuffer sbSql_0 = new StringBuffer();                            

                             

                              sbSql_0.append(" SELECT EMAIL, USER_NAME, USER_ID FROM USER_INFO U, BASIC_CODE B WHERE  U.COMPANY_CODE=B.CODE AND DESC2 like 'AIR%' AND U.EMAIL IS NOT NULL AND U.STATUS='approved' AND U.PTS_MAIL='T' AND USER_TYPE='CARRIERLOAD' ");

                              conn_0 = DriverManager.getConnection(sDB_URL, sDB_USER, sDB_PASSWORD);

                              pstmt_0 = conn_0.prepareStatement(sbSql_0.toString());

                              rs_0 = pstmt_0.executeQuery();                        

                              int cnt_total = 0;

                             

                              while(rs_0.next()){     

                             

                                      int cnt_new = 0, cnt_change = 0, cnt_cancel = 0;

                                     

                                      to = rs_0.getString("EMAIL");

                                     

                                      //Count 보낼 메일 가져오기                                           

                                      StringBuffer sbSql_newmail = new StringBuffer(); //New Mail Count

                                      sbSql_newmail.append(" SELECT INV_NO, BILLNO_, UPDDATE, GETCONSIGNAME(CONSIG) CONSIG_NAME, GETCONSIGNAME(SHIPPE) SHIPPE_NAME, TRSTYP, MLDTUE, GI_DAT , A.CREDATE FROM INV_DOC A, USER_INFO U WHERE  USER_ID=? AND SHIPPE <> 'C100' AND A.SHIPPE = U.DEALING_SUBSIDIARY_CODE AND A.MLCARI = U.COMPANY_CODE AND MLCARI <> 'SITA' AND SHIPPE <> 'C100' AND TRSTYP = 'AIR' AND A.RCDFLG = 'A' AND A.UPDDATE = '99991231235959' AND MAIL_STS='F' ");

 

                                      Connection conn_1 = DriverManager.getConnection(sDB_URL, sDB_USER, sDB_PASSWORD);

                                      PreparedStatement pstmt_1 = conn_1.prepareStatement(sbSql_newmail.toString());

                                      pstmt_1.setString(1, rs_0.getString("USER_ID")); //순차적으로 조건을 셋팅

                                     

                                      ResultSet rs_1 = pstmt_1.executeQuery();

                                     

                                      while(rs_1.next()){                                           

                                             cnt_new = rs_1.getRow();                                            

                                      }

                                     

                                      pstmt_1.close();

                                      rs_1.close();

                                      conn_1.close();                               

                                     

                                      StringBuffer sbSql_changemail = new StringBuffer(); //Changed Mail Count

                                      sbSql_changemail.append(" SELECT INV_NO, BILLNO_, UPDDATE, GETCONSIGNAME(CONSIG) CONSIG_NAME, GETCONSIGNAME(SHIPPE) SHIPPE_NAME, TRSTYP, MLDTUE, GI_DAT , A.CREDATE FROM INV_DOC A, USER_INFO U WHERE  USER_ID=? AND SHIPPE <> 'C100' AND A.SHIPPE = U.DEALING_SUBSIDIARY_CODE AND A.MLCARI = U.COMPANY_CODE AND MLCARI <> 'SITA' AND SHIPPE <> 'C100' AND TRSTYP = 'AIR' AND A.RCDFLG = 'A' AND A.UPDDATE <> '99991231235959' AND MAIL_STS='F'  ");

 

                                      Connection conn_3 = DriverManager.getConnection(sDB_URL, sDB_USER, sDB_PASSWORD);

                                      PreparedStatement pstmt_3 = conn_3.prepareStatement(sbSql_changemail.toString());

                                      pstmt_3.setString(1, rs_0.getString("USER_ID")); //순차적으로 조건을 셋팅

                                      ResultSet rs_3 = pstmt_3.executeQuery();

                                     

                                      while(rs_3.next()){                                           

                                             cnt_change = rs_3.getRow();                                         

                                      }

                                      System.out.println("보낼 Change Content 갯수 "+cnt_change);    

                                      pstmt_3.close();

                                      rs_3.close();

                                      conn_3.close();

                             

                                      StringBuffer sbSql_cancelmail = new StringBuffer(); //Canceled Mail Count

                                      sbSql_cancelmail.append(" SELECT INV_NO, BILLNO_, UPDDATE, GETCONSIGNAME(CONSIG) CONSIG_NAME, GETCONSIGNAME(SHIPPE) SHIPPE_NAME, TRSTYP, MLDTUE, GI_DAT , A.CREDATE FROM INV_DOC A, USER_INFO U WHERE  USER_ID=? AND SHIPPE <> 'C100' AND A.SHIPPE = U.DEALING_SUBSIDIARY_CODE AND A.MLCARI = U.COMPANY_CODE AND MLCARI <> 'SITA' AND SHIPPE <> 'C100' AND TRSTYP = 'AIR' AND A.RCDFLG = 'D' AND MAIL_STS='F'        ");

 

                                      Connection conn_5 = DriverManager.getConnection(sDB_URL, sDB_USER, sDB_PASSWORD);

                                      PreparedStatement pstmt_5 = conn_5.prepareStatement(sbSql_cancelmail.toString());

                                      pstmt_5.setString(1, rs_0.getString("USER_ID")); //순차적으로 조건을 셋팅

                                      ResultSet rs_5 = pstmt_5.executeQuery();

                                     

                                      while(rs_5.next()){                                           

                                             cnt_cancel = rs_5.getRow();                                          

                                      }

                                      System.out.println("보낼 Cancel Content 갯수 "+cnt_cancel);     

                                      System.out.println();

                                      pstmt_5.close();

                                      rs_5.close();

                                      conn_5.close();

                                            

                                      // End 메일 카운터 RS_0 ~ RS_7

                                     

                                      //이쪽에서 한개의 메일을 받아서 아래의 컨텐츠를 보내야 함

                                      StringBuffer sbMessage = new StringBuffer();

                                     

                                      sbMessage.append("<html><head>");                                 

                                      sbMessage.append("<style type=\"text/css\" >");

                                      sbMessage.append("BODY,TD,font {");

                                      sbMessage.append("color: #666666; font-family: Arial;   font-size:9pt;line-height: 130%;}");

                                      sbMessage.append("A:link {color:#00639C;text-decoration: underline;}");

                                      sbMessage.append("A:visited {color:#006699;text-decoration:underline;}");

                                      sbMessage.append("A:active {color:#006699;text-decoration:none;}");

                                      sbMessage.append("A:hover {color:#FFFFFF;text-decoration:none;background-color:#E4628B;}");

                                      sbMessage.append("</style></head><body>");

                                     

                                      sbMessage.append("<table width=700 border=0 cellspacing=0 cellpadding=0>");  

                                      sbMessage.append("<tr><td height=4 bgcolor=#CDCDCD><img src=http://www.samsungitts.com/img/ptmail/blank.gif width=1 height=1></td></tr>");

                                      sbMessage.append("<tr><td height=43 bgcolor=#0A79A8><img src=http://www.samsungitts.com/img/ptmail/logo.gif width=127 height=43></td></tr></table>");

                                     

                                      sbMessage.append("<table width=700 border=0 cellspacing=0 cellpadding=0>");

                                      sbMessage.append("<tr><td width=551 class=text><Br><br><p>Dear,  "+rs_0.getString("USER_ID")+"</p><br><br>");

                                                                             

                                      sbMessage.append("Please, check the documents below.<br>");

                                      sbMessage.append("<b>*Total number of new invoices - <b>"+cnt_new+"</b> cases<br> </b>");

                                      sbMessage.append("<b>*Total number of changed invoices - <b>"+cnt_change+"</b> cases<br> </b>");

                                      sbMessage.append("<b>*Total number of canceled invoices - <b>"+cnt_cancel+"</b> cases<br> </b>");

                                                                           

                                      sbMessage.append("Please check it at <a href=http://www.samsungitts.com target=_blank>http://www.samsungitts.com</a></p> <br></p></td>");

                                      sbMessage.append("<td width=149 valign=top><img src=http://www.samsungitts.com/img/ptmail/img.jpg width=160 height=172></td></tr></table>");

 

                                      sbMessage.append("<table width=700 border=0 cellspacing=0 cellpadding=0><tr><td><p><b>New Invoice</b> (You have not opened or printed.)</p></td></tr></table>");

                                      sbMessage.append("<table width=700 border=0 cellspacing=0 cellpadding=0><tr><td bgcolor=#669900>");

                                      sbMessage.append("<table width=700 border=0 cellspacing=1 cellpadding=0>");

                                      sbMessage.append("<tr align=center bgcolor=#BBDD75>");

                                      sbMessage.append("<td height=20><strong>I/V No.</strong></td>");

                                      sbMessage.append("<td height=20><strong>B/L No.</strong></td>");

                                      sbMessage.append("<td height=20><strong>Consignee</strong></td>");

                                      sbMessage.append("<td height=20><strong>Trans Type</strong></td>");

                                      sbMessage.append("<td height=20><strong>ETA</strong></td>");

                                      sbMessage.append("<td height=20><strong>ETD</strong></td></tr>");          

                                     

                                      StringBuffer sbSql_1= new StringBuffer(); // New Mail Send

                                     

                                      sbSql_1.append(" SELECT INV_NO, BILLNO_,  GETCONSIGNAME(CONSIG) CONSIG_NAME,  TRSTYP, MLDTUE, GI_DAT FROM INV_DOC A, USER_INFO U WHERE  USER_ID=? AND SHIPPE <> 'C100' AND A.SHIPPE = U.DEALING_SUBSIDIARY_CODE AND A.MLCARI = U.COMPANY_CODE AND MLCARI <> 'SITA' AND SHIPPE <> 'C100' AND TRSTYP = 'AIR' AND A.RCDFLG = 'A' AND A.UPDDATE = '99991231235959' AND MAIL_STS='F'  ");

                      

                                      Connection conn_9 = DriverManager.getConnection(sDB_URL, sDB_USER, sDB_PASSWORD);

                                      PreparedStatement pstmt_9 = conn_9.prepareStatement(sbSql_1.toString());

                                      pstmt_9.setString(1, rs_0.getString("USER_ID")); //순차적으로 조건을 셋팅

                                     

                                      ResultSet rs_9 = pstmt_9.executeQuery();

                                     

                                      ok1 = false;

                                      while(rs_9.next()){

                                                 ok1 = true;        

                                                     sbMessage.append("<tr align=center bgcolor=#BBDD75>");

                                                     sbMessage.append("<td height=20>"+rs_9.getString("INV_NO")+"</td>");

                                                     sbMessage.append("<td height=20>"+rs_9.getString("BILLNO_")+"</td>");

                                                     sbMessage.append("<td height=20>"+rs_9.getString("CONSIG_NAME")+"</td>");

                                                     sbMessage.append("<td height=20>"+rs_9.getString("TRSTYP")+"</td>");

                                                     sbMessage.append("<td height=20>"+rs_9.getString("MLDTUE")+"</td>");

                                                     sbMessage.append("<td height=20>"+rs_9.getString("GI_DAT")+"</td>");

                                                     sbMessage.append("</tr>");    

                                                    

                                                     //Update

                                                     StringBuffer sb_update0 = new StringBuffer();

                                                     sb_update0.append (" UPDATE INV_DOC SET MAIL_STS='T' WHERE INV_NO=?  ");

                                                     Connection con_update0 = DriverManager.getConnection(sDB_URL, sDB_USER, sDB_PASSWORD);

                                                     PreparedStatement pstmt_update0 = con_update0.prepareStatement(sb_update0.toString());

                                                     pstmt_update0.setString(1, rs_9.getString("INV_NO"));

                                                     ResultSet rs_update0 = pstmt_update0.executeQuery();

                                                     con_update0.commit();

                                                     rs_update0.close();

                                                     pstmt_update0.close();

                                                     con_update0.close();                                         

                                                    

                                      }// 9 For

                                      pstmt_9.close();

                                      rs_9.close();

                                      conn_9.close();

                                      //데이타 없을때 처리

                                      if(!ok1){

                                                     sbMessage.append("<tr bgcolor=#ffffff><td colspan=6><center><b>No Data Found</b></center></td></tr>");

                                      }

                                     

                                      sbMessage.append("</table></table><br><br>");

 

                                      sbMessage.append("<table width=700 border=0 cellspacing=0 cellpadding=0><tr><td><p><b>Changed Invoice</b></p></td></tr></table>");

                                      sbMessage.append("<table width=700 border=0 cellspacing=0 cellpadding=0><tr><td bgcolor=#669900>");

                                      sbMessage.append("<table width=700 border=0 cellspacing=1 cellpadding=0>");

                                      sbMessage.append("<tr align=center bgcolor=#BBDD75>");

                                      sbMessage.append("<td height=20><strong>I/V No.</strong></td>");

                                      sbMessage.append("<td height=20><strong>B/L No.</strong></td>");

                                      sbMessage.append("<td height=20><strong>Consignee</strong></td>");

                                      sbMessage.append("<td height=20><strong>Trans Type</strong></td>");

                                      sbMessage.append("<td height=20><strong>ETA</strong></td>");

                                      sbMessage.append("<td height=20><strong>ETD</strong></td></tr>");

 

                                      StringBuffer sbSql_2= new StringBuffer(); //Changed Mail Send

                                     

                                      sbSql_2.append(" SELECT INV_NO, BILLNO_,  GETCONSIGNAME(CONSIG) CONSIG_NAME,  TRSTYP, MLDTUE, GI_DAT FROM INV_DOC A, USER_INFO U WHERE  USER_ID=? AND SHIPPE <> 'C100' AND A.SHIPPE = U.DEALING_SUBSIDIARY_CODE AND A.MLCARI = U.COMPANY_CODE AND MLCARI <> 'SITA' AND SHIPPE <> 'C100' AND TRSTYP = 'AIR' AND A.RCDFLG = 'A' AND A.UPDDATE <> '99991231235959' AND MAIL_STS='F'  ");

                                     

                                      Connection conn_10 = DriverManager.getConnection(sDB_URL, sDB_USER, sDB_PASSWORD);

                                      PreparedStatement pstmt_10 = conn_10.prepareStatement(sbSql_2.toString());

                                      pstmt_10.setString(1, rs_0.getString("USER_ID")); //순차적으로 조건을 셋팅

                                     

                                      ResultSet rs_10 = pstmt_10.executeQuery();

                                     

                                      ok2 = false ;

                                      while(rs_10.next()){

                                                     ok2 = true;                                                                                                                              

                                                     sbMessage.append("<tr align=center bgcolor=#BBDD75>");

                                                     sbMessage.append("<td height=20>"+rs_10.getString("INV_NO")+"</td>");

                                                     sbMessage.append("<td height=20>"+rs_10.getString("BILLNO_")+"</td>");

                                                     sbMessage.append("<td height=20>"+rs_10.getString("CONSIG_NAME")+"</td>");

                                                     sbMessage.append("<td height=20>"+rs_10.getString("TRSTYP")+"</td>");

                                                     sbMessage.append("<td height=20>"+rs_10.getString("MLDTUE")+"</td>");

                                                     sbMessage.append("<td height=20>"+rs_10.getString("GI_DAT")+"</td>");

                                                     sbMessage.append("</tr>");

                                                     //Do Update    

                                                     System.out.println("Change Invoice Number :::: "+rs_10.getString("INV_NO"));

                                                     StringBuffer sb_update1 = new StringBuffer();

                                                     sb_update1.append (" UPDATE INV_DOC SET MAIL_STS='T' WHERE INV_NO=?  ");

                                                     Connection con_update1 = DriverManager.getConnection(sDB_URL, sDB_USER, sDB_PASSWORD);

                                                     PreparedStatement pstmt_update1 = con_update1.prepareStatement(sb_update1.toString());

                                                     pstmt_update1.setString(1, rs_10.getString("INV_NO"));

                                                     ResultSet rs_update1 = pstmt_update1.executeQuery();

                                                     con_update1.commit();

                                                     rs_update1.close();

                                                     pstmt_update1.close();

                                                     con_update1.close();                                                 

                                                    

                                      } // 10 For

                                      pstmt_10.close();

                                      rs_10.close();

                                      conn_10.close();

                                      if(!ok2){

                                                     sbMessage.append("<tr bgcolor=#ffffff><td colspan=6><center><b>No Data Found</b></center></td></tr>");

                                      }                                            

                                     

                                      sbMessage.append("</table></table><br><br>");

                                     

                                      sbMessage.append("<table width=700 border=0 cellspacing=0 cellpadding=0><tr><td><p><b>Canceled Invoice</b> (The shipper has canceled.)</p></td></tr></table>");

                                      sbMessage.append("<table width=700 border=0 cellspacing=0 cellpadding=0><tr><td bgcolor=#669900>");

                                      sbMessage.append("<table width=700 border=0 cellspacing=1 cellpadding=0>");

                                      sbMessage.append("<tr align=center bgcolor=#BBDD75>");

                                      sbMessage.append("<td height=20><strong>I/V No.</strong></td>");

                                      sbMessage.append("<td height=20><strong>B/L No.</strong></td>");

                                      sbMessage.append("<td height=20><strong>Consignee</strong></td>");

                                      sbMessage.append("<td height=20><strong>Trans Type</strong></td>");

                                      sbMessage.append("<td height=20><strong>ETA</strong></td>");

                                      sbMessage.append("<td height=20><strong>ETD</strong></td></tr>");

 

                                      StringBuffer sbSql_3= new StringBuffer(); //Canceled Mail Send

                                     

                                      sbSql_3.append(" SELECT INV_NO, BILLNO_,  GETCONSIGNAME(CONSIG) CONSIG_NAME,  TRSTYP, MLDTUE, GI_DAT FROM INV_DOC A, USER_INFO U WHERE   SHIPPE <> 'C100' AND A.SHIPPE = U.DEALING_SUBSIDIARY_CODE AND A.MLCARI = U.COMPANY_CODE AND MLCARI <> 'SITA' AND SHIPPE <> 'C100' AND TRSTYP = 'AIR' AND A.RCDFLG = 'D' AND MAIL_STS='F' AND USER_ID=?   ");

                                     

                                     

                                      Connection conn_11 = DriverManager.getConnection(sDB_URL, sDB_USER, sDB_PASSWORD);

                                      PreparedStatement pstmt_11 = conn_11.prepareStatement(sbSql_3.toString());

                                      pstmt_11.setString(1, rs_0.getString("USER_ID")); //순차적으로 조건을 셋팅

                                     

                                      ResultSet rs_11 = pstmt_11.executeQuery();

                                     

                                      ok3 = false ;

                                      while(rs_11.next()){

                                                     ok3 = true;    

                                                     sbMessage.append("<tr align=center bgcolor=#BBDD75>");

                                                     sbMessage.append("<td height=20>"+rs_11.getString("INV_NO")+"</td>");

                                                     sbMessage.append("<td height=20>"+rs_11.getString("BILLNO_")+"</td>");

                                                     sbMessage.append("<td height=20>"+rs_11.getString("CONSIG_NAME")+"</td>");

                                                     sbMessage.append("<td height=20>"+rs_11.getString("TRSTYP")+"</td>");

                                                     sbMessage.append("<td height=20>"+rs_11.getString("MLDTUE")+"</td>");

                                                     sbMessage.append("<td height=20>"+rs_11.getString("GI_DAT")+"</td>");

                                                     sbMessage.append("</tr>");

                                                     //Do Update                                  

                                                     StringBuffer sb_update2 = new StringBuffer();

                                                     sb_update2.append (" UPDATE INV_DOC SET MAIL_STS='T' WHERE INV_NO=?  ");

                                                     Connection con_update2 = DriverManager.getConnection(sDB_URL, sDB_USER, sDB_PASSWORD);

                                                     PreparedStatement pstmt_update2 = con_update2.prepareStatement(sb_update2.toString());

                                                     pstmt_update2.setString(1, rs_11.getString("INV_NO"));

                                                     ResultSet rs_update2 = pstmt_update2.executeQuery();

                                                     con_update2.commit();

                                                     rs_update2.close();

                                                     pstmt_update2.close();

                                                     con_update2.close();                                                 

                                                    

                                      } // 11 For

                                      pstmt_11.close();

                                      rs_11.close();

                                      conn_11.close();

                                      if(!ok3){

                                                     sbMessage.append("<tr bgcolor=#ffffff><td colspan=6><center><b>No Data Found</b></center></td></tr>");

                                      }                             

                                     

                                      sbMessage.append("</table></table><br><br>");

                                     

                                      sbMessage.append("</table></table><br></td></tr></table><br>");

                                      sbMessage.append("<table width=700 border=0 cellspacing=0 cellpadding=0>");  

                                      sbMessage.append("<tr><td height=1 bgcolor=#CDCDCD><img src=http://www.samsungitts.com/img/ptmail/blank.gif width=1 height=1></td>      </tr>");

                                      sbMessage.append("<tr><td align=center>Copyright(c)2003 Samsung Electronics co.,Ltd. All rights reserved.</td></tr></table> </body></html>");

                                                            

                                      contents = sbMessage.toString();                             

                                     

                                      //System.out.println("내용 확인 222222222222 "+contents);

                                      if(ok1 || ok2 || ok3){

                                             StringTokenizer stTo = new StringTokenizer(to, ";");

                                             while(stTo.hasMoreTokens()){

                                                    

                                                     to = stTo.nextToken();

                                                     //메일 클래스 객체 생성

                                                     Properties prop = System.getProperties();      

                                                     Session session = Session.getInstance(prop, null);    

                                                     MimeMessage message = new MimeMessage(session);

                                                     message.setFrom(new InternetAddress(name+"<"+from+">"));

                                                     message.addRecipient(Message.RecipientType.TO,new InternetAddress(to));    

                                                     message.setSubject(title);

                                                     message.setContent(contents,"text/html;charset=euc-kr");

                                                     //message.setText(contents);

                                                    

                                                     Transport transport = session.getTransport("smtp");

                                                     transport.connect(host,"","");    

                                                     transport.sendMessage(message, message.getAllRecipients());

                                                     transport.close();

                                                     LogMaker lm = new LogMaker();

                                                     lm.println(logDir+File.separator+"AirforwarderMailNCC", to);

                                                                                                 

                                             }

                                             ++cnt_total;

                                             System.out.println("Total Mail 갯수 "+cnt_total); 

                                      }else{

                                                     System.out.println("메일을 보내지 않는다");

                                                     System.out.println();

                                      }                                                                  

                              } //Mail For         

                       Thread.currentThread().sleep(50);

                       }catch(ClassNotFoundException e){

                              e.printStackTrace();

                       }catch(SQLException e){

                              e.printStackTrace();

                       }catch(Exception e){

                              e.printStackTrace();

                       }finally{

                              try{

                                      if(pstmt_0 != null){pstmt_0.close();}

                                      if(rs_0 != null){rs_0.close();}

                                      if(conn_0 != null){conn_0.close();}

                                     

                              }catch(Exception e){

                                      e.printStackTrace();

                              }

                       }

        }

}

 

#####################################################################

 

#####################################################################

42. 날짜 체크하는 메소드 만들기

#####################################################################

import java.util.*;

import java.text.*;

public class DateTest

{             

        public String checkDate(String input){                        

               String reVal = null;           

               //리턴 타입을 설정한다

               try

               {             

                       if ( input == null || input.length() != 8 )

                       {

                              return input;

                              //OR의 우선순위는 앞에 있슴. 에러사항을 체크하여 Return을 한다

                       }             

                       Calendar cl = Calendar.getInstance();

                       int yyyy = Integer.parseInt(input.substring(0, 4));

                       int month = Integer.parseInt(input.substring(4, 6));

                       int day = Integer.parseInt(input.substring(6));

                       //입력값에 대해서 substring으로 나누어 가져온다

                       cl.set(yyyy, month-1, day);

                       //Calendar에 년월일을 셋팅한다

                       /*

                       int yy = cl.get(Calendar.YEAR);

                       int mm = cl.get(Calendar.MONTH)+1;

                       int dd = cl.get(Calendar.DATE);                

                       System.out.println(yy +", "+mm+", "+dd);

                       */                    

                       String date_format = "yyyyMMdd";

                       SimpleDateFormat simpledateformat = new SimpleDateFormat(date_format);     

                       reVal = simpledateformat.format(cl.getTime());                                        

               }catch (Exception e)

               {      

                       e.printStackTrace();

                       return input;

               }

               return reVal;

               //try catch 구분 밖에서 Return 타입을 받는다

        }

        public static void main(String[] args)

        {

               DateTest dt = new DateTest();

               System.out.println( dt.checkDate("20050200") );

               //객체를 생성하여 메소드를 호출한다

        }      

}

 

#####################################################################

41. 버블 소트와 중복체크 예제

#####################################################################

import java.util.*;

public class RandomTest

{

        public static void main(String[] args)

        {

               Random random = new Random();

               boolean[] boo = new boolean[45];

               int[] choo = new int[6];

               for (int i=0; i<boo.length ;  )

               {

                       boo[i] = true;

               }

               for (int i=0; i<choo.length ; i++)

               {

                       int num = random.nextInt(45);

                       if (boo[num])

                       {

                              boo[num] = false;

                choo[i] = num+1;

                       }                             

                       System.out.println(choo[i]);

               }

        }

}

class SortTest

{

        public static void main(String[] args)

        {

               String[] str = {"Orange","Apple","Grape","Peach","Lemon"};

               System.out.println("@@@@@ 정렬 전 @@@@@");

               for (int i=0; i<str.length; i++)

               {

                       System.out.println(str[i]);

               }

               System.out.println("@@@@@ 정렬 후 @@@@@");

               for (int j=0; j<str.length ; j++ )

               {

                       for (int i= j+1 ; i<str.length ; i++)

                       {

                              if ( str[i].compareTo(str[j]) < 0 )

                              {

                                      String temp = str[j];

                                      str[j] = str[i];

                                      str[i] = temp;  

                              }

                       }

                       System.out.println(str[j]);                                     

               }

        }

}

#####################################################################

 

#####################################################################

40. 클래스를 이용하는 샘플예제 소스

#####################################################################

class TopScret

{

        private int scret;

        public void setScret(int x){

               scret = x;

        }

        public int getScret(){

               return scret;

        }

}

public class TopScretMain

{

        public static void main(String[] args){

       

               TopScret top = new TopScret();

               top.setScret(4000);

               int i = top.getScret();

               System.out.println("i ->"+i);

               System.out.println("top.getScret() ->"+top.getScret());

        }

};

 

class MeanCalc

{

        private int sum;

        private int num;

        public void setValue(int x, int y, int z, int n){

               sum = x * y * z;

               num = n;

        }

        public int getValue(){

               return sum - num;

        }

}

public class MeanCalcMain

{

        public static void main(String[] args){

               MeanCalc cal = new MeanCalc();

               cal.setValue(100, 40, 500, 6);

               int z = cal.getValue();

               System.out.println("z ->"+z);

               System.out.println("cal ->"+cal);

        }

};

 

class MotorCycle

{

        private int id;

        private int speed;

        public void setData(int x, int y){

               id = x;

               speed = y;

        }

        public void drive(){

               System.out.println("id ->"+id);

               System.out.println("speed ->"+speed);

        }

}

public class MotorCycleMain

{

        public static void main(String[] args){

               MotorCycle m = new MotorCycle();

               m.setData(5384, 120);

               m.drive();

               System.out.println("m ->"+m);

 

               MotorCycle c = m;

               c.setData(7777, 100);

               c.drive();

               System.out.println("c ->"+c);

        }

};

#####################################################################

 

 

#####################################################################

39. 쿠키 셋팅에 관한 예제

#####################################################################

<form method="post" action="setCookie.jsp">

<input type="text" name="id"><br>

<input type="password" name="passwd"><br>

<input type="submit"><input type="reset">

 

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

<%

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

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

        String value = request.getHeader("Cookie");

        if (value == null){

               Cookie cookie = new Cookie(id, passwd);

               cookie.setMaxAge(60);

               response.addCookie(cookie);

               out.println("Setting Cookie<br><hr>");

               out.println("id :"+id+ "<br>passwd :"+passwd);

 

        }else{

               out.println("Have done Cookie<br><hr>");      

               out.println("id :"+id+ "<br>passwd :"+passwd+"<br>");

               Cookie[] cookies = request.getCookies();

               for (int i=0; i<cookies.length; i++){

                       out.println("name :"+cookies[i].getName()+"<br>");

                       out.println("value :"+cookies[i].getValue()+"<br>");

                       out.println("domain :"+cookies[i].getDomain()+"<br>");

                       out.println("maxage :"+cookies[i].getMaxAge()+"<br>");

                       out.println("path :"+cookies[i].getPath()+"<br>");

                       out.println("secure :"+cookies[i].getSecure()+"<br>");

                       out.println("comment :"+cookies[i].getComment()+"<br>");

                       out.println("version :"+cookies[i].getVersion()+"<br>");

               }

 

        }

%>

#####################################################################

 

#####################################################################

38. 로긴 및 서블릿 관련 소스(한글처리)

#####################################################################

<BODY onContextmenu="return false">

<form name="login" action="/ServletJsp/servlet/loginServlet" method="post">

        <table border=1 cellspacing="0" cellpadding="0">

               <tr>

                       <td>User ID  </td>

                       <td><input type="text" name="id" ></td>

               </tr>

               <tr>

                       <td>Password  </td>

                       <td><input type="password" name="passwd"></td>

               </tr>

               <tr>

                       <td colspan=2 align=center>

                       <input type="submit" value="CONFIRM">

                       <input type="reset" value="CANCEL">

                       </td>

               </tr>

        </table>

</form>

</BODY>

import java.io.*;

import javax.servlet.*;

import javax.servlet.http.*;

import util.HangulConversion;

public class loginServlet extends HttpServlet

{

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

        {             

               //res.setContentType("text/html;charset=euc-kr");// 필히 설정함

               //PrintWriter out = res.getWriter();

               res.setContentType("text/html");        

               PrintWriter out = new PrintWriter( new OutputStreamWriter(res.getOutputStream(), "KSC5601"), true );

               String userid = HangulConversion.toKor(req.getParameter("id")); //util 팩키지에서 메소드 이용

               String passwd = req.getParameter("passwd");

               out.println("<html><body>");          

               if ( userid.equals("") && passwd.equals(""))

               {

                       out.println("NOWHERE");

               }else{         

                       out.println("INPUT ID IS :"+ userid +"<br>");

                       out.println("INPUT PASSWORD IS :"+passwd);

               }

               out.println("<p><font size=2><a href=javascript:history.back()>BACK TO THE FUTURE</a></font>");

               out.println("<body></html>");

               out.close();

        }

}

package util;

import java.io.*;

public class HangulConversion

{

        public static String toEng(String ko){

               if (ko ==null)

               {

                       return null;

               }

               try

               {

                       return new String(ko.getBytes("KSC5601"), "8859_1");

               }

               catch (Exception e)

               {

                       return ko;

               }

        }

        public static String toKor(String en){

               if (en == null)

               {

                       return null;

               }

               try

               {

                       return new String(en.getBytes("8859_1"), "KSC5601");

               }

               catch (Exception e)

               {

                       return en;

               }

        }

}

#####################################################################

37. 세션관련 정리 소스

#####################################################################

<form action="sessionCreate.jsp" method="post">

<table border="1" cellspacing=0 cellpadding=0 >

        <tr>

               <td> IDENTIFICATION </td>

               <td><input type=textfield name=id></td>

        </tr>

        <tr align=center>

               <td colspan=2><input type="submit" value="Confirm"><input type="reset" value="Cancel"></td>

        </tr>

<table>

</form>

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

<%@ page import="util.HangulConversion"%>

<html>

<body>

Session Creation<br>

<%

        String id = HangulConversion.toKor(request.getParameter("id"));

        if (id.equals("")){              

               out.println("<hr>No Data<br>");

               out.println("<a href=javascript:history.back()>Back To The Future</a>");

               //response.sendRedirect("sessionLogin.html");

                return;

        }

        HttpSession session = request.getSession(true);

        if(session.isNew()){

               session.setAttribute("id", id); //세션을 설정한다

               out.println("<hr>New session is created :"+ id+"<br>");

               out.println("Session ID :"+session.getId()+"<br>");

               out.println("<a href=sessionRead.jsp>[Get Session]</a><br>");

        }else{

               out.println("<hr>Already exist session<br>");

               out.println("Input Id :"+id +"<br>");

               out.println("Session ID :"+session.getId()+"<br>"); //기존에 만든 세선 Id를 가져온다

               out.println("<a href=sessionRead.jsp>[Get Session]</a>");

        }

%>

</body>

</html>

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

<html>

<body>

<%

        HttpSession session = request.getSession(false);

        String s = (String)session.getAttribute("id");

        if (s == null){

               out.println("Not Session");     

        }else{

               out.println("Attribute id is :"+s+"<br>");

        }

%>

<hr>

isNew() :<%= session.isNew()%><br>

Session ID :<%= session.getId()%><br>

Session Create Time :<%= new java.util.Date(session.getCreationTime()).toString()%><br>

Session Last Time&nbsp;&nbsp;:<%= new java.util.Date(session.getLastAccessedTime()).toString()%><br>

Session Active Time :<%= session.getMaxInactiveInterval()%> sec<br>

<a href="sessionDelete.jsp">[Session Delete]</a> <a href="sessionLogin.html">[Login Page]</a>

</body>

</html>

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

<%

        HttpSession session = request.getSession(false);

        String s = (String)session.getAttribute("id");

        out.println("Id :"+s+"<br><hr>");

        if (session != null){

               session.invalidate();

        }

%>

Delete Session<br>

<a href="sessionLogin.html">Login Page</a>

 

#####################################################################

36. 메일을 발송하는 프로그램 소스

#####################################################################

import java.sql.Connection;

import java.sql.DriverManager;

import java.sql.PreparedStatement;

import java.sql.ResultSet;

import java.sql.SQLException;

import java.util.Hashtable;

import java.util.Properties;

import javax.mail.Message;

import javax.mail.Session;

import javax.mail.Transport;

import javax.mail.internet.InternetAddress;

import javax.mail.internet.MimeMessage;

public class SendMail {

        /**

         * @param pMAIL

         * @param conn

         */

        public Properties sendCronMail(Properties pARGS, Connection conn) {

               Properties pRETURN = new Properties();

               pRETURN.setProperty("RESULT", "true");

               String sMAIL_SMTP_HOST = pARGS.getProperty("MAIL_SMTP_HOST", "203.254.221.26");

               String sEMAIL_ADDRESS_FROM = pARGS.getProperty("EMAIL_ADDRESS_FROM", "swbupload@samsung.com"); // 보내는 사람 주소

               String sEMAIL_ADDRESS_TO = pARGS.getProperty("EMAIL_ADDRESS_TO", "swbupload@samsung.com"); // 받는 사람 주소

               String sSUBJECT = pARGS.getProperty("SUBJECT", "CronMail Error..."); // 타이틀

               String sTEXT = pARGS.getProperty("TEXT", "CronMail Error!!!"); // 내용

               try {

                       Properties pMAIL = System.getProperties();

                       pMAIL.put("mail.smtp.host", sMAIL_SMTP_HOST);

                       Session sMAIL_SESSION = Session.getDefaultInstance(pMAIL, null);

                       if (sMAIL_SESSION == null) {

                              pRETURN.setProperty("RESULT", "false");

                              pRETURN.setProperty("MSG", "Mail Session can't be created...");

                              return pRETURN;

                       }

                       MimeMessage reply = new MimeMessage(sMAIL_SESSION);

                       reply.setFrom(new InternetAddress(sEMAIL_ADDRESS_FROM));

                       reply.setSubject(sSUBJECT);

                       reply.setText(sTEXT);

                       reply.addRecipient(Message.RecipientType.TO, new InternetAddress(sEMAIL_ADDRESS_TO));

                       Transport.send(reply);

                       StringBuffer sbSQL = new StringBuffer();

                       sbSQL.append(" UPDATE SENDMAIL SET SENDDATE = TO_CHAR(SYSDATE, 'YYYYMMDDHH24MISS') WHERE MAIL_ID = ?");

                       conn.setAutoCommit(false);

                       PreparedStatement pstmt = conn.prepareStatement(sbSQL.toString());

                       pstmt.setString(1, pARGS.getProperty("MAIL_ID", "1"));

                       pstmt.executeUpdate();

                       conn.commit();

               } catch (Exception e) {

                       pRETURN.setProperty("RESULT", "false");

                       pRETURN.setProperty("MSG", "sendCronMail(Properties pARGS) Error : " + e.toString());

               }

               return pRETURN;

        }

        public static void main(String[] args) {

               String sDB_URL = "jdbc:oracle:thin:@165.213.251.202:1521:itts";

               String sDB_USER = "itts";

               String sDB_PASSWORD = "skan00";

               Connection conn = null;

               PreparedStatement pstmt = null;

               ResultSet rs = null;

               try {

                       Class.forName("oracle.jdbc.driver.OracleDriver");

                       conn = DriverManager.getConnection(sDB_URL, sDB_USER, sDB_PASSWORD);

                       if (conn != null) {

                              StringBuffer sbSQL = new StringBuffer();

                              sbSQL.append(" SELECT MAIL_ID, MAIL_FROM, MAIL_TO, MAIL_SUBJECT, MAIL_BODY FROM SENDMAIL WHERE SENDDATE = '99991231235959'");

                              pstmt = conn.prepareStatement(sbSQL.toString());

                              rs = pstmt.executeQuery();

                              Hashtable htSENDMAIL = new Hashtable();

                              for (int i = 0; rs.next(); i++) {

                                      Properties pSendCronMail_ARGS = new Properties();

                                      pSendCronMail_ARGS.setProperty("MAIL_ID", rs.getString("MAIL_ID"));

                                      pSendCronMail_ARGS.setProperty("EMAIL_ADDRESS_FROM", rs.getString("MAIL_FROM"));

                                      pSendCronMail_ARGS.setProperty("EMAIL_ADDRESS_TO", rs.getString("MAIL_TO"));

                                      pSendCronMail_ARGS.setProperty("SUBJECT", rs.getString("MAIL_SUBJECT"));

                                      pSendCronMail_ARGS.setProperty("TEXT", rs.getString("MAIL_BODY"));

                                      htSENDMAIL.put(new Integer(i), pSendCronMail_ARGS);

                              }

                              rs.close();

                              pstmt.close();

                              SendMail cm = new SendMail();

                              for (int i = 0; i < htSENDMAIL.size(); i++) {

                                      cm.sendCronMail((Properties) htSENDMAIL.get(new Integer(i)), conn);

                              }

                       }

               } catch (ClassNotFoundException e) {

                       System.err.println(e.toString());

               } catch (SQLException e) {

                       System.err.println(e.toString());

               } finally {

                       try {

                              conn.close();

                       } catch (SQLException e1) {

                              System.err.println(e1.toString());

                       }

               }

        }

}

#####################################################################

35. 원도우 배치 프로그램 실행하기

#####################################################################

xcopy /s /e /y C:\Tomcat4\webapps\itts\paperless\fileupload e:\paperless\fileupload

 

move /Y C:\Tomcat4\webapps\itts\paperless\swbTempDir\*.* D:\PT-LOG\swbTempDir\

move /Y C:\Tomcat4\webapps\itts\paperless\mProSystem\log\*.* D:\PT-LOG\mProSystem\

move /Y C:\Tomcat4\webapps\itts\paperless\logs\*.* D:\PT-LOG\logs\

 

#####################################################################

34. 특정 폴더에 쌓이는 파일을 없애는 소스

#####################################################################

 

배치 프로그램을 돌리면서 로그파일을 남김.

java paperless.cron.TempPdfDelete e:\\pdf_temp 1 >> PtPDF_TEMP_DIR_DEL.log

 

import java.io.File;

import java.text.SimpleDateFormat;

import java.util.Date;

import java.util.Properties;

public class TempPdfDelete {

        public static void main(String[] args) {

               TempPdfDelete td = new TempPdfDelete();             

               String sTRASH_LOCATION = "e:\\pdf_temp";

               String sTRASH_DELETE_DAY = "1";           

               if( args.length == 2 ) {

                       sTRASH_LOCATION = args[0];

                       sTRASH_DELETE_DAY = args[1];

               }

               Properties pARGS = new Properties();

               pARGS.setProperty("TRASH_LOCATION", sTRASH_LOCATION);

               pARGS.setProperty("TRASH_DELETE_DAY", sTRASH_DELETE_DAY);

               Properties pRETURN = td.trashDelete(pARGS);

               SimpleDateFormat sdfTODAY = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

               Date dTODAY = new Date();           

               System.out.println("[" + sdfTODAY.format(dTODAY) + "] '"+sTRASH_LOCATION+"' Directory Deletion Started...");

               for(int i=0; i<Integer.parseInt(pRETURN.getProperty("DELETED_TRASH_FILE_COUNT")); i++) {

                       dTODAY = new Date();

                       System.out.println("[" + sdfTODAY.format(dTODAY) + "] " + pRETURN.getProperty("#" + i, "Deleted File Name not found") + " was deleted");

               }

               dTODAY = new Date();

               System.out.println("[" + sdfTODAY.format(dTODAY) + "] '"+sTRASH_LOCATION+"' Directory Deletion Ended...");

        }

        /**

         * @param pARGS

         * @return

         */

        private Properties trashDelete(Properties pARGS) {

               Properties pRETURN = new Properties();

               pRETURN.setProperty("RESULT", "true");

               String sTRASH_LOCATION = pARGS.getProperty("TRASH_LOCATION", "e:\\pdf_temp");

               if (sTRASH_LOCATION.trim().equals("")) {

                       pRETURN.setProperty("RESULT", "true");

                       pRETURN.setProperty("MSG", "TRASH_LOCATION is null...");

                       return pRETURN;

               }

               long lTRASH_DELETE_DAY = Long.parseLong(pARGS.getProperty("TRASH_DELETE_DAY", "0")) * 24 * 60 * 60 * 1000;

               File fTRASH_LOCATION = new File(sTRASH_LOCATION);

               int iDELETED_TRASH_FILE_COUNT = 0;

               if (fTRASH_LOCATION.isDirectory()) {

                       File[] fofTRASH_LOCATION_FILES = fTRASH_LOCATION.listFiles();

                       Date dTODAY = new Date();

                       for (int i = 0; i < fofTRASH_LOCATION_FILES.length; i++) {

                              long lTRASH_FILE_AGE = dTODAY.getTime() - fofTRASH_LOCATION_FILES[i].lastModified();

                              if (fofTRASH_LOCATION_FILES[i].isFile() && lTRASH_FILE_AGE >= lTRASH_DELETE_DAY) {

                                      if (fofTRASH_LOCATION_FILES[i].delete()) {

                                             pRETURN.setProperty("#" + String.valueOf(iDELETED_TRASH_FILE_COUNT), fofTRASH_LOCATION_FILES[i].getName());

                                             iDELETED_TRASH_FILE_COUNT++;

                                      }

                              }

                       }

               }

               pRETURN.setProperty("DELETED_TRASH_FILE_COUNT", String.valueOf(iDELETED_TRASH_FILE_COUNT));

               return pRETURN;

        }

}

#####################################################################

33. 암호와 알고리즘을 사용후 복호화 하는 소스와 적용예

#####################################################################

import javax.crypto.*;

import javax.crypto.spec.SecretKeySpec;

import javax.crypto.spec.DESKeySpec;

import javax.crypto.spec.IvParameterSpec;

import java.security.*;

import sun.misc.BASE64Decoder;

import sun.misc.BASE64Encoder;

public class AlgoDES {

    static byte[] seedKeyData = new byte[24];

    public AlgoDES() {

        seedKeyData[0] = 0x01;

        seedKeyData[1] = 0x02;

        seedKeyData[2] = 0x03;

        seedKeyData[3] = 0x04;

        seedKeyData[4] = 0x05;

        seedKeyData[5] = 0x06;

        seedKeyData[6] = 0x07;

        seedKeyData[7] = 0x08;

        seedKeyData[8] = 0x09;

        seedKeyData[9] = 0x10;

        seedKeyData[10] = 0x11;

        seedKeyData[11] = 0x12;

        seedKeyData[12] = 0x13;

        seedKeyData[13] = 0x14;

        seedKeyData[14] = 0x15;

        seedKeyData[15] = 0x16;

        seedKeyData[16] = 0x01;

        seedKeyData[17] = 0x02;

        seedKeyData[18] = 0x03;

        seedKeyData[19] = 0x04;

        seedKeyData[20] = 0x05;

        seedKeyData[21] = 0x06;

        seedKeyData[22] = 0x07;

        seedKeyData[23] = 0x08;

    }

    public static String encTripleDES(String beforeStr) {

        String afterStr = "";

        try {

            SecretKeySpec desKey = new SecretKeySpec(seedKeyData, "DESede"); //seedKeyData로 암호화

            Cipher desCipher = Cipher.getInstance("DESede/ECB/PKCS5Padding");

            byte[] cleartext = beforeStr.getBytes();

            desCipher.init(Cipher.ENCRYPT_MODE, desKey);

            byte[] ciphertext = desCipher.doFinal(cleartext);

            afterStr = (new BASE64Encoder()).encode(ciphertext);

        } catch (Exception e) {

            e.printStackTrace();

        }

        return afterStr;

    }

    public static String decTripleDES(String beforeStr) {        

        String afterStr = "";

        try {

            SecretKeySpec desKeyD = new SecretKeySpec(seedKeyData, "DESede");

            Cipher desCipherD = Cipher.getInstance("DESede/ECB/PKCS5Padding");

            desCipherD.init(Cipher.DECRYPT_MODE, desKeyD);

            byte[] decodedBytes = (new BASE64Decoder()).decodeBuffer(beforeStr);

            byte[] cleartext1 = desCipherD.doFinal(decodedBytes);

            afterStr = new String(cleartext1);

        } catch (Exception e) {

            e.printStackTrace();

        }

        return afterStr;

    }

        public static void main(String args[]) {         

               try{

                       if (args.length > 0) {

                              for (int i = 0; i < args.length; i++) {

                                      String s = AlgoDES.encTripleDES(args[i]);

                                      String s1 = AlgoDES.decTripleDES(s);

                                      System.out.println("Original ["+args[i]+"]");

                                      System.out.println("encTripleDES ["+s+"]");

                                      System.out.println("decTripleDES ["+s1+"]");

                              }

       

                       }      

               } catch (Exception e) {

                       e.printStackTrace();

               }

        }

}

/** 적용예제

        if(secu) {

               _sdbServer = AlgoDES.decTripleDES(ReadConfig.get ("DATABASE", "dbServer")) ;

        }else{

               _sdbServer = ReadConfig.get ("DATABASE", "dbServer") ;

        }

    if(secu){

               _sdbPassword = AlgoDES.decTripleDES(ReadConfig.get ("DATABASE", "dbPassword")) ;

        }else{

               _sdbPassword = ReadConfig.get ("DATABASE", "dbPassword") ;

        }

*/

#####################################################################

32. 특수문자 제거 메소드

#####################################################################

public static String removeSpecialChar(String str) {

               if (str == null || str.trim().length() == 0)

                       return "";

               StringBuffer data = new StringBuffer(str);

               StringBuffer buf = new StringBuffer();

               for (int i = 0; i < data.length(); i++) {

                       char c = data.charAt(i);

                       if (((int) c > 47 && (int) c < 58) || ((int) c > 64 && (int) c < 91) || ((int) c > 96 && (int) c < 123))

                              buf.append(c);

               }

 

               return buf.toString();

}

 

#####################################################################

31. 날짜 관련 함수 이용

#####################################################################

import java.util.*;

import java.io.*;

import java.text.*;

public class DateCheck

{

        public static void main(String[] args)

        {

               SimpleDateFormat date = new SimpleDateFormat();

               date = (SimpleDateFormat)DateFormat.getDateTimeInstance();

               long now = System.currentTimeMillis();

               System.out.println("Now  ->/"+now+"/");

               Date dd = new Date();         

               System.out.println("Date ->/"+dd+"/");

               String str = date.format(new Date(now));

               System.out.println("Time ->/"+str+"/");         

        }

}

 

 

#####################################################################

30. Random 함수로 받은 값을 중복 체크하는 소소

#####################################################################

import java.util.*;

public class RandomTest

{

        public static void main(String[] args)

        {

               Random random = new Random();

               boolean[] total = new boolean[45];

               int[] choose = new int[6];             

               for (int i=0; i<total.length ; i++ )

               {

                       total[i] = true;

               }             

               for (int i=0; i<choose.length ; i++)

               {

                       int num = random.nextInt(45);                 

                       if (total[num])

                       {

                              total[num] = false;

                              choose[i] = num+1;                                  

                       }             

                       System.out.print( choose[i] + " \n");                 

               }

        }

}

 

#####################################################################

29. 버블 소트로 데이타 정렬

#####################################################################

public class SortTest

{

        public static void main(String[] args)

        {

               String[] str = {"Orange","Apple","Grape","Peach","Lemon"};

               System.out.println("@@@@@ 정렬 전 @@@@@");

               for (int i=0; i<str.length; i++)

               {

                       System.out.println(str[i]);

               }

               System.out.println("@@@@@ 정렬 후 @@@@@");

               for (int j=0; j<str.length ; j++ )

               {

                       for (int i= j+1 ; i<str.length ; i++)

                       {

                              if ( str[i].compareTo(str[j]) < 0 ) //음수이면 들어감

                              {

                                      String temp = str[j];

                                      str[j] = str[i];

                                      str[i] = temp;  

                              }

                       }

                       System.out.println(str[j]);                                     

               }

        }

}

#####################################################################

28. MD5로 암호화 하는 알고리즘 (Base64 필요)

#####################################################################

import sun.misc.*;

import java.io.*;

public class Base64Util {      

    public Base64Util() {}

    /**

     *   Base64Encoding을 수행한다. binany in ascii out

     *

     *   @param encodeBytes encoding byte array

     *   @return encoding String

     */

    public static String encode(byte[] encodeBytes) {

        BASE64Encoder base64Encoder = new BASE64Encoder();

        ByteArrayInputStream bin = new ByteArrayInputStream(encodeBytes);

        ByteArrayOutputStream bout = new ByteArrayOutputStream();

        byte[] buf = null;

        try{

            base64Encoder.encodeBuffer(bin, bout);

        } catch(Exception e) {

            System.out.println("Exception");

            e.printStackTrace();

        }

        buf = bout.toByteArray();

        return new String(buf).trim();

    }

    /**

     *   Base64Decoding 수행한다. binany out ascii in

     *

     *   @param strDecode decoding String

     *   @return decoding byte array

     */

    public static byte[] decode(String strDecode) {       

        BASE64Decoder base64Decoder = new BASE64Decoder();

        ByteArrayInputStream bin = new ByteArrayInputStream(strDecode.getBytes());

        ByteArrayOutputStream bout = new ByteArrayOutputStream();

        byte[] buf = null;

        try {           

            base64Decoder.decodeBuffer(bin, bout);

        } catch(Exception e) {

            System.out.println("Exception");

            e.printStackTrace();

        }

        buf = bout.toByteArray();

        return buf;

    }

}

import java.security.*;

public class  SecurityUtil {

    /**

     *   byte[] ret = HashUtil.digest("MD5", "abcd".getBytes());

     *  처럼 호출

     */

    public static byte[] digest(String alg, byte[] input) throws NoSuchAlgorithmException {

        MessageDigest md = MessageDigest.getInstance(alg);

        return md.digest(input);

    }

    public static String getCryptoMD5String(String inputValue) throws Exception {

        if( inputValue == null ) throw new Exception("Can't conver to Message Digest 5 String value!!");

        byte[] ret = digest("MD5", inputValue.getBytes());

        String result = Base64Util.encode(ret);   

        return result;

    }

        public static void main(String[] args) throws Exception

        {

               String passwd = SecurityUtil.getCryptoMD5String("gkskfh2005");

               System.out.println("passwd :"+passwd);

        }

}

#####################################################################

 

#####################################################################

27. TripleDES 을 이용한 암호화 알고리즘

#####################################################################

import javax.crypto.*;

import javax.crypto.spec.SecretKeySpec;

import javax.crypto.spec.DESKeySpec;

import javax.crypto.spec.IvParameterSpec;

import java.security.*;

import sun.misc.BASE64Decoder;

import sun.misc.BASE64Encoder;

public class AlgoDES {

    static byte[] seedKeyData = new byte[24];

    public AlgoDES() {

        seedKeyData[0] = 0x01;

        seedKeyData[1] = 0x02;

        seedKeyData[2] = 0x03;

        seedKeyData[3] = 0x04;

        seedKeyData[4] = 0x05;

        seedKeyData[5] = 0x06;

        seedKeyData[6] = 0x07;

        seedKeyData[7] = 0x08;

        seedKeyData[8] = 0x09;

        seedKeyData[9] = 0x10;

        seedKeyData[10] = 0x11;

        seedKeyData[11] = 0x12;

        seedKeyData[12] = 0x13;

        seedKeyData[13] = 0x14;

        seedKeyData[14] = 0x15;

        seedKeyData[15] = 0x16;

        seedKeyData[16] = 0x01;

        seedKeyData[17] = 0x02;

        seedKeyData[18] = 0x03;

        seedKeyData[19] = 0x04;

        seedKeyData[20] = 0x05;

        seedKeyData[21] = 0x06;

        seedKeyData[22] = 0x07;

        seedKeyData[23] = 0x08;

    }

    public static String encTripleDES(String beforeStr) {

        String afterStr = "";

        try {

            SecretKeySpec desKey = new SecretKeySpec(seedKeyData, "DESede"); //seedKeyData로 암호화

            Cipher desCipher = Cipher.getInstance("DESede/ECB/PKCS5Padding");

            byte[] cleartext = beforeStr.getBytes();

            desCipher.init(Cipher.ENCRYPT_MODE, desKey);

            byte[] ciphertext = desCipher.doFinal(cleartext);

            afterStr = (new BASE64Encoder()).encode(ciphertext);

        } catch (Exception e) {

            e.printStackTrace();

        }

        return afterStr;

    }

    public static String decTripleDES(String beforeStr) {        

        String afterStr = "";

        try {

            SecretKeySpec desKeyD = new SecretKeySpec(seedKeyData, "DESede");

            Cipher desCipherD = Cipher.getInstance("DESede/ECB/PKCS5Padding");

            desCipherD.init(Cipher.DECRYPT_MODE, desKeyD);

            byte[] decodedBytes = (new BASE64Decoder()).decodeBuffer(beforeStr);

            byte[] cleartext1 = desCipherD.doFinal(decodedBytes);

            afterStr = new String(cleartext1);

        } catch (Exception e) {

            e.printStackTrace();

        }

        return afterStr;

    }

        public static void main(String args[]) {         

               try{

                       if (args.length > 0) {

                              for (int i = 0; i < args.length; i++) {

                                      String s = AlgoDES.encTripleDES(args[i]);

                                      String s1 = AlgoDES.decTripleDES(s);

                                      System.out.println("Original ["+args[i]+"]");

                                      System.out.println("encTripleDES ["+s+"]");

                                      System.out.println("decTripleDES ["+s1+"]");

                              }      

                       }      

               } catch (Exception e) {

                       e.printStackTrace();

               }

        }

}

 

import java.security.*;

import javax.crypto.*;

public class TripleDes {

    public static void main(String [] args) throws Exception {

        if( args.length != 1) {

            System.out.println("Usage : java SimpleExample text ");

            System.exit(1);

        }

        String text = args[0];

        System.out.println("Generating a DESded (TripleDES) key...");

        // Triple DES 생성

        KeyGenerator keyGenerator = KeyGenerator.getInstance("DESede");

        keyGenerator.init(168);   // 키의 크기를 168비트로 초기화

        Key key = keyGenerator.generateKey();

        System.out.println("키생성이 완료되었음");

        // Cipher를 생성, 사용할 키로 초기화

        Cipher cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding");

        cipher.init(Cipher.ENCRYPT_MODE, key);

        byte [] plainText = text.getBytes("UTF8");

        System.out.println("Plain Text : ");

        for (int i = 0; i < plainText.length ; i++) {

            System.out.print(plainText[i] + " ");

        }

        // 암호화 시작

        byte [] cipherText = cipher.doFinal(plainText);

        // 암호문서 출력

        System.out.println("\nCipher Text : ");

        for (int i = 0; i < cipherText.length ; i++)       {

            System.out.print(cipherText[i] + " ");

        }

        //복호화 모드로서 다시 초기화

        cipher.init(Cipher.DECRYPT_MODE, key);

        //복호화 수행

        byte [] decryptedText = cipher.doFinal(cipherText);

        String output =  new String(decryptedText, "UTF8");

        System.out.println("\nDecrypted Text : " + output);

    }

};

#####################################################################

 

#####################################################################

26. Random 클래스로 가져온 값을 중복체크하기

#####################################################################

import java.util.*;

public class RandomTest

{

        public static void main(String[] args)

        {

               Random random = new Random();

               boolean[] boo = new boolean[45];

                int[] choo = new int[6];

               for (int i=0; i<boo.length ;  )

               {

                       boo[i] = true;

               }

               for (int i=0; i<choo.length ; i++)

               {

                       int num = random.nextInt(45);

                       if (boo[num])

                       {

                              boo[num] = false;

                              choo[i] = num+1;      

                              System.out.println(choo[i]);

                       }                     

               }

        }

}

#####################################################################

 

#####################################################################

26. MS-SQL JDBC 드라이버 연결하는 방법

#####################################################################

 

다음의 사이트를 방문하여 MS-SQL2000 JDBC 드라이버를 다운로드

http://www.microsoft.com/sql/downloads/2000/jdbc.asp

적절한 위치에 설치하고 다음의 세 파일을 클래스패스에 추가 (%JAVA_HOME%\lib\ext\classes12.zip;)

설치 디렉터리/lib/msbase.jar 

설치 디렉터리/lib/msutil.jar 

설치 디렉터리/lib/mssqlserver.jar

 

MS-SQL2000, Oracle 그리고 MySQL 데이터베이스의 드라이버를 로딩하는 것을 각각 보여주고 있습니다.

Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver");

Class.forName("oracle.jdbc.driver.OracleDriver");

Class.forName("org.gjt.mm.mysql.Driver");

 

 

#####################################################################

 

#####################################################################

25. 날짜 포맷 바꾸는 방법

#####################################################################

 

String ETA_END_DATE = null;

String ETA_START_DATE = null;

String date_format = "yyyy-MM-dd";

SimpleDateFormat simpledateformat = new SimpleDateFormat(date_format);             

ETA_END_DATE = simpledateformat.format(Format.getSwbEndDate());

ETA_START_DATE = simpledateformat.format(Format.getSwbStartDate());

 

#####################################################################

24. 엔터키를 두르면 검색하는 소스

#####################################################################

 

<script language="JavaScript">

function goUrl(command, _url) {

        theForm = document.searchForm;      

        if (command == 'search'  && theForm.BLNO.value != null)

               theForm.BLNO.value = theForm.BLNO.value.toUpperCase();             

        theForm.command.value=command;

        theForm.PAGE.value="1";

        theForm.action = _url;

        theForm.submit();

}

function EnterCheck()

{      

        if(event.keyCode == 13)

               goUrl('search', '/servlet/paperless.SwbListServlet');

}

</script>

<form name="searchForm" method="post" action="">

<table width="98%" border="0" cellspacing="1" cellpadding="3">

    <input type="text" name="BLNO" class="main_input" value = "<%=blno%>"size="20" __onBlur="checkBLNo(this)" onKeyDown="EnterCheck()">

        <img src="../img/btn_multifile_upload.gif" width="92" height="18" border="0"

         onmouseover="this.style.cursor='hand'"

          onClick="goUrl('','/servlet/paperless.SwbUploadServlet')"/>

        <input type="hidden" name="PROCESS_TYPE" value="CARRIER"/>

</table>

</form>

 

#####################################################################

23. 데이터베이스 커넷션하고 로그파일을 만듬

#####################################################################

package common;

import BrokerBean;

import javax.servlet.jsp.PageContext;

import java.sql.SQLException;

import java.sql.Connection;

import java.sql.PreparedStatement;

public class SystemUsageHandler {

            synchronized public static void insertLog(PageContext jspContext, String id, String menu, String func, String comment) throws SQLException, Exception

            {

                       BrokerBean brokerBean = null;

                       Connection conn = null;

                       PreparedStatement pstmt = null;

                       try {

                              brokerBean = (BrokerBean) jspContext.getServletContext().getAttribute("DBPOOL");

                              conn = brokerBean.getDbConnection();

                              conn.setAutoCommit(false);

                              pstmt = conn.prepareStatement("insert into SYSTEM_USAGE_DETAIL (USER_ID, MENU, FUNC, COMMON ) "

                                             + " values (?,?,?,?)");

                              pstmt.setString(1, id);

                              pstmt.setString(2, menu);

                              pstmt.setString(3, func);

                              pstmt.setString(4, comment);

                              pstmt.executeUpdate();

                              conn.commit();

                       } catch (SQLException e) {

                              e.printStackTrace();

                              conn.rollback();

                       } catch (Exception e) {

                              e.printStackTrace();

                              conn.rollback();

                       } finally {

                              try {

                                      if (pstmt != null) pstmt.close();

                                      if (conn != null) brokerBean.freeConnection(conn);

                              } catch (Exception ae) {

                                      ae.printStackTrace();

                              }

                       }

               }

}

#####################################################################

 

 

#####################################################################

01. ServerSocket Socket 간의 채팅 소스

#####################################################################

import java.io.*;

import java.net.*;

import java.util.*;

public class Server_15

{

        public static void main(String[] args)

        {

               try

               {

                       ServerSocket server = new ServerSocket(9999);

                       while (true)

                       {

                              System.out.println("Server Ready");

                              Socket socket = server.accept();

                              ServerHandle_15 sh = new ServerHandle_15(socket);

                              Thread th = new Thread(sh);

                              th.start();

                       }

               }catch (IOException e){}       

        }

}

class ServerHandle_15 implements Runnable

{

        private DataInputStream dis = null;

        private DataOutputStream dos = null;

        private Socket socket = null;

        public static Vector v = new Vector();

        public ServerHandle_15(Socket socket){

               try

               {

                       dis = new DataInputStream(socket.getInputStream());

                       dos = new DataOutputStream(socket.getOutputStream());

                       v.addElement(this);

               }catch (IOException e){}       

        }

        public void run(){

               try

               {

                       while (true)

                       {

                              String str = dis.readUTF();

                              broad(str);

                       }                             

               }catch (IOException e){}

        }

        public void broad(String str){

               for (int i=0; i<v.size() ; i++)

               {

                       try

                       {

                              ServerHandle_15 sh = (ServerHandle_15)v.elementAt(i);

                              sh.dos.writeUTF(str);

                       }catch (IOException e){ }                     

               }                             

        }

};

 

import java.io.*;

import java.net.*;

public class Client_15 implements Runnable

{

        private DataInputStream dis = null;

        private DataOutputStream dos = null;

        private Socket socket = null;

        public Client_15()

        {

               try

               {

                       socket = new Socket("localhost", 9999);

                       dis = new DataInputStream(socket.getInputStream());

                       dos = new DataOutputStream(socket.getOutputStream());

                       Thread th = new Thread(this);

                       th.start();

                       display();

               }catch (IOException e){}

        }

        public void run(){

               try

               {

                       while (true)

                       {

                              String str = dis.readUTF();

                              System.out.println(str);

                       }                                                                  

               }catch (IOException e){}

        }

        public void display(){

               try

               {

                       BufferedReader br = new BufferedReader(new InputStreamReader(System.in));                          

                       while (true)

                       {

                              String str = br.readLine();     

                              dos.writeUTF(str);

                       }                     

               }catch (IOException e){}

        }

        public static void main(String[] args){

               Client_15 sc = new Client_15();

        }

}

#####################################################################

 

 

#####################################################################

02. Swing에서 이미지 아이콘 삽입 및 종료

#####################################################################

import java.awt.*;

import javax.swing.*;

JFrame: Construct

private Container con;

con = this.getContentPane();

con.add(jbutton);

this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //플레임 종료

ImageIcon:

ImageIcon im = new ImageIcon("aa.gif");

this.setIconImage(im.getImage());

#####################################################################

 

 

#####################################################################

03. RMI 정상적인 예제

#####################################################################

package ksh.first;

import java.rmi.*;

public interface FirstRMI extends Remote{

        String getString() throws RemoteException;

        //void setString(String str) throws RemoteException;

}

#####################################################################

package ksh.first;

import java.rmi.*;

import java.rmi.server.*;

public class SecondRMI extends UnicastRemoteObject implements FirstRMI{

        public SecondRMI() throws RemoteException{

               super();

        }

        public String getString() throws RemoteException{

               return "Hello RMI!!!";

        }

}

#####################################################################

import ksh.first.*;

import java.rmi.*;

import java.net.*;

public class ThirdRMI{

        public static void main(String[] ar){

               SecondRMI sr = null;

               try{

                       sr = new SecondRMI();

                       Naming.rebind("first", sr);

                       System.out.println("Server Ready...");

               }catch(RemoteException ee){

               }catch(MalformedURLException ee){}

        }

}

#####################################################################

import ksh.first.*;

import java.rmi.*;

import java.net.*;

public class FourthRMI{

        public static void main(String[] ar){

               FirstRMI fr = null;

               try{

                       fr = (FirstRMI)Naming.lookup("rmi://192.168.0.155/first");

                       String str = fr.getString();

                       System.out.println("실행된 메시지 = " + str);

               }catch(NotBoundException ee){

               }catch(MalformedURLException ee){

               }catch(RemoteException ee){}

        }

}

#####################################################################

 

 

#####################################################################

04. RMI registry 등록하지 않고 사용

#####################################################################

package ksh.second;

import java.rmi.*;

public interface FirstRMI extends Remote{

        String getString() throws RemoteException;

}

#####################################################################

package ksh.second;

import java.rmi.*;

import java.rmi.server.*;

public class SecondRMI extends UnicastRemoteObject   implements FirstRMI{

        public SecondRMI() throws RemoteException{

               super();

        }

        public String getString() throws RemoteException{

               return "Hello RMI2!!";

        }

}

#####################################################################

import ksh.second.*;

import java.rmi.*;

import java.rmi.registry.*;

import java.net.*;

public class ThirdRMI{

        public static void main(String[] ar){

               Registry rg = null;

               SecondRMI sr = null;

               try{

                       rg = LocateRegistry.createRegistry(2000);

                       sr = new SecondRMI();

                       Naming.rebind("rmi://192.168.0.155:2000/second", sr);

                       System.out.println("Server Ready...");

               }catch(RemoteException ee){

               }catch(MalformedURLException ee){}

        }

}

#####################################################################

import ksh.second.*;

import java.rmi.*;

import java.net.*;

public class FourthRMI{

        public static void main(String[] ar){

               FirstRMI fr = null;

               try{

                       fr = (FirstRMI)Naming.lookup(

                                                                    "rmi://192.168.0.155:2000/second");

                       String str = fr.getString();

                       System.out.println("메시지 = " + str);

               }catch(NotBoundException ee){

               }catch(MalformedURLException ee){

               }catch(RemoteException ee){}

        }

}

#####################################################################

 

 

#####################################################################

05. RMI 통신법

#####################################################################

기본 Port 1099

Remote Method Invocation

rmi package & 중요 클래스

---------------------------------------------------------------------

1.서버: 공통 인터페이스, 구현 클래스, 스켈레톤 클래스, 서버실행 클래스

서버기동 bind(String str, Remote obj)

- 공통 인터페이스

        public 인터페이스, Remote 인터페이스를 상속

        abstract Method RemoteException 를 처리

        매개변수들은 객체이거나 직렬화가 가능

- 구현클래스

        public class Second extends UnicastRemoteObject implements FirstRMI 를 상속

- 스텝과 스켈레톤 계증 만들기

        rmic -d . ksh.first.SecondRMI 구현클래스로 생성한다.

- rmiregistry 기동해야 한다. 1099 Port 이용

        대체클래스로 기동할 수도 있다

        start rmiregistry 새창으로 돌려라 (unix에 백앤드 프로그램 생성하는 것과 같다)

- Binding 시키기 (등록시킨다)

        ThirdRMI {

               SecondRMI sr = new SecondRMI();

               sr.rebind("first", sr);

        }

        C\>start java ThirdRMI 로 실행

#####################################################################

2.클라이언트: 공통인터페이스, 스넵 클래스, GUI 클래스

- 서버 파일 가져오기, 스텝 클래스를 가져온다

        공통인터페이스 FirstRMI.class, SecondRMI_Stub.class

- 서버의 기동중인 객체를 얻어오기

        import ksh.first.*;

        import java.rmi.*;

        public class FourthRMI{

               try

               {

                       FirstRMI fr = new First();

                       fr = (FirstRMI)Naming.lookup("rmi://165.213.42.29:1099/first");

               }

               catch (NotBoundException e){}

               catch (MalformedURLException e){}

               catch (RemoteException e){}

        }

- 해당 객체를 통해서 Method 를 사용하기

        String str = fr.getString();

        System.out.println("얻어온 실행된 메시지 "+str);

#####################################################################

3. rmiregistry 대체 클래스

Registry interface (Naming class 와 유사)

LocateRegistry class

 

import ksh.second.*;

import java.rmi.*;

import java.rmi.registry.*;

import java.net.*;

public class ThirdRMI

{

        public static void main(String[] args){

               SecondRMI sc = null;

               Registry rg = null;

               try

               {

                       rg = LocateRegistry.createRegistry(2000);

                       sc = new SecondRMI();

                       Naming.rebind("rmi:192.168.0.155:2000/second", sc);

               }

               catch (RemoteException e){}

               catch (MalformedURLException e){}

        }

};

#####################################################################

 

 

#####################################################################

06. Directory 찾아서 리스트 만들기

#####################################################################

 

import java.io.*;

public class MakeFileList

{

        PrintWriter pw = null;

        public MakeFileList(){

               try

               {

                       FileOutputStream fos = new FileOutputStream(new File("./Text.txt"));

                       OutputStreamWriter osw = new OutputStreamWriter(fos, "EUC-KR");

                       pw = new PrintWriter(osw, true);

               }catch (IOException e){

                       System.out.println("File write error "+e);

               }

               searchDirectory(new File("."));

               pw.flush();

               pw.close();

        }

        public void searchDirectory(File here){

               File[] rootFileList = here.listFiles();

               for (int i=0; i<rootFileList.length ; i++ )

               {

                       if (rootFileList[i].isDirectory())

                       {

                              searchDirectory(rootFileList[i]);

                       }else{

                              try

                              {

                                      String filename = rootFileList[i].getName();

                                      String ext = filename.substring(filename.lastIndexOf("."), filename.length());

                                      if (!ext.equalsIgnoreCase(".gif") && !ext.equalsIgnoreCase(".jpg") )

                                      {

                                             pw.print(rootFileList[i].toURL());

                                             pw.print("\n");

                                             System.out.println(rootFileList[i].toURL());

                                      }else{

                                             System.out.println(ext);

                                      }

                              }catch (Exception e){}

                       }

               }

        }

        public static void main(String[] args){

               MakeFileList mf = new MakeFileList();

        }

};

#####################################################################

 

 

#####################################################################

07. IO 관련 소스

#####################################################################

Abstract OutStream을 이용한 입력하기

 

ch01 - AAA - Exam02_01.java, jar02.jar (jar -cvf jar02.jar *.*)

       BBB - Exam02_Main.java

jar 위치: C:\jdk1.3.1\jre\lib\ext\jar02.jar

 

private PrintStream ps;

public Exam02_03(){

        super();

        ps = System.out;

}

public void write(int i){

        ps.write(i);

        ps.flush();

}

public void close(){

        ps.close();

}

 

Exam02_03 es = new Exam02_03();

es.write(65);

es.write('\r');

es.write('\n');

byte[] bb = {'h','e','l','l','o'};

es.write(bb);

//es.close();

byte[] cc = "HELLO JAVA".getBytes();

es.write('\r');

es.write('\n');

es.write(cc, 0, 5);

es.write("송하연".getBytes("ISO8859_1"));

#####################################################################

private InputStream is;

public Exam02_04(){

        super();

        is  = System.in;

}

public int read() throws IOException{

        int xx = is.read();

        if (xx == '\n')

        {

               return -1;

        }

        return xx;

}

 

/*

byte[] bb = new byte[20];

System.out.print("입력 ");

System.in.read(bb);

int i = System.in.read();

System.out.println("입력된 문자 "+ new String(bb));

*/

Exam02_04 es = new Exam02_04();

byte[] bb = new byte[20];

System.out.print("입력 : ");

es.read(bb);

System.out.println("입력된 문자 : "+ new String(bb));

#####################################################################

 

 

#####################################################################

08. 파일을 읽는 소스

#####################################################################

 

int cnt;

FileReader rf = new FileReader("Test.java");            

cnt = rf.read();

while (cnt != -1)

{

        System.out.print(cnt);

        cnt = rf.read();

}

#####################################################################

 

 

#####################################################################

09. 입력받은 파일을 읽는 소스

#####################################################################

 

int cnt = 0;

System.out.print("Input your filename ");

BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

String str = br.readLine();

RandomAccessFile raf = new RandomAccessFile(str, "r");

cnt = raf.read();

while (cnt != -1)

{

        System.out.print((char)cnt);

        cnt = raf.read();

}

#####################################################################

 

 

#####################################################################

10. 스트링을 파일로 저장하는 소스

#####################################################################

 

String str = "어디로 가야 할지";

char[] ch =  new char[str.length()];

str.getChars(0, ch.length, ch, 0);

FileWriter fw = new FileWriter(args[0]);

fw.write(ch);

fw.close();

#####################################################################

 

 

#####################################################################

11. 파일을 저장하는 소스

#####################################################################

 

FileOutputStream fos = new FileOutputStream(args[0]);

for (int i=0; i<500 ; i++ )

{

        fos.write(i);

}

fos.close();

System.out.println("FileOutputStream 했습니다!");

#####################################################################

 

 

#####################################################################

12. 에디터에는 볼 수 없으나 도스에서는 보임

#####################################################################

 

int cnt;

FileInputStream fis = new FileInputStream(args[0]);             

while ( (cnt = fis.read()) != -1)

{                     

        System.out.println(cnt);

}

System.out.println("FileInputStreamDemo를 확인했습니다.");

#####################################################################

 

 

#####################################################################

13. Properties 파일에 관련된 소스

#####################################################################

파일과 관련해서 Properties 저장하는 소스

 

Properties props = new Properties();

props.put("이름","마법사프로퍼티");

props.put("주소","마법의나라");

props.store(new FileOutputStream("properties.dat"),"프로퍼트테스트");

#####################################################################

 

 

#####################################################################

14. 파일과 관련해서 Properties 에서 읽어 오는 소스

#####################################################################

 

Properties props = new Properties();

props.load(new FileInputStream("properties.dat"));

System.out.println("이름: "+props.getProperty("이름"));

System.out.println("주소: "+props.getProperty("주소"));

#####################################################################

 

 

#####################################################################

15. 읽은 파일입력 후 내용확인하는 소스

#####################################################################

 

String fileInput;

int c = 0;;

System.out.print("Input your file name ");

BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

fileInput = br.readLine();

RandomAccessFile raf = new RandomAccessFile(fileInput, "r");

c = raf.read();

while ( c != -1 )

{

        System.out.print((char)c);

        c = raf.read();

}

raf.close();

#####################################################################

 

 

#####################################################################

16. 입력파일과 저장할 파일을 쓰는 소스

#####################################################################

 

String fileinput;

String fileoutput;

int c;

System.out.print("Input your filename ");

BufferedReader bf1 = new BufferedReader(new InputStreamReader(System.in));

fileinput = bf1.readLine();

System.out.print("Write save filename ");

BufferedReader bf2 = new BufferedReader(new InputStreamReader(System.in));

fileoutput = bf2.readLine();

RandomAccessFile raf1 = new RandomAccessFile(fileinput, "r");

RandomAccessFile raf2 = new RandomAccessFile(fileoutput, "rw");

c = raf1.read();

while (c!=-1)

{

        raf2.write(c);

        System.out.print((char)c);

        c = raf1.read();

}

raf1.close();

raf2.close();

#####################################################################

 

 

#####################################################################

17. 파일을 읽어서 보여주는 소스

#####################################################################

 

FileInputStream fis = new FileInputStream("Tst.java");

byte[] byteTxt = new byte[fis.available()];

fis.read(byteTxt);

fis.close();

System.out.println(new String(byteTxt));

#####################################################################

 

 

#####################################################################

18. 2초마다 출력하는 쓰레드 소스

#####################################################################

 

public class ThreadFromThread extends Thread

{

        public static void main(String[] args)

        {

               ThreadFromThread tt = new ThreadFromThread();

               tt.start();

        }

        public void run(){     

               try{

                       for(int i=0; i<10; i++)

                       {

                               Thread.sleep(2000);

                              System.out.println(i + " 2초 마다 출력되는 소스 !!!");

                       }                     

               }

               catch(InterruptedException e){}

        }

};

#####################################################################

 

#####################################################################

19. 배열과 관련하여

#####################################################################

2차원 배열 출력하는 소스

 

int[][] aa =

        {

               {1,  6, 11, 16, 21},

               {2,  7, 12, 17, 22},

               {3,  8, 13, 18, 23},

               {4,  9, 14, 19, 24},

               {5, 10, 15, 20, 25}

        };

for (int i=0; i<aa.length ; i++)

{

        if (i<5)

        {

               for (int j=0; j<aa[i].length ; j++ )

               {

                       System.out.print(aa[i][j] +"  ");

               }

               System.out.println();

        }                     

}

#####################################################################

 

 

#####################################################################

20. 배열로 합계 평균을 내는 소스

#####################################################################

 

int sum = 0;

long average = 0;             

int[] aa = {20, 30, 40, 50, 30, 70};

int len = aa.length;

for (int i=0; i<aa.length ; i++)

{             

        sum += aa[i];

}

System.out.println("sum ->/"+sum+"/");

System.out.println("average ->/"+(long)sum/len+"/");

#####################################################################

 

 

#####################################################################

21. 프로그램 인수를 받아 평균과 총계를 보여주는 소스

#####################################################################

 

if ( args.length<1 )

{

        System.out.println("Usage : java ArrayDe_05  ");

        System.exit(-1);

}

int aa = Integer.parseInt(args[0]);

int[] bb = new int[aa];

for (int i=0; i<bb.length ; i++ )

{

        bb[i] = i+1;

}

int sum = 0;

long average = 0;

int len = bb.length;

for (int i=0; i<bb.length ; i++ )

{

        sum += bb[i];

}

System.out.println("sum ->/"+sum+"/");

System.out.println("average ->/"+(long)sum/len+"/");

#####################################################################

 

 

#####################################################################

22. [실행되지 않으나 참고해야 할 소스]

#####################################################################

프로그램 실행시간을 체크하는 소스

 

CronLog cl = new CronLog("Maker.log");

Date dSTART_PROG = new Date();

중간 프로세스 처리

Date dEND_PROG = new Date();

long lELAPSED = dEND_PROG.getTime() - dSTART_PROG.getTime();

cl.log("Making started at " + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(dSTART_PROG));

cl.log("Making ended at " + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(dEND_PROG));

cl.log("Making " + lELAPSED / 1000 + " seconds elapsed.");

#####################################################################

 

 

#####################################################################

23. 로그 관련 소스

#####################################################################

import java.io.File;

import java.io.FileNotFoundException;

import java.io.FileOutputStream;

import java.io.PrintStream;

import java.util.Date;

import java.text.SimpleDateFormat;

import java.util.Calendar;

public class CronLog {

        private String sLOG_FILE = null, sLOG_PATH = null;

        private PrintStream out = null;

        SimpleDateFormat formatter;

        int iBACKUPFILE_KEEPING_DURATION = 30;    // 로그 파일 보관 일수(디폴트 30)

        public CronLog() {

               sLOG_FILE = makeLogFileName(Calendar.getInstance(), "MINU.log");

               formatter = new SimpleDateFormat("HH:mm:ss");

               removeLog( sLOG_FILE );

        }

        public CronLog(String sLOG_FILENAME) {

               sLOG_FILE = makeLogFileName(Calendar.getInstance(), sLOG_FILENAME);

               formatter = new SimpleDateFormat("HH:mm:ss");

               removeLog( sLOG_FILE );

        }

        public CronLog(String sLOG_FILENAME, int iBACKUPFILE_KEEPING_DURATION) {

               sLOG_FILE = makeLogFileName(Calendar.getInstance(), sLOG_FILENAME);

               formatter = new SimpleDateFormat("HH:mm:ss");

               this.iBACKUPFILE_KEEPING_DURATION = iBACKUPFILE_KEEPING_DURATION;

               removeLog( sLOG_FILE );

        }

        /** 해당 주기(iBACKUPFILE_KEEPING_DURATION)에 따라 로그 파일을 삭제함... */

        public void removeLog(String sLOG_FILE) {

               String sLOG_PATH = sLOG_FILE.substring(0, sLOG_FILE.lastIndexOf(File.separator)+1);

               if( sLOG_PATH.trim().equals("") ) {

                       sLOG_PATH = ".";

               }

               File fLOG_PATH = new File(sLOG_PATH);

               if( fLOG_PATH.isDirectory() ) {

                       File[] foLOG_FILES = fLOG_PATH.listFiles();

                       for(int i=0; i<foLOG_FILES.length; i++) {

                              File fLOG_FILE = foLOG_FILES[i];

                              long lLOG_FILE_ELAPSED = (new Date().getTime() - fLOG_FILE.lastModified()) / (24 * 60 * 60 * 1000);

                              if( fLOG_FILE.isFile() && lLOG_FILE_ELAPSED >= iBACKUPFILE_KEEPING_DURATION) {

                                      fLOG_FILE.delete();

                              }

                       }

               }

        }

        public void log(String sLOG) {

               if( sLOG_FILE == null ) {

                       sLOG_FILE = makeLogFileName(Calendar.getInstance(), "MINU.log");

               }             

               if( out == null ) {

                       File fLOG_FILE = new File(sLOG_FILE);       

                       FileOutputStream fos = null;

                       try {

                              fos = new FileOutputStream(sLOG_FILE, true);

                       } catch (FileNotFoundException e) {

                              System.err.println(e.toString());

                       }

                       out = new PrintStream(fos);

               }

               out.println("[" + formatter.format(new Date()) + "] " + sLOG);

        }

        public static String makeLogFileName(Calendar cal, String name) {

               java.util.Date dt = cal.getTime();

               SimpleDateFormat formatter = new SimpleDateFormat("@yyyy-MM-dd");

               String dateString = formatter.format(dt);

               int ind = name.indexOf(".");

               String head = name.substring(0, ind);

               String tail = name.substring(ind);

               name = head + dateString + tail;              

               checkDirectory(new File(name.substring(0, name.lastIndexOf(File.separator))));

               return name;

        }

        public static File checkDirectory(File dir) {

               File retVal = null;

               try {

                       if (!dir.isDirectory()) {

                              if (dir.mkdir()) {

                                      System.out.println("[" + dir.toString() + "] Directory Created, sucessfully.");

                              }

                       }

               } catch (Exception e) {

                       e.printStackTrace();

               }

               return dir;

        }

        public static void main(String[] args) {

               CronLog l = new CronLog("KKK.LOG");

               for(int i=0; i<100; i++ ) {

                       l.log(String.valueOf(i));

               }

               l.log("한글은???????????????????????????");

               l.log("Enddddddddddddddddddddddddddddddd");

        }

        public void log(int i) {

               log(String.valueOf(i));

        }

}

#####################################################################


2009. 9. 8. 14:58

[Oracle] 부정형(NOT IN, <>, NOT EXISTS ...)의 비교





PURPOSE
 
부정형의 비교를 긍정형 비교로 바꾸어서 인덱스 사용을 유도하는 방법에 대해서 알아본다.


KEY IDEA
 
부정형의 비교에는 논리적으로 인덱스를 사용할 수 없다. 하지만 약간의 IDEA를 첨부한다면
부정형의 비교를 긍정형의 비교로 바꾸어서 인덱스의 사용을 유도할 수 있다.
(KEY WORD : INDEX 활용, 인덱스, 부정형 비교, NOT IN, NOT EXISTS, <> )


DESCRIPTION
  
다음의 SQL을 보자.
     SELECT ‘Not found’  FROM EMP WHERE EMPNO <> ‘1234’

  • 대개의 Application에서는 사용자가 처리한 데이터의 타당성을 검증하기 위해 이 값의
    존재 유무를 확인하는 경우가 빈번하게 발생한다.  
    이럴 경우 위의 예처럼 부정형의 문장을 사용하는 경우가 자주 있다.

  • 하지만 아래와 같이 ‘NOT EXISTS’를 이용해서 서브쿼리(SUB-QUERY)내의 SQL을 긍정형으로 바꾸면 인덱스를 사용할 수 있다.

     SELECT ‘NOT FOUND’ FROM DUAL
        WHERE NOT EXISTS ( SELECT ‘X’ FROM EMP WHERE EMPNO = ‘1234’ )

  • 그러나 ‘EXISTS’를 사용하는 것이 항상 유리한 것은 아니다. 다음의 3개의 SQL을 보자.

    [SQL1]
      SELECT * FROM TAB1
         WHERE YYYYMM = ‘199910’
             AND NOT EXISTS ( SELECT * FROM TAB2
                                       WHERE COL2 = COL1
                                           AND YYYYMM = ‘199910’ )
    [SQL2]
      SELECT * FROM TAB1
          WHERE YYYYMM =’199910’
              AND COL1 NOT IN (SELECT COL2 FROM TAB2
                                           WHERE YYYYMM = ‘199910’ )
    [SQL3]
       SELECT * FROM TAB1
           WHERE (YYYYMM, COL1) IN ( SELECT ‘199910’, COL1 FROM TAB1
                                                       WHERE YYYYMM = ‘199910’
                                                   MINUS
                                                   SELECT ‘199910’, COL2 FROM TAB2
                                                        WHERE YYYYMM = ‘199910’ )

  • TAB1 테이블의 ‘YYYYMM’, ‘COL1’이 각각 인덱스로 생성되어 있고
    TAB2의 ‘YYYYMM’, ‘COL2’가 각각 인덱스로 생성되어 있다.
     
  • [SQL1] 은 ‘TAB1’의 ‘YYYYMM’ 인덱스만을 사용하여 테이블의 로우를 엑세스하고
    각 로우마다 TAB2 테이블을 엑세스하는 서브쿼리가 수행되어 TAB2 에 존재하지 않는
    로우만 추출하게 된다. 이 SQL은 ‘199910’조건에 해당하는 모든 로우에 대해 서브
    쿼리가 랜덤엑세스를 수행한다. 왜냐하면 서브쿼리내에 메인쿼리의 컬럼인 'COL1'이
    존재하기 때문
    이다.
     
  • [SQL2] 는 서브쿼리 내에 메인쿼리 컬럼을 없애기 위해 작성하였지만 동일한 결과를
    초래한다. 그 이유는 'NOT IN'을 사용한 서브쿼리는 항상 나중에 수행되거나
    필터링(Filtering) 조인방식으로 수행되기 때문
    이다.
     
  • [SQL3]은 각 테이블에 ‘YYYYMM + COL1’, ‘YYYYMM + COL2’의 결합인덱스가 존재한
    다면 먼저 서브쿼리에서 두 개의 테이블을 ‘MINUS’하여 결과를 추출하고 그 결과를
    이용해 메인쿼리를 엑세스하게 할 수 있다. 이 경우에는 서브쿼리가 먼저 수행된다.
    인덱스만으로도 처리가 가능하기 때문에 테이블을 엑세스하지 않고 양쪽 테이블의
    인덱스들만 범위스캔(Range Scan)하여 ‘SORT-MERGE’방식으로 서브쿼리가 처리 된다.
     
  • 위의 경우에서는 결과적으로 [SQL3]가 가장 유리한 처리방법이라 하겠다.

참고 : http://kdonghwa.tistory.com/58?srchid=BR1http%3A%2F%2Fkdonghwa.tistory.com%2F58

2009. 9. 8. 12:41

Java DES/TripleDES 암호화





Java 기반 DES 암호화를 찾던 중 정리한 소스

1. Key는 관리차원에서 고정키로 사용 (키발급 안함)
2. DES, TripleDES 모두 가능
3. TripleDES로 사용하는 경우 Key Size는 24 바이트로 지정 (이하시 에러)

 package system.user.MD5;

import java.security.*;
import javax.crypto.*;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.DESedeKeySpec;

public class DES {

    public static void main(String[] args) throws Exception {
        String text = "java12345";

        String enen = encrypt(text);
        String dede = decrypt(enen);

        System.out.println("\nOrigin key: " + key());
        System.out.println("\nOrigin text: " + text);
        System.out.println("\nEncrypted text: " + enen);
        System.out.println("\nDecrypted text: " + dede);
    }
    
    /**
     * 고정키 정보
     * @return
     */
    public static String key()
    {
        return "ab_booktv_abcd09";
        //return "ab_booktv_abcd0912345678";
    }
    
    /**
     * 키값
     * 24바이트인 경우 TripleDES 아니면 DES
     * @return
     * @throws Exception
     */
    public static Key getKey() throws Exception {
        return (key().length() == 24) ? getKey2(key()) : getKey1(key());
    }

    /**
     * 지정된 비밀키를 가지고 오는 메서드 (DES)
     * require Key Size : 16 bytes
     *
     * @return Key 비밀키 클래스
     * @exception Exception
     */
    public static Key getKey1(String keyValue) throws Exception {
        DESKeySpec desKeySpec = new DESKeySpec(keyValue.getBytes());
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
        Key key = keyFactory.generateSecret(desKeySpec);
        return key;
    }
    
    /**
     * 지정된 비밀키를 가지고 오는 메서드 (TripleDES)
     * require Key Size : 24 bytes
     * @return
     * @throws Exception
     */
    public static Key getKey2(String keyValue) throws Exception {
        DESedeKeySpec desKeySpec = new DESedeKeySpec(keyValue.getBytes());
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DESede");
        Key key = keyFactory.generateSecret(desKeySpec);
        return key;
    }

    /**
     * 문자열 대칭 암호화
     *
     * @param ID
     *            비밀키 암호화를 희망하는 문자열
     * @return String 암호화된 ID
     * @exception Exception
     */
    public static String encrypt(String ID) throws Exception {
        if (ID == null || ID.length() == 0)
            return "";
        
        String instance = (key().length() == 24) ? "DESede/ECB/PKCS5Padding" : "DES/ECB/PKCS5Padding";
        javax.crypto.Cipher cipher = javax.crypto.Cipher.getInstance(instance);
        cipher.init(javax.crypto.Cipher.ENCRYPT_MODE, getKey());
        String amalgam = ID;

        byte[] inputBytes1 = amalgam.getBytes("UTF8");
        byte[] outputBytes1 = cipher.doFinal(inputBytes1);
        sun.misc.BASE64Encoder encoder = new sun.misc.BASE64Encoder();
        String outputStr1 = encoder.encode(outputBytes1);
        return outputStr1;
    }

    /**
     * 문자열 대칭 복호화
     *
     * @param codedID
     *            비밀키 복호화를 희망하는 문자열
     * @return String 복호화된 ID
     * @exception Exception
     */
    public static String decrypt(String codedID) throws Exception {
        if (codedID == null || codedID.length() == 0)
            return "";
        
        String instance = (key().length() == 24) ? "DESede/ECB/PKCS5Padding" : "DES/ECB/PKCS5Padding";
        javax.crypto.Cipher cipher = javax.crypto.Cipher.getInstance(instance);
        cipher.init(javax.crypto.Cipher.DECRYPT_MODE, getKey());
        sun.misc.BASE64Decoder decoder = new sun.misc.BASE64Decoder();

        byte[] inputBytes1 = decoder.decodeBuffer(codedID);
        byte[] outputBytes2 = cipher.doFinal(inputBytes1);

        String strResult = new String(outputBytes2, "UTF8");
        return strResult;
    }

}


결과
==================================
Origin key: ab_booktv_abcd09

Origin text: java12345

Encrypted text: 3nAuFnFNtxDWBHOqueEpdA==

Decrypted text: java12345

 

2009. 7. 28. 13:12

[리눅스/솔라리스] 유닉스 혹은 리눅스용 커맨드 팁 모음입니다..




유닉스 혹은 리눅스용 커맨드 팁 모음입니다.
  1. 서브 디렉토리까지 파일안의 문자열 모두 검색
  2. haha와 huhu가 동시에 들어있는 행 뽑기
  3. 찾아서 지우기
  4. 공사중에 로그인 막기
  5. 크기가 가장 큰 파일, 디렉토리 찾기
  6. 가장 큰 파일을 찾으려면
  7. 현재 디렉토리의 크기만을 파악할때
  8. 시스템 정보 감추기
  9. 어떤 프로세스가 메모리를 가장 많이 잡아먹고 있는지 알아내기
  10. FTP로 들어온 사용자 확인하기
  11. 원하지 않는 사용자 죽이기
  12. less 결과를 vi로 보기
  13. vi에서 블럭 설정하기
  14. man 페이지 프린트하기
  15. ping 무시하기
  16. LILO 다시 살리기
  17. 특정 사용자 ftp 접근 막기
  18. X 윈도우에서 TV보기
  19. ls라는 파일이 포함된 rpm패키지 찾기
  20. 현재 rpm패키지의 의존패키지
  21. 현재 디렉토리크기
  22. 바로 이전 디렉토리로 가기
  23. 프로세스명으로 프로세스 죽이기
  24. 하드웨어 시계맞추기
  25. 원격에서 리모트서버의 X application실행시
  26. 링크 파일
  27. ^M 문자 없애기
  28. 비어있는 행을 찾기
  29. 기타 명령어 떼
  30. 각자가 사용하는 컴퓨터의 정보를 알고 싶을때
  31. 전체 메일
  32. 디렉토리만 빠르게 검색
  33. 호스트 네임 바꾸기
  34. 틀린명령어 틀린글자만 바꿔서 실행
  35. 유닉스의 현재 버젼과 종류 그리고 라이센스등을 알려주는 명령어
  36. 열려있는 포트 알아내기
  37. 텔넷 모든 접속자에게 메세지 보내기
  38. lsof는 열려있는 파일을 나타내 주는 옵션
  39. 사용자가 어디에서 무엇을 하는지 알아내기
  40. 텔넷 화면 수정
  41. 하위 디렉토리 한꺼번에 만들기
  42. 특정디렉토리의 모든 파일 안의 특정 문자열 치환
  43. killall 명령 시뮬레이션 (프로세스명으로 죽이기)
  44. find와 grep
  45. vi 검색, 치환
  46. 파일내의 중복되는 행을 제거 : uniq
  47. 파일의 결합
  48. 파일의 암호화 : crypt
  49. 개행을 제외한 화면내의 보이지 않는 문자 출력
  50. 화일내의 포함된 특정문자열로 찾아서 내용만 출력하기
  51. 특정 파일의 화일명을 비슷하게 여러개 한꺼번에 바꾸기
  52. 어제 날짜 구하기
  53. 원하지 않는 사용자 죽이기
  54. UNIX상에서 한글출력이 깨져 나올경우
  55. 현재 디렉토리의 대량의 파일을 각자의 파일명가운데에 특정문자 추가하여 바꾸기



0.0.0.1 서브 디렉토리까지 파일안의 문자열 모두 검색

find ./ -name "*" -exec grep 'abc' {} \; -print 

find . -name -print -exec grep abc {} \;

grep -r abc *




0.0.0.2 haha와 huhu가 동시에 들어있는 행 뽑기

grep haha foo.txt | grep huhu 




0.0.0.3 찾아서 지우기

find / -name "*.eml" -exec rm -f {} \; 




0.0.0.4 공사중에 로그인 막기


시스템을 공사중일 때, root 이외의 다른 사용자를 로그인 못하게 해야 할 때가 있죠? 그럴 때는, /etc/nologin 이라는 파일을 만들어,공사중 또는 Under Construction이라는 공지를 넣으면 됩니다.


0.0.0.5 크기가 가장 큰 파일, 디렉토리 찾기

가장 큰 디렉토리를 찾으려면,  du -S | sort -n 


0.0.0.6 가장 큰 파일을 찾으려면

 ls -lR | sort +4n 


0.0.0.7 현재 디렉토리의 크기만을 파악할때

[root@dev2 local]# du -c -h --max-depth=0 * 

6.4M apache

35M bin

43M dns

1.7M doc

42k etc

1.0k games

42k geektalkd

1.1M gnuws

1.1M include

41k info

19M jakarta-tomcat-3.2.3

0 jre

15M jre118_v3

25M lib

62k libexec

1011k man

1.3M mm.mysql.jdbc-1.2c

937k sbin

3.8M share

1.8M shoutcast-1-8-3-linux-glibc6

5.2M ssl

159M total




0.0.0.8 시스템 정보 감추기

/etc/inetd.conf 파일을 열어서,

telnet stream tcp nowait root /usr/sbin/tcpd in.telnetd -h 




0.0.0.9 어떤 프로세스가 메모리를 가장 많이 잡아먹고 있는지 알아내기

ps -aux | sort +4n  또는 ps -aux | sort +5n 


0.0.0.10 FTP로 들어온 사용자 확인하기

 ftpwho,ftpcount 


0.0.0.11 원하지 않는 사용자 죽이기

 [root@dream /root]# skill -KILL sunny 
위의 명령을 내리면 sunny 라는 사용자를 완전히 추방시킬수 있습니다. 그런데 이렇게 완전히 추방시키는게 아니구, 특정 터미널에 접속해있는 사용자만 추방시켜야 할 때도 있겠죠? 그럴때는
 [root@dream /root]# skill -KILL -v pts/14 
이런식으로 하면 된다 그럼 pts/14 에 연결되어 있는 사용자가 죽게 됩니다.


0.0.0.12 less 결과를 vi로 보기

less상태에서 v를 누르면 바로 vi로 감


0.0.0.13 vi에서 블럭 설정하기

alt+v 하면, 라인 단위로 블럭 설정을 할 수 있으며, 해제 하시려면 Esc를 누르면 됩니다. 또한 ctl+v를 하시면, 블럭 단위로 블럭을 설정하실 수 있습니다.
블럭을 설정 하신 뒤,
삭제를 하려면 x 복사를 하려면 y 붙여넣기는 p


0.0.0.14 man 페이지 프린트하기

 man -t vi > vi.ps 


0.0.0.15 ping 무시하기

echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_all 

echo 0 > /proc/sys/net/ipv4/icmp_echo_ignore_all




0.0.0.16 LILO 다시 살리기

 boot : vmlinuz root=/dev/hda6 


0.0.0.17 특정 사용자 ftp 접근 막기


/etc/ftpusers 파일에 로그인 네임을 추가하면 됩니다.


0.0.0.18 X 윈도우에서 TV보기

리눅스에서 TV보기 위해서는 드라이버 파일과 TV를 보는 프로그램이 필요합니다. 이 글에서는 미지 리눅스 OS에 탑재된 bttv 칩셋을 사용하는 TV 카드를 기준으로 설명합 니다. 만일 커널을 새로 컴파일 하실 분은 반드시 Character devices -> Video For Linux -> BT848 Video For Linux 항목을 모듈화 시키거나 커널에 포함하십시오.
TV 카드를 리눅스에 인식시키기 위해서 /etc/conf.modules 파일에 다음과 같은 내용을 삽입하고 컴퓨터를 다시 시작합니다.

alias char-major-81 bttv 

# 필립스 튜너의 경우 pre-install bttv modprobe -k tuner

# 알프스 튜너의 경우 pre-install bttv modprobe -k tuner type=9


이제 kwintv나 xawtv 등의 TV 시청 프로그램으로 TV를 볼 수 있습니다. 만약 TV 장치를 찾지 못하는 오류가 있다면 bttv driver 디렉토리에 포함된 MAKEDEV 를 실행하십시오.


0.0.0.19 ls라는 파일이 포함된 rpm패키지 찾기

일단 ls의 절대경로를 알아야 한다. which lswhich로 알아낸 ls의 절대경로로 rpm질의를 한다.

rpm -qf /bin/ls 

[root@piruks /etc]# which ls

/bin/ls

[root@piruks /etc]# rpm -qf /bin/ls

fileutils-4.0i-2mz




0.0.0.20 현재 rpm패키지의 의존패키지

 rpm -qR 패키지명 


0.0.0.21 현재 디렉토리크기

 du -h --max-depth=1 . 


0.0.0.22 바로 이전 디렉토리로 가기

 cd - 


0.0.0.23 프로세스명으로 프로세스 죽이기

killall 프로세스명 

kill -9 `pidof 프로세스명




0.0.0.24 하드웨어 시계맞추기

배포본을 설치하고 나면 시간이 맞지 않는 경우가 많다. 간단히 어느정도 정확한 시간을 설정하는 방법이다.

[root@dev /down]# rdate -s time.kriss.re.kr 

[root@dev /down]# clock -w




0.0.0.25 원격에서 리모트서버의 X application실행시

X윈도 app를 실행할때 다음과 같은 에러가 나면 조치

[kang@dev /home/kang] xclock 

Xlib: connection to "211.222.186.170:0.0" refused by server

Xlib: Client is not authorized to connect to Server

Error: Can't open display: 211.222.186.170:0.0



export DISPLAY=211.222.186.170:0

xhost +211.222.186.170




0.0.0.26 링크 파일

ln -sf 링크할디렉토리 링크로 만들어질 디렉토리  참고로 링크를 걸기만 한다고 접근가능한것은 아니고,링크가 걸린 디렉토리의 퍼미션도 허용으로 바꿔야 한다. 링크로 만들어질 디렉토리는 저절로 생성되고 퍼미션 777로 잡혔음.  ln -sf /www/dir_1/r_photo /www/dir_2/r_photo 


0.0.0.27 ^M 문자 없애기

a = 1^M 

def vartest(a):^M

a = a + 1^M

return a^M

a = vartest(a)^M

print a^M

Unix류 기계에서는 그냥 ^J 하나만을 개행문자로 사용하는데 PC에서는 MJ 이렇게 두 제어문자가 연속으로 사용되어야 개행문자로 받아들이죠. (그래서 PC쪽에서 만들어진 txt문서를 유닉스 기계로 불러와 vi 등을 실행하면


    줄 끝마다 보기싫은 ^M이 붙습니다. 뭐 vi에서 요거 지우는건 간단하지만요.)


PC에서 Unix에서 작성한 텍스트 문서를 보통 ftp로 받아오거나 하면 워드패드 등에서 봤을 때 전혀 개행이 되어있지 않지요. 하지만 MS Word 등 좀더 강력한 편집기에선 대개 잘 처리해서 잘 보여줍니다.
위는 간단한 Python 소스입니다. 위의 경우 처럼 ^M문자가 있을때, dos2unix라는 유틸리티를 많이 사용하기도 하죠. 하지만 vi에서 간단하게 모두 삭제할수도 있습니다. dos2unix가 없거나 빠져나가서 지우는게 귀찮을때 좋겠죠. 명령은  :%s/(ctrl+v)M//g  입니다.  (ctrl+v)M  이거는 ctrl과 v를 눌러준후, ctrl키를 떼지 말고 바로 m을 눌러주시믄 됩니다. 위는 정규표현식을 이용한것이고, 형식은  %s/이것을/요걸로/g  입니다 그럼 문서안의 모든 "이것을" "요걸로" 바꾸게 되죠. 단, M의 경우 ctrl+M의 뜻인데 단순히 문자로 M을 바꾸라도 해도 인식을 못하기 때문에, 위처럼  (ctrl+v)M  으로 해주셔야 합니다.


0.0.0.28 비어있는 행을 찾기

 #grep -n '^$' filename  정규표현 의미 ^ 행의 처음 $ 행의 끝 . 임의의 한 문자

[...] ... 안의 임의의 한 문자. a-z,0-9 같은 범위도 사용 

[^..] .. 안에 없는 임의의 한 문자. 범위 사용가능

r* 0회 이상 r 반복

r+ 1회 이상 r 반복

r? 0 혹은 1회의 r

r{n,m} n회 이상 m회 이하 r 반복

r1|r2 r1 혹은 r2 (egrep 만)

(r) r 의 정규표현(egrep 만)




0.0.0.29 기타 명령어 떼

alias(명령어 간소화하기) 

apropos(관련된 명령어 찾기)

arch(컴퓨터 종류 알기)

arp(같은 서브넷의 IP 보여주기)

at(작업 시간 정하기)

atd(계획성 있는 작업 실행하기)

awk(특정 패턴 문자 처리하기)

a2p(펄 파일로 바꾸기)

badblocks(배드 블럭 검사하기)

bc(계산기)

biff(메일 수신 소리로 확인하기)

bg(후면작업; 배경화면 설정)

bind(키나 함수 순서 결합하기)

break(루프 빠져나가기)

cal(달력보기)

builtin(내부 명령어 알아보기)

case(조건 처리하기)

cat(화면상에서 파일 보기)

cd(디렉토리 변경하기)

cfdisk(디스크 설정하기)

chattr(파일 속성 변경하기)

chfn(사용자 정보 변경하기)

chgrp(파일, 디렉토리가 속했던 그룹 바꾸기)

chmod(파일 권한 바꾸기)

chown(파일 주인 바꾸기)

chsh(지정된 셸 바꾸기)

cksum(CRC값을 점검한다)

clear(화면 청소하기)

clock(CMOS 시각을 조정하기)

cmp(파일 비교하기)

colcrt(문자 변환 필터)

colrm(열 삭제하기)

column(가로 정렬하기)

comm(파일 비교 출력하기)

command(명령어 알아보기)

continue(루프 계속돌기)

cp(파일 복사하기)

cpio(복사본 만들기)

crontab(cron을 관리한다)

csplit(파일에 서식, 규칙 정하기)

cut(필요한 필드만 출력하기)

date(날짜 보기)

dd(블럭장치 읽고 쓰기)

debugfs(ext2 파일 시스템 디버깅하기)

declare(변수 선언하기)

df(파일 시스템의 사용량 보기)

dirs(디렉토리 목록 표시하기)

dmesg(부팅 메시지 보기)

dnsdomainname(DNS 이름 출력)

domainname(NIS 이름 출력&설정)

du(디렉토리와 파일의 용량 파악하기)

dumpe2fs(파일 시스템 정보 보기)

echo(표준 출력하기)

eject(장치 해제하기)

elm(메일 관련)

enable(내부 명령어 지정)

env(환경변수 출력하기)

eval!(인수 읽기)

exec(셸 명령어 실행하기)

exit(종료하기)

expand(탭을 공백으로 변환하기)

export(변수 지정하기)

e2fsck(파일 시스템 복구하기)

fc(지정된 편집기 받기)

fdformat(플로피 디스크 포맷하기)

fdisk(파티션 나누기)

fg(지정된 작업을 전면 프로세스로 시작하기)

file(파일 종류 보기)

find(파일 찾기)

finger(사용자 정보 알기)

fold(정형화하기)

fmt(정형화하기)

for(반복 실행하기)

free(메모리 사용량 알아보기)

fsck(파일 시스템 검사하기)

fstab(파일 시스템에 대한 고정적인 정보 저장하기)

ftp(파일 전송 프로그램)

fuser(프로세스 ID 출력)

getkeycodes(매핑 테이블 출력하기)

grep(특정 문자(열) 검색하기)

gzexe(실행 파일 압축하기)

gzip(압축하기)

halt(시스템 종료하기)

hash(기억해 두기; index 역할)

head(파일의 앞부분 출력하기)

help(도움말 보여주기)

host(호스트 정보 보기)

history(사용 명령어 목록보기)

hostname(서버 이름 알기)

id(계정 정보 알기)

if(조건문 실행하기)

ifconfig(랜카드에 주소 할당하기)

imolamod(모듈 설치하기)

inetd(인터넷 서비스의 최상위 데몬)

init(실행 단계 정하기)

ispell(철자법 검사하기)

jobs(수행중인 프로세스 알기)

kbd_mode(키보드 모드 출력하기)

kill(프로세스 죽이기)

klogd(커널 로그 데몬)

ldd(공유 라이브러리의 의존성 알기)

less(페이지 단위로 출력하기)

let(정규식 표현하기)

lilo(부팅하기)

ln(링크하기)

locate(패턴에 맞는 파일 찾기)

login(로그인하기)

logger(시스템 로그 기록하기)

logname(사용자 로그인명 보여주기)

logout(로그인 셸 종료하기)

look(특정 단어 검색하기)

losetup(중복 장치 확인하기)

lpd(프린트 데몬)

lpq(현재 프린트 작업 상태 출력하기)

lpr(출력하기)

lprm(대기열에 있는 문서 삭제하기)

ls(디렉토리 내용보기)

lsattr(파일 시스템의 속성 보여주기)

lsdev(하드웨어 장치 출력하기)

lsmod(모듈 정보 출력하기)

mail(메일 관련)

make(컴파일하기)

man(매뉴얼 보기)

mattrib

mbadblocks

mcd

mcopy

mdel

mdeltree

mdir

mesg(메시지를 받을 수 있는지 확인하기)

mformat

minfo

mkdir (디렉토리 만들기)

mke2fs(파일 시스템 생성하기)

mkfs(파일 시스템 만들기)

mknod(특수 파일 만들기)

mkswap(스왑 영역 지정하기)

mlabel

mmd

mmount

mmove

mpartition

mount(장치 연결하기)

more(화면 단위로 출력하기)

mrd

mren

mtoolstest

mtype

mutt(메일 관련)

mv(파일 옮기기)

mzip

netstat(현재 네트웍 상황 보기)

nice(프로세스 우선 순위 변경하기)

od(8진수로 파일 보기)

passwd(암호 입력하기)

pidof(실행중인 프로그램의 프로세스 ID 찾기)

pine(메일 관련)

ping(네트웍 확인하기)

popd(pushd 취소)

ps(프로세스 상태 알기)

pstree(프로세스 상관관계 알기)

pwd(절대경로 보여주기)

quota(디스크 한계량 알기)

rarp(rarp 테이블 관리하기)

rcp(원격 호스트에 파일 복사하기)

rdev(루트, 스왑장치, 램 크기, 비디오 모드를 조사하고 설정하기)

rdate(네트웍으로 시간 설정하기)

reboot(재부팅하기)

rmmod(모듈 지우기)

readonly(읽기 전용으로 표시하기)

renice(프로세스 우선 순위 바꾸기)

reset(터미널 초기화하기)

restore(다시 저장하기)

rlogin(바로 접속하기)

rm(파일 지우기)

rmdir (디렉토리 지우기)

route(라우팅 테이블 추가/삭제하기)

rpm(프로그램 추가/삭제)

rpm2cpio(rpm을 cpio로 변환하기)

rsh(원격으로 명령어 실행하기)

rup(호스트 상태 출력하기)

rusers(호스트에 로그인한 사용자 출력하기)

rwall(호스트 사용자에게 메시지 뿌리기)

script(기록하기)

set(변수값 설정하기)

setup(시스템 관련 설정하기)

showmount(호스트의 마운트 정보 보여주기)

shutdown(전원 끄기)

sleep(잠시 쉬기)

source(스크립트 번역하기)

split(파일 나누기)

ssh(암호화된 원격 로그인하기)

stty(터미널라인 설정 보여주기)

su(계정 바꾸기)

suspend(셸 중단하기)

swapoff (스왑 해제하기)

swapon(스왑 활성화하기)

sync(버퍼 재설정하기)

syslogd(로그인 과정 설정하기)

tac(거꾸로 보기)

tail(문서 끝부분 출력하기)

talk(이야기하기)

tar(파일 묶기)

tcpdchk(tcp wrapper 설정하기)

tcpmatch(네트웍 요청에 대해 예측하기)

tee(표준 입력으로부터 표준 출력 만들기)

telnet(원격접속하기)

test(테스트하기)

times(셸에서의 사용자와 시스템 시간 출력하기)

top(cpu 프로세스 상황 보여주기)

tr(문자열 바꿔주기)

true(종료 코드 리턴하기)

type(유형 보기)

ul(밑줄 처리해서 보여주기)

ulimit(제한하기)

umask(매스크 모드 설정하기)

umount(장치 해제하기)

unalias(별명 제거하기)

uname(시스템 정보 보기)

unexpand(공백 문자를 탭으로 변환하기)

uniq(중복된 문장 찾기)

useradd(사용자 계정 만들기)

userdel(계정 삭제하기)

usermod(사용자 계정정보 수정하기)

unset(설정 변수 해제)

uptime(시스템 부하 평균 보여주기)

users(로그인된 사용자 보여주기)

w(시스템에 접속한 사용자 상황 알아보기)

wait(프로세스 기다리기)

wall(모든 사용자에게 메시지 보내기)

wc(문자, 단어, 라인수 세기)

whatis(명령어의 간단한 설명보기)

while(루프 명령어)

who(사용자 알기)

write(콘솔 상에서 간단한 메시지 보내기)

xcopy(반복적으로 복사하기)

XFree86

ypchfn(NIS에서 사용하는 chfn 명령어)

ypchsh(NIS에서 사용하는 chsh 명령어)

yppasswd(NIS에서 사용하는 passwd 명령어)

zcat(압축 파일 보기)

zcmp(압축 파일 비교하기)

zforce(강제로 gz 만들기)

zgrep(압축 상태에서 grep 실행하기)

zmore(압축 상태에서 more 실행하기)

znew(.Z 파일을 .gz로 다시 압축하기)




0.0.0.30 각자가 사용하는 컴퓨터의 정보를 알고 싶을때

 [root ...]#more /proc/cpuinfo  위와 같이 치면 사용자의 컴퓨터 정보를 볼수 있으며,  [root ...]#more /proc/meminfo  라고 치면 사용자의 메모리 정보를 볼수 있습니다.


0.0.0.31 전체 메일

먼저 보낼 내용을 텍스트로 파일로 만들어야 합니다.어디에서든지 가능하지요!  [ root@aromi /root]# vi nea  안녕하세요! 저희 서버에서는 웹서버를 오늘부터 시작합니다. 사용자 여러분의 많은 관심과 이용을 부탁드립니다.

 

:wq

[ root@aromi /root]#

만약, 한글을 사용하지 못하면 윈도우95에서 먼저 쓴다음에 ftp를 이용해서 올리면 됩니다.

[ root@aromi /root]# mail -s "[공지]" `cat /etc/passwd|gawk ?F :'{print$1}'` 

 [공지]->  라고 쓴 것은 보낼 메일의 제목입니다.  'cat /etc/passwd|gawk -F : '{print$1}''  ->먼저 cat으로 passwd파일의 첫번째 나오는 내용을 출력하라는 소리입니다. nea라는 텍스트파일을 메일의 내용으로 보내라는 내용입니다.


0.0.0.32 디렉토리만 빠르게 검색

 ls -al | grep "^d" 


0.0.0.33 호스트 네임 바꾸기

/etc/HOSTNAME file은 부팅시 /etc/sysconfig/network file 의 HOSTNAME 부분을 참조하여 저장합니다. 호스트 네임을 바꾸고자 한다면 /etc/sysconfig/network file 의 HOSTNAME 부분을 바꿔주면 됩니다.

[ root@linux /root]# vi /etc/sysconfig/network 

NETWORKING=yes

HOSTNAME="linux"

GATEWAY=""

GATEWAYDEV=""

FORWARD_IPV4="yes"

바꾸신후 시스템을 재부팅 하신거나, #/etc/rc.d/init.d/network restart 명령을 내리시면 됩니다.


0.0.0.34 틀린명령어 틀린글자만 바꿔서 실행

 # ./configure --prefax=/usr/local/apache  앗, 틀렸습니다. prefax가 아니라 prefix인데... 고쳐야지요...간단하게 화살표키로 왔다갔다 하면서 지워지고 바꿔주면 되겠지만 다른 방법이 있습니다.  # ^fax^fix^  라고 하면...  -> ./configure --prefix=/usr/local/apache  라고 됩니다..


0.0.0.35 유닉스의 현재 버젼과 종류 그리고 라이센스등을 알려주는 명령어

 [ root@aromi /root]# uname -a 


0.0.0.36 열려있는 포트 알아내기

 netstat -anp | grep LISTEN 


0.0.0.37 텔넷 모든 접속자에게 메세지 보내기

wall 내용...  Ctrl-D 


0.0.0.38 lsof는 열려있는 파일을 나타내 주는 옵션

여기에 보안 점검을 위하여, -i 옵션을 사용하면, 현재 열려 있는 포트와 링크되어 있는 서비스 또는 프로그램이 모두 나타나죠. 자신이 열어 놓지 않은 포트가 열려있다던지하면 한번쯤 의심해 봐도 되겠죠?


0.0.0.39 사용자가 어디에서 무엇을 하는지 알아내기

w라는 명령어를 사용하시면 된답니다. 이 때,  w [-s]  를 붙여주시면 -s 옵션이 긴 정보 대신에 필요한 짧은 정보만 알려 준답니다.


0.0.0.40 텔넷 화면 수정

로그인화면:  /etc/issue.net  로그인후화면:  /etc/motd 


0.0.0.41 하위 디렉토리 한꺼번에 만들기

 mkdir -p music/koreanmusic/ost 


0.0.0.42 특정디렉토리의 모든 파일 안의 특정 문자열 치환

for i in $*; do 

sed "s/paper/PAPER/g" < $i > $i.new

mv -f $i.new $i

done



<chihwan.sh>



find ./(chihwan.sh를 포함하지 않는 디렉토리면) -type f -exec chihwan.sh {} \;




0.0.0.43 killall 명령 시뮬레이션 (프로세스명으로 죽이기)

ps aux | grep 프로세스명 | grep -v grep | awk '{ print $w }' | xargs kill -9 



  • 모든 프로세스 나열

  • 지정한 프로세스만 뽑아냄

  • grep 명령이 포함된 라인 제거

  • awk로 두번째 필드만 뽑아냄

  • xargs에 의해 걸러진 아이디로 죽임




0.0.0.44 find와 grep

find . -name "H20021115.*" -exec grep -l '...;........;110100' {} \;


0.0.0.45 vi 검색, 치환

구호스트 서비스 오늘 날짜에서 분류코드가 110100인 파일 찾기 :%s/./\U&/g
모든문자->대문자 g/^$/d


0.0.0.46 파일내의 중복되는 행을 제거 : uniq

입력 파일에서 연속되는 행을 비교하여, 두 번째 이상의 동일한 행들을 제거하고 나머지는 출력파일로 출력 연속되어 표시되지 않으면 동일한 행이 존재할 수 있음.
sort 명령을 사용하여 정렬한 후 사용하는 것이 타당 사용법uniq [-cdu] [+|숫자] [입력파일 [출력파일]] -c : 각 행이 연속적으로 나타난 횟수를 행의 시작부분에 표시 -d : 연속적으로 반복되는 행만 출력 -u : 연속적으로 반복되지 않는 행만 출력 +숫자 : 행의 처음 '숫자' 만큼의 문자는 무시 -숫자 : 행의 처음 '숫자' 만큼의 필드는 무시


0.0.0.47 파일의 결합

여러 개의 텍스트 파일을 하나의 파일로 순차적으로 묶는데 사용

cat [파일명1] [파일명2] ... > [출력파일명] 

cat [파일명1] [파일명2] ... >& [출력파일명]

cat [파일명1] [파일명2] ... >> [출력파일명]

cat [파일명1] [파일명2] ... >>& [출력파일명]

cat - [파일명1], [파일명2] .. >> [출력파일명]

cat - [파일명1], [파일명2] .. >>& [출력파일명]





% cat > file1

파일명 : file1

^D

% cat > file2

파일명 : file2

^D

% cat file1 file2 > file3

% cat file3

파일명 : file1

파일명 : file2

%


행단위 결합 : paste 여러 파일에 대해여 행간 결합을 수행하거나 하나의 파일에 대해 연속되는 행들을 결합 둘이상의 파일에 대해서 테이블상의 하나의 열과 같이 취급하여 동일한 행번호 끼리 결합

 

paste [파일명1] [파일명2]..

paste -d리스트 [파일명1] [파일명2] ...

paste -s [-d리스트] [파일명]

d : 행간 결합시 행간 구분문자들의 리스트

s : 한파일의 연속되는 행을 결합



% cat > paste.data1

홍길동

이순신

김유신

% cat > paste.data2

부산

서울

대구

% paste paste.data1 paste.data2

홍길동 부산

이순신 서울

김유신 대구

% paste -d"\n" paste.data1 paste.data2

홍길동

부산

이순신

서울

김유신

대구

% paste -s -d"::\n" paste.data1

홍길동:이순신:김유신

%


두 파일을 동일한 필드 값에 따라 행 단위 결합 : join
관계형 데이터 베이스에서의 join 연산과 동일 키로 사용할 필드에 대해 정렬된 두 파일의 각 행에 대해 동일한 키 값을 갖는 행들을 결합 입력으로 사용될 두 파일은 키 값에 대해 오름 차순으로 정렬되어 있어야 함 출력 결과는 기본적으로 키 값이 먼저 표시되고, 첫번째 파일에서 키를 제외한 나머지 필드, 두번테 파일에서 키를 제외한 나머지 필드가 표시 필드 구분은 공백, 탭, 개행문자가 기본, 연속적으로 나타날 경우 하나로 취급

% cat > join.data1 

98001:서원일:

98002:홍길동:

98003:김유신:

98004:이순신:

98010:이상관:

% cat > join.data2

부산:98001:441

울산:98002:89

대구:98003:99

서울:98004:120

김해:98010:44

% join -j1 1 -j2 2 -t: join.data1 join.data2

98001:서원일::부산:441

98002:홍길동::울산:89

98003:김유신::대구:99

98004:이순신::서울:120

98010:이상관::김해:44

% join -j1 1 -j2 2 -o 1.2 1.1 2.1 -t: join.data1 join.data2

서원일:98001:부산

홍길동:98002:울산

김유신:98003:대구

이순신:98004:서울

이상관:98010:김해

%




0.0.0.48 파일의 암호화 : crypt

파일을 암호화 하여 키를 알지 못하는 사람은 내용을 볼 수 없도록 함 표준 입출력 사용

% cat > crypt.data 

test test

안녕하십니까?

^D

% crypt <crypt.data > crypt.data1

Enter key: hello

% ls -l crypt*

-rw-r--r-- 1 wiseo pro 24 9월 24일 14:47 crypt.data

-rw-r--r-- 1 wiseo pro 24 9월 24일 14:48 crypt.data1

% crypt < crypt.data1

Enter key:hello

test test

안녕하십니까?

%




0.0.0.49 개행을 제외한 화면내의 보이지 않는 문자 출력

cat -v http://comp-cse.sch.ac.kr/~pl/lecture/linux/file2.html


0.0.0.50 화일내의 포함된 특정문자열로 찾아서 내용만 출력하기

grep -h '20030305......01' ./R00*


0.0.0.51 특정 파일의 화일명을 비슷하게 여러개 한꺼번에 바꾸기

ls *.* | awk '{print "mv",$1, $1 }' | sed "s/ \([a-zA-Z0-9]*\)\.\([a-zA-Z0-9]*\)$/ \1\.\_\2/g" 





  • 현재디렉토리의 모든 *.* 파일을 *._* 형식으로 바꾼다.

  • 더 간단하게 ls *.* | sed "s/\([a-zA-Z0-9]*\)\.\([a-zA-Z0-9]*\)/mv \1\.\2 \1\.\_\2/g"










0.0.0.52 어제 날짜 구하기

$ date -v-1d "+%Y-%m-%d"  [컴퓨터분류]


0.0.0.53 원하지 않는 사용자 죽이기

[root@dream /root]# skill -KILL sunny 
위의 명령을 내리면 sunny 라는 사용자를 완전히 추방시킬수 있습니다. 그런데 이렇게 완전히 추방시키는게 아니구, 특정 터미널에 접속해있는 사용자만 추방시켜야 할 때도 있겠죠? 그럴때는 [root@dream /root]# skill -KILL -v pts/14 
이런식으로 하면 된다 그럼 pts/14 에 연결되어 있는 사용자가 죽게 됩니다.

0.0.0.54 UNIX상에서 한글출력이 깨져 나올경우

유닉스상에서 한글을 stdout출력할 경우 가끔 출력되는 문자들이 몽땅 깨져서 나오는 경우가 있다. 이때부터는 프로그램이 종료된 이후에도 쉘 프람프트를 비롯, 쉘에서 입력하는 모든 커맨드가 깨져서 나온다. 이는 ascii code 로 ^n 에 해당하는 문자가 출력될 때 나오는 현상으로 그 이후로는 MSB가 모두 켜지기 때문이다. 문자가 깨져나오는 이후부터 ascii code 로 ^o 에 해당하는 문자를 출력하면 반대로 된다. 쉘 커맨드 상에서라면, # echo ^v^o 
라고 해야겠지만 커맨드가 깨져나오므로 shell이 해석을 못한다. 따라서, command line에서 ^v^o를 치고 enter 하면 된다


0.0.0.55 현재 디렉토리의 대량의 파일을 각자의 파일명가운데에 특정문자 추가하여 바꾸기

/bin/ls A?????.html | sed 's/A\(.....\)\.html/\1/g' | xargs -t -i mv 'A{}.html' 'A0{}.html' 

/bin/ls는 ls가 보통 -F로 파일 종류 표시(*, @등)까지 하기 때문에 그걸 막기 위한 것이고 xargs의 -t는 트레이스모드이다.
wonie777 블로거 [펌] Unix Tip 유닉스 혹은 리눅스용 커맨드 팁 모음입니다.










  1. 서브 디렉토리까지 파일안의 문자열 모두 검색

  2. haha와 huhu가 동시에 들어있는 행 뽑기

  3. 찾아서 지우기

  4. 공사중에 로그인 막기

  5. 크기가 가장 큰 파일, 디렉토리 찾기

  6. 가장 큰 파일을 찾으려면

  7. 현재 디렉토리의 크기만을 파악할때

  8. 시스템 정보 감추기

  9. 어떤 프로세스가 메모리를 가장 많이 잡아먹고 있는지 알아내기

  10. FTP로 들어온 사용자 확인하기

  11. 원하지 않는 사용자 죽이기

  12. less 결과를 vi로 보기

  13. vi에서 블럭 설정하기

  14. man 페이지 프린트하기

  15. ping 무시하기

  16. LILO 다시 살리기

  17. 특정 사용자 ftp 접근 막기

  18. X 윈도우에서 TV보기

  19. ls라는 파일이 포함된 rpm패키지 찾기

  20. 현재 rpm패키지의 의존패키지

  21. 현재 디렉토리크기

  22. 바로 이전 디렉토리로 가기

  23. 프로세스명으로 프로세스 죽이기

  24. 하드웨어 시계맞추기

  25. 원격에서 리모트서버의 X application실행시

  26. 링크 파일

  27. ^M 문자 없애기

  28. 비어있는 행을 찾기

  29. 기타 명령어 떼

  30. 각자가 사용하는 컴퓨터의 정보를 알고 싶을때

  31. 전체 메일

  32. 디렉토리만 빠르게 검색

  33. 호스트 네임 바꾸기

  34. 틀린명령어 틀린글자만 바꿔서 실행

  35. 유닉스의 현재 버젼과 종류 그리고 라이센스등을 알려주는 명령어

  36. 열려있는 포트 알아내기

  37. 텔넷 모든 접속자에게 메세지 보내기

  38. lsof는 열려있는 파일을 나타내 주는 옵션

  39. 사용자가 어디에서 무엇을 하는지 알아내기

  40. 텔넷 화면 수정

  41. 하위 디렉토리 한꺼번에 만들기

  42. 특정디렉토리의 모든 파일 안의 특정 문자열 치환

  43. killall 명령 시뮬레이션 (프로세스명으로 죽이기)

  44. find와 grep

  45. vi 검색, 치환

  46. 파일내의 중복되는 행을 제거 : uniq

  47. 파일의 결합

  48. 파일의 암호화 : crypt

  49. 개행을 제외한 화면내의 보이지 않는 문자 출력

  50. 화일내의 포함된 특정문자열로 찾아서 내용만 출력하기

  51. 특정 파일의 화일명을 비슷하게 여러개 한꺼번에 바꾸기

  52. 어제 날짜 구하기

  53. 원하지 않는 사용자 죽이기

  54. UNIX상에서 한글출력이 깨져 나올경우

  55. 현재 디렉토리의 대량의 파일을 각자의 파일명가운데에 특정문자 추가하여 바꾸기



0.0.0.1 서브 디렉토리까지 파일안의 문자열 모두 검색

find ./ -name "*" -exec grep 'abc' {} \; -print 

find . -name -print -exec grep abc {} \;

grep -r abc *




0.0.0.2 haha와 huhu가 동시에 들어있는 행 뽑기

grep haha foo.txt | grep huhu 




0.0.0.3 찾아서 지우기

find / -name "*.eml" -exec rm -f {} \; 




0.0.0.4 공사중에 로그인 막기


시스템을 공사중일 때, root 이외의 다른 사용자를 로그인 못하게 해야 할 때가 있죠? 그럴 때는, /etc/nologin 이라는 파일을 만들어,공사중 또는 Under Construction이라는 공지를 넣으면 됩니다.


0.0.0.5 크기가 가장 큰 파일, 디렉토리 찾기

가장 큰 디렉토리를 찾으려면,  du -S | sort -n 


0.0.0.6 가장 큰 파일을 찾으려면

 ls -lR | sort +4n 


0.0.0.7 현재 디렉토리의 크기만을 파악할때

[root@dev2 local]# du -c -h --max-depth=0 * 

6.4M apache

35M bin

43M dns

1.7M doc

42k etc

1.0k games

42k geektalkd

1.1M gnuws

1.1M include

41k info

19M jakarta-tomcat-3.2.3

0 jre

15M jre118_v3

25M lib

62k libexec

1011k man

1.3M mm.mysql.jdbc-1.2c

937k sbin

3.8M share

1.8M shoutcast-1-8-3-linux-glibc6

5.2M ssl

159M total




0.0.0.8 시스템 정보 감추기

/etc/inetd.conf 파일을 열어서,

telnet stream tcp nowait root /usr/sbin/tcpd in.telnetd -h 




0.0.0.9 어떤 프로세스가 메모리를 가장 많이 잡아먹고 있는지 알아내기

ps -aux | sort +4n  또는 ps -aux | sort +5n 


0.0.0.10 FTP로 들어온 사용자 확인하기

 ftpwho,ftpcount 


0.0.0.11 원하지 않는 사용자 죽이기

 [root@dream /root]# skill -KILL sunny 
위의 명령을 내리면 sunny 라는 사용자를 완전히 추방시킬수 있습니다. 그런데 이렇게 완전히 추방시키는게 아니구, 특정 터미널에 접속해있는 사용자만 추방시켜야 할 때도 있겠죠? 그럴때는
 [root@dream /root]# skill -KILL -v pts/14 
이런식으로 하면 된다 그럼 pts/14 에 연결되어 있는 사용자가 죽게 됩니다.


0.0.0.12 less 결과를 vi로 보기

less상태에서 v를 누르면 바로 vi로 감


0.0.0.13 vi에서 블럭 설정하기

alt+v 하면, 라인 단위로 블럭 설정을 할 수 있으며, 해제 하시려면 Esc를 누르면 됩니다. 또한 ctl+v를 하시면, 블럭 단위로 블럭을 설정하실 수 있습니다.
블럭을 설정 하신 뒤,
삭제를 하려면 x 복사를 하려면 y 붙여넣기는 p


0.0.0.14 man 페이지 프린트하기

 man -t vi > vi.ps 


0.0.0.15 ping 무시하기

echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_all 

echo 0 > /proc/sys/net/ipv4/icmp_echo_ignore_all




0.0.0.16 LILO 다시 살리기

 boot : vmlinuz root=/dev/hda6 


0.0.0.17 특정 사용자 ftp 접근 막기


/etc/ftpusers 파일에 로그인 네임을 추가하면 됩니다.


0.0.0.18 X 윈도우에서 TV보기

리눅스에서 TV보기 위해서는 드라이버 파일과 TV를 보는 프로그램이 필요합니다. 이 글에서는 미지 리눅스 OS에 탑재된 bttv 칩셋을 사용하는 TV 카드를 기준으로 설명합 니다. 만일 커널을 새로 컴파일 하실 분은 반드시 Character devices -> Video For Linux -> BT848 Video For Linux 항목을 모듈화 시키거나 커널에 포함하십시오.
TV 카드를 리눅스에 인식시키기 위해서 /etc/conf.modules 파일에 다음과 같은 내용을 삽입하고 컴퓨터를 다시 시작합니다.

alias char-major-81 bttv 

# 필립스 튜너의 경우 pre-install bttv modprobe -k tuner

# 알프스 튜너의 경우 pre-install bttv modprobe -k tuner type=9


이제 kwintv나 xawtv 등의 TV 시청 프로그램으로 TV를 볼 수 있습니다. 만약 TV 장치를 찾지 못하는 오류가 있다면 bttv driver 디렉토리에 포함된 MAKEDEV 를 실행하십시오.


0.0.0.19 ls라는 파일이 포함된 rpm패키지 찾기

일단 ls의 절대경로를 알아야 한다. which lswhich로 알아낸 ls의 절대경로로 rpm질의를 한다.

rpm -qf /bin/ls 

[root@piruks /etc]# which ls

/bin/ls

[root@piruks /etc]# rpm -qf /bin/ls

fileutils-4.0i-2mz




0.0.0.20 현재 rpm패키지의 의존패키지

 rpm -qR 패키지명 


0.0.0.21 현재 디렉토리크기

 du -h --max-depth=1 . 


0.0.0.22 바로 이전 디렉토리로 가기

 cd - 


0.0.0.23 프로세스명으로 프로세스 죽이기

killall 프로세스명 

kill -9 `pidof 프로세스명




0.0.0.24 하드웨어 시계맞추기

배포본을 설치하고 나면 시간이 맞지 않는 경우가 많다. 간단히 어느정도 정확한 시간을 설정하는 방법이다.

[root@dev /down]# rdate -s time.kriss.re.kr 

[root@dev /down]# clock -w




0.0.0.25 원격에서 리모트서버의 X application실행시

X윈도 app를 실행할때 다음과 같은 에러가 나면 조치

[kang@dev /home/kang] xclock 

Xlib: connection to "211.222.186.170:0.0" refused by server

Xlib: Client is not authorized to connect to Server

Error: Can't open display: 211.222.186.170:0.0



export DISPLAY=211.222.186.170:0

xhost +211.222.186.170




0.0.0.26 링크 파일

ln -sf 링크할디렉토리 링크로 만들어질 디렉토리  참고로 링크를 걸기만 한다고 접근가능한것은 아니고,링크가 걸린 디렉토리의 퍼미션도 허용으로 바꿔야 한다. 링크로 만들어질 디렉토리는 저절로 생성되고 퍼미션 777로 잡혔음.  ln -sf /www/dir_1/r_photo /www/dir_2/r_photo 


0.0.0.27 ^M 문자 없애기

a = 1^M 

def vartest(a):^M

a = a + 1^M

return a^M

a = vartest(a)^M

print a^M

Unix류 기계에서는 그냥 ^J 하나만을 개행문자로 사용하는데 PC에서는 MJ 이렇게 두 제어문자가 연속으로 사용되어야 개행문자로 받아들이죠. (그래서 PC쪽에서 만들어진 txt문서를 유닉스 기계로 불러와 vi 등을 실행하면


    줄 끝마다 보기싫은 ^M이 붙습니다. 뭐 vi에서 요거 지우는건 간단하지만요.)


PC에서 Unix에서 작성한 텍스트 문서를 보통 ftp로 받아오거나 하면 워드패드 등에서 봤을 때 전혀 개행이 되어있지 않지요. 하지만 MS Word 등 좀더 강력한 편집기에선 대개 잘 처리해서 잘 보여줍니다.
위는 간단한 Python 소스입니다. 위의 경우 처럼 ^M문자가 있을때, dos2unix라는 유틸리티를 많이 사용하기도 하죠. 하지만 vi에서 간단하게 모두 삭제할수도 있습니다. dos2unix가 없거나 빠져나가서 지우는게 귀찮을때 좋겠죠. 명령은  :%s/(ctrl+v)M//g  입니다.  (ctrl+v)M  이거는 ctrl과 v를 눌러준후, ctrl키를 떼지 말고 바로 m을 눌러주시믄 됩니다. 위는 정규표현식을 이용한것이고, 형식은  %s/이것을/요걸로/g  입니다 그럼 문서안의 모든 "이것을" "요걸로" 바꾸게 되죠. 단, M의 경우 ctrl+M의 뜻인데 단순히 문자로 M을 바꾸라도 해도 인식을 못하기 때문에, 위처럼  (ctrl+v)M  으로 해주셔야 합니다.


0.0.0.28 비어있는 행을 찾기

 #grep -n '^$' filename  정규표현 의미 ^ 행의 처음 $ 행의 끝 . 임의의 한 문자

[...] ... 안의 임의의 한 문자. a-z,0-9 같은 범위도 사용 

[^..] .. 안에 없는 임의의 한 문자. 범위 사용가능

r* 0회 이상 r 반복

r+ 1회 이상 r 반복

r? 0 혹은 1회의 r

r{n,m} n회 이상 m회 이하 r 반복

r1|r2 r1 혹은 r2 (egrep 만)

(r) r 의 정규표현(egrep 만)




0.0.0.29 기타 명령어 떼

alias(명령어 간소화하기) 

apropos(관련된 명령어 찾기)

arch(컴퓨터 종류 알기)

arp(같은 서브넷의 IP 보여주기)

at(작업 시간 정하기)

atd(계획성 있는 작업 실행하기)

awk(특정 패턴 문자 처리하기)

a2p(펄 파일로 바꾸기)

badblocks(배드 블럭 검사하기)

bc(계산기)

biff(메일 수신 소리로 확인하기)

bg(후면작업; 배경화면 설정)

bind(키나 함수 순서 결합하기)

break(루프 빠져나가기)

cal(달력보기)

builtin(내부 명령어 알아보기)

case(조건 처리하기)

cat(화면상에서 파일 보기)

cd(디렉토리 변경하기)

cfdisk(디스크 설정하기)

chattr(파일 속성 변경하기)

chfn(사용자 정보 변경하기)

chgrp(파일, 디렉토리가 속했던 그룹 바꾸기)

chmod(파일 권한 바꾸기)

chown(파일 주인 바꾸기)

chsh(지정된 셸 바꾸기)

cksum(CRC값을 점검한다)

clear(화면 청소하기)

clock(CMOS 시각을 조정하기)

cmp(파일 비교하기)

colcrt(문자 변환 필터)

colrm(열 삭제하기)

column(가로 정렬하기)

comm(파일 비교 출력하기)

command(명령어 알아보기)

continue(루프 계속돌기)

cp(파일 복사하기)

cpio(복사본 만들기)

crontab(cron을 관리한다)

csplit(파일에 서식, 규칙 정하기)

cut(필요한 필드만 출력하기)

date(날짜 보기)

dd(블럭장치 읽고 쓰기)

debugfs(ext2 파일 시스템 디버깅하기)

declare(변수 선언하기)

df(파일 시스템의 사용량 보기)

dirs(디렉토리 목록 표시하기)

dmesg(부팅 메시지 보기)

dnsdomainname(DNS 이름 출력)

domainname(NIS 이름 출력&설정)

du(디렉토리와 파일의 용량 파악하기)

dumpe2fs(파일 시스템 정보 보기)

echo(표준 출력하기)

eject(장치 해제하기)

elm(메일 관련)

enable(내부 명령어 지정)

env(환경변수 출력하기)

eval!(인수 읽기)

exec(셸 명령어 실행하기)

exit(종료하기)

expand(탭을 공백으로 변환하기)

export(변수 지정하기)

e2fsck(파일 시스템 복구하기)

fc(지정된 편집기 받기)

fdformat(플로피 디스크 포맷하기)

fdisk(파티션 나누기)

fg(지정된 작업을 전면 프로세스로 시작하기)

file(파일 종류 보기)

find(파일 찾기)

finger(사용자 정보 알기)

fold(정형화하기)

fmt(정형화하기)

for(반복 실행하기)

free(메모리 사용량 알아보기)

fsck(파일 시스템 검사하기)

fstab(파일 시스템에 대한 고정적인 정보 저장하기)

ftp(파일 전송 프로그램)

fuser(프로세스 ID 출력)

getkeycodes(매핑 테이블 출력하기)

grep(특정 문자(열) 검색하기)

gzexe(실행 파일 압축하기)

gzip(압축하기)

halt(시스템 종료하기)

hash(기억해 두기; index 역할)

head(파일의 앞부분 출력하기)

help(도움말 보여주기)

host(호스트 정보 보기)

history(사용 명령어 목록보기)

hostname(서버 이름 알기)

id(계정 정보 알기)

if(조건문 실행하기)

ifconfig(랜카드에 주소 할당하기)

imolamod(모듈 설치하기)

inetd(인터넷 서비스의 최상위 데몬)

init(실행 단계 정하기)

ispell(철자법 검사하기)

jobs(수행중인 프로세스 알기)

kbd_mode(키보드 모드 출력하기)

kill(프로세스 죽이기)

klogd(커널 로그 데몬)

ldd(공유 라이브러리의 의존성 알기)

less(페이지 단위로 출력하기)

let(정규식 표현하기)

lilo(부팅하기)

ln(링크하기)

locate(패턴에 맞는 파일 찾기)

login(로그인하기)

logger(시스템 로그 기록하기)

logname(사용자 로그인명 보여주기)

logout(로그인 셸 종료하기)

look(특정 단어 검색하기)

losetup(중복 장치 확인하기)

lpd(프린트 데몬)

lpq(현재 프린트 작업 상태 출력하기)

lpr(출력하기)

lprm(대기열에 있는 문서 삭제하기)

ls(디렉토리 내용보기)

lsattr(파일 시스템의 속성 보여주기)

lsdev(하드웨어 장치 출력하기)

lsmod(모듈 정보 출력하기)

mail(메일 관련)

make(컴파일하기)

man(매뉴얼 보기)

mattrib

mbadblocks

mcd

mcopy

mdel

mdeltree

mdir

mesg(메시지를 받을 수 있는지 확인하기)

mformat

minfo

mkdir (디렉토리 만들기)

mke2fs(파일 시스템 생성하기)

mkfs(파일 시스템 만들기)

mknod(특수 파일 만들기)

mkswap(스왑 영역 지정하기)

mlabel

mmd

mmount

mmove

mpartition

mount(장치 연결하기)

more(화면 단위로 출력하기)

mrd

mren

mtoolstest

mtype

mutt(메일 관련)

mv(파일 옮기기)

mzip

netstat(현재 네트웍 상황 보기)

nice(프로세스 우선 순위 변경하기)

od(8진수로 파일 보기)

passwd(암호 입력하기)

pidof(실행중인 프로그램의 프로세스 ID 찾기)

pine(메일 관련)

ping(네트웍 확인하기)

popd(pushd 취소)

ps(프로세스 상태 알기)

pstree(프로세스 상관관계 알기)

pwd(절대경로 보여주기)

quota(디스크 한계량 알기)

rarp(rarp 테이블 관리하기)

rcp(원격 호스트에 파일 복사하기)

rdev(루트, 스왑장치, 램 크기, 비디오 모드를 조사하고 설정하기)

rdate(네트웍으로 시간 설정하기)

reboot(재부팅하기)

rmmod(모듈 지우기)

readonly(읽기 전용으로 표시하기)

renice(프로세스 우선 순위 바꾸기)

reset(터미널 초기화하기)

restore(다시 저장하기)

rlogin(바로 접속하기)

rm(파일 지우기)

rmdir (디렉토리 지우기)

route(라우팅 테이블 추가/삭제하기)

rpm(프로그램 추가/삭제)

rpm2cpio(rpm을 cpio로 변환하기)

rsh(원격으로 명령어 실행하기)

rup(호스트 상태 출력하기)

rusers(호스트에 로그인한 사용자 출력하기)

rwall(호스트 사용자에게 메시지 뿌리기)

script(기록하기)

set(변수값 설정하기)

setup(시스템 관련 설정하기)

showmount(호스트의 마운트 정보 보여주기)

shutdown(전원 끄기)

sleep(잠시 쉬기)

source(스크립트 번역하기)

split(파일 나누기)

ssh(암호화된 원격 로그인하기)

stty(터미널라인 설정 보여주기)

su(계정 바꾸기)

suspend(셸 중단하기)

swapoff (스왑 해제하기)

swapon(스왑 활성화하기)

sync(버퍼 재설정하기)

syslogd(로그인 과정 설정하기)

tac(거꾸로 보기)

tail(문서 끝부분 출력하기)

talk(이야기하기)

tar(파일 묶기)

tcpdchk(tcp wrapper 설정하기)

tcpmatch(네트웍 요청에 대해 예측하기)

tee(표준 입력으로부터 표준 출력 만들기)

telnet(원격접속하기)

test(테스트하기)

times(셸에서의 사용자와 시스템 시간 출력하기)

top(cpu 프로세스 상황 보여주기)

tr(문자열 바꿔주기)

true(종료 코드 리턴하기)

type(유형 보기)

ul(밑줄 처리해서 보여주기)

ulimit(제한하기)

umask(매스크 모드 설정하기)

umount(장치 해제하기)

unalias(별명 제거하기)

uname(시스템 정보 보기)

unexpand(공백 문자를 탭으로 변환하기)

uniq(중복된 문장 찾기)

useradd(사용자 계정 만들기)

userdel(계정 삭제하기)

usermod(사용자 계정정보 수정하기)

unset(설정 변수 해제)

uptime(시스템 부하 평균 보여주기)

users(로그인된 사용자 보여주기)

w(시스템에 접속한 사용자 상황 알아보기)

wait(프로세스 기다리기)

wall(모든 사용자에게 메시지 보내기)

wc(문자, 단어, 라인수 세기)

whatis(명령어의 간단한 설명보기)

while(루프 명령어)

who(사용자 알기)

write(콘솔 상에서 간단한 메시지 보내기)

xcopy(반복적으로 복사하기)

XFree86

ypchfn(NIS에서 사용하는 chfn 명령어)

ypchsh(NIS에서 사용하는 chsh 명령어)

yppasswd(NIS에서 사용하는 passwd 명령어)

zcat(압축 파일 보기)

zcmp(압축 파일 비교하기)

zforce(강제로 gz 만들기)

zgrep(압축 상태에서 grep 실행하기)

zmore(압축 상태에서 more 실행하기)

znew(.Z 파일을 .gz로 다시 압축하기)




0.0.0.30 각자가 사용하는 컴퓨터의 정보를 알고 싶을때

 [root ...]#more /proc/cpuinfo  위와 같이 치면 사용자의 컴퓨터 정보를 볼수 있으며,  [root ...]#more /proc/meminfo  라고 치면 사용자의 메모리 정보를 볼수 있습니다.


0.0.0.31 전체 메일

먼저 보낼 내용을 텍스트로 파일로 만들어야 합니다.어디에서든지 가능하지요!  [ root@aromi /root]# vi nea  안녕하세요! 저희 서버에서는 웹서버를 오늘부터 시작합니다. 사용자 여러분의 많은 관심과 이용을 부탁드립니다.

 

:wq

[ root@aromi /root]#

만약, 한글을 사용하지 못하면 윈도우95에서 먼저 쓴다음에 ftp를 이용해서 올리면 됩니다.

[ root@aromi /root]# mail -s "[공지]" `cat /etc/passwd|gawk ?F :'{print$1}'` 

 [공지]->  라고 쓴 것은 보낼 메일의 제목입니다.  'cat /etc/passwd|gawk -F : '{print$1}''  ->먼저 cat으로 passwd파일의 첫번째 나오는 내용을 출력하라는 소리입니다. nea라는 텍스트파일을 메일의 내용으로 보내라는 내용입니다.


0.0.0.32 디렉토리만 빠르게 검색

 ls -al | grep "^d" 


0.0.0.33 호스트 네임 바꾸기

/etc/HOSTNAME file은 부팅시 /etc/sysconfig/network file 의 HOSTNAME 부분을 참조하여 저장합니다. 호스트 네임을 바꾸고자 한다면 /etc/sysconfig/network file 의 HOSTNAME 부분을 바꿔주면 됩니다.

[ root@linux /root]# vi /etc/sysconfig/network 

NETWORKING=yes

HOSTNAME="linux"

GATEWAY=""

GATEWAYDEV=""

FORWARD_IPV4="yes"

바꾸신후 시스템을 재부팅 하신거나, #/etc/rc.d/init.d/network restart 명령을 내리시면 됩니다.


0.0.0.34 틀린명령어 틀린글자만 바꿔서 실행

 # ./configure --prefax=/usr/local/apache  앗, 틀렸습니다. prefax가 아니라 prefix인데... 고쳐야지요...간단하게 화살표키로 왔다갔다 하면서 지워지고 바꿔주면 되겠지만 다른 방법이 있습니다.  # ^fax^fix^  라고 하면...  -> ./configure --prefix=/usr/local/apache  라고 됩니다..


0.0.0.35 유닉스의 현재 버젼과 종류 그리고 라이센스등을 알려주는 명령어

 [ root@aromi /root]# uname -a 


0.0.0.36 열려있는 포트 알아내기

 netstat -anp | grep LISTEN 


0.0.0.37 텔넷 모든 접속자에게 메세지 보내기

wall 내용...  Ctrl-D 


0.0.0.38 lsof는 열려있는 파일을 나타내 주는 옵션

여기에 보안 점검을 위하여, -i 옵션을 사용하면, 현재 열려 있는 포트와 링크되어 있는 서비스 또는 프로그램이 모두 나타나죠. 자신이 열어 놓지 않은 포트가 열려있다던지하면 한번쯤 의심해 봐도 되겠죠?


0.0.0.39 사용자가 어디에서 무엇을 하는지 알아내기

w라는 명령어를 사용하시면 된답니다. 이 때,  w [-s]  를 붙여주시면 -s 옵션이 긴 정보 대신에 필요한 짧은 정보만 알려 준답니다.


0.0.0.40 텔넷 화면 수정

로그인화면:  /etc/issue.net  로그인후화면:  /etc/motd 


0.0.0.41 하위 디렉토리 한꺼번에 만들기

 mkdir -p music/koreanmusic/ost 


0.0.0.42 특정디렉토리의 모든 파일 안의 특정 문자열 치환

for i in $*; do 

sed "s/paper/PAPER/g" < $i > $i.new

mv -f $i.new $i

done



<chihwan.sh>



find ./(chihwan.sh를 포함하지 않는 디렉토리면) -type f -exec chihwan.sh {} \;




0.0.0.43 killall 명령 시뮬레이션 (프로세스명으로 죽이기)

ps aux | grep 프로세스명 | grep -v grep | awk '{ print $w }' | xargs kill -9 



  • 모든 프로세스 나열

  • 지정한 프로세스만 뽑아냄

  • grep 명령이 포함된 라인 제거

  • awk로 두번째 필드만 뽑아냄

  • xargs에 의해 걸러진 아이디로 죽임




0.0.0.44 find와 grep

find . -name "H20021115.*" -exec grep -l '...;........;110100' {} \;


0.0.0.45 vi 검색, 치환

구호스트 서비스 오늘 날짜에서 분류코드가 110100인 파일 찾기 :%s/./\U&/g
모든문자->대문자 g/^$/d


0.0.0.46 파일내의 중복되는 행을 제거 : uniq

입력 파일에서 연속되는 행을 비교하여, 두 번째 이상의 동일한 행들을 제거하고 나머지는 출력파일로 출력 연속되어 표시되지 않으면 동일한 행이 존재할 수 있음.
sort 명령을 사용하여 정렬한 후 사용하는 것이 타당 사용법uniq [-cdu] [+|숫자] [입력파일 [출력파일]] -c : 각 행이 연속적으로 나타난 횟수를 행의 시작부분에 표시 -d : 연속적으로 반복되는 행만 출력 -u : 연속적으로 반복되지 않는 행만 출력 +숫자 : 행의 처음 '숫자' 만큼의 문자는 무시 -숫자 : 행의 처음 '숫자' 만큼의 필드는 무시


0.0.0.47 파일의 결합

여러 개의 텍스트 파일을 하나의 파일로 순차적으로 묶는데 사용

cat [파일명1] [파일명2] ... > [출력파일명] 

cat [파일명1] [파일명2] ... >& [출력파일명]

cat [파일명1] [파일명2] ... >> [출력파일명]

cat [파일명1] [파일명2] ... >>& [출력파일명]

cat - [파일명1], [파일명2] .. >> [출력파일명]

cat - [파일명1], [파일명2] .. >>& [출력파일명]





% cat > file1

파일명 : file1

^D

% cat > file2

파일명 : file2

^D

% cat file1 file2 > file3

% cat file3

파일명 : file1

파일명 : file2

%


행단위 결합 : paste 여러 파일에 대해여 행간 결합을 수행하거나 하나의 파일에 대해 연속되는 행들을 결합 둘이상의 파일에 대해서 테이블상의 하나의 열과 같이 취급하여 동일한 행번호 끼리 결합

 

paste [파일명1] [파일명2]..

paste -d리스트 [파일명1] [파일명2] ...

paste -s [-d리스트] [파일명]

d : 행간 결합시 행간 구분문자들의 리스트

s : 한파일의 연속되는 행을 결합



% cat > paste.data1

홍길동

이순신

김유신

% cat > paste.data2

부산

서울

대구

% paste paste.data1 paste.data2

홍길동 부산

이순신 서울

김유신 대구

% paste -d"\n" paste.data1 paste.data2

홍길동

부산

이순신

서울

김유신

대구

% paste -s -d"::\n" paste.data1

홍길동:이순신:김유신

%


두 파일을 동일한 필드 값에 따라 행 단위 결합 : join
관계형 데이터 베이스에서의 join 연산과 동일 키로 사용할 필드에 대해 정렬된 두 파일의 각 행에 대해 동일한 키 값을 갖는 행들을 결합 입력으로 사용될 두 파일은 키 값에 대해 오름 차순으로 정렬되어 있어야 함 출력 결과는 기본적으로 키 값이 먼저 표시되고, 첫번째 파일에서 키를 제외한 나머지 필드, 두번테 파일에서 키를 제외한 나머지 필드가 표시 필드 구분은 공백, 탭, 개행문자가 기본, 연속적으로 나타날 경우 하나로 취급

% cat > join.data1 

98001:서원일:

98002:홍길동:

98003:김유신:

98004:이순신:

98010:이상관:

% cat > join.data2

부산:98001:441

울산:98002:89

대구:98003:99

서울:98004:120

김해:98010:44

% join -j1 1 -j2 2 -t: join.data1 join.data2

98001:서원일::부산:441

98002:홍길동::울산:89

98003:김유신::대구:99

98004:이순신::서울:120

98010:이상관::김해:44

% join -j1 1 -j2 2 -o 1.2 1.1 2.1 -t: join.data1 join.data2

서원일:98001:부산

홍길동:98002:울산

김유신:98003:대구

이순신:98004:서울

이상관:98010:김해

%




0.0.0.48 파일의 암호화 : crypt

파일을 암호화 하여 키를 알지 못하는 사람은 내용을 볼 수 없도록 함 표준 입출력 사용

% cat > crypt.data 

test test

안녕하십니까?

^D

% crypt <crypt.data > crypt.data1

Enter key: hello

% ls -l crypt*

-rw-r--r-- 1 wiseo pro 24 9월 24일 14:47 crypt.data

-rw-r--r-- 1 wiseo pro 24 9월 24일 14:48 crypt.data1

% crypt < crypt.data1

Enter key:hello

test test

안녕하십니까?

%




0.0.0.49 개행을 제외한 화면내의 보이지 않는 문자 출력

cat -v http://comp-cse.sch.ac.kr/~pl/lecture/linux/file2.html


0.0.0.50 화일내의 포함된 특정문자열로 찾아서 내용만 출력하기

grep -h '20030305......01' ./R00*


0.0.0.51 특정 파일의 화일명을 비슷하게 여러개 한꺼번에 바꾸기

ls *.* | awk '{print "mv",$1, $1 }' | sed "s/ \([a-zA-Z0-9]*\)\.\([a-zA-Z0-9]*\)$/ \1\.\_\2/g" 





  • 현재디렉토리의 모든 *.* 파일을 *._* 형식으로 바꾼다.

  • 더 간단하게 ls *.* | sed "s/\([a-zA-Z0-9]*\)\.\([a-zA-Z0-9]*\)/mv \1\.\2 \1\.\_\2/g"










0.0.0.52 어제 날짜 구하기

$ date -v-1d "+%Y-%m-%d"  [컴퓨터분류]


0.0.0.53 원하지 않는 사용자 죽이기

[root@dream /root]# skill -KILL sunny 
위의 명령을 내리면 sunny 라는 사용자를 완전히 추방시킬수 있습니다. 그런데 이렇게 완전히 추방시키는게 아니구, 특정 터미널에 접속해있는 사용자만 추방시켜야 할 때도 있겠죠? 그럴때는 [root@dream /root]# skill -KILL -v pts/14 
이런식으로 하면 된다 그럼 pts/14 에 연결되어 있는 사용자가 죽게 됩니다.

0.0.0.54 UNIX상에서 한글출력이 깨져 나올경우

유닉스상에서 한글을 stdout출력할 경우 가끔 출력되는 문자들이 몽땅 깨져서 나오는 경우가 있다.. 이때부터는 프로그램이 종료된 이후에도 쉘 프람프트를 비롯, 쉘에서 입력하는 모든 커맨드가 깨져서 나온다. 이는 ascii code 로 ^n 에 해당하는 문자가 출력될 때 나오는 현상으로 그 이후로는 MSB가 모두 켜지기 때문이다. 문자가 깨져나오는 이후부터 ascii code 로 ^o 에 해당하는 문자를 출력하면 반대로 된다. 쉘 커맨드 상에서라면, # echo ^v^o 
라고 해야겠지만 커맨드가 깨져나오므로 shell이 해석을 못한다. 따라서, command line에서 ^v^o를 치고 enter 하면 된다..


0.0.0.55 현재 디렉토리의 대량의 파일을 각자의 파일명가운데에 특정문자 추가하여 바꾸기

/bin/ls A?????.html | sed 's/A\(.....\)\.html/\1/g' | xargs -t -i mv 'A{}.html' 'A0{}.html' 

/bin/ls는 ls가 보통 -F로 파일 종류 표시(*, @등)까지 하기 때문에 그걸 막기 위한 것이고 xargs의 -t는 트레이스모드이다. 


2009. 6. 25. 00:51

[MySQL] Replication 환경 싱크 깨지는것 회피하기





MySQL의 리플리케이션 환경을 운영하다 보면 유난히도 싱크가 어긋나는 일이 많이 일어나는 것을 알 수 있습니다.

확실히 MySQL은 아직 엔터프라이즈 환경에서의 도입에 무리가 있는 제품이 아닐까 생각이 드는군요.

하지만 리플리케이션 기능이 추가된지 얼마 되지 않았고 저장프로시저도 생겼고 나날이 발전하는 모습을 보면 더더욱 좋아질것이라고 기대해 봅니다.

그러면 이미 MySQL을 이용한 리플리케이션 상황을 운영중이고 또 관련 오류가 많이 나는 상황이라면 어떻게 해야 할까요?

다음의 방법을 시도해볼만합니다.

MySQL의 경우 리플리케이션 환경 중 에러가 나면 그 Slave 서버는 리플리케이션이 중단됩니다.

갑자기 좀비 서버가 되어 버리는 것이죠. 에러를 확인해 봅시다.

[root@SLAVE ~]# mysql
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2060
Server version: 5.0.51

Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

mysql> show slave status\G
*************************** 1. row ***************************
             Slave_IO_State: Waiting for master to send event
                Master_Host: MASTER
                Master_User: replicator
                Master_Port: 3306
              Connect_Retry: 60
            Master_Log_File: mysql-bin.000005
        Read_Master_Log_Pos: 96305365
             Relay_Log_File: slave-relay-bin.000006
              Relay_Log_Pos: 73184178
      Relay_Master_Log_File: mysql-bin.000005
           Slave_IO_Running: Yes
          Slave_SQL_Running: No
            Replicate_Do_DB: THEEYE
        Replicate_Ignore_DB: 
         Replicate_Do_Table: 
     Replicate_Ignore_Table: 
    Replicate_Wild_Do_Table: 
Replicate_Wild_Ignore_Table: 
                 Last_Errno: 1062
                 Last_Error: Error 'Duplicate entry '116069-10002826' for key 1' on query. Default database: 'THEEYE'. Query: 'INSERT INTO    THEEYE_INFO_LOG    ( IDX, NAME, REG_DATE    )    VALUES ( 3, "GOOD", NOW() )'
               Skip_Counter: 0
        Exec_Master_Log_Pos: 73184876
            Relay_Log_Space: 96304951
            Until_Condition: None
             Until_Log_File: 
              Until_Log_Pos: 0
         Master_SSL_Allowed: No
         Master_SSL_CA_File: 
         Master_SSL_CA_Path: 
            Master_SSL_Cert: 
          Master_SSL_Cipher: 
             Master_SSL_Key: 
      Seconds_Behind_Master: NULL
1 row in set (0.00 sec)

mysql> exit



show slave status\G 명령으로 현재 슬레이브의 상태를 확인할 수 있습니다.

상태를 보니 Last_Errno 가 1062이고 Last_Error에는 어떤 에러인지 표시가 됩니다.

근데 에러를 확인해 보니 같은 똑같은 Entry가 존재한다는군요. 위의 디비 설계상 같은 키값을 가진 값이 두개가 들어갈 필요가 없다는것을 알았습니다.

그런데 저런 사소한 문제로 리플리케이션이 중단된다는것도 억울한 일이죠. 위와 같은 사소한 에러는 무시하도록 해보겠습니다.

--slave-skip-errors 라는 옵션이 있는데요. 에러코드값을 지정해 주거나 all로 모든 에러를 무시할 수 있습니다.
--slave-skip-errors=[err_code1,err_code2,...|all]


서버측 에러 코드는 [ 이곳 ] 에서 확인 하실 수 있습니다.

1062번 에러의 경우 사소한 문제이기 때문에 서버 설정에 추가해 보도록 하겠습니다.

저같은 경우에는 /etc/my.cnf 파일에 다음의 내용을 추가하였습니다.
[mysqld]
...
slave-skip-errors = 1062


앞으로는 위의 코드에 해당하는 에러가 발생할 경우 에러를 건너뛰고 Master의 Log Position에 강제적으로 맞춰질 것입니다.
2009. 6. 19. 11:13

XSS(Cross Site Scripting: 크로스 사이트 스크립팅) == CSS





IE 8 ㅡㅡ;; "교차"라는 말도 맞긴 하지만, 은근히  애매한듯...

 

자, 이제 크로스사이트 스크립팅(XSS)에 관하여 정리해보자.

 

날도 뻐근하고, 봄이면.. 잠만 퍼질러 자는 체질이라.. 너무 놀았네..

 

XSS사이트 스크립트의 일반적인 공식에 대해서 알아보겠다..

 

웹 사이트를 들어가보게 되면, 기본적인 게시판, 메일등 사용자가 직접 올릴수 있는 부분이 한개씩은 있기 마련이다.

위의 그림이 XSS의 기본적인 그림을 그린것이다.

 

1. 공격자는 서버에게 타겟(불특정 다수)이 읽을수 있도록, 내용과 악성 스크립트를 포함시킨 코드를 올리게 된다.

 

2. 타겟은 글을 읽음으로서, 공격자에게 자신이 의도치 않은 쿠키값을 전송하게 된다.

 

3. 쿠키 정보를 수집한 공격자는 타겟의 계정과 동일하게 모든 권한을 가지게 된다.

 

[ 쿠키(Cookie) ]

 

 

- 사용자가 어떠한 웹서버의 접속을 요청하게 되면, 로컬 시스템은 쿠키값을 참조하여 접속하게 된다.

   

   기존의 사이트 쿠키값이 없을 경우, 웹 서버에 접속하게 되면 자신의 시스템에 4kbyte이하의 쿠키값이 생성한다.

  

   쿠키값은 사용자의 브라우저의 정보를 쿠키값에 지정하게 되며, Windows_Server에서의 경로를 표시하였다.

 

각각의 포함된 쿠키값은 Web_Server별로 정리되어져 있으며, 사용자 ID와 접속 서버로 이루어져 있다.

 

일반적으로 확인하게 되면, Domain Name Server / 구분 ID(숫자) / 쿠키만기일 등의 구조로 이루어질 것이다.

 

그렇다면?? 왜 쿠키값이 위험한 것일까??

 

쿠키는 일반적으로 위의 정보를 제외한, 접속자의 개인 정보까지 포함되어 있어 취약점으로 발전해온 것이다.

 

내가 만약 네이버에 접속하였을 경우, 그에 대한 ID와 PW는 쿠키값이 포함되어져 있다.

 

네이버에 처음 접속하였다고 하자. 그렇다면 네이버 서버에 접속하게 되면, 4kbyte이하의 쿠키값이 접속 호스트에 저장이 될것이며,

 

그에 대한 쿠키값은 다음 접속시 접속할 서버는 쿠키값을 가지고, 파악하게 된다.

 

쿠키값은 접속 종료시 즉각, 정보가 사라지는 것이 아니다.

 

간혹가다 사이트 계정으로 접속하여, 브라우저를 끄고, 다시 접속해보면 기존의 ID계정으로 접속해있는 것을 보았을 것이다.

 

[ 쿠키(Cookie)의 중요성 ]

 

1. 사용자의 계정 정보

 

2. 자주 방문하는 서버의 정보

 

3. 장바구니 시스템(물건 구매시 쿠키값에 남는 현상)

    위와 같은 것들이 일반적인 쿠키의 적용 방식이다.

 

[ XSS 공격 특성 ]

- 기본적인 설명은 위에서 하였으므로, XSS에 대해서 더욱더 들어가보자.

 

[ 공격 순서 ]

1. 게시판과 같은 응용 프로그램에 스크립트 작성 언어를 올려놓게 된다.(불특정 다수)

 


2. 파일 열람시 타겟은 자신도 모르게 쿠키값을 가로 채이게 된다.

 

3. 일반적으로, 공격자는 파로스와 같은 툴로서 쿠키값을 확인하게 된다.



 

4. 쿠키값을 이용하여, 계정 도용이 가능하다

 

[ 방어 대책 ]

1. 쿠키 값에 중요한 정보는 응용 프로그램 관리자가 포함되지 않도록 설정.

 

2. 사용자의 입력 값에대한 필터링

    <script></script> / <javascript> / document.cookie

 

3. HTML 태그의 미활성화(동적 웹 특성에 대한 HTML활성화.)

 

4. 스크립트 언어(ASP,PHP,JAVA등)의 문구를 다른 코드로 대체, 혹은 필터링

 

5. 가장 중요한 것은 관리자의 지속적인 점검

2009. 6. 11. 14:55

mysql show status




mysql 에 접속후  mysql> show status; 로도 볼수 있습니다.

 

설명:
Aborted_clients : 클라이언트가 연결을 적절히 닫지않아서 죽었기때문에 끊어진 연결수.
Aborted_connects : 연결실패된 mysql서버에 연결시도 수.
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 :  한테이블에 한 row를 insert요청하는 수
Key_blocks_used :  key 캐시에서 블럭을 사용하는 수
Key_read_requests : 캐시에서 키블럭을 읽기를 요청하는 수
Key_reads : 디스크로부터 키블럭을 물리적으로 읽는 수
Key_write_requests : 캐시에서 키블럭을 쓰기위해 요청하는 수
Key_writes :  디스크에 키블럭을 물리적으로 쓰는 수
Max_used_connections : 동시사용 연결 최대수
Not_flushed_key_blocks : 키캐시에서 키블럭이 바뀌지만 디스크에는 아직 flush되지 않는다.
Not_flushed_delayed_rows :  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 : 서버가 스타트된 후로 지금까지의 시간

2009. 6. 4. 15:01

HTTP 에러코드와 상태 코드 정리





상태코드 메세지 설명
100 Continue
클라이언트로부터 일부 요청을 받았으니 나머지 요청 정보를 계속 보내 주시오.
101 Switching Protocols
서버는 클라이언트의 요청대로 Upgrade 헤더를 따라 다른 프로토콜로 바꿀 것임.
200 Ok
모든 것이 정상적임. GET이나 POST 요청 뒤에 문서가 온다. 이것은 서블릿의 기본 상태다. setStatus를 사용하지 않으면 이 상태코드를 얻게 된다.
201 Created
서버에서 문서를 만들었음. Location 헤더는 그 URL을 가리킨다.
202 Accepted
요청이 수행되었지만 처리는 끝나지 않았음.
203 Non-Authoritative Information
문서는 정상적으로 반환되었지만 복사본이 사용되었으므로 응답 헤더중 일부가 정확하지 않을 수 도 있음.
204 No Content
새 문서 없음. 브라우저는 이전 문서를 계속 보여줘야 한다. 이것은 사용자가 페이지를 주기적으로 리로드를 하던 중 이전 페이지가 이미 만료되었을 때 사용할 수 있다. 하지만 Refresh 응답 헤더나 같은 헤더를 사용 해서 페이지를 자동으로 리로드 시켰을 때는 동작하지 않는다. 왜냐하면 이 상태 코드를 반환하면 추후의 리로딩이 멈추기 때문이다. 하지 만 자바 스크립트로 리로드하게 해 주는 것은 작동한다.
205 Reset Content
새 문서 없음. 하지만 브라우저는 문서 창을 리셋해야 한다. 브라우저가 CGI 폼 필드를 전부 지우도록 할 때 사용 된다.
206 Partial Content
클라이언트가 Range 헤더와 함께 요청의 일부분을 보냈고 서버는 이를 수행했음.
300 Multiple Choices
요청된 문서가 여러 군데서 발견되었음. 이 때 서버는 해당하는 모든 문서들을 나열할 것이다. 만약 서버가 선호하는 선택이 있으면 Location 응답 헤더에 나열해야 한다.
301 Moved Permanently
요청된 문서는 어딘가에 있고 그 문서에 대한 URL은 Location 응답 헤더에 주어졌음. 브라우저는 자동적으로 새 URL의 링크를 따라가야 한다.
302 Found
301과 비슷하지만 새 URL은 임시 저장 장소로 해석된다. 이 메시지는 HTTP 1.0에서는 ‘Moved Temporarily'였다. 그리고 HttpServletResponse의 상수는 SC_FOUND가 아니라 SC_MOVED_TEMPORARILY다. 이것은 매우 유용한 헤더인데 이 헤더를 통해 브라우저가 자동적으로 새 URL의 링크를 따라가기 때문이다. 이 상태 코드는 아주 유용하기 때문에 이 상태 코드를 위해 sendRedirect 라는 특별한 메소드가 있다. response.sendRedirect(url)을 사용하는 것은 response.setStatus(response.SC_MOVED_TEMPORARILY)과 response.setHeader("Location", url)를 쓰는 것에 비해 몇 가지 장점이 있다. 첫째, 더 쉽게 사용할 수 있다. 둘째, sendRedirect을 써서 서블릿이 그 링크를 포함한 페이지를 자동으로 만들어 준다(자동으로 redirect를 따라갈 수 없는 오래 된 브라우저에서도 볼 수 있게 해 준다). 마지막으로, sendRedirect에서는 상대 URL이 절대 URL로 해석되기 때문에 상대 URL도 다룰 수 있다. 이 상태 코드는 종종 301번과 혼용된다. 예를 들어 (맨 마지막에 ‘/'이 빠짐)과 같이 오류가 있는 요청에 대해 어떤 서버는 301을 어떤 서버는 302 를 보낸다. 기술적으로 브라우저는 원 요청이 GET이었다면 자동적으로 리다이렉션을 따라 가도록 되어 있다. 더 자세한 사항은 307 헤더를 보세요.
303 See Other
301/302과 같지만 원래 요청이 POST였을 경우 리다이렉트 되는 문서(Location 헤더에 주어졌다) GET을 통해 받아야 한다.
304 Not Modified
클라이언트의 캐시에 이 문서가 저장되었고 선택적인 요청에 의해 수행됨(보통 지정된 날짜보다 더 나중의 문서만을 보여주도록 하는 If-Modified-Since 헤더의 경우). 서버는 클라이언트에게 캐시에 저장된 이전 문서를 계속 사용해야 한다고 말할 것이다.
305 Use Proxy
요청된 문서는 Location 헤더에 나열된 프록시를 통해 추출되어야 함.
307 Temporary Redirect
Temporary Redirect 이것은 302 ("Found" 또는 "Temporarily Moved")와 같다. 많은 브라우저에서 메시지가POST일 때 원래는 303 응답의 POST 요청의 리다이렉션을 따라 가야 함에도 불구하고 302의 응답을 따르기 때문에 HTTP 1.1에서 추가되었다. 303 응답은 모호하지 않도록 의도되었다. 303 응답의 경우에 대해서는 리다이렉트 된 GET과 POST 요청을 따르고 307 응답의 경우에는 GET 요청만 따른다. 몇 가지 이유로 HttpServletResponse에는 이 상태코드에 해당하는 상수가 없다.
400 Bad Request
요청에 문법적으로 잘못된 부분이 있음.
401 Bad Request
클라이언트가 올바른 허가를 받지 않고 허가가 필요한 페이지에 접근하려 함. 여기에 대한 응답으로 브라우저가 대화창을 열어 사용자 이름과 암호를 받아들이도록 하는 WWW-Authenticate 헤더를 포함해야 한다.
403 Forbidden
사용 권한에 관계없이 내용을 볼 수 없음. 종종 파일 이름이 잘못되었거나 서버의 디렉터리 퍼미션이 잘못 되었을 때 나온다.
404 Not Found
이 주소에서는 어떤 내용도 발견할 수 없음. 이것은 표준 ‘no such page'응답이다. 이 상태 코드는 아주 일반적인 응답이다. 그래서 이 상태코드를 위한 HttpServletResponse:sendError(message)라는 특별한 메소드가 있다. sendError는 serStatus에 비해 에러 메시지를 보여주는 에러 페이지를 자동적으로 만들어 준다는 장점이 있다.
405 Method Not Allowed
요청 메소드(GET, POST, HEAD, DELETE, PUT, TRACE 등) 를 특정 자원에 대해서는 쓸 수 없음.
406 Not Acceptable
지정된 자원이 클라이언트의 Accept 헤더에 명시된 것과 호환 되지 않는 MIME content-type을 생성함.
407 Proxy Authentication Required
401과 비슷하지만 서버가 Proxy-Authenticate 헤더를 반환해야 한다.
408 Request Timeout
클라이언트가 요청을 보내는 데 너무 오랜 시간이 걸림.
409 Conflict
보통 PUT 요청과 관계 있다. 보통 틀린 버전의 파일을 업로드할 경우 발생한다.
410 Gone
문서가 사라졌고 포워딩할 주소도 없음. 404와 다른 점은 이 경우 문서가 완전히 사라졌다는 것을 서버가 안다는 점이다. 404는 어떤 이유인지는 모르는데 단지 요청한 것을 사용할 수 없다는 것을 의미한다.
411 Length Required
클라이언트가 Content-Length를 보내지 않으면 서버가 처리할 수 없음.
412 Precondition Failed
요청 헤더에 설정되어 있는 어떤 조건이 맞지 않음.
413 Request Entity Too Large
요청된 문서가 현재 서버가 다룰 수 있는 크기보다 큼. 만약 서버에서 나중에 다룰 수 있다고 생각되면 Retry-After 헤더를 포함시켜야 한다. (HTTP 1.1에서 새로 등장)
414 Request URI Too Long
URI가 너무 길다.
415 Unsupported Media Type
요청이 알려지지 않은 형태임
416 Requested Range Not Satisfiable
클라이언트가 요청에 적당하지 않은 Range 헤더를 포함시켰음
417 Expectation Failed
Expect 요청 헤더의 값이 맞지 않음.
500 Internal Server Error
일반적인 ‘server is confused' 메시지. 종종 CGI 프로그램이나 서블릿의 결과가 잘못되거나 적절하지 않은 헤더를 만들었을 때 발생한다.
501 Not Implemented
요청한 것을 서버에서 지원하지 않음. 예를 들면 클라이언트가 서버에서 지원하지 않는 PUT과 같은 명령을 내렸을 때 발생한다.
502 Bad Gateway
프록시나 게이트웨이의 역할을 하는 서버에서 볼 수 있다. 초기 서버가 원격 서버로부터 부적절한 응답을 받았음을 나타낸다.
503 Service Unavailable
처리할 수 있는 한계를 벗어나 과도하게 요청이 들어와서 서버가 응답할 수 없음. 예를 들면 스레드나 데이터베이스 연결이 가득 차 있을 때 서블릿에서 이런 헤더를 반환한다. 서버는 Retry-After 헤더를 낼 수 있다.
504 Gateway Timeout
프록시나 게이트웨이의 역할을 하는 서버에서 볼 수 있다. 초기 서버가 원격 서버로부터 응답을 받을 수 없음을 나타낸다.
505 HTTP Version Not Supported
서버가 요청 라인에 지정된 HTTP 버전을 지원하지 않음.


 자세한건 RFC2616 문서를 보세요.

(Request For Comments :

http://www.rfc-editor.org/cgi-bin/rfcdoctype.pl?loc=RFC&letsgo=2616&type=ftp&file_format=txt

http://www.w3.org/Protocols/rfc2616/rfc2616.html )

 

1xx : 안내코드

100 : CONTINUE

101 : SWITCHING_PROTOCOLS , 규약을 전환

102 : PROCESSING

 

2xx : SUCCESS에 관한 코드

200 : OK , 성공적으로 요구를 전달하였음.

201 : CREATED , 요구가 충족되어 새로운 자원을 생성하였음

202 : ACCEPTED , 요구가 접수되었으며 아직 처리가 완료되지는 않았음. (단순한 접수여부이며 처리의 성공여부는 아님)

203 : NON_AUTHORITATIVE Information , 인증되지 않은 정보 (서버에서 사용하도록 정의되지 않는 정보세트를 말함)

204 : NO_CONTENT , 클라언트 요구을 처리했으나 전송할 데이터가 없음

       (기존내용의 변화없는 추가적인 정보입력을 실행할 경우에 해당함)

205 : RESET_CONTENT , 내용을 reset

206 : PARTIAL_CONTENT , 부분적으로 요구를 완료하였음.

207 : MULTI_STATUS

 

3xx : REDIRECT에 관한 코드 (처리를 위해 추가적인 동작이 필요함)

300 : MULTIPLE_CHOICES , 복수 선택

301 : MOVED_PERMANENTLY , 요청한 자원이 영구한 URI가 할당되어 이동함.

302 : MOVED_TEMPORARILY , 요청한 자원이 별도의 임시 URI에 할당되어 이동함.

303 : SEE_OTHER , 다시 다른것을 참조함.

304 : NOT_MODIFIED , 별다른 변경이 없이 응답되었음

305 : USE_PROXY , 요청된 자원은 프락시를 통해야만 접근이 됨

306 : TEMPORARY_REDIRECT

 

4xx : CLIENT_ERROR에 관한 코드 (요구 메시지가 처리할 수 없을 때)

400 : BAD_REQUEST , 클라이언트의 요청을 서버가 이해하지 못함.

401 : UNAUTHORIZED , 요청에 대한 응답이 사용자인증을 필요로 할 경우.

402 : PAYMENT_REQUIRED  , 예약되어 있음

403 : FORBIDDEN , 금지됨 (요청은 이해하였으나 금지되어있는 요청임)

404 : NOT_FOUND , Request-URI를 찾을 수 없음

405 : METHOD_NOT_ALLOWED , URI에서 사용되지 않는 method를 요청함.

406 : NOT_ACCEPTABLE , 접수할수없음을 나타냄.

407 : PROXY_AUTHENTICATION_REQUIRED , 프락시에서 먼저 인증을 해야함.

408 : REQUEST_TIME_OUT , 요청한 시간내에 응답을 하지 못함.

409 : CONFLICT , 충돌 (어떠한 부분의 충돌로 응답하지 못함)

410 : GONE , 영구적으로 사용할 수 없는 경우에 해당하며 그렇지 않으면 401로 응답함.

411 : LENGTH_REQUIRED , 유효하지 못한 Content-Length로 요청을 하였음.

412 : PRECONDITION_FAILED , 전체조건 실패 ( 하나이상의 Request-Header에 기재된 내용이 실패됨)

413 : REQUEST_ENTITY_TOO_LARGE , 요구 entity가 너무커서 처리가 거부됨.

414 : REQUEST_URI_TOO_LARGE ,URI길이가 허용보다 커서 처리가 거부됨.

415 : UNSUPPORTED_MEDIA_TYPE ,  지원되지 않는 포맷으로 거부됨.

416 : RANGE_NOT_SATISFIABLE

417 : EXPECTATION_FAILED

422 : UNPROCESSABLE_ENTITY

423 : LOCKED

424 : FAILED_DEPENDENCY

 

5xx : SERVER_ERROR에 관한 코드 (서버가 요청을 처리하는 과정에서 문제발생)

500 : INTERNAL_SERVER_ERROR , 내부서버 오류 (잘못된 스크립트 실행과 같은 예상하지 못한 오류일 경우)

501 : NOT_IMPLEMENTED , 구현되지 않았음 (요청을 처리하는데 필요한 기능이 구현되지 않았음)

502 : BAD_GATEWAY , 나쁜 게이트웨이 (게이트웨이 서버가 올바르지 않은 응답을 수신 할 경우)

503 : SERVICE_UNAVAILABLE , 과부하 또는 여러가지 이유로 현재 요청을 처리하지 못함.

       (임시적이며 일정한 시간뒤에 정상적으로 서비스 가능)

504 : GATEWAY_TIME_OUT , 게이트웨이(또는 프락시)서버가 시간내에 요청의 처리를 완료하는 수신을 받지 못함.

505 : VERSION_NOT_SUPPORTED , 지원되지 않는 HTTP 버젼임.

506 : VARIANT_ALSO_VARIES

507 : INSUFFICIENT_STORAGE

510 : NOT_EXTENDED

 

601 : 접근불가. HTTP CONNECT TIMEOUT

ㅇ 3초내에 CP로 HTTP Connection을 하지 못한 경우

   () Network 이상, CP 과부하로 인해 CP Web서버로 connection 안될 )

2009. 6. 2. 09:14

JBoss DataSource 설정





JBoss에서 DataSource 설정 절차

(1) JDBC 라이브러리 설치

     해당 DB 벤더의 JDBC 라이브러리를 $JBOSS_HOME/server/<instance>/lib 디렉터리에 복사한다.

     절대로 어플리케이션과 함께 패키징해서는 안된다. 예를 들어 ojdbc14.jar를 WEB-INF/lib에 두면 다양한 에러를 경험할 수 있다.

 

(2) xxx-ds.xml 작성 및 디플로이

     JBoss에서 데이터소스 설정은 파일명이 -ds.xml로 끝나는 XML 파일을 작성해 deploy 디렉터리에 두면 된다. $JBOSS_HOME/docs/examples/jca 디렉터리를 보면 벤더별 데이터소스 설정 예제들을 볼 수 있다.

 

이제 예제를 통해 설정항목들을 살펴본다.

 $JBOSS_HOME/server/default/deploy/example-ds.xml

 <?xml version="1.0" encoding="UTF-8"?>
<datasources>
  <local-tx-datasource>
    <jndi-name>jdbc/OracleDS</jndi-name>
    <connection-url>jdbc:oracle:thin:@203.231.14.100:1521:XE</connection-url>
    <driver-class>oracle.jdbc.OracleDriver</driver-class>
    <user-name>scott</user-name>
    <password>tiger</password>
    <transaction-isolation>TRANSACTION_READ_COMMITTED</transaction-isolation>


    <min-pool-size>0</min-pool-size>
    <max-pool-size>20</max-pool-size>


    <blocking-timeout-millis>5000</blocking-timeout-millis>
    <idle-timeout-minutes>15</idle-timeout-minutes>


    <prepared-statement-cache-size>100</prepared-statement-cache-size>
    <track-statements>false</track-statements>


    <valid-connection-checker-class-name>
        org.jboss.resource.adapter.jdbc.vendor.OracleValidConnectionChecker
    </valid-connection-checker-class-name>
    <exception-sorter-class-name>
        org.jboss.resource.adapter.jdbc.vendor.OracleExceptionSorter
    </exception-sorter-class-name>


    <metadata>
         <type-mapping>Oracle9i</type-mapping>
    </metadata>
  </local-tx-datasource>
</datasources>

 

먼저 root element가 <datasources>로 복수형인게 눈에 띄는데 글자 그대로 하나의 -ds.xml 파일 하나에 여러 개의 데이터소스를 설정할 수 있다.

 

그 하위에 <local-tx-datasource>가 선언되어 있는데 JBoss에서는 트랜잭션 유형에 따라 <local-tx-datasource>, <xa-datasource>, <no-tx-datasource>로 element 레벨에서 구분해서 데이터소스를 설정한다. 분산 트랜잭션 처리를 위해 XA를 사용한다면 <xa-datasource>를, 그렇지 않다면 <local-tx-datasource>를 사용하면 된다.

 

그러면 <local-tx-datasource>로 선언할 때의 기본 설정 항목부터 살펴본다.

 

기본 설정 항목

1) <driver-class>

 위의 example-ds.xml에서와 같이 <local-tx-datasource>를 사용할 경우에는 java.sql.Driver 인터페이스를 구현한 드라이버 클래스를 <driver-class>에 설정한다.

Oracle 8i

oracle.jdbc.driver.OracleDriver

Oracle 9i/10g

oracle.jdbc.OracleDriver

Informix

com.informix.jdbc.IfxDriver

MS SQL

com.microsoft.jdbc.sqlserver.SQLServerDriver

MySQL

com.mysql.jdbc.Driver

 

2) <connection-url>

 DB접속 URL을 명시한다.

Oracle thin

jdbc:oracle:thin:@host:port:sid

Oracle thin (description)

jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=host)(PORT=port))(CONNECT_DATA=(SERVICE_NAME=sid)))

Oracle oci

jdbc:oracle:oci:@sid

Informix

jdbc:informix-sqli://host:port/dbname:INFORMIXSERVER=servername

MS SQL

jdbc:microsoft:sqlserver://host:port;DatabaseName=dbname

MySQL

jdbc:mysql://host:port/dbname

 

3) <jndi-name>과 <use-java-context>

 JNDI에서 데이터소스를 찾을 때 사용할 이름으로 jdbc/xxx 형식을 사용하는 것을 권장한다.

주의할 점은 데이터소스는 JNDI에 바인딩될 때 java: 네임스페이스로 바인딩된다는 점이다. 이때문에 Context.lookup()시에 java:/jdbc/xxx와 같이 명시해야 데이터소스를 찾을 수 있다.

만약 WebLogic에서 처럼 global하게 바인딩하려면 <use-java-context>false</use-java-context>로 설정하면 된다. 이 때는 Context.lookup()시에 jdbc/xxx로 명시한다.

 

4) <user-name>과 <password>

 DB 접속 계정과 패스워드를 명시한다. 패스워드를 따로 암호화할 필요가 있다면 이전 포스트를 참고한다.

 

5) <transaction-isolation>

트랜잭션 격리 레벨을 설정한다. TRANSACTION_NONE, TRANSACTION_READ_UNCOMMITTED, TRANSACTION_READ_COMMITTED, TRANSACTION_REPEATABLE_READ,
TRANSACTION_SERIALIZABLE 중에서 DB에서 지원하는 레벨을 설정할 수 있다.

 

Connection Pool 크기 설정

1) <min-pool-size>

 Pool에 유지할 최소 connection 개수로 기본값은 0. 기본적으로 최초 getConnection() 호출전까지 물리적인 db connection은 만들어지지 않는다. 데이터소스 디플로이시에 <min-pool-size>만큼 connection을 만들고자 한다면 <prefill>true</prefill>을 추가로 설정해준다.

 

2) <max-pool-size>

 최대 connection 개수를 설정한다. 기본값은 20.

 

각종 Timeout 설정

1) <blocking-timeout-millis>

 모든 connection이 사용중일 때 getConnection()에서 connection이 반환될 때까지 기다릴 시간으로 ms 단위이다.

 

2) <idle-timeout-minute>

 pool에서 일정 시간동안 사용되지 않고 있는 connection을 닫도록 설정할 수 있는데 그 시간을 분 단위로 설정한다.

 

3) <query-timeout>

 query에 대한 응답을 기다리며 대기할 수 있는 시간을 초 단위로 설정한다.  트랜잭션 Timeout이 설정되어 있는 경우에는 <set-tx-query-timeout>true</set-tx-query-timeout>을 추가로 설정해 트랜잭션 timeout까지 남아 있는 시간을 query timeout으로 자동으로 설정할 수 있다.

 

Connection 에러 처리 설정

1) <check-valid-connection-sql>

 getConnection()시 pool에서 어플리케이션에 connection을 반환하기 전에 connection 상태를 체크하는데 사용할 SQL을 명시한다.

 ex) SELECT 1 FRORM DUAL

 

2) <valid-connection-checker-class-name>

 getConnection()시 pool에서 어플리케이션에 connection을 반환하기 전에 connection 상태를 체크하는 DB 벤더별 클래스를 명시한다. Oracle, MySQL에 대한 구현체가 제공된다

Oracle

org.jboss.resource.adapter.jdbc.vendor.OracleValidConnectionChecker

MySQL

org.jboss.resource.adapter.jdbc.vendor.MySQLValidConnectionChecker

 

3) <exception-sorter-class-name>

 SQLException 발생시 connection error를 검출하는데 사용할 클래스를 명시한다. 예외가 Connection 문제로 발생한 경우 해당 connection을 close하게 된다.

Oracle

org.jboss.resource.adapter.jdbc.vendor.OracleExceptionSorter

MySQL

org.jboss.resource.adapter.jdbc.vendor.MySQLExceptionSorter

Sybase

org.jboss.resource.adapter.jdbc.vendor.SybaseExceptionSorter

Informix

org.jboss.resource.adapter.jdbc.vendor.InformixExceptionSorter

 

4) <background-validation>

 connection 상태를 매번 getConnection()시마다 체크하지 않고 일정주기로 백그라운드에서 체크할지 여부를 설정한다. 기본값은 false이다.

 

5) <background-validation-minutes>

 connection 상태를 백그라운드로 체크하도록 설정한 경우 그 주기를 분 단위로 설정한다. 기본값은 10분

 

최적화 관련 설정 항목

1) <prepared-statement-cache-size>

 PreparedStatement를 캐쉬해서 성능 향상을 꾀한다. 기본값은 0이다. 이 값이 Oracle에 설정된 open_cursor 값 보다 크면 ORA-01000 "maximum open cursors exceeded"가 발생할 수 있다.

 

Connection 초기 설정

1) <new-connection-sql>

 새로 물리적인 connection을 생성할 때 마다 수행할 SQL을 설정한다. DB session 설정이 필요한 경우 유용하다.

  ex) <new-connection-sql>ALTER SESSION SET nls_date_format="YYYY-MM-DD HH24:MI:ss"</new-connection-sql>