IT_Programming/ASP.NET (WEB)

[펌] 우편번호 XML 웹서비스(Web Services) 구축

JJun ™ 2007. 2. 11. 13:29
LONG

우편번호 XML WebServices 구축

                                      롯데정보통신

                                                                칠성IS사업팀

                                                                            용희

 

 

 

  

l        칠성 웹서버에서 가장 최신의 우편번호 XML 웹서비스를 제공하고 있다.
http://XXX.XXXX.co.kr/postcode/postcode.asmx

l        .NET을 이용하여 다른 프로그램을 원격 조종할 수 있다.

l        DTS를 이용하여 스케쥴링을 할 수 있다.

 

 

 

XML 웹서비스

 

근래들어 마이크로소프트에서는 웹서비스라는 것을 상당히 강조하고 있다. 2002년도에는 직접 빌게이츠가 한국에 와서 XML 웹서비스에 대해 강연을 하고 간 적도 있다. 그만큼 마이크로소프트에서 웹서비스라는 것에 큰 관심을 가지고 있고, 무게를 두고 있다.

그러면, 웹서비스라는 것이 무엇이고 어떤 효과가 있길레 그렇게 관심을 가지고 있는지, 이번에 우편번호 XML 웹서비스를 구축하면서 그 기능을 맛보도록 해볼 것이다.

 

웹서비스라는 것을 한다미로 말하자면, 어떤 기능을 하는 컴포넌트를 외부로 확장하여 누구나 가져다 쓸 수 있는 원격 컴포넌트라고도 할 수 있다. 예를 들면, 롯데쇼핑에서 고객들을 상대로 회원 가입을 받는 기능을 하는 홈페이지를 만든다고 하자. 그러면 반드시 필요한 것이 주소를 통해서 우편번호를 받는 기능이다. 이러한 기능은 간단히 이미 구현되어 있는 우편번호 복사해 와서 롯데쇼핑 서버에 컴포넌트를 설치해서 끌어다 쓰면 된다.

 

 

 

이러면 단순히 로컬 서버에서만 그 컴포넌트는 기능을 하게 된다. 그런데 만약 이번에는 롯

데마트에서도 회원 가입 화면을 만든다고 하자. 그렇다고 자기네도 그 컴포넌트를 복사해다가 자기 서버에 설치 한다고 하면 이는, 낭비가 될 수 있을 것이다. (물론 속도는 빠르겠지만…) 만약 우편번호가 바뀌었다고 하자, 그러면 롯데쇼핑과 롯데마트의 데이터를 모두 수정 해주어야 하는 것이다. 그래서 나온 것이 분산컴포넌트이다. 원격지에 있는 컴포너트를 이용해서 데이터의 일관성을 유지하는 방법이라고 할 수 있다. 그래서 롯데쇼핑의 컴포넌트를 쓰려고 한다고 하자. 이럴 경우에는 현재 기술로는 두 회사의 서버가 같은 환경이어야만 한다. 예를 들어 MS환경이라면 DCOM을 쓰면 될 것이고, 자바 환경이라면 CORBA를 사용하여 분산컴포넌트 기술을 사용하면 된다. 그런데 이는 결국 같은 환경이어야만 한다는 제약이 있고, 또한 컴포넌트가 통신을 하기 위해서는 별도의 포트를 열어주어야 하는 문제점이 있다.(이는 만약 방화벽이 있다면, 별도의 포트를 열어주는 것은 또 다른 보안의 위험 요소가 된다)

 

 

처음에 컴포넌트 환경의 아키텍처가 각광을 받더니, 조금 지나자 이번에는 분산 환경에서의 컴포넌트가 주목을 받았다. 그러나 이제는 XML 웹서비스가 주목을 받기 시작한 것이다. 분산 컴포넌트 시대의 단점인, 동기종간이라는 제약과, 방화벽 문제를 해결하고 태어난 것이 XML 웹 서비스 이다.

 

