얼마전 백기선님의 "스프링 MVC에서 타일즈 2 사용하기" 포스팅을 참조로 스트라이프에서 스프링 MVC + 타일즈로 갈아탔었다. 당시에는 급박해서 그냥 그대로 하긴 했었는데 다음과 같이 페이지마다 definition 을 설정하는 것은 영 성가신게 아니다.

<definition name="cm/meta/meta.create" extends="tiles/cm">

<put-attribute name="title" value="메타 속성 등록" />

<put-attribute name="menu" value="/tiles/menu.cm.jsp" />

<put-attribute name="description" value="메타 속성을 등록합니다." />

<put-attribute name="body" value="/cm/meta/meta.create.spring.jsp" />

</definition>

<definition name="cm/meta/meta.modify" extends="tiles/cm">

<put-attribute name="title" value="메타 속성 수정" />

<put-attribute name="menu" value="/tiles/menu.cm.jsp" />

<put-attribute name="description" value="메타 속성을 수정합니다." />

<put-attribute name="body" value="/cm/meta/meta.modify.spring.jsp" />

</definition>

<definition name="cm/meta/meta.delete" extends="tiles/cm">

<put-attribute name="title" value="메타 속성 삭제" />

<put-attribute name="menu" value="/tiles/menu.cm.jsp" />

<put-attribute name="description" value="메타 속성을 삭제합니다. 이미 컨텐츠 유형이나 분류체계 유형에서 사용하고 있다면 삭제할 수 없습니다. 정말 삭제하시겠습니까?" />

<put-attribute name="body" value="/cm/meta/meta.delete.spring.jsp" />

</definition>


1. 기본 스프링 & 타일즈 설정


그래서 이런 노가다를 없앨 수 있는 방법을 타일즈에서는 여러가지 방법으로 제공하고 있다.

이번에 적용할 방법은 EL 표현식과 와일드카드를 이용하는 방법이다.

이런 방법을 사용하기 위해서는 타일즈 팩토리를 만들어 낼 때, 몇가지 설정이 추가되어야하는데 다행히 스프링에서 엄청 간단한 방법을 제공하고 있다.


<bean id="viewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver">

<property name="viewClass" value="org.springframework.web.servlet.view.tiles2.TilesView"></property>

<property name="order" value="1" />

</bean>

<bean id="viewResolver2" class="org.springframework.web.servlet.view.BeanNameViewResolver" >

<property name="order" value="2"></property>

</bean>

<bean id="jspViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">

<property name="prefix" value="/" />

<property name="suffix" value=".spring.jsp" />

<property name="order" value="3" />

</bean>

<bean id="tilesConfigurer" class="org.springframework.web.servlet.view.tiles2.TilesConfigurer">

<property name="completeAutoload"><value>true</value></property>

<property name="definitions">

<list>

<value>/WEB-INF/tiles2/tiles-*.xml</value>

</list>

</property>

</bean>


위 소스는 뷰리졸버로, 첫번째로 타일즈 뷰 그거없으면 빈네임으로, 그것도 없으면 jsp 렌더링으로 하라는 소스다. 요건 하든지 말든지 알아서 하시고 ㅎㅎ,

여튼, 중요한건 타일즈 속성의 completeAutoload 속성을 true 로 하면 여러가지 표현식을 사용할 수 있게 된다.

물론 이러한 기능을 사용하기 위해서는 tiles-core 가 아닌 tiles-extra 라이브러리가 필요하다.

메이븐 설정에 다음이 들어가 있어야한다.(물론 메이븐을 안 쓰면, 라이브러리만 구해다가 클래스 패스에 등록하면 된다)


<dependency>

<groupId>org.apache.tiles</groupId>

<artifactId>tiles-extras</artifactId>

<version>2.2.2</version>

</dependency>


자, 이제 필요한 설정은 전부 끝났다.

와일드카드와 EL 표현식을 적용한 샘플을 작성해보자.

우선 레이아웃 페이지를 작성한다.


/layout/admin-layout.xml

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %><%@ 

taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %><%@ 

taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %><%@

taglib prefix="tiles" uri="http://tiles.apache.org/tags-tiles"

%><!doctype html>

<html lang="ko">

<head>

<meta charset="utf-8">

<meta name="description" content="타일즈 어플리케이션">

<meta name="keywords" content="">

<title><tiles:insertAttribute name="title" /></title>

</head>

<body>

<div id="header">

<h1><tiles:insertAttribute name="title" /></h1>

