출처 : http://www.okjsp.pe.kr/seq/99301

해결된 문제

1. 한글 문제

2. 아헿헿 류 파일명

3. %20등 인코드 되버리는 문자열 포함 파일명

4. 대화 상자에서 한글 깨지는 문제


테스트 방법

C:/PDS에 첨부한 아헿헿1.ppt와 %B0%F8%C7%F6%C1%D61_eparinara.jpg를 추가한다.

http://localhost:8082/WebTest/FileDownload.jsp?FILENAME=아헿헿1.ppt

http://localhost:8082/WebTest/FileDownload.jsp?FILENAME=%B0%F8%C7%F6%C1%D61_eparinara.jpg

<%@ page import="java.util.*,java.io.*" contentType="text/html; charset=MS949"%><%
String queryString = request.getQueryString();
String dialogFilename = request.getParameter("FILENAME");
String fname = new String(dialogFilename.getBytes("8859_1"), "MS949");
if(queryString.contains("%")) {
 fname = request.getQueryString();
 String startWord = "FILENAME=";
 int start = fname.indexOf(startWord) + startWord.length();
 int end = fname.indexOf("&");
 if(end !=-1)
  fname = fname.substring(start, end);
 else
  fname = fname.substring(start);
}
String fpath = "현재 서버의 실제 디렉토리 경로 - 예) C:/PDS";
File file = new File(fpath+fname);
if(!file.exists()) {
 out.println("<script>");
 out.println("alert('요청한 파일을 찾을 수 없습니다.');");
 out.println("history.back();");
 out.println("</script>");
 return;
}

BufferedInputStream input = null;
BufferedOutputStream output = null;
response.reset();
String strClient = request.getHeader("User-Agent");
if (strClient.indexOf("MSIE 5.5") != -1) {
 response.setHeader("Content-Disposition", "filename=" + dialogFilename + ";");
} else {
 response.setHeader("Content-Disposition", "attachment; filename=" + dialogFilename + ";");
 response.setHeader("Content-Type", "application/octet-stream; charset=MS949");
}
response.setHeader("Content-Length", ""+ file.length());
response.setHeader("Content-Transfer-Encoding", "binary;");
response.setHeader("Pragma", "no-cache;");
response.setHeader("Expires", "-1;");

try {
 input = new BufferedInputStream( new FileInputStream(file) );
 byte buffer[] = new byte[1024];
 int len = 0;
 out.clear();
 out.flush();
 output = new BufferedOutputStream(response.getOutputStream());
 while((len = input.read(buffer)) > 0 ){
  output.write(buffer,0,len);
  }
} catch(Exception e) {
 e.printStackTrace();
} finally{
 response.flushBuffer();
 if(input !=null)try{input.close();}catch(Exception e){}
 if(output !=null)try{output.close();}catch(Exception e){}
}
%>

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

: 응답 캐릭터셋을 utf-8 로 지정하고, 소스 코드의 캐릭터셋은 euc-kr 로 지정.
: 따라서, 작업은 euc-kr 로 하면서, 결과는 utf-8로 처리한다.

(이거.. 자꾸 까먹는단 말이다..)

출처 : http://www.javastudy.co.kr/docs/techtips/020502.html

javax.util.regex 패키지는 J2SE(Java 2 Platform, Standard Edition) 1.4 에서 새로 추가된 패키지이다.
이 패키지는 정규식(regular expression) 라이브러리를 제공한다.
정규식은 일련의 집합으로 표현되는 문자들의 패턴이고, 패턴 매칭(pattern matching)에서 자주 사용되어진다.
javax.util.regex 패키지에 있는 클래스들은 정규식을 고려하여 문자들의 순서를 일치시켜준다.
정규식 라이브러리를 포함하는 이러한 클래스들은 펄(Perl) 5 정규식 패턴 문법(syntax)을 사용한다.
그리고, 문장을 분석하는 일에 있어 이전에 java.io.StreamTokenizer와 java.util.StringTokenizer 클래스를 이용하여 것 보다 훨씬 더 강력한 방법을 제공한다.

정규식 라이브러리는 다음 세개의 클래스를 포함한다. Pattern, Matcher, PatternSyntaxException.
예외(exception)와 관련된 클래스를 중요하지 않게 생각하면, 정말 필요한 것은 일치하기를 원하는 정규식을 정의하기 위한 클래스(Pattern) 하나와, 주어진 문자열에서 패턴을 찾아내기 위한 또 다른 클래스(Matcher) 하나, 이렇게 단 두개의 클래스뿐이다.

