2009년 12월 22일 화요일

2000년 이후 IT산업 10대 사건

지난 시간에 대한 이야기이니 한 편의 역사이다.


역사라고 하기엔 너무나도 짧은가? 하지만 지난 100년의 역사보다 2000년 이후의 10년의 역사가 휠씬 많은 사람들에게 다양한 영향력을 행사했다.
읽다보면 꼭 먼 옛날의 역사를 읽고 있다는 느낌이 들 정도이다.
하지만 고작 10년 동안 있었던 사건이고, 그 시대를 나도 살아갔다는 것이다.

구글 - 검색엔진, 쇼설 비지니스, 애플 - 아이폰, 아이튠즈
로 대변할 수 있는 지난 10년이다.

향후 10년은 또 누가 어디서 역사를 만들어갈까?

2009년 12월 14일 월요일

박원순 변호사님 명함 득탬하다!

회사 동료들과 저녁을 먹고 잠시 소담을 나누던 중,
식당 입구에서 수수한 마이차림의 낮익은 듯한 모습이 순간 눈에 들어왔다.

순간!! 내 눈을 잠시 의심하며 다시금 보았는데, 분명히 박원순 변호사님이었다.
'어~~' 하고는 회사 동료들에게 박원순 변호사님을 봤냐고 물었더니 아무도 본 사람이 없었다...ㅡㅡ;;

'잘못 봤나...' 하면서 다시금 생각해 보고 있는데, 분명 사진이나 동영상으로 본 그대로(?)의 모습이었다.
회사 동료들이 일어나자고 하길래 혹시나 하는 마음에 찾아봐야지... 하고는
걸어나가는데 바로 앞에 정말로 박원순 변호사님이 자리하고 있었다...ㅎㅎ

수수하면서도 떼 묻지 않고, 겸손한 듯한 늘~~ 매체를 통해서 보았던 모습이었다.
흠... 용기를 내어서 고개를 숚여 인사를 하니 통화를 하는 중이셨는데도 반갑게 인사를 해 주셨다.
조용히 '혹시 박원순 변호사님이세요?' 물었더니 환하게 웃으시면서 고개를 끄덕이시고는 자리에서 일어나셔서 악수도 청하셨다.
히야... 신기한 것이 정말 오랫동안 알고 지내던 동네 아저씨(친하게 지내던 지인)를 만나는 기분이었다. 덕분에 멋젆게 인사도 하고 '아~ 여기서 일하세요? 전 여기 처음인데 정말 대단한 곳이더라구요...' 하면서 구로/가신 지역엔 처음이어서 그렇다고 하셨다.

소탈하면서도 다정하게 맞아주시고 누구에게나 알려진 분 같지 않게 반갑게 맞아주셨다^^
그리고는 어색할 수도 있는 풍경이었는데, 회사 동료들과 저녁을 먹으로 왔다고 답변하고는 맛있게 식사하시라고 앉기를 권해드렸다.
좀... 아쉬운 마음이 들어 잠시 용기를 내어 '저.. 혹시 명함 한 장 주실 수 있으세요?' 라고 물었더니 흔쾌히 '그럼요' 하시면서 '회원 가입하세요~' 하셨다. 아무래도 '아름다운 재단'을 말씀하시는 거겠지?

덕분에 명함을 득탬하고는 기분 좋게 식당을 나올 수 있었다. 회사내 동료들이 아무도 박원순 변호사를 모르길래 잠시 이야기 해 주고, 좋은 분을 소개하는 것도 조금 더 아름다운 세상을 만들어가는 것이 아닐까?^^

오늘 나... 횡재했다ㅋㅋ 흠... 청소년들이 연애인을 만나면 이런 기분일까?^^;;

2009년 12월 11일 금요일

옷걸이 독서대 - 이름은 '북스탠드업', 아이폰 거치대

피자가게 사장님 염치홍님께서 만든 독서대이다.
우연히 블로그를 통해서 알게된 것인데 참 재미있다.
나도 집에가서 만들어볼 예정이다^^



더불어 위의 블로그에서 소개하는 아이폰 거치대 동영상을 소개한다.


우와~~ 볼수록 아이디어가 좋다. 이런건 특허가 안 되나?ㅋㅋ

2009년 12월 10일 목요일

구글의 미래기술 소개

이미 뉴스나 각종 블로그를 통해서 캘리포니아 마운틴뷰 컴퓨터 박물관에서 발표한 구글의 미래기술에 대한 소개를 많이들 접했을 것이다.
정보란 것이 너무 많은 것을 접해도 혼란을 가중할 수도 있는 터...

그래서 이에 대한 나름의 정리를 해 보고자 한다.
먼저 구글 공식 블로그를 통해서 나오기 전에 이미 뉴스와 블로거들은 이에 대한 소개를 하고 있었다.


많은 위의 블로그를 처음 접해본 사람은 놀라지 않을 수 없을 것이다. 물론 우리가 한번 쯤은 상상해 본 적이 있는 생활상의 첫 모델을 직접볼 수 있는 기회다.

요즘은 블로거들이 뉴스의 속도를 이기는 시대이니 이미 많은 블로그에서 소개하고 있다. 찾아보는 것도 좋을 듯 하다.
그리고 다음은 일간시 인터넷 신문에도 해당 내용을 기사화하고 있는 링크이다.


재밌는 사실은 기사의 내용이다 보니 사실에 많이 입각해서 쓰고 있다. 인터넷 특성상 블로그처럼 동영상도 소개해 주면 좋을텐데... 하는 아쉬움이 나온다.

구글의 미래기술의 소개이면서 해당 기술에 대한 내용은 이번 포스팅에서 하나도 없다. 전부 링크를 따라서 가보면 볼 수 있다.
내용들을 전부 읽어보고 생각해 보니 또 나의 생각을 담을 경우에는 길어지기도 하고(^^), 사실에 입각한 내용이 더 중요한 것을 놓칠 수 있을거란 생각이 들어서이다.

자, 그럼 이제 구글 공식 블로그를 통해서 해당 내용을 소개하고 있는 것을 살펴보자.


구글스럽게도 제목도 거창하다. 하지만 확실히 지금은 PC 시대를 넘어서고 있다. 이미 우리나라도 노트북이 테스트탑 시장을 거의 넘어서고 있고, 아이폰을 시점으로 스마트폰이 대세를 이루어가고 있는 형국이다.

그리고 말그대로 스마트한 이 손 안의 핸드셋이 그동안 상상으로만 여겨졌던 일들을 하나씩 앞당기고 있는 것이다.
더군다나 언젠가는 보게 되겠지... 하는 기술이 구글에 의해서 그 시기가 앞당겨지고 있는 느낌을 지울 수 없다. 물론 누군가가 개발하겠지... 하던 것이 거대한 자본과 기술, 뛰어난 사람들을 통해서 앞당겨지고 있는 것이다.(좋은 것도 있고 나쁜 것도 언제나 발생하겠지...)

더불어 한 가지만 더 소개하자. 구글이 소개하고 있으니...


검색이 더 이상 어떻게 발전할까? 하는 안일한 생각이 국내 포털 또는 기술 업체들이 하고 있을 때 구글은 페이지랭크 개념을 이용한 검색엔진으로 세상을 바꾸었다.
이런 사례를 보고도 국내 포털이나 검색기술을 가진 업체들은 여전히 기술이나 새로운 서비스 면에서도 많이 뒤쳐진 느낌이다. 국내 시장에 어울리는 서비스도 좋치만 미래를 선도하는 기술을 선보일 수는 없을까?

결국 구글은 이렇게 또 앞서가고 있다!!

다음은 이번 포스팅에서 소개한 기술들에 대한 동영상이다. 유튜브도 구글 소유이다...ㅎㅎ

실시간에 가까운 음성번역

비주얼 검색기능, 구글 고글스(Google Goggles)

실시간 검색기능


세상은 우리가 상상해 보고 영화로만 보았던 것이 현실화되어 가고 있다... 곧 철학의 부재에 대한 논의도 언제나 따라오겠지? 언제나 기술을 다루고 있지만 인문과 철학의 부재를 고민하던 1인이 글을 남겨본다.

2009년 12월 6일 일요일

안드로이드의 다양한 이미지 소개

블로거님께서 어디서 찾으셨는지는 모르지만 정말 많은 안드로이드 이미지들이 있다^^



2009년 12월 1일 화요일

사내 아이폰 열풍

아이폰 열풍이 국내 모바일 시장을 뒤흔들고 있다.
그리고 그 여파가 우리 회사에서도 미치고 있다.

벌써 3명이 아이폰을 신청했고, 그 중 두 명의 아이폰이 개통되어 사람들이 구경하는 사태(?)가 벌어졌다.
아이폰의 여파가 정말 대단한 거 같다.
국내에도 변화의 조짐이 아니 이미 변화되고 있다.

2009년 11월 25일 수요일

크롬 OS 소스코드가 공개되었습니다

드디어 구글 공식 블로그를 통해서 크롬OS 소스코드가 공개되었습니다.


세간의 관심일 수 밖에 없는데, 과연 그 실체가 무엇인지는 소스 코드를 받아서 설치해 보면 되겠죠?
아~~ 점점 리눅스를 공부해야겠다는 생각이 듭니다.
우분투를 조금씩 사용하면서도 느끼고 있는 바인데 크롬OS를 보니 더욱 리눅스 공부에 대한 욕구가 생깁니다.

현재는 소스를 받아보아도 과연 PC 환경에서 설치를 할 수 있을지는 의문입니다...ㅡㅡ;;

다음은 위의 링크를 통해서 공식적으로 소개하는 세 가지 크롬OS의 특징입니다.