<nav id="main-menu"><tiles:insertAttribute name="menu" /></nav>

</div>

<div id="page-content">

<tiles:insertAttribute name="body" />

</div>

</body>


주의 깊게 볼 부분은 레이아웃에 넘겨줄 속성 부분이다. 위 샘플은 title, menu, body 를 넣도록 하고 있다.


그다음은 타일즈에서 해당 레이아웃을 사용하고, 각 속성을 넣을 방법을 정의하는 타일즈 deifnition 설정 부분이다.


/WEB-INF/tiles2/tiles-layout.jsp

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE tiles-definitions PUBLIC "-//Apache Software Foundation//DTD Tiles Configuration 2.1//EN" "http://tiles.apache.org/dtds/tiles-config_2_1.dtd">

<tiles-definitions>

<!-- Default Layout -->

<definition name="default-layout" template="/layout/default-layout.jsp">

<put-attribute name="title" value="무제" />

<put-attribute name="menu" value="/layout/empty.jsp" />

<put-attribute name="body" value="/layout/empty.jsp" />

</definition>

<!-- Content -->

<definition name="tiles/admin/index" extends="default-layout">

<put-attribute name="title" value="관리자 페이지" />

<put-attribute name="menu" value="/layout/menu.admin.jsp" />

<put-attribute name="body" value="/admin/index.jsp" />

</definition>

</tiles-definitions>


일단은 definition 에서 수동으로 들어갈 값을 직접 입력해보았다. 이후에 el 표현식과 와일드 카드를 순차적으로 적용하는 것을 보여드릴테니, 조급해하지 마시길:)


그다음은 컨트롤러다.


import org.springframework.stereotype.Controller;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.servlet.ModelAndView;


@Controller

public class AdminController {

@RequestMapping("/admin/index.do")

public ModelAndView adminIndex() {

ModelAndView mav = new ModelAndView("tiles/admin/index");

return mav;

}

}



위와 같이 작성하면 /admin/index.do 로 접근시에 다음과 같이 렌더링된다.

<!doctype html>
<html lang="ko">
<head>
<meta charset="utf-8">
<meta name="description" content="타일즈 어플리케이션">
<meta name="keywords" content="">
<title>관리자 페이지</title>
</head>
<body>
<div id="header">
<h1>관리자 페이지</h1>
<nav id="main-menu">
<ul>
<li>전광판 관리</li>
<li>사용자 관리</li>
</ul>
</nav>
</div>
<div id="page-content">
<p>관리자 페이지입니다.</p>
</div>
</body>




자, 이제 노가다를 없애보자.


2. EL 적용


우선 타이틀을 타일즈 설정 파일에서 박는게 아니라 컨트롤러에서 값을 유동적으로 변경 가능하도록 해보자.

컨트롤러를 다음과 같이 title attirbutue 를 추가한다.

@Controller

public class AdminController {

@RequestMapping("/admin/index.do")

public ModelAndView adminIndex() {

ModelAndView mav = new ModelAndView("tiles/admin/index");

mav.addObject("title", "관리자 페이지");

return mav;

}

}


그리고 타일즈 설정파일에 해당 값을 el 표현식으로 바꾼다. value 속성이 아닌 expression 속성을 사용한다는 것을 명심하자.


<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE tiles-definitions PUBLIC "-//Apache Software Foundation//DTD Tiles Configuration 2.1//EN" "http://tiles.apache.org/dtds/tiles-config_2_1.dtd">

<tiles-definitions>

<!-- Default Layout -->

<definition name="default-layout" template="/layout/default-layout.jsp">

<put-attribute name="title" value="무제" />

<put-attribute name="menu" value="/layout/empty.jsp" />

<put-attribute name="body" value="/layout/empty.jsp" />

</definition>

<!-- Content -->

<definition name="tiles/admin/index" extends="default-layout">

<put-attribute name="title" expression="${title}" />

<put-attribute name="menu" value="/layout/menu.admin.jsp" />

<put-attribute name="body" value="/admin/index.jsp" />

</definition>


</tiles-definitions>


끝이다. 

만약, template 속성에도 el 을 적용하고 싶을 경우에는 template 속성 대신, templateExpression 속성을 


3. 와일드 카드 적용


이번엔 와일드 카드를 이용해서, body 영역과 메뉴도 동적으로 변경해보자. (이부분도 el 표현식을 이용해도 상관은 없다. 이 글에선 샘플 작성을 위해 일부러 와일드 카드를 이용한다.)


