나 자신을 다스리는 자가 세상을 다스린다.

테스트 없이 눈으로만 코딩할 때 가장 틀리기 쉬운 부분이 call by value 와 call by refence 를 정확히 이해하지 못할 때 생기는 오류가 아닐까 싶다.

기본형과 객체가 있는데
기본형은 call by value 이고 객체는 call by refence 라는 것은 대부분의 java 개발자들이 알고 있을꺼라 생각한다.

그 예로 swap 함수를 가장 많이 설명하는데..

예제 1)

class Test {
    private static void swap(int a, int b) {
        int temp = a;
        a = b;
        b = temp;
    }

    public static void main(String args[]) {
        int a = 1;
        int b = 2;

        System.out.println("a => " + a);
        System.out.println("b => " + b);

        swap(a, b);

        System.out.println("------- swap 후 -------");

        System.out.println("a => " + a);
        System.out.println("b => " + b);
    }
}

예제 1 의 경우 원하던 결과가 아닌 것을 바로 알아 낼 수 있을 것이다.
swap 메소드에 넘기는 것은 reference 가 아닌 value 이기 때문에...
쉽다. 넘어가자.

다음 예제 2 를 보자
예제 2)

class Test {
    private static void swap(Integer a, Integer b) {
        Integer temp = a;
        a = b;
        b = temp;
    }

    public static void main(String args[]) {
        Integer a = new Integer(1);
        Integer b = new Integer(2);

        System.out.println("a => " + a.intValue());
        System.out.println("b => " + b.intValue());

        swap(a, b);

        System.out.println("------- swap 후 -------");

        System.out.println("a => " + a.intValue());
        System.out.println("b => " + b.intValue());
    }
}

예제 2 의 경우 Integer 는 Object 이다. Object 는 call by reference 다.
따라서 위의 예제는 원하는 결과를 가져올 것이다.
그러나 실행을 하면 예제 1과 전혀 다르지 않다는 것을 알 수 있다.

왜? 객체는 call by reference 라며 사기친거야?

결론부터 말하면 객체는 call by reference 맞다

그러나 해당 객체를 보는 새로운 reference 를 참조해서 넘기는 것이다.

따라서 동일한 객체를 가르키고 있지만
main 에서의 reference 값과 swap 함수에서의 reference 값은 다르다.

따라서 위의 예제의 경우 원하는 결과가 나오지 않는다.

그렇다면 어떻게 해야 해?

예제 3 을 보자.

예제 3)

class Test {
    int value;

    Test(int value) {
        this.value = value;
    }

    private static void swap(Test a, Test b) {
        int temp = a.value;
        a.value = b.value;
        b.value = temp;
    }

    public static void main(String args[]) {
        Test a = new Test(1);
        Test b = new Test(2);

        System.out.println("a => " + a.value);
        System.out.println("b => " + b.value);

        swap(a, b);

        System.out.println("------- swap 후 -------");

        System.out.println("a => " + a.value);
        System.out.println("b => " + b.value);
    }
}

예제 2와 같이 객체의 reference 를 넘긴다.
reference 를 직접 변경하는 게 아니라.
reference 가 참조하는 객체의 value 를 변경하고 있다.
따라서 같은 객체를 보고 있는 main 에서도 값이 바뀌는 것을 알 수 있다.

call by reference

해당 객체의 주소값을 직접 넘기는 게 아닌 객체를 보는 또 다른 주소값을 만들어서 넘기다는 사실을 잊지 말자~
신고
TAGjava
Posted by trypsr Trackback 0 Comment 2
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;

import org.apache.commons.lang.StringUtils;

public class ZipUtils {

    private static final int COMPRESSION_LEVEL = 8;

    private static final int BUFFER_SIZE = 1024 * 2;