데이터를 XML 이라는 통일된 데이터를 사용하고 SOAP이라는 표준 프로토콜을 사용하여 이기종간에도 통신이 가능하게 했으며, 웹서버인 80포트를 이용하므로 별도의 포트를 열어주지 않아도 기존의 웹서버만으로 충분히 분산컴포넌트 환경을 구축하도록 해주는 것이 XML 웹서비스이다. , 기존의 홈페이지는 사용자를 위한 보기 위한 홈페이지이지만, XML 웹서비스는 기존의 홈페이지를 개발자를 위한 데이터 통신을 위한 홈페이지로 변질 시켜서 사용하는 것이다. 그래서 실제로 XML 웹서비스를 직접 URL을 넣고 조회해 보면 알 수 없는 XML 문서들이 주루룩 나온다. 혹자는 이것을 보고 겨우 이거야 라고 실망 할 수도 있다. 하지만 본질적으로 XML 웹서비스는 시각적인 정보를 제공하기 위함이 아닌, 데이터를 제공하기 위한 홈페이지 이기 때문이다.

 

이제 컴포넌트가 외부로 공개도 되었으니, 컴포넌트라고 부르기는 그렇고 외부에 어떤 편의를 제공하는 것이므로 서비스라는 명칭을 붙여보자. 게다가 별도의 포트가 아닌 웹을 이용하므로 웹서비스라고 부르자. 그런데 이왕이면 데이터 표현 방법으로 XML이라는 구조를 사용하므로 XML 웹서비스라고 부르면 좋을 것이다. 그래서 XML WebServices라는 용어가 태어난 것이다.

 

이러한 서비스를 이용해서 또 다른 시장을 만들 수 있을 것이다. 예를 들면, 위와 같은 우편번호 서비스 이외에도, 기업간에는 보안상 데이터를 암호화 하는 일이 있을 것이다. 이때 일반적으로는 암호화 모듈을 별도로 구매해서 설치할 것이다. 그런데 어느날 그 암호화를 풀수 있는 방법을 어떤 해커가 개발 되었다고 하자. 그러면 이번에는 개선된 암호화 모듈을 다시 설치해야 할 것이다. 그런데 이를 웹서비스로 이용하게 되면, 내부 구현은 어차피 서비스를 제공하는 쪽에서 구현할 것이므로 사용하는 사람 입장에서는 상관하지 않고 가져다 쓰기만 하면 된다. 그러므로 별도의 노력 없이도 자동으로 업데이트 된 최신의 암호화 모듈을 유지할 수 있는 것이다. 이러한 개념은 OOP의 추상화 개념과도 일맥 상통하는 부분이다. 즉 내부 구현은 숨기고, 인터페이스만 외부로 노출하는 방법인 것이다.

MS는 이러한 서비스 시장의 잠재력을 보고 그 부분을 키워가고 있는 것이다.

 

사실 이러한 서비스는 정부쪽에서 제공할 서비스가 많다. 일례로 지금 구축하려는 우편번호 서비스도 그렇고, 실명인증과 같은 서비스도 그럴 것이다. 우체국에서 우편번호를 XML 웹서비스로 제공만 해 준다면, 우리나라 전체에 각 회사 서버에 있는 우편번호 DB는 있을 필요가 없다. 모두 우체국 서버의 데이터를 가져다 쓰면 되기 때문이다. 그러면 매번 우편번호 개편이 있을때마다 각자 서버의 데이터를 업데이트 하는 일도 없을 것이다. 하지만 현실이 그렇지 못하기(사실 속도 문제와 항상 네트웍에 연결되어 있어야 한다는 문제도 있다) 때문에, 이번에 우편번호 웹서비스를 구축하려고 해보는 것이다.

 

 

 

최신 우편번호 데이터 유지

 

 

먼저 우편번호 XML 웹 서비스를 우체국이 아닌 로컬 서버에서 서비스 하기 위해서는 항상 최신의 우편번호가 있어야만 한다. 그러기 위해서는 항상 우체국 홈페이지에 접속해서 우편번호가 개편 되었는지 안 되었는지 확인해 보고 최신 데이타를 유지해야 하는 것이다. 이 부분을 컴퓨터가 알아서 자동으로 동작하게 만들어 보자.

 

아래는 우체국에서 우편번호를 다운 받아 볼 수 있는 홈페이지 이다.