정규식 라이브러리를 사용하기 위해서 가장 필요한 것은 패턴 문법을 이해하는 것이다.
실제로 문장을 분석하는 것은 비교적 쉬운 부분이다. 그러므로, 여기서는 정규식을 구성하는 것들이 무엇인지 살펴보도록 하자.

정규식의 가장 간단한 예제는 리터럴(literal)이다.
리터럴은 정규식에 포함되어 있는 단순한 문자가 아니라, 정규식에 포함된 어떤 특별한 배합이나 식의 일부분이 아닌 문자이다.

예를 들면, 리터럴 "x"는 정규식이다.
리터럴과 매처(matcher), 그리고 문자열을 사용하면, "정규식 'x'가 전체 문자열과 일치하는가?"라고 물어볼 수 있다.
다음은 이러한 질문에 대한 소스 코드이다.

boolean b = Pattern.matches("x", someString);


 만약 패턴 "x"가 someString 과 일치하는 일련의 문자라면, b는 true 값을 가지게 된다.
그렇지 않다면, b의 값은 false가 된다. 홀로 사용되는 경우에, 리터럴은 이해하기 위해서 분석하는 것이 어렵지 않다.
매처(matcher)가 Matcher 클래스가 아닌 Pattern 클래스에 의해서 만들어진다는 것을 주의해야 한다.
정규식이 단 한번만 사용되는 경우에 손 쉽게 사용 하기 위해서, matches 메서드는 Pattern 클래스에 정의된다.
일반적으로, Pattern 인스턴스를 정의하고, 그 Pattern 에 대한 Matcher 인스턴스를 정의한 후에, Matcher 클래스에 정의된 matches 메서드를 사용하는 것이 좋다.

Pattern p = Pattern.compile("x");  
Matcher m = p.matcher("sometext");
boolean b = m.matches();


이 팁의 후반부에 이런 단계를 다룰것이다.

물론, 정규식은 리터럴보다 더 복잡해질 수 있다.
와일드카드(wildcard)와 한정사(quantifier)를 추가하면 더 복잡해진다.
정규식에서는 오직 하나의 와일드카드만이 존재하는데, 바로 마침표(.) 문자이다.
와일드카드는 어느 한 문자와 일치시키기 위해서 사용되어지는데, 심지어는 개행문자도 가능하다.
한정사를 나타내는 문자는 +와 *이다.(원칙적으로는, 물음표 또한 한정사를 나타내는 문자이다)
정규식 뒤에 위치하는 + 문자는 정규식이 한번 또는 여러번 나타나는 것을 인정한다.
* 문자는 + 문자와 비슷하지만, 한번도 나오지 않거나 여러번 나오는 것을 인정한다.
예를 들어, 만약 처음에 j로 시작해서 마지막은 z로 끝나고 이 두 문자 사이에 적어도 하나의 문자가 존재하는 문자열을 찾기를 원한다면, 식 "j.+z"를 사용하면 된다. 만약 j와 z 사이에 문자가 없을수도 있다면, 앞에 나오는 식 대신 "j.*z"를 사용하면 된다.

패턴 매칭은 문자열 내에서 패턴을 만족시키는 가장 긴 문자열을 찾으려고 한다는 사실에 대해 주의해라.
만일 문자열 "jazjazjazjaz"가 주어지고 패턴 "j.*z"과 일치하는 문자열을 요구한다면, 하나의 "jaz" 문자열이 아닌 전체 문자열을 리턴한다. 이러한 특징을 "greedy behavior"라고 부른다.
만약 정규식에 다른 설정이 없다면, 이 특징이 정규식의 기본(default)이 된다.

이제 좀 더 복잡한 예제를 살펴보도록 하자.
소괄호 안에 여러개의 식을 사용하면, 여러문자 패턴들에 대해 일치하는 문자열을 찾게 할 수 있다.
예를 들어, j 다음에 z가 나타나는 문자열을 원하는 경우에, "(jz)" 패턴을 사용할 수 있다.
이렇게 홀로 사용되는 경우에는, 추가적인 기능을 활용할 수 없다. 즉, "jz"와 똑같게 된다.
그러나, 소괄호를 사용함으로써, 한정사를 사용할수 있게 되고 "jz" 패턴이 여러번 나타난다는 표현을 할 수 있다: "(jz)+".