    /**
     * 지정된 폴더를 Zip 파일로 압축한다.
     * @param sourcePath - 압축 대상 디렉토리
     * @param output - 저장 zip 파일 이름
     * @throws Exception
     */
    public static void zip(String sourcePath, String output) throws Exception {

        // 압축 대상(sourcePath)이 디렉토리나 파일이 아니면 리턴한다.
        File sourceFile = new File(sourcePath);
        if (!sourceFile.isFile() && !sourceFile.isDirectory()) {
            throw new Exception("압축 대상의 파일을 찾을 수가 없습니다.");
        }

        // output 의 확장자가 zip이 아니면 리턴한다.
        if (!(StringUtils.substringAfterLast(output, ".")).equalsIgnoreCase("zip")) {
            throw new Exception("압축 후 저장 파일명의 확장자를 확인하세요");
        }

        FileOutputStream fos = null;
        BufferedOutputStream bos = null;
        ZipOutputStream zos = null;

        try {
            fos = new FileOutputStream(output); // FileOutputStream
            bos = new BufferedOutputStream(fos); // BufferedStream
            zos = new ZipOutputStream(bos); // ZipOutputStream
            zos.setLevel(COMPRESSION_LEVEL); // 압축 레벨 - 최대 압축률은 9, 디폴트 8
            zipEntry(sourceFile, sourcePath, zos); // Zip 파일 생성
            zos.finish(); // ZipOutputStream finish
        } finally {
            if (zos != null) {
                zos.close();
            }
            if (bos != null) {
                bos.close();
            }
            if (fos != null) {
                fos.close();
            }
        }
    }

    /**
     * 압축
     * @param sourceFile
     * @param sourcePath
     * @param zos
     * @throws Exception
     */
    private static void zipEntry(File sourceFile, String sourcePath, ZipOutputStream zos) throws Exception {
        // sourceFile 이 디렉토리인 경우 하위 파일 리스트 가져와 재귀호출
        if (sourceFile.isDirectory()) {
            if (sourceFile.getName().equalsIgnoreCase(".metadata")) { // .metadata 디렉토리 return
                return;
            }
            File[] fileArray = sourceFile.listFiles(); // sourceFile 의 하위 파일 리스트
            for (int i = 0; i < fileArray.length; i++) {
                zipEntry(fileArray[i], sourcePath, zos); // 재귀 호출
            }
        } else { // sourcehFile 이 디렉토리가 아닌 경우
            BufferedInputStream bis = null;
            try {
                String sFilePath = sourceFile.getPath();
                String zipEntryName = sFilePath.substring(sourcePath.length() + 1, sFilePath.length());

                bis = new BufferedInputStream(new FileInputStream(sourceFile));
                ZipEntry zentry = new ZipEntry(zipEntryName);
                zentry.setTime(sourceFile.lastModified());
                zos.putNextEntry(zentry);

                byte[] buffer = new byte[BUFFER_SIZE];
                int cnt = 0;
                while ((cnt = bis.read(buffer, 0, BUFFER_SIZE)) != -1) {
                    zos.write(buffer, 0, cnt);
                }
                zos.closeEntry();
            } finally {
                if (bis != null) {
                    bis.close();
                }
            }
        }
    }

    /**
     * Zip 파일의 압축을 푼다.
     *
     * @param zipFile - 압축 풀 Zip 파일
     * @param targetDir - 압축 푼 파일이 들어간 디렉토리
     * @param fileNameToLowerCase - 파일명을 소문자로 바꿀지 여부
     * @throws Exception
     */
    public static void unzip(File zipFile, File targetDir, boolean fileNameToLowerCase) throws Exception {
        FileInputStream fis = null;
        ZipInputStream zis = null;
        ZipEntry zentry = null;

        try {
            fis = new FileInputStream(zipFile); // FileInputStream
            zis = new ZipInputStream(fis); // ZipInputStream

            while ((zentry = zis.getNextEntry()) != null) {
                String fileNameToUnzip = zentry.getName();
                if (fileNameToLowerCase) { // fileName toLowerCase
                    fileNameToUnzip = fileNameToUnzip.toLowerCase();
                }

                File targetFile = new File(targetDir, fileNameToUnzip);

                if (zentry.isDirectory()) {// Directory 인 경우
                    FileUtils.makeDir(targetFile.getAbsolutePath()); // 디렉토리 생성
                } else { // File 인 경우
                    // parent Directory 생성
                    FileUtils.makeDir(targetFile.getParent());
                    unzipEntry(zis, targetFile);
                }
            }
        } finally {
            if (zis != null) {
                zis.close();
            }
            if (fis != null) {
                fis.close();
            }
        }
    }