<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE tiles-definitions PUBLIC "-//Apache Software Foundation//DTD Tiles Configuration 2.1//EN" "http://tiles.apache.org/dtds/tiles-config_2_1.dtd">

<tiles-definitions>

<!-- Default Layout -->

<definition name="default-layout" template="/layout/default-layout.jsp" templateExpression="">

<put-attribute name="title" value="무제" />

<put-attribute name="menu" value="/layout/empty.jsp" />

<put-attribute name="body" value="/layout/empty.jsp" />

</definition>

<!-- Content -->

<definition name="WILDCARD:tiles/*/**" extends="default-layout">

<put-attribute name="title" expression="${title}" />

<put-attribute name="menu" value="/layout/menu.{1}.jsp" />

<put-attribute name="body" value="/{1}/{2}.jsp" />

</definition>

</tiles-definitions>


우선 와일드 카드를 사용하는 부분에 대해선 "WIDCARD:" 라고 prefix 코드를 넣어줘야한다. 

그러며 * 패턴에 대해 매칭되는 갑사을 순차적으로 {1}, {2} 등으로 사용할 수 있게 한다.


위 설정대로라면 "/tiles/admin/index" 라는 뷰네임은 다음과 같이 매핑된다.

  • {1} : admin
  • {2} : index
패턴중에 ** 라고 기입을 하면, '이하' 로 풀이한다. (앤트 표현식)
위와 같이 설정한 이유는 다음과 같은 방식에서도 유효하게 하기 위함이다.

예를 들어 "tles/admin/user/manage" 일 경우
  • {1} : admin
  • {2} : user/manage
이렇게 와일드 카드와 el 표현식을 이용해 노가다를 상당히 줄여줄 수 있을 것이다. 다만, 스트라이프처럼 jsp 에 레이아웃으로 값을 넘기는 방법에 대해서는 아직 모르겠다. (타일즈 3.x 에서는 있으려나 모르겠다.)


이 문서는 스프링 3.0.7, tiles 2.2.2 로 작성되었다.


참조링크

  • http://whiteship.me/?p=11657
  • http://tiles.apache.org/2.2/framework/tutorial/advanced/wildcard.html
  • http://tiles.apache.org/2.2/framework/tutorial/advanced/el-support.html
  • http://kaludin.egloos.com/2799009



저의 전공들입니다. 배워도 배워도 끝도 없는 세상. 언제쯤 마무리 지을런지..

오픈 소스, Maven, Hibernate, Spring ,Stripes , Spring, Spring Security, Java,Css,Web 2.0,iBatis,EJB,J2EE,Dojo Toolkit, Prototype.js, Script.aculo.us, jQuery, Trac, Eclipse

 

이젠 저 혼자 아는 것도 외로워서리, Java 개발자라면 Java 개발자다운 세상을 만들어 가보고 싶네요.

궁금한게 있으시다면 질문 언제나 환영입니다. 비록 포스팅은 많이 하지 않지만..;;


Spring

이제 거의 모든 프로젝트에 스프링을 필수 입니다. 물론 스프링 프레임웍이 최고라고 단정할 수 없겠습니다만, 세계적으로 이만한 기반을 쌓아놓았다는 것 자체가 힘입니다.

스프링은 그저 Dependency Injection(Inversion of Control), AOP(Aspect Oriental Programming) 밖에 없습니다. 이2개로 다 해결하죠. 

또한 이놈을 씀으로서 자연스럽게 소스를 구조화시키죠. 스파게티로부터 일단 한단계는 벗어나는겁니다.

묻지 마시고, 일단 이건 시작하십시오.

 

Maven

정말 이놈을 만난 순간 이런 세상에 내가 태어났다는게 참으로 감사했죠. 이놈이 나오기전에 내가 있엇으면 참 얼마나 뻘짓들을 하면서 살았을련지.

Ant 를 대체하며, 태스크 중심이 아닌 프로젝트 빌드에 초점을 맞춘 툴입니다.

전세계의 97% 오픈소스가 Maven 으로 기반으로 되어있다고 합니다.

우리 회사는 오픈 소스 아니니깐 상관없어?

무슨 그런 말씀을..ㅡㅡ;;; Maven 을 도입하고 조금 더 게을러져봅시다. 

Hibernate

오랜 시간동안 하이버네이트를 다뤄왔습니다. 국내에서는 별로 쓰이지도 않음에도 불구하고, 그 매력에 빠져 헤어나오지를 못하네요..^^