1. 모든 소프트웨어가 웹 애플리케이션입니다.
2. 모든 애플리케이션이 브라우저 안에 있기 때문에 보안 측면에서 상당한 이점이 있습니다. 그리고 부팅시 자체 코드를 검증한다고 하네요...
3. 부팅속도, 빠른 속도
4. 오픈소스 진영과의 협업(GNU, Linux kernel, Ubuntu, Mobin, WebKit)

얼마 전 Microsoft의 Windows7이 발표되었는데요... 과연 넷북시장에서 얼마나 크롬 OS의 임팩트가 있을지 지켜봐야 할 듯 합니다.
흠... 테스크탑 시장에선 아직이겠죠?

2009년 11월 20일 금요일

한 달간의 생활

지난 한 달 간의 생활을 돌아보면 야근과 밤샘의 연속이었다.
그것도 본업은 개발은 뒤로 한 채, 제안서, 업무미팅, 타 부서 개발 지원 등의 업무로...ㅡㅡ;;

그동안 함께 일하는 친구가 잘 해 주어서 본 개발에는 문제가 없어서 다행이지... 만약 이것마저 그렇게 되었다면 정말 힘들게 힘들게 가지 않았을까? 하는 생각이 든다.

불행인건 한 달간의 야근/밤샘의 생활로 인해 몸이 많이 힘들어 한다는 것이다. 중간중간에 짬을 내어 한의원에서 침을 맞기도 했지만 어깨는 여전히 아프고, 최근엔 허리도 좀 안 좋은 거 같다.
아내는 부황을 뜬 등을 보고는 한참을 멍하게 쳐다 보고는 한다. 다행이 울지는 않는다^^;;

몸을 좀 추스려야겠다는 생각이 들어서 다음 주 월요일은 휴가를 신청했다.
허... 올해도 아쉬운 건 월요일 휴가를 내어도 연차가 5일이나 남았다는 사실이다ㅜㅜ;;
올해도 연차는 다 사용해 보지도 못하고 지나갈거 같다.

연말까지 개발을 완료해야 하는 것도 있고 해 보고 싶은 것도 있어 휴가는 하루로 만족해야 할지도 모른다.
하지만 여름휴가를 떠 나는 것처럼 안식과 기대에 설레인다^^

어제까지 내 자리에 앉아 있는 시간이 없을 정도로 바빴던 터이고(주로 야근과 밤샘은 일과시간에 하지 못한 준비며 개발에 소비하고...ㅎㅎ 그동안 자리에 앉아있긴 했었네...), 오늘에서야 한 달간의 생활도 잠시 뒤돌아보게 된다.

잠시 쉬면서 아내와 영화도 보고, 함께하는 시간을 잠시 보내어야겠다.
다녀와서는 또 바쁜 업무의 연속이겠지만, 즐거운 마음을 잃어버리지 않고 살았으면 좋겠다.

크롬OS - TV처럼 바로 켜지는 PC 나온다

기사의 제목만으로는 크롬OS에 대한 소개인지를 알 수가 없었다.


그도 그럴것이 크롬 OS는 넷북 시장을 타켓으로 나오는 OS이고 테스크탑, 노트북을 타켓으로 하는 PC 시장과는 조금 다른 양상이 펼쳐지지 않을까?

인터넷을 기반으로 하는 문서작성용 OS라고 컨셉만으로는 한계에 부딪힐 것이 뻔하고, 과연 구글이 들고 나오려는 OS의 실체는 무엇일까?

최근 안드로이드 개발을 하면서도 언제나 안드로이드의 발전 방향을 주위깊게 살펴보려고 한다.
안드로이드 이후, PC 시장에서의 OS에 대한 구글의 향방은 언제나 관심의 대상이었다.
그리고 그 실체를 내년 말이면 볼 수 있다는 정보이다.

크롬 OS가 안드로이드만틈 시장에서의 임패트를 보일 수 있을까?






2009년 11월 9일 월요일

삼성, 독자 모바일 플랫폼 '바다' 공개

삼성에서 얼마전부터 독자적인 모바일 플랫폼을 공개한다는 말이 들렸는데, 정말로 그렇게 되나 보다...




사뭇 기대되는 면도 있지만 한편으로는 우려되는 기분도 든다.
국내에도 아이폰, 안드로이드와 같은 모바일 개방형 플랫폼이 나온다는 것은 사뭇 긍정적이 아닐 수 없다. 하지만, 듣기로는 삼성에 예전에 해외에서는 '바다' 플랫폼을 적용한 사례가 있다는 말도 들었다. 당시로선 플랫폼 자체가 무거워서 좀 그랬다는 말을 들었는데... 지금은 어떨지...?

그리고 몇 년에 걸친 플랫폼인지는 모르지만 그동안 숨겨진 상태로 있다가 돌연 아이폰, 안드로이드의 방향에 맞추어 공개를 한다는 것도 조금은 걱정이 된다.
오랫동안 플랫폼을 위한 개발과 실패를 거듭한 끝에 나온 아이폰, 현재까진 현존하는 좋다는 오픈소스는 거의 모아서 컴팩트하게 만들어둔 안드로이드, 몇 년 동안의 개발을 통해서 만들었는지 모르지만 충분한 검증이 되었을까? 하는 생각이 든다.

그래도 언제나 부정적인 면만 있는 것은 아닌듯...
삼성이란 브랜드를 통해서 충분히 노키아의 심비안과 비슷한 행보를 취하는 것을 보아선 충분히 의미가 있는 것이다. 이젠 독자적인 모바일 플랫폼을 가지는 것은 어쩌면 모바일 에코 시스템 내에 있는 경쟁력 있는 기업이라면 당연히 가야할 길이 되었기 때문이다.

그리고 그 가운데 한국기업의 하나가 있다는 것은 새삼 자긍심을 가질 수도 있기 때문이다.

부디, 좋은 평가가 이루어져 좋은 이미지, 시장의 한 획이 되길 조심해서 바래본다.

2009년 11월 3일 화요일

위대한 리더는?

요즘 리더십에 대한 고민이 많다.

리더는 사람들을 원하는 곳으로 데려간다.
위대한 리더는 사람들을 원하지는 않아도 가야 하는 곳으로 데려간다.
- 로잘린 카터 -

찾아보니 로잘린 카터는 지미 카터 전 미국 대통령의 부인이다.
짧지만 긴 여운을 남기는 말이다.

2009년 10월 29일 목요일

구글, 네비게이션 시장 진출에 대한 생각

최근 트랜드라고 할 수 있는 것을 보면 e-book 이라고 할 수 있는 듯 하다.
수 천년의 세월 동안 인쇄, 책, 출판 형태의 시장을 단기간 그것도 저렴한 가격에 디지털 형태의 읽기가 보편화 될지가 이슈이다.
e-book이 많이 팔리는 걸 보면 사람들의 시각이 많이 바뀐거 같기도 하다.

e-book에 대한 기사만 간략하게 소개하더라도 다음과 같다.


구글이 네비게이션 시장에 진출한다는 제목에 웬 e-book에 대한 소개일까? 생각해 보니 그동안 하드웨어 시장의 이슈는 단연 애플의 iPhone, iPod 같은 휴대폰, Media device 시장이 이슈였다.
그 외는 이렇다할 이슈라기 보다는 시대를 살아가면서 늘 사용해 오는 하드웨어의 발전이었다.

하지만 e-book 은 위의 기사의 소개처럼 출판의 미래를 바꿀 수도 있을 뿐 만 아니라, 사람들의 라이프 스타일을 바꿀 수도 있는 제품이 될 수 있다는 점이다.
잠시 이런 관점에서 주목해 본다면 e-book 시장을 그냥 지나쳐서는 안 된다는 것을 인지할 수 있다.

그런데, 구글이 e-book 시장에 진출하는 방안이 되는 플랫폼이 바로 안드로이드이다.
단순히 핸드셋 플랫폼이 아니니 e-book 플랫폼으로도 사용할 수 있다.

그리고 이러한 안드로이드 플랫폼을 이용하여 '네비게이션' 시장에도 진출하는 것이다.
'어~ 네비게이션 시장은 레드오션일텐데...' 하는 생각이 스친다. 왜냐하면 이미 네이게이션 공급업체의 포화 상태여서 시장에서는 네이게이션 단말 업체의 아우성이 들린지가 오래이다.
조금만 살펴봐도 살아남은 업체만 힘들게 새로운 시장을 탈출구로 찾고 있기 때문이다.

'이런 시장에 구글이 진출한다고?' 하는 생각이 들지 않을 수 없다. 그럼에도 많은 기사 꺼리가 될 정도로 이슈가 되는 것은  기존의 네비게이션 단말이 없이 핸드폰으로 제공되는 서비스이기 때문이다.


기사에는 쓰나미라고 표현하고 있지만 실제 시장에 나와서 임팩트가 얼마나 큰지 지켜봐야 한다. 하지만 그리 적지는 않을 거란 것이 추측이다.

안드로이드2.0 기반의 스마트폰으로 제공될 예정인데, 미국에는 버라이존을 통해서 향후 제공될 예정이라고 한다.
그러면 네비게이션 시장이 레드오션에서 블루오션으로 돌아서는 것일까? 구글에게는 새로운 수익 모델이 되어서 그럴지도 모르지만 기존의 제조업체는 반가운 일이 아니다.

기존 제조업체는 이제 가격경쟁, 고급화/차별화 서비스, 막강한 하드웨어 성능 등으로 더욱 격렬한 시장에 놓이게 될 것이란게 나름대로의 전망이다.