    /**
     * Zip 파일의 한 개 엔트리의 압축을 푼다.
     *
     * @param zis - Zip Input Stream
     * @param filePath - 압축 풀린 파일의 경로
     * @return
     * @throws Exception
     */
    protected static File unzipEntry(ZipInputStream zis, File targetFile) throws Exception {
        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream(targetFile);

            byte[] buffer = new byte[BUFFER_SIZE];
            int len = 0;
            while ((len = zis.read(buffer)) != -1) {
                fos.write(buffer, 0, len);
            }
        } finally {
            if (fos != null) {
                fos.close();
            }
        }
        return targetFile;
    }
}

위의 소스는 문제점이 있다.
사실 소스문제라기 보다는 java.util.zip 문제이다.
zip 파일안의 파일명의 인코딩을 UTF-8 로 하기 때문에 압축 대상 파일명에 한글이 있을경우 문제가 생긴다.
만약 압축 대상 파일명에 한글이 포함되어 있다면 jazzlib 를 사용하기 바란다.

jazzlib 는 java.util.zip 과 구조 및 사용법이 똑같으므로 위의 소스에서 ZipEntry, ZipOutputStream 의 import 문만 변경하여 주면 된다.

import net.sf.jazzlib.ZipEntry;
import net.sf.jazzlib.ZipInputStream;
신고
TAGjava
Posted by trypsr Trackback 0 Comment 1
jdk1.5.0_08 와 jakarta-tomcat-5.0.28 에서 내포하고 있는 w3c dom 의 버전 차이로 인하여 문제가 발생한다.

Node 의 getTextContent() 메소드를 사용하는데

컴파일시에는 jdk1.5.0_08 의 w3c dom 을 사용 하므로 아무이상없이 실행된다.

그러나 Tomcat 으로 실행을 하게 되면 아래와 같이 메소드를 찾지 못한다.
   
java.lang.NoSuchMethodError: org.w3c.dom.Node.getTextContent()Ljava/lang/String;

Tomcat 설치 디렉토리/common/endorsed 디렉토리를 보면 xml-apis.jar 파일이 있는데

Tomcat 실행시에는 xml-apis.jar 의 w3c dom 을 먼저 읽게 되므로 메소드를 못 찾는 현상..

그래서 과감히 xml-apis.jar 를 이동시키면 임시적으로 문제 해결...

더 좋은 해결 방법은 뭐가 없을까??

관련 링크 : http://forum.java.sun.com/thread.jspa?threadID=699041&messageID=4057479
신고
TAGjava, XML
Posted by trypsr Trackback 0 Comment 0
선수의 수와 그 선수가 싫어하는 선수의 정보를 입력받아
두 개의 팀으로 구성하여라.

예)
1번째 선수의 정보를 입력하세요(싫어하는 선수의 번호, ...)
3
2번째 선수의 정보를 입력하세요(싫어하는 선수의 번호, ...)
1
3번째 선수의 정보를 입력하세요(싫어하는 선수의 번호, ...)
----------------
A Team : 1
B Team : 2 3

싫어하는 선수가 여러명일 경우 1,2 ... 와 같이 , 로 구분하여 입력받는다.


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

나는 아래와 같이 작성하였다.

알고리즘을 생각하는데 많은 시간이 걸렸다..

처음에는 단순하게 for 문 돌리면서 넣었다 뺐다 하면 되겠지 생각했는데...

생각보다 쉽지가 않았다.

