반응형
반응형
반응형
StringTokenizer 와 String.split()
가끔씩 StringTokenzer를 사용해서 문자열을 분해 할 때 특정 요소의 값이 없을 경우 처리하는 것에 대한 질문을 받아서 문자열을 특정 구분자를 기준으로 분해 하는 것에 대해 정리를 해봤습니다.

jdk1.4.x를 기준으로 정리한 것입니다.

잘 못 된 부분이 있으면 지적 해주십시요.

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

특정 구분자(경계기호:Delimter)를 기준으로 문자열을 분해 할 때 흔히 사용하는 방법이 java.util.StringTokenizer를 이용해서 분해를 하거나 jdk1.4대에 새로 추가 된 java.lang.String.split(String regex)을 사용하는 방법입니다.



이들 둘은 "문자열에서 특정 구분자를 기준으로 문자열을 분해 한다"는 기본 기능은 같지만 그 결과는 "분해 할 문자열이 어떻게 구성이 되어 있느냐"에 따라서 서로 다른 결과값을 도출합니다.



예를 살펴보기 위해서 다음과 같은 가정을 하겠습니다.

분해 할 문자열은 "아이디, 이름, 전자우편주소,휴대전화"로 구성 된다.
"아이디, 이름" 이외의 항목은 있을 수도 있고 그렇지 않을 수도 있다.
각 항목을 구분하는 구분자는 ","로 한다.
1. 먼저 각 항목이 모두 존재 하는 경우를 살펴 보겠습니다. 이 경우라면 다음과 같은 형태가 될 것입니다.

neoburi,inkuk,neoburi@neoburi.com,019-366-5815
이 경우는 다음과 같이 분해를 할 수 있을 것입니다.

String str = "neoburi,inkuk,neoburi@neoburi.com,019-366-5815";

String[] values = str.split(",");

또는,

StringTokenizer values = new StringTokenizer( str, "," );

이 때에는 String.split(String regex)이나 StringTokenizer의 결과 값은 같게 나옵니다.



그런데 문제는 이렇게 모든 항목이 존재하지 않는 경우가 있을 때입니다.




2. 일부 항목만으로 문자열이 구성 된 경우를 살펴 보겠습니다.



예를 든다면 다음과 같은 값을 가질 때겠지요.

"아이디,이름,,전화번호" 일 경우
"아이디,이름,전자우편," 일 경우
또는 "아이디,이름,," 일 경우
1) "아이디,이름,,전화번호" 일 경우를 살펴 보겠습니다.

문자열은 다음과 같이 구성이 될 것입니다.



String str = "neoburi,inkuk,,019-366-5815";



String[] values = str.split(",");을 사용 할 경우 해보면 결과는 아래와 같습니다.
for( int x = 0; x < values.length; x++ ){

System.out.println( "문자(열) " + (x+1) + " : " + values[x] );

}



결과 :

문자(열) 1 : neoburi

문자(열) 2 : inkuk

문자(열) 3 :

문자(열) 4 : 019-366-5815



StringTokenizer tokens = new StringTokenizer( str, "," );를 사용 할 경우
for( int x = 1; tokens.hasMoreElements(); x++ ){

System.out.println( "문자(열) " + x + " : " + tokens.nextToken() );

}



결과 :

문자(열) 1 : neoburi

문자(열) 2 : inkuk

문자(열) 3 : 019-366-5815



결과와 같이 split(String regex)을 이용한 경우에는 비록 값이 존재하지 않더라고 해당 데이터가 없다는 것을 확실하게 판단을 할 수 있습니다. 즉 구분자를 기준으로 데이터가 없는 부분도 그 결과를 반환해준다는 얘기지요.



그렇지만 StringTokenizer는 비록 구분자로 문자열간 구분이 되어 있더라도 구분자와 구분자 사이에 데이터가 존재하지 않으면 (",,"의 경우) 해당 데이터는 무시를 하고 실제 값이 존재하는 부분만 값을 반환합니다.



두 결과 사이에는 많은 차이가 남을 볼 수 있습니다.

2) "아이디,이름,전자우편," 일 경우

이 역시 문자열은 다음과 같이 구성이 될 것입니다.



String str = "neoburi,inkuk,neoburi@neoburi.com,";



String[] values = str.split(",");
for( int x = 0; x < values.length; x++ ){

System.out.println( "문자(열) " + (x+1) + " : " + values[x] );

}



결과 :

문자(열) 1 : neoburi

문자(열) 2 : inkuk

문자(열) 3 : neoburi@neoburi.com



StringTokenizer tokens = new StringTokenizer( str, "," );
for( int x = 1; tokens.hasMoreElements(); x++ ){

System.out.println( "문자(열) " + x + " : " + tokens.nextToken() );

}

결과 :

문자(열) 1 : neoburi