패턴을 사용하는 또 다른 방법은 다른 문자 종류(class)들과 함께 사용하는 것이다.
특정 문자 종류를 사용하면, 각각의 문자들을 하나 하나 지정하는 대신에 가능한 문자들의 범위를 지정할 수도 있다.
예를 들어, j에서 z사이의 어떤 문자와도 일치하기를 원한다면, 대괄호를 사용하여 j-z의 범위를 지정할 수 있다:
"[j-z]". 또한 j와 z 사이에 적어도 한 문자와 일치하면서 이것이 여러번 나타날 수 있는 식이 필요하다면, 위의 식에 예를 들어 다음과 같이, "[j-z]+", 한정사를 추가할 수도 있다.

어떤 문자 종류들은 미리 정의되어져 있다. 이러한 문자 종류들은 공통으로 사용되어지므로, 공통의 단축 문자를 가지고 있다.
미리 정의된 몇개의 문자 종류는 다음과 같다.

\d    숫자: ([0-9])
\D    숫자가 아닌 문자: ([^0-9])
\s    공백 문자: [ \t\n\x0B\f\r]
\S    공백이 아닌 문자: [^\s]
\w    word 문자: [a-zA-Z_0-9]
\W    word가 아닌 문자: [^\w]

문자 종류에 있어서, ^ 문자는 식의 부정을 나타내기 위해서 사용되어짐을 주의하자.

다음은 POSIX 문자 셋이라 불리는 미리 정의된 문자 종류이다. 다음의 항목들은 POSIX 기술 명세서에서 가져왔고, 오직 US-ASCII 문자들과만 함께 동작한다.

\p{Lower}    알파벳 소문자: [a-z]
\p{Upper}    알파벳 대문자: [A-Z]
\p{ASCII}    모든 ASCII 문자: [\x00-\x7F]
\p{Alpha}    알파벳 문자: [\p{Lower}\p{Upper}]
\p{Digit}    10진법의 숫자: [0-9]
\p{Alnum}    문자숫자식의(alphanumeric) 문자: [\p{Alpha}\p{Digit}]
\p{Punct}    구두점(punctuation): !"#$%&'()*,-./:;<=>?@[\]^_`{|}~ 중의 하나
\p{Graph}    눈에 보이는 문자: [\p{Alnum}\p{Punct}]
\p{Print}    프린트 가능한 문자: [\p{Graph}]
\p{Blank}    공백(space) 또는 탭: [ \t]
\p{Cntrl}    제어 문자: [\x00-\x1F\x7F]
\p{XDigit}   16진법의 숫자: [0-9a-fA-F]
\p{Space}    흰공백(whitespace) 문자: [ \t\n\x0B\f\r]

마지막으로 언급되는 문자 종류의 집합은 경계를 나타내는 매처이다.
다시말해 문자(구체적으로 말하면 행, 단어 또는 패턴)들의 순서의 처음 또는 끝이 일치한다는 것을 의미한다.

^     행의 시작
$     행의 끝
\b    단어의 경계
\B    단어가 아닌 것의 경계
\A    입력의 시작
\G    이전 일치의 끝
\Z    마지막 종결자가 없을 경우 입력의 끝
\z    입력의 끝

문자 종류의 표현에 대해 이해하기 위해서 꼭 알아야 할 것은 \ 의 사용이다.
자바 문자열로 정규식을 만들때는, \ 문자를 사용하지 말아야 한다.
그렇지 않고 \ 문자를 사용하면, \ 다음에 오는 문자는 자바 컴파일러에 의해 특별하게 다루어 진다. \ 문자를 사용하기 위해서는, \\ 로 지정하면 된다. 즉, 문자열에 \\ 를 사용하면, 실제로 그 자리에 \ 문자가 오기를 원한다고 말하는 것이 된다.
예를 들어, 만약 문자숫자(alphanumeric) 문자로 이루어진 모든 문자열에 대한 패턴을 사용하기를 원하는 경우, 간단하게 \p{Alnum}* 만을 포함하는 문자열로는 충분하지 않다.
꼭 다음과 같이 \ 문자를 피해야만 한다.

boolean b = Pattern.matches("\\p{Alnum}*", someString);