코드 작성 초기에는 TDD 도 익힐 겸 JUnit 제대로 적용하고 Exception 처리도 말끔히 해볼까 했는데...

회사에서 눈치보면서 한 것이라 막 코딩이 되어버렸다. ㅠ.ㅠ

그래도 재미있는 문제였다.


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

public class Test{

    private final int POSSIBLE = 1; // 위치한 자리

    private final int IMPOSSIBLE = -1; // 불가 자리

    private final int HOLD = 0; // 빈 자리

    int[] aTeam; // A Team

    int[] bTeam; // B Team

    int[] otherTeam; // Other

    String[][] playerInfo = null; // 싫어하는 선수 정보

    private void doProcess(InputStream is) {
        while (true) {
            System.out.println("선수의 수를 입력하십시요 : ");
            int totalNum = readTotal(is);

            if (totalNum > 0) {

                playerInfo = new String[totalNum][];
                aTeam = new int[totalNum];
                bTeam = new int[totalNum];
                otherTeam = new int[totalNum];
                // 선수 정보 입력
                for (int i = 1; i < totalNum + 1; i++) {
                    System.out.println(i + "번째 선수의 정보를 입력하세요(싫어하는 선수의 번호, ...)\n싫어하는 선수가 없을 시에는 Enter");
                    playerInfo[i - 1] = readPlayerInfo(is);
                }

                makeTeam();
                System.out.println("결과는 다음과 같습니다.");
                System.out.println("A Team : " + printTeam(aTeam));
                System.out.println("B Team : " + printTeam(bTeam));
                System.out.println("Not Team : " + printTeam(otherTeam));
                System.exit(0); // 종료
            } else {
                System.out.println("잘못된 입력입니다.\n 다시 입력하여 주십시요.");
            }
        }
    }

    /**
     * 전체 선수의 수 읽어오기
     * @param is
     * @return
     */
    private int readTotal(InputStream is) {
        String total = null;
        int totalNum = 0;
        try {
            total = readLine(is);
            if ("exit".equalsIgnoreCase(total)) {
                System.out.println("프로그램을 종료합니다.");
                System.exit(0);
            }
            totalNum = Integer.parseInt(total); // 전체 player
        } catch (NumberFormatException nfe) {
            // nothing doto
        }
        return totalNum;
    }

    /**
     * player 정보 입력
     * @param is
     * @return
     */
    private String[] readPlayerInfo(InputStream is) {
        String info = readLine(is);
        return ("".equals(info.trim())) ? null : info.trim().split(",");
    }

    /**
     * make Team
     *
     */
    private void makeTeam() {
        for (int i = 0; i < playerInfo.length; i++) {
            boolean conBoolean = true;

            // aTeam check
            conBoolean = checkTeam(playerInfo[i], aTeam, i);

            if (conBoolean) // aTeam 자격 안되면 bTeam 체크
                conBoolean = checkTeam(playerInfo[i], bTeam, i);

            if (conBoolean) // aTeam, bTeam 둘다 자격 안되면 otherTeam
                otherTeam[i] = POSSIBLE;
        }
    }

    /**
     * Team check
     *
     * @param pInfos
     * @param team
     * @param i
     * @return
     */
    private boolean checkTeam(String[] pInfos, int[] team, int i) {
        boolean retVal = true;
        if (team[i] == HOLD) { // 해당 자리 있을 경우에만
            if (pInfos == null) { // 싫어하는 선수 없으면 현재 team 소속
                team[i] = POSSIBLE;
                retVal = false; // 다음 team 작업 중지
            } else { // 싫어하는 선수 리스트 있으면...
                if (checkHate(team, pInfos)) { // 싫어하는 선수 중에 이미 자리잡은 경우가 있는지 체크, 없을 경우 아래 작업 진행
                    for (int j = 0; j < pInfos.length; j++) {
                        int hateNum = Integer.parseInt(pInfos[j]) - 1;
                        team[hateNum] = IMPOSSIBLE; // 싫어하는 선수의 자리 불가로 표시..
                        team[i] = POSSIBLE; // 현재 team 소속
                        retVal = false; // 다음 team 작업 중지
                    }
                }

            }
        }
        return retVal;
    }