문자(열) 2 : inkuk

문자(열) 3 : neoburi@neoburi.com



위에서 보는 바와 같이 분해하고자 하는 문자열의 마지막 요소가 존재하지 않을 경우 String.split(String regex)과 StringTokenizer는 같은 결과를 보여줍니다.



두 결과사이에는 차이가 없음에도 불구하고 잃어 버리는 데이터가 생겼습니다. 개발자는 분명히 사용자의 정보로부터 4개의 항목을 얻어 표현을 하고 싶지만 그렇게 할 수가 없습니다. 물론 어거지로 한다면 가능은 하겠지만요.^^



그러면 String.split(String regex)과 StringTokenizer를 사용 하더라고 분해하고자 하는 마지막 항목이 없을 경우는 분해 할 방법이 없을까요? 그렇지 않습니다.



API를 어느정도 보신 분들이라면 아마 "그것은 이렇게 하면 되지!"라고 속으로 생각 하실 겁니다.



java.lang.String클래스에는 split()메소드가 2개가 있습니다.

하나는 split( String regex )이고
다는 하나는 split( String regex, int limit )입니다.
String.split( String regex, int limit )를 사용해서 분해를 해보겠습니다.

String[] values = str.split(",", 4);
for( int x = 0; x < values.length; x++ ){

System.out.println( "문자(열) " + (x+1) + " : " + values[x] );

}



결과 :

문자(열) 1 : neoburi

문자(열) 2 : inkuk

문자(열) 3 : neoburi@neoburi.com

문자(열) 4 :



비록 마지막 분해 요소의 값이 존재하지 않더라고 split( String regex, int limit )를 이용하면 고스란히 원하는 형태의 데이터를 얻는 것을 볼 수 있습니다.


StringTokenizer의 경우는 구분자 사이에 분해할 요소의 값이 존재하지 않으면 무시하게 되어 있습니다. 완전하게 모든 요소의 값이 존재하는 경우라면 사용을 해도 되겠지만 예에서 본 바와 같이 가변적인 데이터라면 사용하기 불편한(?) 것이 사실입니다.




String.split()의 경우 limit를 저정 하지 않았을 경우에는 제일 마지막에 오는 요소의 값이 없을 경우 그 요소를 무시하도록 되어 있습니다. 이 역시 데이터가 정형화 되어 있는 경우라면 사용해도 무리 없겠지만 가변요소가 존재 한다면 StringTokenizer와 크게 다를 게 없습니다.



대신 limit를 지정 했을 경우 해당 숫자만큼만 분해를 합니다. limit는 분해를 한 후 얻고자 하는 String[]의 요소크기라고 보시면 됩니다.

limit가 분해하고자 하는 요소의 개수와 같거나 클 경우 요소의 개수만큼의 String[]을 되돌려 주지만, 요소의 개수보다 작을 경우 지정한 숫자만큼의 String[]으로 되돌려 줍니다.

반응형

'프로그래밍 > Java' 카테고리의 다른 글

[이클립스] JVM 메모리 용량 세팅  (0) 2009.02.11
[JSTL] 사용법  (0) 2009.02.11
JSTL fmt  (0) 2009.02.11
배열 정렬.  (0) 2009.02.11
UTF-8 개발에 관한 정리  (0) 2009.02.11
반응형
JSTL

날짜 포멧..
<fmt:parseDate value='2007-11-11' var='contStartDate' pattern='yyyy-MM-dd'/>
<fmt:formatDate value='${contStartDate}' pattern='yyyyMMdd'/>



숫자 포멧.
<fmt:formatNumber type="number" maxFractionDigits="0" minFractionDigits="0" value="${item.price}" />

반응형

'프로그래밍 > Java' 카테고리의 다른 글

[JSTL] 사용법  (0) 2009.02.11
StringTokenizer 와 String.split()  (0) 2009.02.11
배열 정렬.  (0) 2009.02.11
UTF-8 개발에 관한 정리  (0) 2009.02.11
Request 내부 객체  (0) 2009.02.11
반응형
배열 정렬 함수.

ex)

String[] arr;

Arrays.sort(arr);

오름차순으로 정열됨.

^^

반응형

'프로그래밍 > Java' 카테고리의 다른 글

StringTokenizer 와 String.split()  (0) 2009.02.11
JSTL fmt  (0) 2009.02.11
UTF-8 개발에 관한 정리  (0) 2009.02.11
Request 내부 객체  (0) 2009.02.11
JSP 액션, 선언, 스크립트릿  (0) 2009.02.11
반응형
UTF-8 개발에 관한 정리입니다.

1. 모든 문서는 UTF-8 인코딩으로 저장되어야 합니다.

에디트 플러스의 경우 도구 -> 기본설정 -> 파일 부분에서 새 파일 형식을