이제 하이버네이트에 대한 부담감이 없지만, 초창기에는 국내 커뮤니티가 참으로 작아 힘들었더랬죠.

이젠 제가 여러분에 도움을 드릴 수 있지 않을까 합니다.

 

 

Stripes

스트라이프를 써보셨나요? 들어본 적도 없으시죠?

스트럿츠, 스프링 웹MVC 모두 저리가라입니다. 프레임워크에 학을 때시나요?

현재는 스트라이프가 답일 거라 생각합니다. 이또한 국내 커뮤니티가 전무하군요..

워낙 쉬워서 사실 국내문서화가 얼마나 필요할까 싶기도 합니다만..^^

스트러츠를 갈아버리는 그 날까지 제가 일조를 했으면 하는군요


Prototype.js, jQuery, Dojo Toolkit, Ajax

사실 Ajax 라는 것은 무척쉽습니다. 한줄이면 끝나는 말인걸요.

비동기적으로 서버에 메시지 보내서 받아오는 것

이미 알고 계신가요ㅎㅎ 그저 자바스크립트가 싫을 뿐인거죠? 

이러한 자바스크립트 라이브러리를 사용해 보십시오. 자바 스크립트도 나름 재밌구나라는 생각도 듭니다.

지긋한 스크립트 지옥으로부터 탈출하는 습관을 만들어 줄겁니다.



이 글은 스프링노트에서 작성되었습니다.

maven 의 assmbly 기능을 이용해서 단일 dependency 로 만들었을 경우(jar-with-dependencies 사용)에 만들어진 jar 파일로 실행하면 spring.scheas 파일들이 중복되는 오류가 발생한다.

해당 이슈에 대하여서 Spring JIRA 에 등록되어 있다. http://jira.codehaus.org/browse/MASSEMBLY-360

여하튼, 해결 방법은 assembly:assembly 를 시행할 프로젝트의 리소스 폴더에 META-INF 하위로 스프링 스키마 파일들을 복사해놓고 assembly 시키는 것이다.

예를 들어
디렉터리 구조
src/main/resources/META-INF/spring.handlers
src/main/resources/META-INF/spring.schemas

console>mvn assembly:assembly

하면 된다. 스키마 파일들은 스프링 jar 파일들을 풀면 구할 수 있다.
Filter 안에서 스프링을 사용하기 위해선 스프링에서 제공하는 DelegatingFilterProxy 를 이용한다. 스프링 필터 체인방식은 예전에 Acegi 에서 사용된 시큐리티 필터 체인으로부터 가져온것으로 현재는 Spring-Securtity 프로젝트로 통합되었다.

여하튼, 사용하는 방법은 javax.servlet.Filter 인터페이스를 상속받은
DelegatingFilterProxy 필터 체인 클래스를 사용하면 된다.

1.
GenericFilterBean 클래스 상속받은 Filter 클래스 작성


package com.vine.edms.web;

 

import java.io.IOException;

 

import javax.servlet.FilterChain;

import javax.servlet.ServletException;

import javax.servlet.ServletRequest;

import javax.servlet.ServletResponse;

 

import org.springframework.web.filter.GenericFilterBean;

 

import com.vine.edms.webapp.envirement.WebAppEnvirementService;

import com.vine.util.CommonWebFilter;

 

public class VineWebFilter extends GenericFilterBean {

       private WebAppEnvirementService envirement; // Spring beans

       public void setWebAppEnvirementService(WebAppEnvirementService envirement) {

             this.envirement = envirement;

       }

 

       public void doFilter(ServletRequest request, ServletResponse response,   FilterChain chain) throws IOException, ServletException {

             CommonWebFilter.addCommonAttributes(request);

             request.setAttribute("_VW_SKIN", envirement.getSkin());

             request.setAttribute("_VW_TITLE", envirement.getAppTitle());

             chain.doFilter (request, response);

       }

}


2. Spring bean 설정

<bean id="edmsWebAppCommonFilter" class="com.vine.edms.web.VineWebFilter" p:webAppEnvirementService-ref="edmsWebAppEnvirementService" />



3. web.xml 등록

가장 중요한 web.xml 설정 부분이다. init-param 속성을 이용하여 별도의 bean 을 설정하지도 않지만, 기본적으로 filter-name 과 동일한 bean 을 사용하여 필터를 매핑한다.