    /**
     * team 에 싫어하는 선수가 자리 잡고 있는지 체크
     *
     * @param team
     * @param infos
     * @return 해당 팀에 들어갈 수 있는지 여부 return
     */
    private boolean checkHate(int[] team, String[] infos) {
        for (int i = 0; i < infos.length; i++) {
            if (team[i] == POSSIBLE) { // 현재 team 에 싫어하는 사람 있는 경우
                return false; // 해당 팀에 들어갈 수 없음
            }
        }
        return true;
    }

    /**
     * InputStream 으로 부터 read Line
     * @param is
     * @return
     */
    private String readLine(InputStream is) {
        InputStreamReader isr = new InputStreamReader(is);
        BufferedReader br = new BufferedReader(isr);

        String retVal = null;
        try {
            retVal = br.readLine();
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("프로그램에 오류가 발생하였습니다.");
            System.exit(1);
        }
        return retVal;
    }

    /**
     * team print
     *
     * @param team
     * @return
     */
    private String printTeam(int[] team) {
        StringBuffer retVal = new StringBuffer();
        for (int i = 0; i < team.length; i++) {
            if (team[i] == POSSIBLE)
                retVal.append(i + 1).append(" ");
        }
        return retVal.toString();
    }

    public static void main(String[] args) {
        System.out.println("프로그램을 시작합니다.");
        Test t = new Test();
        t.doProcess(System.in);
    }
}
신고
TAGjava
Posted by trypsr Trackback 0 Comment 0
그동안 귀찬니즘으로 인하여 test 를 멀리했었다.

하지만 이제는 tdd 를 습관화 해봐야지ㅣ

그런데.. 전에 junit 이 4.x 버전 부터 완전히 바꼈다... ㅠ.ㅠ


더 편해졌다고들 하는데.. 전에 봤던 것과 너무 많이 바껴서...ㅠ.ㅠ

그래도 열심히 해봐야지..

testNG 가 junit 보다 더 낫다고 하던데... 나는 그냥 이클립스 기본 플러그인인 junit 4 로 습관화 하기로 했다.
신고

'작업공간 > 프로그래밍' 카테고리의 다른 글

모 회사 기출문제 3  (0) 2007.02.08
tdd 를 생활화 하기에 앞서..  (0) 2007.02.05
나 자신을 또 한번 생각하게 만드는...  (0) 2007.02.02
모 회사 기출문제 2  (0) 2007.02.01
Posted by trypsr Trackback 0 Comment 0
2번째 기출문제..

입력받은 알파벳의 합을 구하라.
- A = 1 ~ Z= 26

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

class Test{

    public int calculate(String inputString) {
        int sum = 0;
        for (int i = 0; i < inputString.length(); i++) {
            int charNum = Character.getNumericValue(inputString.charAt(i)) - 9;

            if (charNum > 0 && charNum < 27) {
                sum += charNum;
            }
        }
        return sum;
    }