UTF-8 로 해놓음으로써 새파일 작성시 UTF-8을 기본으로 작성할수 있고,

이미 다른 인코딩 타입에서 작성된 문서인 경우 내용을 모조리 Ctrl+C로 복사후

문서 -> 인코딩 변경 로드에서 UTF-8로 변경후 다시 붙여넣기 하면 됩니다.

 

이클립스의 경우 Package Explorer 에서 프로젝트에서 우측 버튼을 누른 후

Properties->Info->Text file encoding->Other 을 UTF-8 로 잡아주면 됩니다.

( 기존 다른 인코딩 타입에서 작성된 문서 내부 한글은 모조리 깨지게 됨 )

 

* ascii 로 작성된 자바스크립트 파일을 utf 문서에서 불러와 수행시킬 경우

자바스크립트 에러 나는 문제도 있더군요.(한글 주석이 영향을 줬을수도...)

 

2. jsp 파일 상단에는 다음과 같은 방식으로 UTF-8 설정합니다.

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

 

3. 서블릿은 다음과 같은 방식으로 UTF-8을 설정합니다.

request.setCharacterEncoding("utf-8")

 

4. 자바스크립트에서 encodeURIComponent 처리 및 톰캣 server.xml 의 설정 변경

위 1,2,3번의 방식으로 하면 post 방식의 데이터는 잘 받지만

get 방식의 데이터는 한글이 깨집니다.

이와 같은 경우 자바스크립트의 encodeURIComponent 함수와

server.xml 을 이용하여 처리하면 됩니다.

 

4.1 server.xml

톰캣 폴더의 conf 폴더에는 server.xml 파일이 존재합니다.

에디터로 열어보면

 

예)

    <Connector port="8080" maxHttpHeaderSize="8192"
               maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
               enableLookups="false" redirectPort="8443" acceptCount="100"
               connectionTimeout="20000" disableUploadTimeout="true" />

 

값이 약간 틀릴수 있지만 초기 셋팅 값이 보통 저러하고,

Connector 은 초기에 2개가 있는데 8080 포트 부분을 수정하면 됩니다.

수정하는 방법은

URIEncoding="UTF-8" 을 추가하면 됩니다.

 

예)

    <Connector port="8080" maxHttpHeaderSize="8192"
               maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
               enableLookups="false" redirectPort="8443" acceptCount="100"
               connectionTimeout="20000" disableUploadTimeout="true" URIEncoding="utf-8" />

 

위와 같이 했다고 해결되는 것은 아닙니다. get 방식으로 데이터를 전송하면

자바 파일에서 확인 했을 경우 물음표 값만 넘어옵니다.

 

get 방식으로 보낼 경우 자바스크립트로 변환을 해줍니다.

예를 들어 "한글"을 자바스크립트에서

<SCRIPT>alert( encodeURIComponent("한글") )</SCRIPT>

처럼 encodeURIComponent 함수로 변환하게 되면 %ED%95%9C%EA%B8%80 으로

변환됩니다. 이 값을 주소에 "한글" 대신에 넣게 되면 자바에서 알아서 잘~ 받습니다 ^^

 

5. HttpURLConnection 을 통하여 UTF-8 로 된 URL 을 읽을 경우.

다른 부분은 동일하고, 

BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));

로 변경합니다.

 

6. jsp -> bean 데이터 전송은 문제 없지만 jsp -> jsp 에서 한글이 깨진다면

받는 부분에서

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

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

처럼 변환해서 저장합니다.

 

ps. 참고 사이트

http://cafe.naver.com/phpinfo.cafe?iframe_url=/ArticleRead.nhn%3Farticleid=434


반응형

'프로그래밍 > Java' 카테고리의 다른 글

JSTL fmt  (0) 2009.02.11
배열 정렬.  (0) 2009.02.11
Request 내부 객체  (0) 2009.02.11
JSP 액션, 선언, 스크립트릿  (0) 2009.02.11
파일 다운로드 구현할때 한글 이름 깨지는 문제..  (0) 2009.02.11
반응형
♣ request 내부객체

HTTP 요청이 있을 때 발생하는 모든 정보와 이 정보를 얻어 낼 수 있는 여러가지 기능을 하는 객체가 바로 request 객체입니다.
이 객체는 response와 더불어 _jspService의 매개변수역할을 하며, Server Page 프로그램에서 가장 기본이 되는 객체입니다.

HTTP 프로토콜로 사용자 요청이 있을 때 요청된 메세지는 HTTP 헤더 부분과 HTTP 몸체 부분으로 나뉘어 집니다.
HTTP 메시지 자체의 목적지가 Java Server Page라면 JSP는 HTTP 메세지 전부를 이용하여 HttpServletRequest 객체를 생성하게 되며, 이것을 _jspServer 메서드내에서 매개변수로 넘겨받게 되는 것입니다.
코딩을 할때, 가장 많이 사용하게 될 request.getParameter()라는 메소드가 여기에 해당됩니다.
Request 객체에는 request.getParameter() 말고도 많은 메소드가 있으며, 메소드의 종류는 아래 표와 같습니다.