무엇인가 결론을 내고자하는 글이 아니니 한 번쯤은 '내가 만약 이런 상황에 네이게이션 제조업체의 CEO라면 어떤 탈출구를 마련할까?' 하는 생각이 해 볼 필요가 있을 거란 생각이 들었다.
이는 시장의 흐름, 레드오션을 블루오션 시장으로 만들 수 있는 기회 포착, 라이프 스타일을 바꿀 수 있는 플랫폼의 진화 등을 고민해 볼 수 있지 않을까?

간단한 예를들어 보면 네비게이션이 원격자동차 제어, 홈 네트워크와의 연결, 자동차 + IT 기술 접목의 선두에 선다면? 무엇인가 돌파구를 찾을 수 있지 않을까?
그냥 레드오션이고 경쟁이 힘드니 포기하는 것 보다는 낫지 않을까?



The Java Developers Almanac 1.4 소스 사이트

The Java Developers Almanac 1.4 책에 해당하는 소스 사이트이다.


구글에서 간단한 자바 소스를 찾다보면 많이 나오게 되는 사이트이다.
책의 내용을 본 적은 없지만 구글 검색 엔진 결과의 상위에 랭크가 되는 걸 보면 상당히 유용한 사이트이 인거 같다.

실제로 간단한 소스 코드가 잘 정리되어 있다.

2009년 10월 19일 월요일

JBoss강좌-3.2(BMP Example)

예전에 강좌로 썼던 파일은 여기까지이다. 이것 때문에 많은 사람들에게 연락도 받아보고, 문의도 받고, 스터디도 했었는데...ㅎㅎ
지금 생각해 보니 참 새삼스럽다. 다음에 기회가 닿으면 또 JBoss 하게 될 날이 있을까?

JBoss강좌-3.1(BMP Example)

흠.. 지금 보니 거의 사용하지 않는 EJB 이다. 당시엔 이것으로 많은 프로젝트를 했었는데, 지금은 거의 사용하지 않는 자바 표준이 되었다.
아직도 내가 모르는 곳에서 많이 사용하고 있을지도 모른다^^;;

JBoss강좌-2(JBossIDE-Tutorial)


JBoss IDE turorial

JBoss강좌-1(설치 및 실행)


무려 5년이 지난 자료이다. 2004년에 처음으로 강좌를 쓰기 시작했으니깐....
회고해보면 JBoss로 해서 마소에 기고도 해 본 적 있다.

그리고... 이제는 JBoss 책도 나올 정도로 많이 알려지고 쓰이고 있는 듯 하다. 더군다나 몇 년 전에 Redhat에 인수되면서 국내에서도 상당히 많은 유저를 확보하고 있는 듯 하다.

그래서 오래된 자료지만 아직도 웹 상에서 돌아다닌 것을 보니 새삼스럽게 느껴졌다.
그래도 내가 가지고 있는 것이 원본이니 올려도 되지 않을까?^^

2009년 10월 14일 수요일

드디어 '구글 도서검색' 서비스가 시작되다

구글 공식 블로그를 통해 '구글 도서검색' 서비스가 시작됨을 알렸다.


국내에도 도서검색 서비스가 가능하다.


오래전 부터 구글 도서검색 서비스는 논란이 많이 되었던 서비스...
그래도 쉽게 책을 찾거나 보고자 할 때는 소비자 입장에서는 확실히 좋은 서비스라 할 수 있다.

흠... 잠시 전체 공개가 되어 있는 유홍준의 "나의 문화 유산 답사기"를 잠시 보았는데, 저작권이 걸린 이미지를 제외하고는 다 볼 수 있었다.
그리고 책을 보기에 그렇게 어려움이 없었다. 모니터로 본다는 게 아무래도 피로감을 더하긴 하겠지만 뭔가를 책에서 찾고자 할 때는 정말 유용할 거 같다.

2009년 10월 13일 화요일

사람이 사람에게

"사람이 사람에게" 라는 강연 제목으로 방송인 김제동씨가 강연을 하였다.
최근 스타 골든벨의 사회자에서 하차하게 되면서 외압에 의한 것이 아닌가해서 사회가 들썩이고 있다.
손석희 교수의 100분 토론도 같은 반열에 올라있어 한 사람의 힘이 얼마나 대단한지를 볼 수 있다.
그러고보면 역사는 사람에 의해서 만들어지고 흘러간다고 해도 과언이 아니다.
역사는 결국 한 사람 한 사람이 걸어오고 살았던 삶을 후대에 기억하는 것이다.

인터넷을 가장 가까이 접하고 있지만 실제로 동영상을 잘 보질 않는다.
영화는 즐겨 보는 편이지만 스트리밍되는 동영상은 중간에 잘 끊어지다보니 기다리는 시간이 싫어서인지 잘 보지 않게 된다. 하지만 일전에 안철수 교수님의 강연, 그리고 이번에 김제동씨의 강연을 처음부터 끝까지 보게 되었다.

한참을 같이 웃다가도 숙역해 지기도 하고, 어떻게 저런 사람이 있을까? 감탄해지기도 한다.
흠... 말을 참 잘한다라고만 하기에는 좀 다른 느낌을 받을 정도이다.
그리고 생각하는 바가 성실하고, 강연에서처럼 상식적인 사람이라는 생각이 든다.
구구절절한 나의 느낌보다는 소개하는 기사와 동영상을 보는 것이 더 좋으리라 생각된다.

다행히 참 오랫동안 기억하고, 생각해 보고 싶은 사람이다. 방송인 김제동!





2009년 10월 12일 월요일

우리의 상상이 조금씩 이루어진다

만화나 영화에서 본 장면들이 과학기술을 발달하면서 하나씩 이루어지는 것을 보게 된다.

하늘을 나는 자동차도 이러한 상상들 중에 하나!
영화 '백투더퓨쳐'가 가장 대표적인 영화일까?
아무튼 이러한 상상의 결과들을 하나씩 살펴보는 것은 재미있다.

이미 오래전부터 개발되어 왔던 하늘을 나는 자동차는 미국에서 상당히 많이 발달되어 있고 시범/운영이 되고 있는 것으로 안다.
하나씩 자료를 모아보진 않치만 이미 많은 매채를 통해서 나오고 있으니 증명할 필요는 없을 듯 하다.
그리고 이러한 것을 기록해 두기 위해서 기사 하나를 소개한다.




아직은 가격이 비싸고, 스포츠 비행기 조종사 자격을 따야 한다는 부담은 있지만 너무 재미있지 않을까?
막히는 도로에서 뻥~ 뚫린 하늘을 날아서 간다는 것은... 와~~ 상상만으로도 즐겁다^^


2009년 10월 9일 금요일

구글코드 안에 Android 관련된 코드를 찾아보자

이미 구글코드는 상당히 많은 코드를 호스팅하고 있고, 구글이 직접 다양한 오픈소스를 공개한 사이트로 유명하다.
여러 변천이 있은 가운데 각 나라별로 언어를 지원하는 경우에는 약간의 UI를 포함해서 서비스하고 있다.
이 중에서 Android 관련 호스팅과 검색을 해 보자.


적당할 때 찾아보면 되지만 최근엔 자주 들어가게 된다^^

2009년 10월 7일 수요일

소유를 넘어 접속의 시대 열린다

최근에 읽은 책 중에 가장 기억에 남고 호감이 가는 책이 "소유의 종말"이란 책이다.
블로그 리뷰를 통해서도 소개했던 적이 있었는데, 조금 지난 ZDNet 기사 중에 다음의 제목을 가진 기사 내용이 있어 잠시 소개한다.


아마도 기자가 "소유의 종말"이란 책을 읽었기에 이런 카피를 쓸 수 있지 않았을까? 하는 생각이 든다.
기사의 내용은 클라우드 컴퓨팅에 대한 내용이다. 아마존 EC2 서비스를 시작으로 클라우드 컴퓨팅을 소개하고 컨퍼런스에 대한 소개이다.

가만히 생각해 보면 기자의 혜안을 조금은 들여다 볼 수 있다. 기사를 해석하는 것은 독자의 마음이니^^;;

기자는 클라우드 컴퓨팅을 접속의 시대를 향한 포문으로 보고 있다. 그도 그럴 것이 IT 인프라를 전기나 수도처럼 저렴한 가격에 하드웨어, 소프트웨어에 이르는 대부분은 빌려서 쓸 수 있는 시대가 열렸기 때문이다.
클라우드 컴퓨팅의 특성상 대형 기업이 아니면 소유하거나 서비스를 하기가 힘든데 이를 이용하는 중소기업의 입장에선 잘만 사용하면 필요한 유틸리티를 쉽게 싼 가격에 빌려 쓸 수 있는 시대가 열린 것이다.

이미 인터넷 시대를 거친 지금은 사용자의 접속을 넘어 경험에 대한 관점으로 이동하고 있다.
그리고 사용자 또는 개발자도 경험에 의한 접속의 결과를 찾아야 하지 않을까?(내가 말하고도 풀어 쓰기 힘듬^^;;)

즉, 사용자의 경험에 의한 피드백을 통한 또 다른 접속 & 경험...
흠... 누군가는 새로운 서비스로 이전과는 다른 시대를 열어가는 것이 미래이다. 적어도 스티브 잡스와 같은 인물은 인류 역사상에 계속해서 배출될 것이다.


접속의 시대에 무엇이 우리는 새로운 세계로 인도할까?
클라우드 컴퓨팅, 모빌리티, SNS, 게임, Web2.0, Mobile2.0, Mobile Web 등...

수도 없이 새로운 용어가 쏟아진다. 그리고 이들은 모두 접속을 기반으로 하고 있다. 개인 개인을 중심으로 한 경험에 의한 소셜 네트워크로...