    public static void main(String[] args) {
        System.out.println("프로그램을 시작합니다.");
        System.out.print(">>");

        while (true) {
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
            Test t = new Test();

            String inputString = null;
            try {
                inputString = br.readLine();

                if (!"exit".equals(inputString)) {
                    System.out.println("SUM : " + t.calculate(inputString));
                    System.out.println(">>");
                } else {
                    System.out.println("프로그램을 종료합니다.");
                    System.exit(0);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
신고
TAGjava
Posted by trypsr Trackback 0 Comment 0
내가 가고 싶은 회사 중에 하나인 곳의 기출문제 라는데..

나도 한 번 풀어보았다.

나의 풀이가 원하는 정답이 아닐 수 있지만..
나의 코드 스타일이 어떤지 되집어 보고는 싶었다.
뭐 많이 고민하고 구현한건 아니라지만... 역시 맘에 안든다...ㅠ.ㅠ
이런 간단한 것도 맘에 안들어 하는데... 그동안 돈 받고 팔아먹었던 것들은?
후회없는 프로그래밍은 과연 가능할까?



특정 문자열 계산
- 문장을 입력받아 문자열중 bab은 1점, baby는 -2점으로 계산
- 기본점수는 50점
- babbab 과 같이 한 단어에 bab 중복일 경우 한 번만 계산
- babbaby일 경우 bab 과 baby 가 같이 있을 경우 baby만  계산

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

class Test {

    public int calculate(String inputString) {
        int retVal = 0;
        retVal = getWordCount(inputString, "A") * 1 + getWordCount(inputString, "B") * -2;
        return retVal;
    }

    private int getWordCount(String inputString, String gubun) {
        int count = 0;

        String[] inputWord = inputString.split(" ");

        for (int i = 0; i < inputWord.length; i++) {
            if (gubun.equals("A")) {
                if (containsIgnoreCase(inputWord[i], "bab") && !containsIgnoreCase(inputWord[i], "baby"))
                    count++;
            } else if (gubun.equals("B")) {
                if (containsIgnoreCase(inputWord[i], "baby"))
                    count++;
            }
        }
        return count;
    }

    private boolean containsIgnoreCase(String str, String searchStr) {
        if (str == null || searchStr == null) {
            return false;
        }
        str = str.toUpperCase();
        searchStr = searchStr.toUpperCase();
        return str.indexOf(searchStr) >= 0;
    }

    public static void main(String args[]) {

        System.out.println("프로그램을 시작합니다.");
        System.out.print(">>");

        while (true) {
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
            int point = 50;

            Test t = new Test();

            String inputString = null;
            try {
                inputString = br.readLine();

                if (!"exit".equals(inputString)) {

                    point += t.calculate(inputString);

                    System.out.println("point : " + point);
                    System.out.println(">>");
                } else {
                    System.out.println("프로그램을 종료합니다.");
                    System.exit(0);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
신고
TAGjava
Posted by trypsr Trackback 0 Comment 0
※ Log4j 의 로그 레벨
    Level.FATAL : 어플리케이션에 치명적인 심각한 에러를 나타낼때 사용
    Level.ERROR : 어플리케이션이 수행 가능한 정도의 에러를 나타낼 때 사용
    Level.WARN : 시스템에 문제를 일으킬 수 있는 상황을 나타낼 때 사용
    Level.INFO : 어플리케이션의 정보를 나타낼 때 사용
    Level.DEBUG : 어플리케이션의 상태에 대한 상세 정보를 나타낼 때 사용
 
※ 로깅을 위한 Logger 클래스의 메소드
    fatal(Object message)
    fatal(Object message, Throwable t)
    error(Object message)
    error(Object message, Throwable t)
    warn(Object message)
    warn(Object message, Throwable t)
    info(Object message)
    info(Object message, Throwable t)
    debug(Object message)
    debug(Object message, Throwable t)
 
※ Log4j 의 구조
    - Logger, Appender, Layout 3가지 요소
    - Appender 의 종류
        1) org.apache.log4j.ConsoleAppender : 콘솔에 로그 메세지를 출력
        2) org.apache.log4j.FileAppender : 파일에 로그 메세지를 기록
        3) org.apache.log4j.RollingFileAppender : 파일에 로그 메세지를 기록, 파일이 일정 크기가 되면 다른 이름으로 저장하고 새로운 로그 메세지를 기록
        4) org.apache.log4j.DailyRollingFileAppender : 파일에 로그 메세지를 기록, 하루 단위로 로그 파일을 변경
        5) org.apache.log4j.net.SMTPAppender : 로그 메세지를 이메일로 전송
        6) org.apache.log4j.nt.NTEventLogAppender : NT의 이벤트 로그 시스템에 로그 메세지를 전송. 윈도우 시스템에서만 사용 가능
    - PatternLayout (가장 많이 사용하는 Layout) 이 지원하는 패턴
        1) C : 로그 메세지를 기록하려는 클래스의 완전한 이름을 출력. 패키지 계층이 얼마나 출력될지 제어 가능.
            사용 예) com.javacan.mail.MailManager ( %C{2} 일 경우 )  => mail.MailManager
        2) d : 로그 메세지를 기록한 시간을 출력. 괄호를 사용하여 포맷지정 가능. 사용하는 문자열 포맷은 java.text.SimpleDateFormat과 같은 포맷을 따른다.
            사용 예) %d(yyyy-MM-dd HH:mm:ss) => 2006.05.26 14:09:23
        3) p : 로그 메세지의 우선순위를 출력
        4) m : 로그 메세지 자체를 출력
        5) M : 로그 메세지를 기록하려는 메소드의 이름을 출력
        6) n : 플랫폼의 라인 구분자를 출력
        7) t : 쓰레드
        8) F : 파일명
        9) L : 소스의 line number
        10) % : %% 는 '%' 자체를 출력
            사용 예)
                [%p] %d{yyyyMMddHHmmss} %C{1}.%M-%m%n
                [DEBUG] 20050526140923 SomeClass.methodName()-로그메세지