여기선 edmsWebAppCommonFilter 명을 가진 빈을 만들었고, web.xml 에서 또한 필터 이름을 edmsWebAppCommonFilter 로 정의하였다.


그리고 필터 체인은 2개 이상을 사용해도 무방하다. 아래 샘플은 스프링 시큐티리 체인 필터 또한 같이 사용하는 것을 알 수 있다.

    

<filter>

<filter-name>springSecurityFilterChain</filter-name>

<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>

</filter>

      

<filter>

<filter-name>edmsWebAppCommonFilter</filter-name>

<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>

</filter>

 

  

<filter-mapping>

<filter-name>edmsWebAppCommonFilter</filter-name>

<url-pattern>/*</url-pattern>

</filter-mapping>



요즘 스프링 시큐리티에 좀더 깊이있는 정보가 필요하다. 레퍼런스 또한 부족하기 그지 없으니.. 어디 좋은 책이라도 없으려나ㅡㅜ
얼마전 사내 svn 서버를 이동하면서 svn 서버를 업그레이드를 해버렸다.
visual svn 1.6 대에서 1.7버젼으로.
덕분에 기존 소스를 동기화시킬때, 오류가 났다. svn 스펙에 따라 서버 버젼이 정의되고 있는지 모른것이 화근.


Visual SVN Server 1.6.x 는 SVN 1.4.x 스펙
Visual SVN Server 1.7.x 는 SVN 1.6.x 스펙이다.

그래서 이 기회에 다시 한번 기본 환경구축에 대한 가이드를 작성해본다.

==================================================

* Eclipse 설치.
eclispe 는 eclipse.org 에서 j2ee 용으로 설치한다. 현재 버젼은 3.4.2 버젼까지 릴리즈되어있다.

* svn 플러그인 설치
1. Eclipse 실행 후 [Help] -> [Software Updates] 를 클릭하여 플러그인 업데이트 화면을 연다.

2.[Available Software] 탭을 선택한 후 [Add Site] 클릭

3.다음 업데이트 URL 을 기입한다.
http://subclipse.tigris.org/update_1.6.x

만일 svn 서버가 1.4.x 스펙을 사용한다면 다음 url 을 사용하라.
http://subclipse.tigris.org/update_1.4.x

4.업데이트 URL 을 추가하면 아래와 같이 플러그인 사이트가 등록된다. 해당 항목에 체크한 후 [Install] 클릭

5.의존 플러그인에 대해서 확인을 진행한다. 시간이 좀 걸릴거다-_-

6.의존 플러그인에 대해 적합하고, 이미 설치되어있는 것이 없다면 아래와 같이 나타난다. 만약 Details 항목에 에러 메세지가 뜬다면 영어만 잘 읽어도 오류 원인을 파악할 수 있을 거다. [Next] 클릭

7.라이센스에 동의한 후 [Finish] 클릭

8. 실제 설치가 진행된다.

9. 설치 완료 후 이클립스의 재실행을 요구한다. [Yes] 클릭

10. 끝

* mylyn, trac 플러그인 설치
trac 은 버그 추적 관리 툴이다. jira 등, 다른 bts 를 사용한다면 이 플러그인은 설치하지 않아도 좋다. 그러나 mylyn 플러그인은 필요할 것이다. (bts 가 용어가 맞던가?-_-a)
아래의 url 을 추가한다.
http://trac-hacks.org/svn/eclipsetracplugin/eclipse/update


또한 [Manage] 를 클릭하여
http://download.eclipse.org/tools/mylyn/update/extras 항목을 체크한다.



그리고 다음 2개의 항목에 대해서 체크 후 [Install] 한다. 만일 jira 를 사용한다면 extras 항목에서 trac 대신 jira 를 선택하면 된다.




* Maven 플러그인 설치
maven 플러그인은 sonatype 의 m2clipse 플러그인을 이용한다.
설치 과정은 svn 플러그인과 동일하다. 다만 업데이트 URL 과 설치 항목에 대해서만 적절하게 설정하면 된다.
필자는 아래와 같이 설정하였다.
(m2eclipse update url : http://m2eclipse.sonatype.org/update )



* Spring IDE 플러그인 설치
스프링을 사용한다면 이 플러그인은 필수다. 물론 없어도 되지만, 사용한다면 엄청.. 유용할것이다
스프링 플러그인 URL : http://springide.org/updatesite

스프링에서 사용하는 부분들에 대해서 적절히 체크한 후 [Install]


끝.

+ Recent posts