⊙ 클라이언트가 넘겨주는 파라미터에 관련된 정보를 얻는 메서드

메소드
설명
public Enumeration getParameterNames()
모든 요청 매개변수의 이름을 Enumeration으로 반환한다.
public String getParameter( String name )
해당 이름값에 해당하는 매개변수의 값을 반환한다.
지정된 이름의 파라미터가 존재하지 않을 경우 null을 반환한다.
public String[] getParameterValues( String name )
해당 이름값에 해당되는 매개변수의 모든 값을 String 배열로 반환한다.

⊙ HTTP 헤더와 관련된 메소드

메소드
설명
public String getHeader( String headerName )
HTTP요청 헤더에 지정된 headerName의 값을 문자열로 반환한다.
HTTP요청헤더에 headerName헤더가 존재하지 않는 경우 null을 반환한다.
public Enumeration getHeaderNames()
HTTP요청 헤더에 포함된 모든 헤더의 이름을 Enumeration으로 반환한다.
public Enumeration getHeaders( String headerName)
HTTP요청 헤더에 포함된 headerName헤더의 모든값을 Enumeration으로 반환한다.
public int getIntHeader( String headerName )
HTTP요청헤더에 포함된 headerName헤더의 값을 int로 반환한다.
지정된 headerName헤더의 값을 int로 변환할 수 없는 경우 NumberFormatException이 발생하고, headerName헤더가 HTTP요청헤더에 존재하지 않는 경우에는 -1 값을 반환한다.
public long getDateHeader( String headerName )
HTTP요청헤더에 포함된 headerName헤더 값을 1970년 1월 1일 00시 00분 기준으로 현재까지의 밀리초를 long형으로 반환한다.
HTTP요청 헤더에 headerName헤더가 존재하지 않은 경우 -1을 반환한다.
headerName헤더를 long형 숫자로 변환자지 못할 경우 IllegalArgumentException을 발생시킨다.  
getCookies()
요청에 대한모든 쿠키를 반환한다.

⊙ 세션데이터에 관련된 메서드

메소드
설명
public HttpSession getSession()
요청을 시도한 클라이언트에 지정된 HttpSession객체를 얻어낸다.
이전에 생성된 HttpSession객체가 없었다면 새로운 세션 객체를 생성하게 된다.
public HttpSession getSession( boolean create )
요청을 시도한 클라이언트에 지정된 HttpSession 객체를 얻어낸다.
create가 false로 지정된 경우 해댱 클라이언트에 대해 생성 된 HttpSession객체가 없는 경우 null을 반환한다.
create가 true로 지정된 경우 이미 존재하는 경우 생성된 HttpSession객체를 리턴하고 해당 클라이언트에 생성된 HttpSession객체를 리턴하고 해당 클라이언트에 생성된 HttpSession객체가 없으면 새로운 HttpSession객체를 생성하여 반환한다.
public String getRequestedSeeionId()
요청을 시도한 클라이언트이 세션 id를 문자열로 반환한다.
public String isRequestedSessionIdValid()
요청에 포함된 클라이언트이 세션id가 유효하면 true아니면 false를 반환한다.
isRequestedSessionIdFromCookie()
요청에 포함된 클라이언트이 세션 id가 쿠키로부터 전달된 경우 true 아니면 false를 반환한다. 

⊙ 기타 메소드

메소드
설명
getRequestURI()
요청에 사용된 URL로부터 URI부분을 문자열로 반환한다. 
getMethod()
요청에 사용된 요청방식 GET, POST 등을 문자열로 반환한다.
getRequestURL()
요청 URL을 반환 한다.(질의 문자열은 안 한다.)
getQueryString()
요청 URL을 반환 한다.( 질의 문자열 포함)
getRequestDispatcher(path)
Path에 지정된로컬URL에 대한 요청 전달자를 반환한다.
getRemoteHost()
요청을 보낸 호스트의 이름을 반환한다.
getRemoteAddr()
요청을 보낸 호스트의 IP를 반환한다.
getRemoteUser()
요청을 보낸 사용자의 이름을 반환한다.

사용 예) String name = request.getParameter(“name”);

반응형

'프로그래밍 > Java' 카테고리의 다른 글

배열 정렬.  (0) 2009.02.11
UTF-8 개발에 관한 정리  (0) 2009.02.11
JSP 액션, 선언, 스크립트릿  (0) 2009.02.11
파일 다운로드 구현할때 한글 이름 깨지는 문제..  (0) 2009.02.11
자바용 nl2br  (0) 2009.02.11

+ Recent posts