※ log4j 설정 파일
    log4j.properties, log4j.xml 의 이름으로 classpath 경로에 있으면 소스상에서 따로 경로지정을 하지 않아도 log4j가 자동으로 인식
    ---------------------------------------------------------------
    # rootLogger 설정
    # appender_name 은 ','로 구분하여 여러 개 올 수 있음
    # [level] : OFF, FATAL, ERROR, INFO, DEBUG, ALL
        log4j.rootLogger=[Level], appender_name, ...
    # LEVEL 대신 INHERITED 를 넣어주면 상위 logger 의 레벨을 사용
        log4j.logger.logger_name=[Level|INHERITED], appender_name, ...
    # 상위 logger 의 Appender 사용 여부 지정
        log4j.additivity.logger_name=true|false
        log4j.appender.appender_name=[appender_class_name]
        log4j.appender.appender_name.option1=value1
        log4j.appender.appender_name.option2=value2

        log4j.appender.appender_name.layout=[layout_class_name]
        log4j.appender.appender_name.layout.option1=value1
        log4j.appender.appender_name.layout.option2=value2
    ---------------------------------------------------------------
    사용 예)
    1) log4j.properties
    # Global logging configuration
    log4j.rootLogger=DEBUG, stdout, fileout

    # Console output...
    log4j.appender.stdout = org.apache.log4j.ConsoleAppender
    log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
    log4j.appender.stdout.layout.ConversionPattern = %5p ({%t} %F[%M]:%L) [%d] - %m%n

    # Rolling log file output...
    log4j.appender.fileout = org.apache.log4j.RollingFileAppender
    log4j.appender.fileout.File = mylog.log
    log4j.appender.fileout.MaxFileSize = 100KB
    log4j.appender.fileout.MaxBackupIndex = 1
    log4j.appender.fileout.layout = org.apache.log4j.PatternLayout
    # log4j.appender.fileout.layout.ConversionPattern = %5p ({%t} %F[%M]:%L) [%d] - %m%n
    log4j.appender.fileout.layout.ConversionPattern = %5p (%F[%M]:%L) - %m%n

    # Turn off Apache log
    log4j.logger.org.apache=OFF

    2) log4j.xml : xml 형태로도 가능
    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
    <log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
        <root>
            <level value="WARN"/>
            <appender-ref ref="CONSOLE"/>
        </root>
        <appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender">
            <layout class="org.apache.log4j.PatternLayout">
                <param name="ConversionPattern" value="%5p ({%t} %F[%M]:%L) [%d] - %m%n"/>
            </layout>
        </appender>
        <logger name="org.apache">
            <level value="OFF"/>
        </logger>
    </log4j:configuration>