2009년 9월 30일 수요일

안철수 KAIST 석좌교수 "개발자가 성공하는 길"

데브멘토를 동영상 자료에 인터뷰 형태로 안철수 카이스트 석좌교수님의 "개발자가 성공하는 길"이 있다. 일단 판도라 TV에 동영상이 올라와 있어 해당 동영상을 가져왔다.


안철수 교수님의 강연이나 세미나이면 챙겨서 듣는 편인지라 업무시간임에도 불구하고 보게 되었다.
인터뷰 내용을 짧게나마 기억을 더듬어 살펴보면 다음과 같다.

1. 개발자가 성공하는 5가지 요건
- 전문지식(전문성)
- 창조적인 마인드(Creative Mind)
- 장인정신
- 커뮤니케이션 능력
- 팀워크(희생정신)

2. 추천도서
- 세계는 평평하다
- 좋은 기업을 넘어 위대한 기업으로
- 성공하는 사람들의 7가지 습관
- 티핑 포인트
- 아웃 라이어

3. 전망은 부질없다. 비전을 가져라.

4. 성공의 기준은 각자 다르다. 자신의 성공 조건을 기준으로 성공의 잣대를 세워야 한다.

기억을 더듬어 적다보니 자세한 내용을 적기는 힘들다. 그래도 좋은 내용인지라 가능한 기억해 두어야 한다. 다행히 추천도서 중에 세 권은 읽었네^^

HashMap의 key에 MultiKey object 사용해 보자.

자바가 Generic 프로그래밍 방식을 지원하면서 많은 자바 유틸 클래스중 Collection 객체들이 generic을 이용한다.

여기서 잠시 다루어 보려는 HashMap 컬렉션 유틸리티 객체도 generic을 이용한 코딩을 할 수 있다.
이와 같이 HashMap 클래스의 정의를 HashMap<K, V>로 하고 있다.

K : Key
V : Value

형태인데 key와 value에 generic을 이용하면 자바 클래스및 사용자 클래스를 줄 수 있다. 하지만 보통은 HashMap을 이용한 간단한 샘플 코드는 Integer 또는 String 을 이용한 코드가 대부분이다. 예를 들면 다음과 같다.

public class HashMap1
  {
  public static void main( String[] args )
    {
    HashMap map = new HashMap();
    map.add( new Integer( 2 ), "two" );
    map.add( new Integer( 4 ), "four" );
    System.out.println( map );
    System.out.println();

    System.out.println( "Enumerate the HashMap" );
    Enumeration e = map.elements();
    while ( e.hasMoreElements() )
      System.out.println( e.nextElement() );
    System.out.println();

    System.out.println( "Iterate through the HashMap" );
    for ( HashMapIterator i = map.begin(); !i.atEnd(); i.advance() )
      System.out.println( i.get() + ", key = " + i.key() + ", value = " + i.value() );
    System.out.println();

    System.out.println( "Demonstrate access" );
    System.out.println( "map.get( 2 ) = " + map.get( new Integer( 2 ) ) );
    System.out.println( "map.get( 5 ) = " + map.get( new Integer( 5 ) ) );
    System.out.println( "map = " + map );
    System.out.println();

    System.out.println( "Show that duplicates cannot be added." );
    Object value = map.add( new Integer( 8 ), "eight" );
    if ( value != null )
      System.out.println( "Could not add 8." );
    else
      System.out.println( "Added 8." );
    System.out.println( "map = " + map );

    value = map.add( new Integer( 4 ), "FOUR" );
    if ( value != null )
      System.out.println( "Could not add 4." );
    else
      System.out.println( "Added 4." );
    System.out.println( "map = " + map );
    System.out.println();

    System.out.println( "Demonstrate modification" );
    map.put( new Integer( 4 ), "FOUR" );
    System.out.println( "map = " + map );
    }
  }


위의 코드가 문제가 된다는 것은 아니다. 다만 HashMap의 Key에 해당하는 클래스가 두 개의 좌표값을 가진 클래스인 경우를 생각해 보자. UserKey라는 클래스는 두 개의 좌표(x, y) 값을 가진 간단한 클래스이다.

/**
 * @author Sang-Hyup Lee
 *
 */
public class UserKey {

private int x;
private int y;
/**
* @param x
* @param y
*/
public UserKey(int x, int y) {
super();
this.x = x;
this.y = y;
}

/**
* @return the x
*/
public int getX() {
return x;
}

/**
* @param x the x to set
*/
public void setX(int x) {
this.x = x;
}

/**
* @return the y
*/
public int getY() {
return y;
}

/**
* @param y the y to set
*/
public void setY(int y) {
this.y = y;
}
}

다음은 Value 클래스에 해당하는 UserValue 객체를 만들어보자.

import java.util.UUID;

/**
 * @author Sang-Hyup Lee
 *
 */
public class UserValue {

private int x, y;
private String uniKey;
public UserValue(int x, int y) {
this.x = x;
this.y = y;
this.uniKey = "" + UUID.randomUUID();
}
/**
* @return the uniKey
*/
public String getUniKey() {
return uniKey;
}

/**
* @param uniKey the uniKey to set
*/
public void setUniKey(String uniKey) {
this.uniKey = uniKey;
}

/**
* @return the x
*/
public int getX() {
return x;
}

/**
* @param x the x to set
*/
public void setX(int x) {
this.x = x;
}

/**
* @return the y
*/
public int getY() {
return y;
}

/**
* @param y the y to set
*/
public void setY(int y) {
this.y = y;
}

}

위의 두 개의 key, value 클래스를 이용하여 HashMap 테스트를 위한 JUnit 코드를 만들어보자. 아래의 UnikeyHashMap junit 코드의 결과값을 예상해 보자.

import java.util.HashMap;

import junit.framework.TestCase;

/**
 * @author Sang-Hyup Lee
 *
 */
public class UnikeyHashMap extends TestCase {

private HashMap<UserKey, UserValue> userHashMap = new HashMap<UserKey, UserValue>();
protected void setUp() throws Exception {
super.setUp();
for ( int x=0; x < 10; x++ ) {
int y = x + 1;
UserKey userKey = new UserKey(x, y);
UserValue sohiPoint = new UserValue(x, y);

userHashMap.put(userKey, sohiPoint);
}
}
public void testUnikeyHashMap() {
UserKey targetUserKey = new UserKey(2, 3);
/*
UserValue userValue = null;
if ( userHashMap.get(targetUserKey) != null ) {
userValue = userHashMap.get(targetUserKey);
}
*/
assertNotNull(userHashMap.get(targetUserKey));
// assertEquals(2, foundSohi.getX());
// assertEquals(3, foundSohi.getY());
}

}

주석문으로 처리된 부분은 UserValue가 정상적으로 찾았을 때를 대비해서 최종 체크하기 위한 코드이다. 적절한 형태로 사용해도 된다.

여기서 중요한 건 testUnikeyHashMap() 테스트가 정상적으로 동작할까? 하는 것이다.
결과는 에러를 리턴한다. 즉, userHashMap.get(targetUserKey)의 결과값이 null 이란 것이다. 일반적인 생각에는 Key를 주어진 Value를 찾아야 한다.
HashMap 클래스의 get 메소드를 따라가보면 문제가 발생한 곳은 파라미터로 받는 key object의 equals 메소드 구현에 있다는 것을 알 수 있다.

이미 이러한 문제는 실무에서 사용할 일이 많았던 거 같다. 즉 HashMap과 같은 Key를 가진 컬렉션 객체에 다중의(Multi) 값을 가진 key 객체를 사용하고 싶은 요구사항인 것이다.
Apache commons collections 오픈소스에 이에 대한 해답이 있다. MultiKey라는 클래스이다.

사용법은 다음과 같이 정의하고 있다.

Example usage:

 // populate map with data mapping key+locale to localizedText
 Map map = new HashMap();
 MultiKey multiKey = new MultiKey(key, locale);
 map.put(multiKey, localizedText);

 // later retireve the localized text
 MultiKey multiKey = new MultiKey(key, locale);
 String localizedText = (String) map.get(multiKey);

간단하다. 실제로 아파치 라이센스를 따르니 해당 소스를 가져와도 상관이 없다. 해당 전체 소스 코드를 살펴볼 필요가 있다.

여기서는 MultiKey 클래스를 이용해서 UnikeyHashMap 테스트 코드를 다음과 같이 수정해 보자.

import java.util.HashMap;

import junit.framework.TestCase;

/**
 * @author Sang-Hyup Lee
 *
 */
public class UnikeyHashMap extends TestCase {

private HashMap<MultiKey, UserValue> userHashMap = new HashMap<MultiKey, UserValue>();
protected void setUp() throws Exception {
super.setUp();
for ( int x=0; x < 10; x++ ) {
int y = x + 1;
MultiKey userKey = new MultiKey(x, y);
UserValue sohiPoint = new UserValue(x, y);

userHashMap.put(userKey, sohiPoint);
}
}
public void testUnikeyHashMap() {
MultiKey targetUserKey = new MultiKey(2, 3);
UserValue userValue = null;
if ( userHashMap.get(targetUserKey) != null ) {
userValue = userHashMap.get(targetUserKey);
}
assertNotNull(userHashMap.get(targetUserKey));
assertEquals(2, userValue.getX());
assertEquals(3, userValue.getY());
}

}

UserKey에 해당하는 Key 클래스를 MultiKey로 바꾼 것 말고는 실제로 코드를 수정한 것은 아니다. testUnikeyHashMap 메소드의 세 개의 unit test 메소드가 정상적으로 실행될 것이다. 그리고 실제로 x, y 좌표값에 해당하는 value 객체도 얻어진 것을 확인할 수 있다.