http://www.koreapost.go.kr/html/postsrv/internal/postno_04.jsp?bLink=false


 

 

위 홈페이지에 접속해서 [우편번호 검색기]라는 프로그램을 이용해서 최신의 우편번호 데이터 파일을 받아 올 수 있다. 먼저 [우편번호 검색기] 프로그램을 다운 받아 설치하면 아래와 같은 ZipPro라는 프로그램이 설치 된다.

 

 

 
위 프로그램은 우편번호 정보를 로컬PC에 다운로드 받아서 검색하는 기능을 제공한다. 따라서 그 다운로드 하는 기능을 매일 일정시간이 되면 자동으로 눌러지게 하면, 항상 그 PC의 우편번호 정보는 최신 정보로 유지가 된다. 아래는 우편번호가 저장되는 폴더이다.
 

 

 
위의 파일중 post.csv 파일을 읽어서 DB서버에 SQL Server DTS기능을 이용하여 옮기면 된다. 아래는 post.csv 파일의 일부이다.
 

 

 

여기에서 [우편번호 검색기] 프로그램의 [업데이트]버튼을 자동으로 눌러주게 하는 부분은 별도의 프로그램을 만들어야 한다. 이런 전체 적인 그림을 그려보면 아래와 같다.

 

 

 

 

(1) 원격 작동 프로그램

[우편번호 검색기] 프로그램(ZipPro)을 원격으로 작동시키기 위해서는 별도의 프로그램을 따로 만들어서 작동을 시켜주어야 한다. 그 프로그램을 .NET환경에서 C#을 이용해서 만들어 보자.

다른 프로그램을 버튼을 원격으로 눌러주기 위해서는 그 프로그램의 버튼 누르는 메시지를 알아내서 그 메시지를 대신 날려주면 버튼을 누르는 효과가 난다. 그러면 그 메시지가 무엇인지 한번 훔쳐보자. 아래는 VS.NET SPY++를 이용하여 메시지를 훔쳐보는 장면이다.

 

 

 

ZipPro 프로그램의 [업데이트] 버튼의 텍스트를 확인하고, 마우스로 버튼을 눌렀을 때 어떤 메시지들이 왔다갔다 하는지 그 과정을 살펴보면 아래와 같다.


 

 

, 마우스 버튼이 눌러지는 WM_LBUTTONDOWN 메시지가 전달되는 것을 볼 수 있다. 버튼도 하나의 원도우라 할 수 있으므로 결과적으로 버튼 윈도우에 WM_LBUTTONDOWN 메시지를 날려주면 버튼이 눌러지는 것과 같은 효과를 나타낸다. 이를 C# 코딩으로 해보면 아래와 같다.

 

public static int RemoteWindow()

{

 

         EventLog myLog;

         IntPtr hParent = IntPtr.Zero;

         IntPtr hNext = IntPtr.Zero;

 

         hParent = NativeWIN32.FindWindow(null,"우편번호 검색 및 다운로드 프로그램");

         if ( hParent.Equals(IntPtr.Zero) )

         {

                  myLog = new EventLog();

                  myLog.Source = "우편번호 프로그램";       

 

                  myLog.WriteEntry("우편번호 검색 프로그램이 실행중이 아닙니다.", EventLogEntryType.Error);

                  return 0;

                 

         }

 

         do

         {

                  hNext = NativeWIN32.FindWindowEx(hParent,hNext,null,IntPtr.Zero);

 

                  // we've got a hwnd to play with

                  if ( !hNext.Equals(IntPtr.Zero) )

                  {

                           // get window caption

                           NativeWIN32.STRINGBUFFER sTitle;

                           NativeWIN32.GetWindowText(hNext, out sTitle, 256);

 

                                           

                           if ( sTitle.szText == "업데이트" )

                           {

                                   Console.WriteLine("found");

                                   NativeWIN32.SendMessage(hNext, NativeWIN32.WM_LBUTTONDOWN, 0, IntPtr.Zero);

                                   NativeWIN32.SendMessage(hNext, NativeWIN32.WM_LBUTTONUP, 0, IntPtr.Zero);

 

                                                    

                                   return 1;

                           }

                  }

         }

         while (!hNext.Equals(IntPtr.Zero));

 

         myLog = new EventLog();

         myLog.Source = "우편번호 프로그램"; 

         myLog.WriteEntry("우편번호 자동 업데이트 실패.", EventLogEntryType.Error);

 

         return 0;

}

 
 