신고

'작업공간 > 프로그래밍' 카테고리의 다른 글

Ant 주요 사용법  (0) 2007.01.09
Log4J 사용하기  (0) 2006.12.27
XML을 String으로 변환  (0) 2006.12.27
Tomcat 디렉토리 리스트 막기  (0) 2006.12.27
TAGjava
Posted by trypsr Trackback 0 Comment 0
1. JAXP 사용하여 XML -> String

import javax.xml.transform.TransformerFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Source;
import javax.xml.transform.dom.DOMSource;
import java.io.StringWriter;
import javax.xml.transform.Result;
import javax.xml.transform.stream.StreamResult;
...

// XSL 변환기 생성
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");

// XML 문서 출력
Source xmlSource = new DOMSource( document );
StringWriter stringWriter = new StringWriter();
Result xmlResult = new StreamResult(stringWriter);
transformer.transform(xmlSource, xmlResult);
System.out.println(stringWriter.toString());


2. JDOM 사용하여 XML <-> String

1) String -> Document
import java.io.StringReader;
import org.jdom.Document;
import org.jdom.input.SAXBuilder;
...
Document docu = new SAXBuilder().build(new StringReader(String str));

2) Document -> String
import org.jdom.Document;
import org.jdom.output.XMLOutputter;
...
XMLOutputter xo = new XMLOutputter();
String str = xo.outputString(Document docu);
신고

'작업공간 > 프로그래밍' 카테고리의 다른 글

Log4J 사용하기  (0) 2006.12.27
XML을 String으로 변환  (0) 2006.12.27
Tomcat 디렉토리 리스트 막기  (0) 2006.12.27
Tomcat Encoding filger 적용하기  (0) 2006.12.18
TAGjava, XML
Posted by trypsr Trackback 0 Comment 0

jakarta commons fileupload 사용 예제..

그러나 지금 진행중인 project 에서는 cos 를 사용하였다.

이유가 있었는데 기억이 안난다.

rename policy?  아닌데...

commons 에서 뭔가 불편한 것이 있었는데... (이놈의 단기 기억력)

기억해내면 꼭 적어놓아야지...

아무튼 jakarta commons fileupload 간단 사용 예제..

필요한 jar : jakarta commons fileupload 뿐만 아니라 jakarta commons io 도 필요하다.


import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

import org.apache.commons.lang.StringUtils;
import java.io.File;
...

// Create a factory for disk-based file items
DiskFileItemFactory factory = new DiskFileItemFactory();
factory.setSizeThreshold(1024*10); // memory 에 저장할 최대 싸이즈 : 10K
factory.setRepository(tmpDir); // 저장할 디렉토리

ServletFileUpload upload = new ServletFileUpload(factory);
upload.setSizeMax(1024*1024*10); // upload 파일의 최대 크기 : 10M

HashMap param = new HashMap();

try {
   List items = upload.parseRequest(req);
   Iterator iter = items.iterator(); // Process the uploaded items

   while (iter.hasNext()) {
       FileItem item = (FileItem) iter.next();
       if (item.isFormField()) {
           param.put(item.getFieldName(), item.getString());
       } else {
           String fileName = uploadDir + StringUtils.substringAfterLast(item.getName(), File.seperator);
          item.write(new File(fileName));
       }
   }
} catch (Exception e) {
   log.error("에러 발생 : ", e);
}

...



http://blog.naver.com/minki0504/70008010059   ---> 여기 보시면 자세히 설명해 놓으셨네요.. 
신고

'작업공간 > 프로그래밍' 카테고리의 다른 글

Tomcat Encoding filger 적용하기  (0) 2006.12.18
commons fileupload 사용예제  (0) 2006.12.18
iBATIS 의 SqlMaps 에서 result class 오류  (0) 2006.12.18
달력 스크립트  (0) 2006.12.15
Posted by trypsr Trackback 0 Comment 0


티스토리 툴바