2009년 9월 25일 금요일

블로그를 textcube 로 이전하다!!

흠... 오늘 또 다시 서버 하드 디스크가 벅 났습니다^^;;
PC 환경에 IDE 하드이다보니 1년을 버티질 못하는군요...^^;;

그래서 이 참에 텍스트큐브로 블로그를 이전합니다.
네임서버를 새로 설정해야 해서 24시간 정도 소요가 될 것으로 보입니다.

참고로 텍스트큐브 블로그와 도메인을 연결해서 사용하는 방법

주말 또는 다음 주 중으로 복귀된 모습으로 오겠습니다.

감사합니다.

2009년 9월 22일 화요일

[링크]HTC 안드로이드폰 국내 출시된다

몇 일지난 기사입니다. HTC 코리아와 SKT가 2010년 HTC 안드로이드폰 HERO(히어로)를 국내에 출시한다는 소식이네요.
Sense UI가 참 마음에 들던데...
SMS/MMS 개발은 HTC가 직접하는 걸까요? SKT가 MMS는 OEM으로 모두 넘긴걸로 아는데...

암튼 핵심기능도 그대로 유지한다고 하니 곧 나올 모토롤라, LG, Samsung과 경쟁일 할거 같군요...
다른 단말사가 어떤 UI를 가지고  나올지 궁금해 집니다.



닌텐도는 화투 팔던 회사였다

닌텐도가 화투를 개발하고 팔던 회사였던 것을 알게되었다. 흠... 그동안 내가 잘 몰랐던거 같다.
게임에 많은 관심이 있는 편은 아니었던지라 조금은 생소한 분야가 아니었나 싶다...
잠시 신문기사를 통해서 닌텐도 회사에 대해서 이야기를 들어보자!

닌텐도는 화투 팔던 회사였다
[스토리텔링으로 성공하기]닌텐도의 개발스토리(상)

"95살에게도 게임기를" 닌텐도의 변신
[스토리텔링으로 성공하기]닌텐도의 개발스토리(하)

닌텐도DS, 닌텐도 Wii 등은 사용해 보진 않았지만 엄청난 인기를 끌고 많은 사람들이 사용하고 있다. 사실 주위에 게임을 좋아하는 사람들은 한 번씩 다 사용하고 있다^^;;

흠... 그런데 뜬금없이 화투를 만들었던 회사라니? 이런 이야기를 듣고는 자료를 찾아보던 중에 위의 기사를 찾게 되었다.

관심이 화투에 있는 것이 아니라 '스토리텔링', '창의성', '혁신', '좌절하지 않는 열정' 등에 있다.
쉽고 간단한 게임을 개발? 누구나 생각할 수 있지만, 대부분 매니아나 게임을 좋아하는 사람들만 게임을 할 것이라 생각할 때 나이 많은 성인이나 여성들이 쉽고 재밌게 할 수 있는 게임이 잘 될거란 생각 자체가 역발상과 혁신이 아닐까?

섣부른 판단을 하려는 것은 아니지만 스마트폰에도(특히,안드로이드폰) 이렇게 간단하고 사용층이 두꺼운 게임을 개발하는 것은 어떨까?

혼자서 궁금한 것이 많아졌다. 이런 아이디어에 동참할 사람!!!!! 손!!!

2009년 9월 17일 목요일

[링크]TDD(테스트 주도 개발) WIKI

TDD(Test Driven Development) 에 대한 설명을 잘 해 둔 위키 페이지가 있다.
회사에서 간혹 일전에 TDD 세미나를 잠시 진행한 적이 있었는데,
아직은 많은 사람들이 적용을 잘 하진 못한다.
나중에라도 소개할 때 사용해야겠다.


2009년 9월 11일 금요일

집단지성이란 무엇인가 - 우리는 나보다 똑똑하다

사용자 삽입 이미지
'웹2.0'이란 새로운 웹 플랫폼에 대한 논의가 한창이던 때가 지나고 이젠 실생활에서 웹2.0 이 실현되고 현실화되고 있는 시점이다.
당시 단순한 마케팅이나 버블에 불과하거란 의견도 상당히 많았는데 어쨌든 웹은 발전하고 변화하고 거듭나고 있다.

그리고 상당부분 웹은 사회와 문화, 정치, 생활방식에 변화를 가져왔다. IT에 종사하지 않는 사람들이 '웹2.0'이란 단어를 모른다고 하더라도 이미 사람들은 새로운 웹 생태계에서 살아가고 있는 것이다.
"집단지성이란 무엇인가"라는 책은 단순히 웹에서 일어나는 기술적인 이슈나 문제, 아이디어를 말하는 것이 아니라 사람들이 부딪히고 현실 속에서 만날 수 있는 다양한 이슈들을 '공유', '참여', '함께' - 저자의 말을 빌림 - 등의 단어를 통해 풀어가고 있다.

즉, 웹을 넘어 경제와 정치, 실생활을 지배하는 집단지성의 모든 것을 파헤치고 있다 - 책의 표지의 카피에 정치란 단어를 더했을 뿐이다.

집단지성의 예를 들어보면 빼 놓을 수 없는 것이 리눅스와 위키피디어 그리고 오픈소스에 대한 이야기인데 여러 가지 관점에서 재밌게 생각해 볼 수 있다.
재밌는 것은 책의 첫 부분에 나오는 '캐논' 기타 연주 동영상의 소개부터 나온다. 책의 상당 부분에서 한국의 인터넷 문화, 정치에 끼친 영향, 미래 등을 보여 주는 부분이다.

이 책에서 말하고자 하는 바는 웹을 넘어 '집단지성', 즉 우리는 나보다 똑똑하기 때문에 20세기와는 다른 서로 함께 사회적 문제도 해결하고 더 나은 공동체를 세워가려고 하는 의미가 담겨져 있다.
저저 역시 인터넷 공유 문화가 가진 문제들, 지식의 공유로 인한 부작용 등을 알고 소개하면서 염려하는 부분이 있다는 것을 이야기한다. 그러나 더 나은 문화와 사회, 인류의 발전을 위해선 참여하고 공유하면서 함께해야 한다는 것을 계속해서 강조한다. 너무나도 공감하는 말이다.

21세기에는 기술은 더욱 빠른 속도 발전할 것이고 사람들의 생활도 상당 부분은 마치 영화같은 삶을 살아가게 될 것이다. 하지만 그 속에 철학이 부재하고, 문화가 올바로 성장하지 못하고, 더불어 함께하는 사회가 되어 있지 못하면 오히려 과학기술로 인해 대부분의 사람들은 통제 속에서 자아를 상실한 채 살아갈 것이다.
앞으로 계속해서 이러한 책이나 논의를 통해서 더불어 살아가는 사회를 웹과 과학기술, 문화가 집단-공동체-를 통해서 발전하지 않을까?

끝으로 책의 말미에 함께하는 아이디어에 대한 좋은 정의가 있어 소개한다.

아이디어는 다른 사람과 나눌 때 비로소 움직인다. 혁신과 창조, 더 근본적으로는 번영과 행복, 그리고 미래에 대한 희망은 우리가 아이디어를 축적하고, 교환하고, 개발하는 데 이용할 수 있는 도구를 얼마나 갖고 있느냐에 따라 결정된다. 아이디어는 표현되고, 검토되고, 다듬어지고, 차용되고, 수정되고, 개작되고, 확장되면서 성정한다. 이런 활동은 한 사람의 머릿속에서 한꺼번에 이루어지는 경우는 거의 드물고, 대개 다양한 관점과 안목을 가진 수많은 사람들을 거치면서 이루어진다.
- p. 276

우리는 아이디어를 공유해야 한다. 그것만이 아이디어를 실현할 수 있는 방법이다. 아이디어를 공유하면 아이디어는 점점 늘어나고 자라나서 아이디어를 더욱 강화하는 순환고리를 이룬다. 우리는 무엇을 갖고 있느냐뿐만 아니라 무엇을 공유하고 있느냐에 따라서도 규정된다. 이것은 우리가 앞으로 백년 동안 신조로 삼아야 할 가치관이다.
- p. 296 책의 끝...


2009년 8월 25일 화요일

[링크]괜찮은 아이콘 다운로드 사이트

우연찮게 찾게된 사이트이다.
프로그램 아이콘으로 사용할 수 있는 많은 아이콘을 다운받을 수 있다.
그것도 OS(윈도우, 리눅스, 맥) 별로 파일이 준비되어 있다.

모아두기용 링크^^


2009년 8월 24일 월요일

[축하해주세요^^]SDN(Sun Developer Networks) 인기 블로그에 두 개나 올리다!!

그동안 블로그에 뜸하다가 최근 몇 개 올린 포스팅이 썬테크 인기 블로그에 두 개나 올려졌다ㅋㅋ
기념해서 캡쳐셧 공개^^

사용자 삽입 이미지

축하해주세요^^

그러고보니 "안드로이드 입문서"가 오늘 도착했는데 봐야 할 책이 너무 많다...^^


2009년 8월 23일 일요일

[링크] Android Graphics tutorial

안드로이드가 Java API를 가져가지 않은 부분이 AWT 즉, Graphics 관련된 부분이다.
사실 안드로이드 전체 소스에 보면 awt package가 포함되어 있다(%ANDROID_SOURCE_HOME%/frameworks/base/awt).

하지만 배포되는 SDK android.jar 에는 awt 패키지들이 빠져 있다. 그래서 Android Graphics를 위해서는 안드로이드 API를 이용한 코딩을 해 주어야 한다.
Android graphics 관련된 자료를 국내에선 거의 찾을 수 없는거 같고, 찾다보니 괜찮은 tutorial이 있어 링크로 소개한다.