.NET CLR에서는 WINDOWS API 기능을 모두 제공하는 것이 아니기 때문에 윈도우 내부 컨트롤을 하기 위해서는 윈도우 API를 직접 끌어다가 써야 한다. 아래는 그 부분의 일부이다.

 

[DllImport("user32.dll", CharSet=CharSet.Auto)]

public static extern int SendMessage(IntPtr hWnd, int msg, int wParam, int lParam);

 

[DllImport("user32.dll", CharSet=CharSet.Auto)]

public static extern IntPtr SendMessage(IntPtr hWnd, int msg, int wParam, IntPtr lParam);

 

 

[DllImport("user32.dll", CharSet=CharSet.Auto)]

public static extern bool EnumThreadWindows(int threadId, EnumThreadProc pfnEnum, IntPtr lParam);

 

[DllImport("user32.dll", CharSet=CharSet.Auto)]

public static extern IntPtr FindWindowEx(IntPtr parent, IntPtr next, string sClassName, IntPtr sWindowTitle);

 

[DllImport("user32.dll", CharSet=CharSet.Auto)]

public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

 

[DllImport("user32.dll", CharSet=CharSet.Auto)]

public static extern int GetWindowText(IntPtr hWnd,  out STRINGBUFFER ClassName, int nMaxCount);

 

 

현재 바탕화면에 실행중인 프로그램 중, 윈도우 텍스트가 [우편번호 검색 및 다운로드 프로그램] 인 것을 먼저 찾는다. 그러한 윈도우를 찾은 후, 그 내부에서 또 윈도우 텍스트가 [업데이트] 인 것을 찾아서, 그 윈도우에 WM_LBUTTONDOWN 이라는 마우스 누름 메시지를 날려주면 그 프로그램은 업데이트 버튼을 눌러지는 동작을 하게 된다.

 

 

(2) DTS를 이용한 스케쥴링과 DB 복사

위 원격 프로그램을 이용하여 최신의 우편번호 데이터 파일 post.csv을 받았다면, 이를 이제는 DB에 넘기야 한다. 그러기 위해서는 DTS를 이용하면 간단히 해결할 수 있다. 또한 매일 일정 시간이 되면 이 원격 프로그램이 자동으로 실행이 되고 DTS도 작동 되어야 하므로 이를 하나의 DTS 작업으로 묶어서 스케쥴링을 걸어주면 매일 자동으로 업데이트를 수행 한다. 아래는 DTS 작업 흐름도 이다.
 

 

 

우편번호 원격 프로그램을 실행시키고 그 프로그램이 성공 코드를 리턴 했을 때에만 기존 우편번호 데이터를 삭제하고 post.csv 파일에서 데이터를 읽어서 DB에 쏟아 붓는 작업을 한다.

 

이때 이 작업을 매일 하는 것은 낭비가 될 수 있다. 우편번호 파일이 변했을 때에만 이 작업 하는 것이 효과적일 것이다. 그래서 원격 프로그램에서 그 체크를 미리 하고, 변하지 않았을 때에는 실패 코드를 리턴해서 전체 작업을 중지 시키고, 새로운 우편번호 데이터가 들어 왔을 때에만 전체 작업을 수행해야 한다. 이를 체크하기 위해서는 post.csv 파일이 최신 파일인지 아닌지를 구분해야 하는데, 그 파일보다는 함께 받아지는 다른 작은 사이즈의 파일을 이용하는 것이 더 효과적이기 때문에 postver.txt 파일을 이용하여 비교를 할 것이다. 아래는 postver.txt 파일의 내용이다.
 

 

  

