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

2009년 8월 12일 수요일

[링크]JDK6 한글문서

JDK6 문서를 한글화해둔 사이트가 있다.
아마도 일본 사이트를 번역해 둔 사이트인 듯 하다.
그래도 참조할 부분이 있다.



중학교과서에 ‘안철수 코너’ 생긴다

안철수 카이스트 석좌교수님이 중학교 교과서에 소개된다고 한다.
얼마전 무릎팍도사에 출연하면서 안철수 신드롬을 불러 일으켰고, 학부모들이 안철수 교수님을 통한 교육에 대단한 관심을 보였었다.


책에서는 "꿈을 향하여"라는 주제로 한 학생과 안교수님과의 대화 형식으로 이루어진다고 한다.

자신의 성공과 철학을 소신과 겸손으로 설파하는 모습이 기대된다^^

2009년 8월 4일 화요일

'텍스트큐브' 오픈

태터앤컴퍼니의 대표 서비스인 '텍스트큐브' 설치형 블로그가 진화했다.
태너앤컴퍼니가 구글코리아에 인수되면서 이후의 방향이 궁금했었는데 그 모습을 일반인에게 공개한 것이다.

먼저 기사의 내용을 보자.


그리고 궁금함을 못 이겨 일단 텍스트큐브 블로그를 오픈해 보았다.


인터페이스 자체가 많이 바뀌었다. SKIN이 바뀌었다는 말이 아니라 관리자 페이지가 많이 바뀌었다^^
이전의 텍스트큐브 백업 파일로 복원해보니 정상적으로 잘 복원도 되었다.

중요한 건 한국 기업의 서비스가 전세계를 상대로 서비스가 될 것이란 것이다.
블로그의 특성상 SNS를 대표하는 웹2.0 기반의 서비스이다 보니 주목하지 않을 수 없다.

계정은 구글 계정을 사용할 수 있으니 쉽게 블로그를 만들 수 있다.
'텍스트큐브'를 이용한 블로그를 할 지는 모르겠지만 일단 만들어 둔 상태로 두어야겠다.
그동안 블로그가 없던 사람들은 새롭게 블로그를 개설해 볼 만 하다