정리하다보니 현재는 2D Graphics에 관심이 있는 관계로 2D Graphics 관련 tutorial은 링크 전체를 걸어둔다.

2009년 8월 17일 월요일

Spring MVC를 활용한 정적인 페이지 개발

이전에 okjsp wiki에 올려둔 글이었다. wiki가 복원되지 않아 잃어버렸다고 생각했었는데, 네이버 블로그에 누군가 복사해둔 포스트가 있어 다시금 올려놓는다. 중간중간에 이미지가 나오질 않는다. 아무래도 이미지가 okjsp wiki에 있었던지라 사라진거 같다. 그냥 텍스트로만 보시길...^^;; 이것으로 Spring 으로의 회귀?^^ 흠...


Spring MVC를 활용한 정적인 페이지 개발

- web.xml 설정(웹 애플리케이션 설정)

Spring MVC를 이용하여 구현하고자 하면 가장 먼저, WEB-INF/web.xml에 DiapatcherServlet을 WAS초기에 실행하고 이를 매핑하는 셋팅을 해 주어야 한다. 직접 web.xml를 수정하기에 앞서 다음에서 소개하고 있는 Spring MVC에서 클리이언트 요청의 처리과정을 반드시 이해해야 한다. 따라서 위에서 소개한 Spring framework 워크북의 306 페이지부터 나오는 "클라이언트 요청을 처리하는 과정"을 꼭 읽어보길 바란다. 그렇치 못할 경우에는 javajigi wiki에 소개되는 클라이언트 요청을 처리하는 과정을 반드시 읽어보아야 한다.

Spring MVC에서 클라이언트 요청의 처리 과정

여기에는 DiapatcherServlet의 소스까지 간략하게 소개됨으로 반드시 읽어보길 권한다.

Spring MVC에서 클라이언트 요청을 처리하는 과정을 이해했다면 웹 애플리케이션을 다음과 같이 설정한다.


 > 파일명 : web.xml

<servlet>
<servlet-name>action</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>

<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>*.html</url-pattern>
</servlet-mapping>

- sitemesh framework의 decorators.xml 수정

책에서 소개한 것 처럼 어느 웹 애플리케이션마다 정적인 페이지 하나 쯤은 존재하기 마련이다. 이를 처리하기 위해서 url 정보를 그대로 노출한 채 html이나 jsp를 구현하면 보안이나 인증, 공통적인 기능을 구현할 때 문제가 발생할 수 있다. 따라서 이를 해결하기 위해서 책에서는 일반인들이 직접 접근할 수 없는 WEB-INF 디렉토리에 JSP파일을 관리하고 있다. 좋은 방법이므로 이와 같은 방법으로 계속해서 구현한다.
지금까지는 웹 애플리케이션 Root에 해당하는 디렉토리에서 JSP를 관리, 구현하였다면 앞으로의 예제에서는(Spring MVC를 적용하면서는) "WEB-INF/jsp" 디렉토리에서 JSP파일을 구현 또는 관리하도록 한다.

책의 순서를 따라해 보았다면 Presentation Layer Framework로 sitemesh를 사용한 것을 알 수 있는데, 먼저 sitemesh를 적용하기 위해서 다음과 같이 "defaultdir"를 수정해 주어야 한다.

기존 decorators.xml

<decorators defaultdir="/decorators">

<decorator name="main" page="main.jsp">

<pattern>/*</pattern>

</decorator>

<decorator name="panel" page="panel.jsp"/>

<decorator name="printable" page="printable.jsp"/>

<decorator name="black" page="black.jsp"/>

<decorator name="nopanelsource" page="nopanelsource.jsp"/>

<decorator name="badpanelsource" page="badpanelsource.jsp"/>

</decorators>

변경후 decorators.xml

<decorators defaultdir="/WEB-INF/jsp/decorators"> 
 <decorator name="main" page="main.jsp"> 
 <pattern>/*</pattern> 
</decorator> 
<decorator name="panel" page="panel.jsp"/> 
<decorator name="printable" page="printable.jsp"/> 
<decorator name="black" page="black.jsp"/> 
<decorator name="nopanelsource" page="nopanelsource.jsp"/> 
<decorator name="badpanelsource" page="badpanelsource.jsp"/> 
</decorators> 

변경된 부분은 "defaultdir"의 value 밖에 없다.

- action-servlet.xml 파일 생성

위에서 정의한 DispatcherServlet을 선언하여 웹 애플리케이션을 실행할 때, init() 메소드가 호출되면서 빈 설정 파일의 초기화가 진행된다.

<servlet> 
<servlet-name>action</servlet-name> 
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> 
<load-on-startup>1</load-on-startup>
 </servlet>
여기서 <load-on-startup> 태그를 통해서 진행이 되는 것을 알 수 있다.
action-servlet.xml은 DispatcherServlet이 초기화 될 때 정의한 <servlet-name>의 값인 
빈 설정 파일의 이름이 "서블릿이름-servlet.xml"이 되는 것임으로 여기서는 
"action-servlet.xml"이 된다. 이는 Spring MVC에서 사용할 디폴트 빈 설정 파일이 된다.

직접 action-servlet.xml을 먼저 구현해 보자.

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"> <beans> <!-- static view controller --> <bean id="staticViewController" class="com.mediachorus.middleware.common.web.MyUrlFilenameViewController" /> <!-- URL Mapping --> <bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"> <property name="mappings"> <props> <!-- static view mapping --> <prop key="**/*.html">staticViewController</prop> </props> </property> </bean> </beans>
아직까지는 예제를 실행하기 위한 완전한 형태는 아니다. 
앞으로 진행하면서 완성된 형태로 만들어질 것이다. 
위의 action-servlet.xml의 내용을 보면 두 가지를 살펴보아야 하는 것을 알 수 있다.

<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
 "http://www.springframework.org/dtd/spring-beans.dtd">와 <beans> 태그를 사용하는 
것을 보면 금방 Spring framework에서 사용하는 웹 애플리케이션 설정 파일인 것을 알 수 있다. 
살펴보아야 할 것은 <bean>태그로 포함되어져 있는 urlMapping과 staticViewController이다.
먼저, bean id으로 "urlMaping"을 살펴보면 "org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"를 클래스로 사용하고 있다. 
SimpleUrlHandlerMapping은 Spring MVC에서 URL과 Controller를 연결시켜주는 매커니즘 중에 하나이다. 
이에 대한 내용은 Spring framework 워크북 323 페이지를 참조하기 바란다. 
여기서 간략하게 살펴보면 SimpleUrlHandlerMapping은 mappings name을 사용하여 
<props></props> 태그안에 정의된 <prop>에 포함된 key를 URL와, 
<prop></prop>태그에 value로 정의된 Controller를 연결시켜 주는 역할을 하는 클래스이다.
따라서 위의 예제에서는 "**/*.html"에 해당하는 URL은 "staticViewController"로 정의한 
bean 이름을 가지는 컨트롤러와 연결되는 것을 알 수 있다. 
이는 "**/*.html"로 들어오는 URL은 DispatcherServlet을 통해서 들어오게 되면 
DispatcherServlet은 HandlerMapping에게 URL 정보를 넘겨줌으로 Controller를 얻어오게 되는데, 
HanlerMapping이 SimpleUrlHandlerMapping가 되고, 
Controller가 staticViewController가 된다. 
이에 대한 과정은 "Spring MVC의 클라이언트 요청 처리과정"을 이해하면 알 수 있다.

그리고 한 가지 남은 것은 staticViewController로 정의해 둔 클래스이다.
여기서는 MyUrlFilenameViewController인데 책의 예제소를 그대로 이용하는 것으로 한다. 
MyUrlFilenameViewController에 대한 설명은 책을 참조하기 바란다. 
package com.mediachorus.middleware.common.web; 
import java.util.Enumeration; 
import javax.servlet.http.HttpServletRequest; 
import javax.servlet.http.HttpServletResponse; 
import org.apache.log4j.Logger; 
import org.springframework.web.servlet.ModelAndView; 
import org.springframework.web.servlet.mvc.Controller; 
/** 
* @author javajigi.net 박재성 * 
*/ 
public class MyUrlFilenameViewController implements Controller { 
protected final Logger logger = Logger.getLogger(getClass()); 
/* (non-Javadoc) 
* @see org.springframework.web.servlet.mvc.Controller# 
* handleRequest(javax.servlet.http.HttpServletRequest, 
 javax.servlet.http.HttpServletResponse) 
*/ 
public ModelAndView handleRequest(HttpServletRequest request, 
 HttpServletResponse response) throws Exception { 
// TODO Auto-generated method stub 
 String contextPath = request.getContextPath();
 String uri = request.getRequestURI(); 
if ( logger.isDebugEnabled() ) { 
 logger.debug("ContextPath : " + contextPath); 
 logger.debug("URI : " + uri); 
} 
int begin = 0; 
if ( (contextPath == null) || (contextPath.equals("")) ) { 
 begin = 1; 
} else { 
 begin = contextPath.length() + 1; 
} 
if ( logger.isDebugEnabled() ) { 
logger.debug("Begin : " + begin); 
} 
int end; 
if ( uri.indexOf(";") != -1 ) { 
 end = uri.indexOf(";"); 
} else if ( 
 uri.indexOf("?") != -1 ) { 
 end = uri.indexOf("?"); 
} else { 
end = uri.length(); 
} 
String filename = uri.substring(begin, end); 
if ( filename.indexOf(".") != -1 ) { 
 filename = filename.substring(0, filename.lastIndexOf(".")); 
} 
for ( Enumeration en = request.getParameterNames(); en.hasMoreElements(); ) {
 String attribute = (String)en.nextElement(); 
 Object attributeValue = request.getParameter(attribute);
 if ( logger.isDebugEnabled() ) { 
 logger.debug("set Attribute in Request : " + attribute + "=" + attributeValue); 
} 
request.setAttribute(attribute, attributeValue); 
} 
if ( logger.isDebugEnabled() ) { logger.debug("filename : " + filename); } 
return new ModelAndView(filename); } } 