최신 버전의 데이터를 받게 되면 위 내용 중 날짜 부분이 바뀌게 된다. 따라서 이 파일 내용이 변경이 되었는지 안 되었는지를 비교하면 되므로, 기존의 postver.txt 파일을 따로 postverold.txt 파일명으로 복사해 두고, postver.txt 파일을 새로 받을 때 마다 postverold.txt 파일과 비교를 하고 다르면 신버전임이 맞으므로 postver.txt 파일을 postverold.txt 파일에 overwrite를 하고 성공 코드를 리턴해 주면 된다.

 

이러한 DTS 작업을 한 후 DB에 우편번호 데이터를 기록하게 되는데, 그 구조는 아래와 같다.

 

 

 

이제 이를 XML 웹 서비스로 제공하면 된다.

 

 

 

 

우편번호 XML 웹 서비스

아래 주소로 XML 웹서비스를 사용해 보자.

 

http://XXX.XXXXX.co.kr/postcode/postcode.asmx

 

 

 

위 주소는 외부로 공개된 주소 이므로, 롯데 전계열사에서 우편번호 XML 웹서비스를 제공받을 수 있는 주소이다.

 

먼저 내부적으로 테스트를 해보면, GetAddress함수는 매개변수로 을 받는다. 그러면 그에 해당하는 우편번호 리스트를 리턴해 준다. 아래는 내부에서 실행한 화면이다.

 

 

 

 

질의문으로 [쌍문2]이라는 질의문을 보냈고, 결과문으로 쌍문2동의 모든 우편번호를 XML 데이터로 받았다.

 

이는 .NET을 이용하면 손쉽게 구현할 수 있다.

아래는 위 웹서비스의 소스이다.

 

[WebMethod]

                  public DataSet GetAddress(string strDong)

                  {

                           try

                           {

                                   dbConn = new SqlConnection("server=XXX.XXX.XX.XXX; uid=XXXX; pwd=XXXX; database=XXX;");

                                   SqlDataAdapter sqlCmd = new SqlDataAdapter( "SAPAddressQry " + strDong , dbConn );

 

                                   DataSet ds = new DataSet();

                                   sqlCmd.Fill(ds);

                                   return ds;

                           }

                           finally

                           {

                                   dbConn.Close();

                           }

                 

                          

                  }

 

 

마치면서

우편번호 XML 웹서비스라는 것을 우체국 서버에서 바로 서비스 해주면 가장 좋겠지만, 현실이 그렇지 못하기 때문에 칠성 웹서버에서 서비스를 제공하도록 설치를 해두었다. 이제 롯데 전계열사에서는 칠성 웹서버(http://XXX.XXXXX.co.kr/postcode/postcode.asmx

)에 접속해 오면 가장 최근의 우편번호 서비스 데이터를 XML 형식으로 받아 갈 수 있다.
ARTICLE

출처: http://blog.naver.com/woom333?Redirect=Log&logNo=60024962856&vid=1000589087

 

2004년 10월 우편번호를 위한 XML Web Service를 만들었다.

앞으로 우편번호를 가져올 때는 매번 서버의 오래된 우편번호를 가져올 것이 아니라,

이것을 이용하라고 했다.

 

이 프로그램을 서버에 설치하면 자동으로 하루에 한번씩 우체국 서버에 접속하여 최신의

데이터를 가져와서 유지하므로 이 웹서비스를 어떤 프로그램에서는 가져다가 쓰면 된다.

또한 그룹의 전계열사에서도 가져다 쓸 수 있으므로 그룹 전체가 하나의 우편번호를 공유할

수 있는 것이다.

 

하지만 그 당시 전산실장님이 우리 웹 주소가 외부에 노출이 된다며 반대를 했다.

그래서 결국 채택을 안했다. 이 역시 개발하라고 시킨 것이 아니라 내 나름대로 업무 개선을 위해

개발한 것이라서 포기했다.

 

대신 매번 새로운 우편번호가 바뀔때 마다 해당 인사팀 담당자가 수동으로 우편번호를

지금까지도 업데이트 하고 있다.

 

아래 문서에 보면 우편번호 자동 업데이트를 위한 프로그램을 SPY++을 이용해서

윈도우 메세지를 분석해서 그 메시지를 사용하는 방법이 나와있다.

 

편의상 우편번호 웹서비스 웹사이트는 현재 운영하지 않으므로 XXX 처리를 하였다.