검색결과 리스트
글
오랜만에 포스팅을 하네요 :)
오늘은 Java를 가지고 application 프로토콜을 만드는 방법에 대해서 포스팅을 하려고 합니다.
"application 프로토콜이면, 그냥 header 와 data 구조를 정의하고 포트만 결정하면 되지 않나?" 라고 생각하실 겁니다.
이 시간에 말하고자 하는건 이런 프로토콜하고는 조금 다릅니다.
URL 에 사용되는 프로토콜(스키마)를 말하는 것입니다.
http, https, ftp 등등 이런 것들 말이죠.
cube://Hong-gildong/profile
이런식의 URL 을 만들어 보도록 하겠습니다.
Java 에서는 내부적으로 이런것이 가능하도록 지원해 주고 있습니다.
URL Class 를 보면, static 으로 URL.setURLStreamHandlerFactory(URLStreamHandlerFactory arg) 라는 메소드를 제공합니다.
안에 들어가는 파라미터인 URLStreamHandlerFactory 는 interface 로서 아래와 같습니다.
package java.net;
/**
* This interface defines a factory for <code>URL</code> stream
* protocol handlers.
* <p>
* It is used by the <code>URL</code> class to create a
* <code>URLStreamHandler</code> for a specific protocol.
*
* @author Arthur van Hoff
* @version %I%, %G%
* @see java.net.URL
* @see java.net.URLStreamHandler
* @since JDK1.0
*/
public interface URLStreamHandlerFactory {
/**
* Creates a new <code>URLStreamHandler</code> instance with the specified
* protocol.
*
* @param protocol the protocol ("<code>ftp</code>",
* "<code>http</code>", "<code>nntp</code>", etc.).
* @return a <code>URLStreamHandler</code> for the specific protocol.
* @see java.net.URLStreamHandler
*/
URLStreamHandler createURLStreamHandler(String protocol);
}
그리고 리턴해야 하는 URLStreamHandler 는 abstract 클래스 입니다.
먼저 URLStreamHandlerFactory 를 먼저 봅시다.
이름을 보면 어떤 패턴인지 감이 오시나요?
바로 '추상 팩토리 패턴'입니다.
URL 은 내부적으로 factory 라는 녀석을 가지고 있습니다.
이 녀석이 하는 일은 http, https, ftp 와 같은 protocol 을 보고, 어떤 URLStreamHandler 를 만들지 결정하는 것이지요.
바로 Factory 입니다.
cube 를 URL 이 인식하도록 URLStreamHandler 를 아래와 같이 구현해 봅시다.
public class CubeURLStreamHandlerFactory implements URLStreamHandlerFactory {
@Override
public URLStreamHandler createURLStreamHandler(String protocol) {
try {
// 내가만든 cube 프로토콜이면 CubeURLStreamHandler 를 리턴
if(protocol.equals("cube") == true) {
return new CubeURLStreamHandler();
}
// 아니라면 원래 코드 수행
String className = "sun.net.www.protocol." + protocol + ".Handler";
Class<?> type = Class.forName(className);
if(type == null) { return null; }
return (URLStreamHandler)type.newInstance();
} catch(Exception e) {
return null;
}
}
}
코드를 보시면 아시겠지만, 하는 역할이라고는 protocol 이 cube 이면, 우리가 만든(만들) CubeURLStreamHandler 를 리턴할 것입니다.
만약 그게 아니고 http, https, ftp 와 같은 것들이면, 그에 맞는 URLStreamHandler 를 리턴하는 것이지요.
switch(protocol) { case "http": return new sun.net.www.protocol.http(); break; case "https": .......}
이런식으로 해도 되는데, 귀찮아서 조금 간결하게 짠 코드입니다.
오해 없으시기 바랍니다.
자, 그럼 CubeURLStreamHandler 가 구현해야 하는 추상클래스인 URLStreamHandler 에 대해서 살펴보죠.
생각보다 간단합니다. 저게 전부입니다. 별도로 이녀석이 상속받은게 없습니다. Object 바로 아래에 있는 최상위 클래스입니다.
가장 중요한 메소드는 openConnection() 입니다. URL 이 connect 를 할때 불리는 함수이지요.
그리고 cube://Hong-gildong/profile 과 같이 cube:// 다음에 사람 이름을 쓰고 싶다면, 어떤 메소드를 override 하면 될까요?
바로 parseURL(URL, String, int, int) 입니다.
이곳에서 URL 의 Hong-gildong 부분을 가져와서 member 로 저장하고 있으면 되겠죠.
(url 의 getAuthority() 메소드를 호출하면 손쉽게 가져올 수 있습니다.)
이제 다 끝났습니다.
openConnection() 호출시, URLConnection 을 상속은 나만의 URLConnection 을 리턴하면 됩니다.
URLConnection 역시 abstract 클래스입니다.
안에 있는 중요 메소드들을 보면, connect, getOutputStream, getInputStream 정도가 되겠습니다.
getOutputStream, getInputStream 의 리턴값으로 사용할 나만의 Stream 을 만들수도 있습니다.
connect() 호출시, c:\abc.txt 라는 파일을 만들고,
getOutputStream(), getInputStream() 에서 각각 FileStream 을 리턴해 주면 어떻게 될까요?
아마 접속시 전송되는 데이타가 c:\abc.txt 에 써 지겠죠.
물론 http header 도 포함해서 말입니다.
이제 Application 을 만들고, url 을 입력받는 창을 하나 만듭니다.
그리고 이곳에 사용자가 cube://Hong-gildong/profile 이라고 치면, c:\abc.txt 에 request 가 작성되도록 할 수 있습니다.
물론 http://naver.com 이라고 치면, 정상적으로 naver.com 에 연결도 되고요.
즉, 기존 protocol 은 손대지 않고 그대로 살려두고, 새로 protocol 을 추가한 것입니다.
어떤가요?
나머지 부분은 쉽게 구현하실 수 있을거라고 믿습니다. :)
참,, 지금 설명드린 부분은 Client 쪽인데, Server 부분도 마찬가지로 '추상 팩토리 패턴'으로 되어 있습니다.
조금만 응용하시면 나만의 프로토콜을 인식하는 Server 도 만드실 수 있습니다.
오늘 포스팅은 이것으로 마치도록 하겠습니다.
퇴근해야 겠네요 ㅎ;
'Java' 카테고리의 다른 글
FolderMonitoring - 파일 변경 감지하는 방법 (0) | 2011.09.30 |
---|---|
Runtime.getRuntime().exec() 호출시 종료되지 않는 문제 (6) | 2011.06.01 |
[팁] JNI 의 jstring 을 LPCWSTR(wchar_t)로 변환하기 (0) | 2011.05.25 |
JNI 를 사용한 Folder Monitoring (1) | 2011.05.24 |
RECENT COMMENT