이름이 함축하고 있는것처럼, Pattern 클래스는 패턴을 정의하기 위한 것이다.
패턴을 정의한다는 것은, 일치하기를 원하는 정규식을 정의하는 것이다.
패턴이 전체 문자열과 일치하는지를 알기 위해서 사용하는 것 보다는, 패턴이 문자열의 다음 부분과 일치하는지를 확인하기 위해서 사용하는 것이 일반적이다.

패턴을 사용하기 위해서는 먼저 패턴을 컴파일 해야 한다. compile 메서드를 사용하면 된다.

Pattern pattern = Pattern.compile(somePattern);


패턴 컴파일에는 약간의 시간이 필요하므로 한번만 하는 것이 현명하다.
Pattern 클래스의 matches 메서드는 매번 호출이 될때마다 패턴을 컴파일한다.
만약 패턴을 여러 번 사용해야 하는 경우라면, Pattern 클래스에서 Matcher 클래스를 얻고 Matcher 클래스를 사용함으로써 컴파일이 여러번 발생하는 것을 피할 수 있다.

패턴을 컴파일한 후에는, 명시된 문자열에 대한 Matcher 클래스를 얻을 수 있다.

Matcher matcher = pattern.matcher(someString);


Matcher 클래스는 전체 문자열을 검사하는 matches 메서드를 제공한다. 이 클래스는 패턴과 일치하는 것을 다음 부분(문자열의 시작이 아니라)에서부터 찾아주는 find() 메서드도 제공한다.

일치하는 것을 찾아낸 후에는, group 메서드를 사용해서 일치하는 것을 얻을 수 있다.

if (matcher.find()) {
  System.out.println(matcher.group());
}

또한 일치하는 것을 검색하고 바꾸기 위해서 matcher 클래스를 사용할 수 있다. 예를 들면, 문자열 내부에서 패턴과 일치하는 모든 부분을 바꾸기 위해서, 다음과 같이 사용할 수 있다.

String newString = matcher.replaceAll("replacement words");


이렇게 하면, 패턴이 발생하는 모든 부분은 교체 단어로 변경된다.

다음은 패턴 매칭에 대한 실제 예제이다.
다음 프로그램은 세 개의 명령줄 아규먼트를 필요로 한다.
첫 번째 인자는 검색하기 위한 문자열이다. 두번째는 검색하기 위한 패턴이다.
세번째는 교체 문자열이다. 검색하기 위한 문자열에서 패턴과 일치하는 모든 부분은 교체 단어로 변경된다.

import java.util.regex.*;

public class MyMatch {
  public static void main(String args[]) {

    if (args.length != 3) {
      System.out.println(
        "Pass in source string, pattern, " +
        "and replacement string");
      System.exit(-1);
    }

    String sourceString = args[0];
    String thePattern = args[1];
    String replacementString = args[2];

    Pattern pattern = Pattern.compile(thePattern);
    Matcher match = pattern.matcher(sourceString);
    if (match.find()) {
      System.out.println(
        match.replaceAll(replacementString));
    }
  }
}


예를 들어, 프로그램이 컴파일 되어 있다면 다음과 같이 실행할 수 있다.

java MyMatch "I want to be in lectures" "lect" "pict"

실행의 결과는 다음과 같다.

I want to be in pictures


그리고 이 프로그램을 실행할때, 명령줄에서 \ 문자의 사용은 불필요하다.
그 이유는 자바 컴파일러가 그러한 정보를 처리하지 않기 때문이다.
예를 들어, 만약 검색하기 위한 문자열이 

"I want to be in lectures\I want to be a star"

위와 같다면, 똑같은 패턴 ("lect")과 똑같은 교체 문자열("pict")을 이용하여 프로그램을 실행하면, 실행의 결과는 다음과 같다.

I want to be in pictures\I want to be a star

패턴 매칭과 정규식에 대한 자세한 정보는, 기술적인 기사(technical article)인 Regular Expressions and the Java Programming Language 를 참고하면 된다.

MySql 셋팅.

> 4.1 버전에서 한 내용.

1. Mysql 를 설치

2. mysql/bin/mysqld-nt --install 로 윈도우 서비스에 등록.
(mysql 제거: mysqld-nt --remove)

3. mysql 설치 폴더에
(1) 메모리가 1g 이상 -> my-huge.cnf
(2) 메모리 512mb 이상 -> my-large.cnf

를 my.ini 파일로 이름 변경한다.

