2009년 12월 22일 화요일
2000년 이후 IT산업 10대 사건
2009년 12월 14일 월요일
박원순 변호사님 명함 득탬하다!
2009년 12월 11일 금요일
옷걸이 독서대 - 이름은 '북스탠드업', 아이폰 거치대
2009년 12월 10일 목요일
구글의 미래기술 소개
2009년 12월 6일 일요일
2009년 12월 1일 화요일
사내 아이폰 열풍
2009년 11월 25일 수요일
크롬 OS 소스코드가 공개되었습니다
2009년 11월 20일 금요일
한 달간의 생활
크롬OS - TV처럼 바로 켜지는 PC 나온다
2009년 11월 9일 월요일
삼성, 독자 모바일 플랫폼 '바다' 공개
2009년 11월 3일 화요일
위대한 리더는?
2009년 10월 29일 목요일
구글, 네비게이션 시장 진출에 대한 생각
The Java Developers Almanac 1.4 소스 사이트

2009년 10월 19일 월요일
JBoss강좌-3.2(BMP Example)
JBoss강좌-3.1(BMP Example)
JBoss강좌-1(설치 및 실행)
2009년 10월 14일 수요일
드디어 '구글 도서검색' 서비스가 시작되다
2009년 10월 13일 화요일
사람이 사람에게
2009년 10월 12일 월요일
우리의 상상이 조금씩 이루어진다
2009년 10월 9일 금요일
구글코드 안에 Android 관련된 코드를 찾아보자
2009년 10월 7일 수요일
소유를 넘어 접속의 시대 열린다
2009년 9월 30일 수요일
안철수 KAIST 석좌교수 "개발자가 성공하는 길"
HashMap의 key에 MultiKey object 사용해 보자.
{
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 );
}
}
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);
2009년 9월 25일 금요일
블로그를 textcube 로 이전하다!!
2009년 9월 22일 화요일
[링크]HTC 안드로이드폰 국내 출시된다
닌텐도는 화투 팔던 회사였다
2009년 9월 17일 목요일
[링크]TDD(테스트 주도 개발) WIKI
2009년 9월 11일 금요일
집단지성이란 무엇인가 - 우리는 나보다 똑똑하다

2009년 8월 25일 화요일
[링크]괜찮은 아이콘 다운로드 사이트
2009년 8월 24일 월요일
[축하해주세요^^]SDN(Sun Developer Networks) 인기 블로그에 두 개나 올리다!!

2009년 8월 23일 일요일
[링크] Android 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에 소개되는 클라이언트 요청을 처리하는 과정을 반드시 읽어보아야 한다.
여기에는 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 출간

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 연동