이것으로 action-servlet.xml과 MyUrlFilenameViewController.java에 대해서 살펴보았다. 하나의 웹 애플리케이션 매핑과 클래스를 연결시켰다. 그러나 실제 구현하고자하는 정적인 페이지는 다음 그림과 같이 간략한 소개 페이지와 Menu와 로그인 페이지가 포함된 것을 알 수 있다.

정적인 메인 페이지는 javajigi 예제소스를 이용해서 개발했던 페이지를 약간 수정한 것을 밝힌다.


 만약, 책의 순서대로 실행을 해 봤다면 지금까지는 sitemesh framework를 통해서 "WebRoot/decorators/main.jsp"에서 Menu와 로그인 페이지는 "leftbody.jsp"로 include하고 있고, 소개 글은 <decorator:body> 태그 라이브러리를 이용한 index.jsp에서 처리하는 것을 알 수 있다.
이를 Spring MVC에서는 Menu와 login 페이지를 분리하고, "WEB-INF/jsp/decorators" 디렉토리에서 JSP 페이지를 구현, 관리하고 있음으로 변경이 된다. 이러한 변경으로 말미암아 action-servlet.xml이 수정되고 해당하는 Controller가 추가되는 것을 하나씩 살펴보기 전에 main.jsp를 살펴보도록 한다.

"WEB-INF/jsp/decorators/main.jsp" 살펴보기

main.jsp를 설명하기에 앞서 경로를 위와 같이 표시한 이유는 JSP페이지를 구현, 관리하기 위해서 일반인들이 접근할 수 없는 "WEB-INF"디렉토리에 아래로 이동했다는 것을 강조하기 위함이다.
변 경된 main.jsp 예제소스를 살펴보면 다음과 같다. JSP 소스여서 중요한 부분만 표시한다. 살펴볼 부분은 sitemesh page 태그 라이브러리가 포함된 것과 menu.do와 user/login.do가 좌측 메뉴 쪽에 포함되었다는 것이다. 그리고 <decorator:body />는 동일하다.

<%@page contentType="text/html; charset=euc-kr"%> <%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c"%> <%@ taglib uri="http://www.opensymphony.com/sitemesh/decorator" prefix="decorator"%> <%@ taglib uri="http://www.opensymphony.com/sitemesh/page" prefix="page"%> <html> <head> <title><decorator:title default="Mediachorus Middleware System" /></title> <link href="${pageContext.request.contextPath}/css/main.css" rel="stylesheet" type="text/css"> <script type="text/javascript" src="${pageContext.request.contextPath}/scripts/global.js"></script> <decorator:head /> </head> <body> <table width="900" border="0" align="center"> <tr> <td> <table width="100%" border="0"> <tr> ...(중략) <table width="100%" height="100%"> <tr> <td valign="top" height="100%"> <page:applyDecorator name="panel" page="/menu.do" /> <page:applyDecorator name="panel" page="/user/login.do" /> </td> </tr> </table> </td> <td> <table width="100%" height="100%"> <tr> <td id="pageTitle"><decorator:title /></td> </tr> <tr> <td valign="top" height="100%"><decorator:body /></td> </tr> </table> </td> </tr> ...(중략) </table> </body> </html> 

menu.do와 Controller 연결하기

main.jsp 페이지는 간단하고 sitemesh page 태그 라이브러리가 포함되었다는 것만 수정된 것이다. 그럼으로 더 이상의 언급은 하지 않는 것으로 하고 중요한 URL과 Controller를 어떻게 연결하는지를 살펴보자.
Spring MVC를 이용하여 웹 애플리케이션을 개발하는데 있어 Spring MVC가 클라이언트의 요청을 어떤 과정으로 처리하는 지를 아는 것이 중요하다고 서두에 언급하였는데, 이 처리과정에서 중요한 부분이 URL과 Controller를 연결시키는 매커니즘과 방법이다. 이미 staticViewController와 "**/*.html" URL 요청에 대해서 action-servlet.xml에서 살펴보았는데, 각각의 Controller를 연결시키는 방법이 다른 것을 앞으로 볼 것이다. 따라서 중요한 부분인 만큼 중복된 면이 없지 않아 있지만 살펴보는 것으로 한다.

먼저, main.jsp에서 <page:applyDecorator name="panel" page="/menu.do" />를 통해서 menu.do가 main.jsp에 include 된다는 것을 알 수 있다. 이는 이전 sitemesh를 이용한 include 방식과 동일하다. 다만 URL이 menu.do로 변경된 것 뿐이다. 그런데 *.do는 이미 웹 애플리케이션 설정 파일인 web.xml에서 정의해 두어 확장자가 do인 것을 DispatcherServlet이 처리하는 것을 알 수 있다. 즉, *.do로 들어오는 URL은 DispatcherServlet이 요청을 받아 Spring MVC에서 클라이언트의 요청을 처리하는 과정을 따르게 되는 것이다.

다음은 menu.do를 Controller와 연결시키는 부분을 담당하는 action-servlet.xml을 살펴보자. 앞에서 구현한 action-servlet.xml을 menu.do를 연결시키기 위해서 수정한 것을 살펴보면 다음과 같다.

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"> <beans> <!-- static view controller --> <bean id="staticViewController" class="com.mediachorus.middleware.common.web.MyUrlFilenameViewController" /> <!-- simple view controller --> <bean id="indexController" class="org.springframework.web.servlet.mvc.ParameterizableViewController"> <property name="viewName"> <value>/index</value> </property> </bean> <!-- leftMenuController --> <bean id="leftMenuController" class="com.mediachorus.middleware.common.web.MenuController" /> <!-- View Resolver --> <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="viewClass"> <value>org.springframework.web.servlet.view.JstlView</value> </property> <property name="cache" value="false" /> <property name="prefix" value="/WEB-INF/jsp/" /> <property name="suffix" value=".jsp" /> </bean> <!-- URL Mapping --> <bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"> <property name="mappings"> <props> <!-- static view mapping --> <prop key="**/*.html">staticViewController</prop> <prop key="index.do">indexController</prop> <prop key="/menu.do">leftMenuController</prop> </props> </property> </bean> </beans> 

먼저, "urlMapping" bean id를 가지는 <prop>태그를 보면 <prop key="index.do">indexController</prop>, <prop key="/menu.do">leftMenuController</prop> 가 추가되었다. "index.do"로 들어오는 URL에 대해서 indexController를 얻게 된다. 이는 결과적으로 살펴보면 index.html 이나 index.do 모두 동일한 결과를 가지게 됨을 의미한다. 즉, 우리가 만들고자 하는 정적인 페이지를 최종 랜더링 하게 된다. 결국 "index.do"도 Spring MVC 클라이언트 처리의 과정을 거치게 된다.

다음으로는 <prop key="/menu.do">leftMenuController</prop> 추가된 것을 살펴볼 차례이다. key값을 정의된 URL이 "/menu.do"이면 leftMenuController를 bean으로 가지는 것을 의미한다. 이는 자세하게 설명하자면 클라이언트가 menu.do로 URL을 요청하면 DispatcherServlet은 HandlerMapping에게 URL 정보를 넘겨주고, Handler Mapping은 넘겨진 URL에 대한 Controller(여기서는 leftMenuController)를 찾아 DiapatcherServlet에게 반환한다. 그러면 DispatcherServlet은 leftMenuController에게 위임을 하는데 이 때 사용하는 클래스가 MenuController 이다. MenuController는 논리적인 이름으로 ModelAndView를 반환하여 InternalResourceViewResolver를 통해서 최종 랜더링이 된다.
이 때 만약 MenuController가 View객체로서 ModelAndView를 반환하면 View 객체를 통해서 랜더링 하게 된다.

MenuController

MenuController의 역할은 이미 위에서 설명한바 있다. HandlerMapping이 반환한 Controller에 해당하는 객체로서 논리적인 이름으로 최종 JSP를 랜더링 하기 위한 클래스이다. 소스 코드는 다음과 같다. 이 때 javajigi에 없는 주석을 넣어 위에서 설명한 것과 main.jsp가 호출되는(클라이언트가 요청하는) 단계부터 Spring MVC가 요청을 처리하는 과정을 기입해 두었다.