4. my.ini 파일을 c:/winnt 폴더에 이동한다.(mysql 폴더에 my.ini 파일이 없게하자.)

5. my.ini 을 편집
:
[mysqld] 를 편집.
basedir=d:/server/mysql
datadir=d:/server/mysql/data

basedir 은 설치 폴더// datadir는 data폴더

6. 위도우 mysql 서비스를 재 시작한다.
: 콘솔에서
: mysql/net start mysql -- 시작
: mysql/net stop mysql -- 중지
: 으로도 서비스를 관리할 수 있다.

7. root 비번 변경.
D:\SERVER\mysql\bin>mysql -u root -p mysql
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 7 to server version: 4.0.21-nt-log

Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

mysql> update user set password=password('root123') where user='root';
Query OK, 2 rows affected (0.09 sec)
Rows matched: 2  Changed: 2  Warnings: 0

mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)

8. database 와 user 생성
:mysql> create database samtech_db;
:mysql> grant select,insert,update,delete,create,drop,alter,index on samtech_db.*
 to samtech@"localhost" identified by 'pass123';

9. databae 생성과 user 생성 후, mysql 서버에서 나옿후(exit;), database 접속
: mysql -u samtech -p samtech_db (로칼에서)
: mysql -h 111.222.0.2 -u samtechuser -p samtech_db (네트웍 접속)

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

 +------------+-------------+------+-----+---------+----------------+
| Field      | Type        | Null | Key | Default | Extra          |
+------------+-------------+------+-----+---------+----------------+
| qna_id     | int(8)      |      | PRI | NULL    | auto_increment |
| title      | varchar(40) | YES  |     | NULL    |                |
| content    | text        | YES  |     | NULL    |                |
| name       | varchar(12) | YES  |     | NULL    |                |
| email      | varchar(50) | YES  |     | NULL    |                |
| pwd        | varchar(20) | YES  |     | NULL    |                |
| write_date | datetime    | YES  |     | NULL    |                |
| read_cnt   | int(8)      | YES  |     | 0       |                |
| group_id   | int(8)      | YES  |     | NULL    |                |
| group_loc  | int(8)      | YES  |     | NULL    |                |
| step       | int(8)      | YES  |     | NULL    |                |
+------------+-------------+------+-----+---------+----------------+

mysql> create table qnaboard(
    -> qna_id int(8) not null auto_increment,
    -> title varchar(40),
    -> content text,
    -> name varchar(12),
    -> email varchar(50),
    -> pwd varchar(20),
    -> write_date datetime,
    -> read_cnt int(8),
    -> group_id int(8),
    -> group_loc int(8),
    -> step int(8),
    -> primary key(qna_id)
    -> );