/** * MenuController * org.springframework.web.servlet.mvc.Controller을 implements하여 구현한 클래스 * * 메뉴를 디스플레이하기 위한 클래스이다. 
* action-servlet.xml의 menuController id를 가지는 bean 태그와 연결된다. 
* * 실행순서 * 
1. index.html 또는 index.do 형태로 URL접속을 한다. * 
2. sitemesh framework를 사용함으로서 WEB-INF/jsp/decorators/main.jsp를 통해서 
   static page를 랜더링한다. * 
3. 이 때, main.jsp에 포함된 두 개의 jstl 태그 중 
  * <page:applyDecorator name="panel" page="/menu.do" />에 해당하는 
  URL을 처리한다. * 
4. menu.do로 호출함으로서 action-servlet.xml의 urlMapping id를 가지는 
  bean을 사용한다. * 
5. urlMapping bean 중에 <prop key="/menu.do">leftMenuController</prop>에 대한 
  처리를 실시한다. * 
6. pro 태그의 key 값이 /menu.do이고, 해당 value가 leftMenuController임으로 * 
   action-servlet.xml의 leftMenuController bean을 실행한다. * 
7. leftMenuController에 해당하는 클래스가 MenuController인 것을 
  action-servlet.xml에서 확인할 수 있다. * 
8. 이는 최종적으로 랜더링 하기위한 jsp로 WEB-INF/jsp/decorators/menu.jsp를 호출한다. */
 package com.mediachorus.middleware.common.web; 
 import javax.servlet.http.HttpServletRequest; 
 import javax.servlet.http.HttpServletResponse; 
 import org.springframework.web.servlet.ModelAndView; 
 import org.springframework.web.servlet.mvc.Controller; 
 /**
  * @author Sang Hyup LEE 
  * 2006년 3월 14일에 주석작성 */ 
 public class MenuController implements Controller { 
  /* (non-Javadoc) 
  * @see org.springframework.web.servlet.mvc.Controller# 
  * handleRequest(javax.servlet.http.HttpServletRequest, 
   javax.servlet.http.HttpServletResponse) */ 
 public ModelAndView handleRequest(HttpServletRequest request, 
  HttpServletResponse response) throws Exception { 
  //TODO Auto-generated method stub 
  return new ModelAndView("/decorators/menu"); 
  }
 } 

loginFormController

main.jsp에는 menu.do와 함께 /user/login.do URL이 포함되어야 하는 것을 위에서 보았다. 이번 세션에서는 바로 "/user/login.do"를 처리하는 과정을 살펴볼 것이다. 앞에서 했던 것 처럼 먼저 살펴볼 부분은 action-servlet.xml 이다. 이제 action-servlet.xml은 완성된다(이 때의 완성은 정적인 메인페이지 하나를 표현하기 위한 샘플로 완성된 것이다. javajigi님의 Spring MVC 전체 예제소스를 완성하기 위해서는 추가적인 작업이 필요한데 여건이 허럭한다면 계속해서 살펴볼 예정이다).
수정된 action-servlet.xml은 다음과 같다.

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"> <beans> <!-- static view controller --> <bean id="staticViewController" class="com.mediachorus.middleware.common.web.MyUrlFilenameViewController" /> <!-- simple view controller --> <bean id="indexController" class="org.springframework.web.servlet.mvc.ParameterizableViewController"> <property name="viewName"> <value>/index</value> </property> </bean> <!-- leftMenuController --> <bean id="leftMenuController" class="com.mediachorus.middleware.common.web.MenuController" /> <!-- loginFormController --> <bean id="loginFormController" class="com.mediachorus.middleware.member.web.LoginFormController"> <property name="validator" ref="beanValidator" /> <property name="formView" value="/decorators/login" /> <property name="successView" value="redirect:/index.html" /> <property name="memberService" ref="memberService" /> </bean> <!-- View Resolver --> <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="viewClass"> <value>org.springframework.web.servlet.view.JstlView</value> </property> <property name="cache" value="false" /> <property name="prefix" value="/WEB-INF/jsp/" /> <property name="suffix" value=".jsp" /> </bean> <!-- URL Mapping --> <bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"> <property name="mappings"> <props> <!-- static view mapping --> <prop key="**/*.html">staticViewController</prop> <prop key="index.do">indexController</prop> <prop key="/menu.do">leftMenuController</prop> <prop key="/user/login.do">loginFormController</prop> </props> </property> </bean> <!-- beanValidator --> <bean id="beanValidator" class="org.springmodules.commons.validator.DefaultBeanValidator"> <property name="validatorFactory" ref="validatorFactory" /> </bean> </beans> 

action-servlet.xml을 하나씩 살펴보다 보니 중복된 코드가 많다. 보는 이들의 비교 자료가 될 거 같아서 이렇게 진행하는 것을 양해해 주기 바란다.
추 가된 내용은 "urlMapping"에 <prop key="/user/login.do">loginFormController</prop>와 loginFormController를 bean id로 하는 bean 태그, 그리고 beanValidator bean이다.
loginFormController bean은 LoginFormController를 클래스로 가지고 있으며, property로 validator, formView, successView, memberService를 가진다. 다시 validator는 beanValidator를 참조하고 있으며 beanValidator은 DefaultBeanValidator를 클래스로 가지며, validatorFactory를 참조한다. validatorFactory은 applicationContext-validator.xml 파일에 별도로 정의되어져 있다.
다음은 applicationContext-validator.xml 파일의 내용이다.

<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" 
 "http://www.springframework.org/dtd/spring-beans.dtd"> 
 <beans> 
 <bean id="validatorFactory" class="org.springmodules.commons.validator.DefaultValidatorFactory"> 
  <property name="validationConfigLocations"> 
  <list> 
   <value>/WEB-INF/validation.xml</value> 
   <value>/WEB-INF/validator-rules.xml</value>
  </list> 
 </property> 
 </bean>
 </beans> 

applicationContext-validator.xml은 웹 애플리케이션 실행될 때, web.xml의 contextConfigLocation를 통해서 초기에 로딩되어져 사용되고 action-servlet.xml의 beanValidator에 의해서 호출되어 진다. 그리고 validatorFactory은 다시 DefaultValidatorFactory 클래스를 가지며 property로 validationConfigLocations를 가진다. validatonConfigLocations은 두 개의 파일 - validation.xml과 validator-rules.xml - 을 가지는데 이는 검증 규칙을 정의한 것으로 Spring을 이용한 유효성 체크를 위해서 사용된다. validation.xml과 validator-rules.xml 에 해당하는 내용은 여기서 생략하고 실제 예제 소스를 통해서 살펴보기 바란다.

formView는 value로 "/decorators/login"를 가지고 있어 실제 "WEB-INF/jsp/decorators/login.jsp"를 view(랜더링)하게 된다. successView는 검증일 거친 후, redirect 되는 경로를 지정하고, memberService(javajigi 예제에서는 userService로 정의되어져 있다)는 "memberService"를 참조하여 memberService Impl 클래스를 이용할 수 있도록 설정한 것이다.

여기서 잠시 언급하는 부분은 Spring에서 설정 파일들을 이해하는 것이 대단히 중요하다는 것이다. 각각의 bean을 설정하고 수정, 셋팅하는 부분에 의해서 많은 차이가 있다.

이 제 각자 loginFormController를 살펴보기 바란다. LoginFormController 소스를 살펴보면 파라미터에 따라서 login을 수행하기도 하고, logout을 수행하기도 한다. Authenticate 클래스를 model package에 생성하여 로그인/로그아웃 처리를 수행하며 로그인 처리는 memberService로 선언된(javajigi의 Spring 예제에서는 setter injection으로 IoC를 구현했다) login 메소드를 통해서 로그인 하고, findUser를 통해서 얻어진 User 객체를 session에 저장함으로서 로그인 처리를 완료한다.

마무리 및 테스트

이것으로 정적인 페이즈를 랜더링 하기 위한 대부분의 구현이 완료되었다. 마지막으로 "WEB-INF/jsp/decorators" 디렉토리에 있어야 할 JSP 페이지를 언급하면 다음과 같다. 물론 실제 책의 예제소스에서는 더 많은 JSP 파일이 존재하는 데 여기서는 점차적으로 애플리케이션을 발전 시키는 과정에서의 정적인 페이지에 대한 예제임으로 필요한 파일만 언급한다.

  • login.jsp
  • main.jsp
  • menu.jsp
  • panel.jsp : panel.jsp가 생략되면 menu와 login 화면이 약간 이상하게 되는 것을 확인할 수 있다. 시험삼아 해 보는 것도 권장한다.

그리고 "WEB-INF/jsp/index.jsp" 이다. 각각의 jsp 파일은 책의 예제 소스를 참조하기 바란다.

이것으로 Spring MVC를 활용한 정적인 페이지 호출에 대한 모든 과정이 완료된 것이다. 앞에서 미리 보고자 했던 페이지를 살펴보길 바란다.

[책소개]안드로이드 입문서 - kandroid 출간

아래의 주소를 통해서 구입이 가능합니다.
다른 곳에서는 판매를 하지 않기 때문에 kandroid.org 에서만 구입이 가능합니다.

Google Android Developer's Guide를 번역한 책입니다. 상당한 도움이 될듯 합니다^^


사용자 삽입 이미지

Spring framework jpetstore 샘플 분석기

지금은 안드로이드 애플리케이션을 개발하다보니 spring framework, JEE, Java 에 대한 포스팅을 할 기회가 잘 없게 된다.
그런데, 이전에 해둔 경험이 있는지라 회사내 프로젝트를 진행하는 중에 지원을 많이 해 주게 된다.
세미나, 제안서 작성, 질의에 대한 응답 등으로 상당한 시간을 보내다보니 잊혀질만 하면 기억해야 하는 수고가 생긴다.
그러던 중에 이전에 작성해 둔 spring 자료를 찾다보니 정리할 필요가 있어 해 둔다.

다음은 javajigi.net 에 Spring 프레임워크내에 jpetstore를 구현해 놓았는데 공부하면서 분석해 놓은 자료가 있어 링크해 둔다.
이 버전은 Spring1.x 버전이어서 최근에 도움이 될지는 의문이 들기도 한다^^

Spring jpetstore 샘플 분석기

1. jpetstore 설치하기
2. jpetstore 에서의 Spring 초기 설정과 IoC
3. jpetstore 에서의 Spring MVC 설정
4. jpetstore 에서의 HandlerMapping
5. jpetstore 에서의 InternalResourceViewResolver
6. jpetstore 예제로 살펴보는 Spring MVC와 iBatis 연동