== Server ==
> apache http server 설치 ( http://httpd.apache.org/download.cgi )
    ** WEBSVN 와 apache 를 연동해서 사용할 경우만 설치하며, SubVersion 보다 먼저 설치한다. **
    -. 설치안내 문서
    http://httpd.apache.org/docs/2.2/
    http://httpd.apache.org/docs/2.2/platform/windows.html
    -. {APACHE_HOME}/conf/httpd.conf 에서 아래 문장 주석제거
    LoadModule dav_module modules/mod_dav.so
    -. LoadModule dav_svn_module modules/mod_dav_svn.so
    : 문장도 주석을 제거 하라는데, 본인은 에러발생.
    : {Subversion_home}\bin\mod_dav_svn.so 파일을 {APACHE_HOME}/conf/modules 에 복사해도 에러가 발생.
> SubVersion 설치 ( http://subversion.tigris.org/servlets/ProjectDocumentList?folderID=91 )
    -. 환경변수 Path 설정
    : D:\dev_kit\Subversion\bin
    -.저장소 설정
    1. 저장폴더 root를 D:\repository 로 설정
    2. 프로젝트 단위별로 폴더생성(test 프로젝트)을 위해 command 창에서 svnadmin 명령어를 사용해야 한다.
    : 버전 1.2.0 에서 부터 버클리 DB를 사용한다고 한다. 저장소 생성시 버클리 인지 파일sys 잘 모르겠음.
    : 아마 버클리로 하는것을 추천할 것 같음.
    -.버클리 DB를 이용한 저장소
    svnadmin create --fs-type bdb D:\repository\test
    -.파일시스템을 이용한 저장소
    svnadmin create --fs-type fsfs D:\repository\test
    -. 인증 단계를 위한 D:/repository/test/conf/svnserve.conf 수정.
    [general]
    anon-access = none
    auth-access = write
    password-db = passwd
    -. 인증받지 않은 접근을 차단을 위한 D:/repository/test/conf/passwd 수정.
    [users]
    harry = harryssecret
    와 같이 ID=PW 형식으로 설정
> SVNSERVE Manager 설치 ( http://www.pyrasis.com/main/SVNSERVEManager )
: 매뉴얼로 subversion 을 관리한다. 윈도우 서비스로 관리 하려면 아래 SVN Service Wrapper for Windows 를 설치한다.
> SVN Service Wrapper for Windows 설치 ( http://kaistizen.net/Project/SubversionOnWindows/CustomImages/SVNService.zip )
: 윈도우 서비스 관리로 install 하는 툴이다.
    -. 설치 후 command 창에서 SVNService -install -d -r d:\repository
> PHP 설치(WEBSVN 설치를 위한) ( http://www.php.net/downloads.php )
> WEBSVN 설치 ( http://websvn.tigris.org/servlets/ProjectDocumentList )
    -.다운 받은 파일을 {APACHE_HOME}/htdocs/websvn 폴더에 복사한다.
    : {APACHE_HOME}/htdocs 은 default root 이며,
    http://localhost/ 로 접속하면 {APACHE_HOME}/htdocs/index.html 파일에 접속된다.
    : 나중에 http://localhost/websvn/ 로 접속을 하면 websvn 홈을 접속하게 되는것이다.
    > GnuWin32 Packages 설치 (WEBSVN 를 위한) ( http://sourceforge.net/project/showfiles.php?group_id=163416 )
    -. {APACHE_HOME}/htdocs/websvn/include/distconfig.inc 를 {APACHE_HOME}/htdocs/websvn/include/config.inc 로 복사.
    -. {APACHE_HOME}/htdocs/websvn/include/config.inc 의 아래문장 주석 제거.
        : 윈도우 서버인지 설정.
        $config->setServerIsWindows();
        -> 주석을 하나마나 상황이 같은데.. 모르겠음.
        : Subversion Binary와 GnuWin32 Packages의 경로 설정
        // Configure these lines if your commands aren't on your path.
        //
        $config->setSVNCommandPath("D:\\dev_kit\\Subversion\\bin");
        $config->setDiffPath("D:\\dev_kit\\GNUWIN32\\GetGnuWin32\\bin");
        // For syntax colouring, if option enabled...
        $config->setEnscriptPath("D:\\dev_kit\\GNUWIN32\\GetGnuWin32\\bin");
        $config->setSedPath("D:\\dev_kit\\GNUWIN32\\GetGnuWin32\\bin");
        // For delivered tarballs, if option enabled...
        $config->setTarPath("D:\\dev_kit\\GNUWIN32\\GetGnuWin32\\bin");
        // For delivered GZIP'd files and tarballs, if option enabled...
        $config->setGZipPath("D:\\dev_kit\\GNUWIN32\\GetGnuWin32\\bin");
        : Subversion 저장소 경로 설정
        $config->parentPath("D:\\repository");
        :웹사이트 템플릿(디자인) 선택하기
        $config->setTemplatePath("$locwebsvnreal/templates/Standard/");
        : 언어 설정
        -> LANGUAGE SETUP 을 검색하여 주석을 제거한다. 아무것도 선택하지 않으면 English가 기본값입니다.
        (한글이 제대로 되는것 같지 않음.)
        : Tarball Download 활성화
        $config->allowDownload();
        : Syntax Colorization
        $config->useEnscript();

== client ==
TortoiseSVN  ( http://tortoisesvn.net/downloads )

주의) 해봤는데, 잘 안되네요. ㅠㅠ

스트럿츠를 사용하면서 메시지 파일을 매번 native2ascii로 컴파일하기 짜증나고 귀찮으셨죠?

build.xml에 걸어놔도 결국 똑같은 파일이 2개씩 유지되는게 왠지 찜찜하지 않으신가요?

이것은 스트럿츠에서 메시지 파일을 읽어올때 사용하는 Java의 Properties 클래스가 ISO 8859-1만 지원해서 생기는 문제로, 스트럿츠의 MessageResourcesFactory를 상속받아 메시지 파일을 UTF-8로 읽도록 구현하면 해결할 수 있습니다. UTF-8은 단일 문자셋으로 여러 언어를 지원하므로 한국어 뿐만 아니라 다른 언어를 사용할때도 번거롭게 native2ascii를 사용할 필요가 없게 됩니다.

스트럿츠 1.2 코어에서 테스트했습니다. (Validiator는 안해봐서 모름)

소스는 PUBLIC DOMAIN(저작권 없음)입니다. 상업적으로 쓰던 일부만 잘라쓰던 고쳐쓰던 마음껏 쓰세요.

추가:Locale 검색하는 메소드는 스트럿츠의 코드이며 스트럿츠 코드는 아파치 라이센스입니다.

출처 : okjsp

HTTP

CODE

Associated Message

Meaning

100

Continue

클라이언트로부터 일부 요청을 받았으니 나머지 요청 정보를 계속 보내 주시오. (HTTP 1.1에서 처음 등장)

101

Switching Protocols

서버는 클라이언트의 요청대로 Upgrade 헤더를 따라 다른 프로토콜로 바꿀 것임. (HTTP 1.1에서 처음 등
장)    

200

OK

모든 것이 정상적임. GET이나 POST 요청 뒤에 문서가 온다. 이것은 서블릿의 기본 상태다. setStatus를 사용하지 않으면
이 상태코드를 얻게 된다.

201

Created

서버에서 문서를 만들었음. Location 헤더는 그 URL을 가리킨다.    

202

Accepted

요청이 수행되었지만 처리는 끝나지 않았음.

203

Non-Authoritative Information

문서는 정상적으로 반환되었지만 복사본이 사용되었으므로 응답 헤더중 일부가 정확하지 않을 수
도 있음. (HTTP 1.1에서 처음 등장)

204

No Content

새 문서 없음. 브라우저는 이전 문서를 계속 보여줘야 한다. 이것은 사용자가 페이지를 주기적으로 리로드를 하던
중 이전 페이지가 이미 만료되었을 때 사용할 수 있다. 하지만 Refresh 응답 헤더나 <META HTTP-EQUIV="Refresh" ...> 같은 헤더를 사용
해서 페이지를 자동으로 리로드 시켰을 때는 동작하지 않는다. 왜냐하면 이 상태 코드를 반환하면 추후의 리로딩이 멈추기 때문이다. 하지
만 자바 스크립트로 리로드하게 해 주는 것은 작동한다.

205

Reset Content

새 문서 없음. 하지만 브라우저는 문서 창을 리셋해야 한다. 브라우저가 CGI 폼 필드를 전부 지우도록 할 때 사용
된다. (HTTP 1.1에서 처음 등장)

206

Partial Content

클라이언트가 Range 헤더와 함께 요청의 일부분을 보냈고 서버는 이를 수행했음. (HTTP 1.1에서 처음 등장)

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번과
혼용된다. 예를 들어 <http://host/~user(> (맨 마지막에 ‘/’이 빠짐)과 같이 오류가 있는 요청에 대해 어떤 서버는 301을 어떤 서버는 302
를 보낸다.  기술적으로 브라우저는 원 요청이 GET이었다면 자동적으로 리다이렉션을 따라 가도록 되어 있다. 더 자세한 사항은 307 헤더
를 보라.      

303

See Other

301/302과 같지만 원래 요청이 POST였을 경우 리다이렉트 되는 문서(Location 헤더에 주어졌다) GET을 통해 받아
야 한다. (HTTP 1.1에서 처음 등장)

304

Not Modified

클라이언트의 캐시에 이 문서가 저장되었고 선택적인 요청에 의해 수행됨(보통 지정된 날짜보다 더 나중의 문서만
을 보여주도록 하는 If-Modified-Since 헤더의 경우). 서버는 클라이언트에게 캐시에 저장된 이전 문서를 계속 사용해야 한다고 말할 것이
다.

305

Use Proxy

요청된 문서는 Location 헤더에 나열된 프록시를 통해 추출되어야 함. (HTTP 1.1에서 처음 등장)

307

Temporary Redirect

Temporary Redirect      이것은 302 ("Found" 또는 "Temporarily Moved")와 같다. 많은 브라우저에서 메시지가 POST일 때 원래는 303 응답의 POST 요청의 리다이렉션을 따라 가야 함에도 불구하고 302의 응답을 따르기 때문에 HTTP 1.1에서 추가되었다. 303 응답은 모호하지 않도록 의도되었다. 303 응답의 경우에 대해서는 리다이렉트 된 GET과 POST 요청을 따르고 307 응답의 경우에는 GET  요청만 따른다. 몇 가지 이유로 HttpServletResponse에는 이 상태코드에 해당하는 상수가 없다. (HTTP 1.1에서 처음 등장)  

400

Bad Request

요청에 문법적으로 잘못된 부분이 있음.

401

Unauthorized

클라이언트가 올바른 허가를 받지 않고 허가가 필요한 페이지에 접근하려 함. 여기에 대한 응답으로 브라우저가 대화창을 열어 사용자 이름과 암호를 받아들이도록 하는 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 등) 를 특정 자원에 대해서는 쓸 수 없음. (HTTP 1.1에서 새로 등장)

406

Not Acceptable

지정된 자원이 클라이언트의 Accept 헤더에 명시된 것과 호환 되지 않는 MIME content-type을 생성함. (HTTP 1.1에서 새로 등장)

407

Proxy Authentication Required

401과 비슷하지만 서버가 Proxy-Authenticate 헤더를 반환해야 한다. (HTTP 1.1에서 새로 등장)

408

Request Timeout

클라이언트가 요청을 보내는 데 너무 오랜 시간이 걸림.(HTTP 1.1에서 새로 등장)

409

Conflict

보통 PUT 요청과 관계 있다. 보통 틀린 버전의 파일을 업로드할 경우 발생한다. (HTTP 1.1에서 새로 등장)

410

Gone

문서가 사라졌고 포워딩할 주소도 없음. 404와 다른 점은 이 경우 문서가 완전히 사라졌다는 것을 서버가 안다는 점이다.
404는 어떤 이유인지는 모르는데 단지 요청한 것을 사용할 수 없다는 것을 의미한다. (HTTP 1.1에서 새로 등장)

411

Length Required

클라이언트가 Content-Length를 보내지 않으면 서버가 처리할 수 없음.(HTTP 1.1에서 새로 등장)

412

Precondition Failed

요청 헤더에 설정되어 있는 어떤 조건이 맞지 않음. (HTTP 1.1에서 새로 등장)

413

Request Entity Too Large

요청된 문서가 현재 서버가 다룰 수 있는 크기보다 큼. 만약 서버에서 나중에 다룰 수 있다고 생각
되면 Retry-After 헤더를 포함시켜야 한다. (HTTP 1.1에서 새로 등장)

414

Request URI Too Long

URI가 너무 길다. (HTTP 1.1에서 새로 등장)

415

Unsupported Media Type

요청이 알려지지 않은 형태임(HTTP 1.1에서 새로 등장)    

416

Requested Range Not Satisfiable

클라이언트가 요청에 적당하지 않은 Range 헤더를 포함시켰음 (HTTP 1.1에서 새로 등장)

417

Expectation Failed

Expect 요청 헤더의 값이 맞지 않음. (HTTP 1.1에서 새로 등장)    

500

Internal Server Error

일반적인 ‘server is confused’ 메시지. 종종 CGI 프로그램이나 서블릿의 결과가 잘못되거나 적절하지 않은
헤더를 만들었을 때 발생한다.    

501

Not Implemented

요청한 것을 서버에서 지원하지 않음. 예를 들면 클라이언트가 서버에서 지원하지 않는 PUT과 같은 명령을
내렸을 때 발생한다.         

502

Bad Gateway

프록시나 게이트웨이의 역할을 하는 서버에서 볼 수 있다. 초기 서버가 원격 서버로부터 부적절한 응답을 받았음
을 나타낸다.  

503

Service Unavailable

처리할 수 있는 한계를 벗어나 과도하게 요청이 들어와서 서버가 응답할 수 없음. 예를 들면 스레드나 데이
터베이스 연결이 가득 차 있을 때 서블릿에서 이런 헤더를 반환한다. 서버는 Retry-After 헤더를 낼 수 있다.

504

Gateway Timeout

프록시나 게이트웨이의 역할을 하는 서버에서 볼 수 있다. 초기 서버가 원격 서버로부터 응답을 받을 수 없
음을 나타낸다. (HTTP 1.1에서 새로 등장)

505

HTTP Version Not Supported

서버가 요청 라인에 지정된 HTTP 버전을 지원하지 않음. (HTTP 1.1에서 새로 등장)

+ Recent posts