전체 글

[eclipse] JRebel HotSwap 설정

2013. 12. 17. 14:15
반응형
  • JRebel HotSwap 설정 방법

Web Application개발을 하다 보면 가장 귀찮은 점이 바로 테스트를 하면서 개발을 할 때, Java를 고치고 난 후에 Class를 컨테이너에 적용 시키기 위해서 웹서버를 내렸다가(서버를 정시시키는 것) 다시 올리는 것(서버를 가동시키는 것)이라고 할 수 있습니다.

조그마한 실수 하나에도, 또는 이게 맞는지 저게 맞는지 확신이 서지 않아서 테스트 할 때 이와 같은 서버를 재부팅하는 것은 많은 시간적 소모를 가지고 올 수 있는데, 이런 귀찮은 부분을 수정한 것이 바로 HotSwap기능이라 할 수 있습니다.

HotSwap기능이라는 것이 사실은 컴퓨터의 하드웨어적인 기능이지만 여기서 말하는 HotSwap이란 JAVA에서 말하는 Class로드 부분인 것 같다는 생각이 듭니다. 어쨌든 HotSwap기능이 있는 JRebel을 공짜로 한 번 써봅시다!!!!

 

Step 1 등록하기!!!!

우선 아래 링크로 접속을 합니다.

http://social.jrebel.com

그러면 아래와 같은 웹페이지가 나타나죠

Social JRebel 첫화면

Social JRebel 첫화면

참고! : Social JRebel은 말그대로 SNS 계정이 필요로 하는 JRebel입니다. 자세히는 않읽어 봤지만, 대략 읽어 보니 Social Network를 이용해서 홍보를 하는 것이며, 한달에 한 번 정도 자신의 SNS계정을 통해서 홍보성글을 올리는 걸로 봤습니다. 어쨌든 그래서 공짜인듯 해요. 아! 그리고 또 하나 주의 점은 non-commercial 용도라는 것입니다.

 

위에 밑줄 그은 부분(그림에서)을 클릭합니다. 그러면 다음 화면이 나타납니다.(Facebook을 하고 있다는 가정에서 하는 것입니다. Twitter 계정으로 하시는 분은 조금 다를 수 있습니다.)

1. Facebook 화면

Social JRebel 등록하기(Facebook)

Social JRebel 등록하기(Facebook)

2.Twitter계정으로 할 때의 화면

 

Social JRebel 등록하기(Twitter)

Social JRebel 등록하기(Twitter)

 

 

Facebook화면은 제 Web Browser가 이미 Facebook에 로그인이 되어있어서 바로 허가 화면이 뜬것입니다. 만약 Facebook에 로그인이 되어있지 않다면 로그인해야 할 것이고, 만약 계정이 (Twitter 계정역시) 없다면 계정을 만들어야 할 것입니다.

 

 

Social JRebel 등록화면

Social JRebel 등록화면

이제 트위터에 로그인 헀다거나, Facebook에 Social JRebel이 사용자의 계정을 가지고 광고를 해도 된다고 수락하고나면, 위와 같은 화면이 나타납니다. 뭐 기본적인 Profile을 적는 것이죠. 작성을 다 하셨다면.....아래 그림을 참고 합니다.

 

Social JRebel 등록화면

Social JRebel 등록화면

자신이 사용하는 언어와, Container(그러니까 일반적으로 웹 어플리케이션 서버)를 선택하고, 사용계정에대한 Agreement를 동의하고 JRebel을 다운받았는지 않받았는지를 선택하고 나서 "Register"(등록)을 클릭합니다.

그러면 아래와 같은 화면이 나타납니다.

등록이 완료된 화면

등록이 완료된 화면

 

여기서 Next를 누르면 라이센스키 화면으로 넘어가게 됩니다.(아래그림)

 

Social JRebel Keycode

Social JRebel Keycode

 

Step 2 Eclipse에 JRebel Plugin 설치하고 License Key Code입력하기

 

 

Eclipse 에서 JRebel 설치

Eclipse 에서 JRebel 설치

 

Eclipse에 Help>Marketplace에 가면 일반적으로 가장 먼저 보이는 것이 JRebel일 것입니다. 않보이면 JRebel을 조회해서 설치를 합니다.

Plugin 설치가 끝나고 나면 위와 같이  Eclipse메뉴에서 Window>Preferences에 가면 설정화면이 보입니다. 항목중에 JRebel이라는 항목을 클릭합니다.

JRebel plugin for Eclipse 설치 후 설정

JRebel plugin for Eclipse 설치 후 설정

 

그러면 위와 같은 설정화면이 보이는데 여기에서 "Configuration Wizard"를 클릭하시면 아래와 같은 Popup창이 하나 뜨게 됩니다.

 

JRebel plugin for Eclipse 설치 후 Configure화면

JRebel plugin for Eclipse 설치 후 Configure화면

 

팝업창이 뜨면 조금 느려 질 것입니다. 제 컴퓨터 스펙이 그닥 딸리는 편은 아닙니다. i-5코어 2.5Ghz에 RAM 8G인데도 버벅거렸으니까요;;;; 아마 대부분 느려지실 겁니다. 하지만 인내를 가지고 하시다보면 금방 끝나고, 끝이나면 괜찮아지니까요.....포기하지 마세용!!! ㅋㅋ

어쨌든 위와 같이 라디오 버튼 항목중에 "I want to use JRebel Social(FREE for non-commercial user)"라는 항목을 선택하고 하단에 "Next" Botton을 클릭합니다. 그러면 아래의 화면이 보입니다.

JRebel Configure에서 Keycode입력하기

JRebel Configure에서 Keycode입력하기

 

위에 말풍선에 표시했듯이 아까 Social Jrebel등록후에 나온 Key Code를 공간에 붙여 넣기 하고 "Next"를 누룹니다.

그리고 끝까지 가서 Finish를 누르면 일단 License Key Code등록은 끝이 났습니다.

 

마지막으로 Preferences창에 JRebel에서 아까는 Configuration Wizard를 선택했다면, 이번에는 그 바로 아랫줄에 있는 "Agent Settings"을 선택하고 아래와 같이 Project의 Root위치를 설정해 줍니다.(사실 이거 왜하는지 모르겠어요 안들어가 있어도 잘되던데;;;;;)

JRebel Agent Setting화면

JRebel Agent Setting화면

 

Step 3 Project에 설정하기!!!

자 이제 프로젝트에 설정을 해야 하는데요, Configuration Wizard에 설명은 아래 그림과 같이 나와있습니다. 그런데 저는 Eclipse Indigo를 쓰고 있는데 창이 이런 식으로는 안뜨더군요.....(다른 버전에서는 아래와 같이 뜰 수도 있지만 저는 조금 다르게 뜹니다.)

Eclipse Project에 JRebel 설정하기

Eclipse Project에 JRebel 설정하기

 

바로 아래와 같이 조금 다르게 뜨는데요. 화면은 아래와 같습니다. 

 

Eclipse Project에 JRebel 설정하기

Eclipse Project에 JRebel 설정하기

 

일반적으로 Project의 Source폴더가 src로 지정 되어있다면 위에 빨간줄 친것 처럼 "Generate rebel.xml in src"를 클릭하면 되지만 만약 Source폴더가 다를 경우에는 바로 위의 메뉴인 "Generate rebel.xml"을 눌러 Source폴더가 어디인지 지정해 줍니다.

주의! Source폴더는 *.java가 모여있는 Project내의 최상위 폴더를 이야기 합니다.

 

자 rebel.xml을 Generate했다면 이제 마지막으로 Eclipse에서 돌아가는 Tomcat서버의 설정만 하면 됩니다. 아래의 빨간줄 그은 부분들로 체크하고 저장하면 됩니다(물론 Tomcat Server는 중지시켜 놓구요)

 

JRebel을 위해서 Tomcat서버 설정하기

JRebel을 위해서 Tomcat서버 설정하기

 

이제 모든 것이 끝났습니다.

이제는 *.java파일을 아무리 고쳐도 Tomcat서버를 멈췄다가 재가동해야 하는 부분은 문명히 필요 없게 되었습니다.

 

*한가지 아쉬운점

JRebel은 다 좋은데 한가지 아쉬운 점은 바로 xml로드는 지원하지 않는다는 것입니다.

저의 경우 Struts에 iBatis를 쓰고 있는데, iBatis에서 정의해 놓은 SQL문들이 있는 XML을 아무리 바꿔도, HotSwap기능과는 거리가 있는 것 같더군요;;;;; 뭐 그부분을 빼면 나쁘진 않은 것 같습니다......^^잘 사용하세요!!!

 

 

 

 

 

반응형

[maven] maven + jenkins 연동

2013. 7. 19. 22:49
반응형

※ 본 세팅의 환경은 Win7 64Bit 입니다.

재시작 java -jar jenkins.war --ajp13Port=-1 --httpPort=8082 

1. Jenkins 설치

http://jenkins-ci.org/ 이동

Tomcat 서버를 구축한 사용자라면 war 파일로 된 Java Web Archive 를 다운 받으시고

처음 설치하시는 유저분들이라면 Native Package 를 설치하시기 바랍니다.

다운 받은 파일을 특정 폴더로 복사 한 후 cmd를 열고 war파일이 위치한 루트로 이동 후 

java -jar jenkins.war --ajp13Port=-1 --httpPort=8082 

 

 

2. 시스템 설정

-http://localhost:8082 로 이동

-설치 가능 탭 이동

-ssh 관련 플러그인 설치 후 jenkins 재부팅  

4. jdk 설정.

아래와 같이 Jenkins 관리 > 시스템설정으로 가시면

image

 

아래와 같이 JDK 설정하십시요

image

 

JDK 는 Jenkins 서버 내의 JDK Path 를 설정해주시면 되고

5. 새로운 Job 생성

- Job 이름을 짓고

아래와 같이 설정해주시면 됩니다.

새잡

6. 새로운 Job 설정

우선은 SVN 부터 설정을 하자

아래에서 설정으로 가겠습니다.

image

그러면 아래와 같이 많은 설정 중에 SVN 을 보도록 하겠습니다

image

위와 같이 SVN 으로 설정하시고 Check-out Strategy[Always check out a fresh copy] 로 설정하도록 하겠습니다

 

7. Ant 빌드 세팅하기

그럼 빌드에 앞서서 Ant 빌드를 하도록 하겠습니다.

Jenkins 는 이클립스로 빌드를 하는 것이 아니기 때문에 구글에서 제공해주는 Ant Build 툴을 사용하여야 합니다.

우선 커맨드창을 켜신 다음 ${WorkSapce}\${Project} 로 이동하시기 바랍니다.

※ Android SDK\tools 폴더가 시스템 변수로 선언되어 있어야 합니다.

커맨드 상에서 [android –help] 를 실행하시면 다양한 도움말이 나오는데

Ant 빌드용 Build.xml 을 생성하기 위해 아래와 같이 작성을 할 것입니다.

[android update project -p . -n first_project]

image

 

위와 같이 3개의 파일이 새로 생성 됩니다.

 

8. 자 이제 위의 자료를 SVN 에 커밋하시면 모든 준비가 완료되었습니다.

다시 Jenkins 프로젝트 관리 페이지로 돌아오겠습니다.

image

 

위와 같이 프로젝트 설정을 해주신 다음에

9.

[Build Now]

를 시작합니다.

각 빌드별로 콘솔 화면을 볼 수 있으니 아래와 같은 출력을 확인 할 수 있습니다.

image

위와 같이 이동하시면 아래 화면을 보실 수 있습니다.

image

위와 같이 BUILD SUCCESSFUL 을 보셨다면 빌드 성공!

 

반응형
반응형

개인적으로 SiteMesh의 동장 방식이 Tiles보다 좋기 때문에 SiteMesh를 선호하는데, SiteMesh를 사용하면서 언제나 아쉬운 점은 <servlet-mapping>의 <url-pattern>의 값을 /catalog/*와 같은 경로 기반으로 설정한 경우 SiteMesh의 데코레이터 설정 파일에서 경로 패턴에 기반한 매칭을 사용할 수 없다는 점이다. (관련글: SiteMesh를 이용한 웹 페이지 데코레이션, http://javacan.tistory.com/entry/131) 특히 요즘처럼 (REST 방식의 유행으로) 확장자 없는 URL을 제공하는 게 멋처럼 느껴질 때에는 더더욱 SiteMesh의 지원이 아쉬웠다.


이런 아쉬움을 해소하기 위해 <servlet-mapping>의 <url-pattern>의 값에 상관없이 URL 경로를 이용해서 패턴 매칭을 하는 DecoratorMapper 클래스를 작성해보았다.

WemadeConfigDecoratorMapper 클래스 구현 코드

아래 코드는 실제로 구현해서 사용하고 있는 코드이다.

package com.wemade.sitemesh;

import java.util.Properties;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;

import com.opensymphony.module.sitemesh.Config;
import com.opensymphony.module.sitemesh.Decorator;
import com.opensymphony.module.sitemesh.DecoratorMapper;
import com.opensymphony.module.sitemesh.Page;
import com.opensymphony.module.sitemesh.mapper.AbstractDecoratorMapper;
import com.opensymphony.module.sitemesh.mapper.ConfigLoader;

/**
 * 서블릿 경로가 아닌 컨텍스트 경로를 제외한 요청 URI를 이용해서 패턴 매칭을 수행한다.
 * 
 * Sitemesh 2.4.1 버전의 ConfigDecoratorMapper로부터 코드를 가져와서 작성하였음.
 * 
 * @author 최범균
 * @version 2010. 3. 5.
 */
public class WemadeConfigDecoratorMapper extends AbstractDecoratorMapper {

    private ConfigLoader configLoader = null;

    /** Create new ConfigLoader using '/WEB-INF/decorators.xml' file. */
    public void init(Config config, Properties properties,
            DecoratorMapper parent) throws InstantiationException {
        super.init(config, properties, parent);
        try {
            String fileName = properties.getProperty("config",
                    "/WEB-INF/decorators.xml");
            configLoader = new ConfigLoader(fileName, config);
        } catch (Exception e) {
            throw new InstantiationException(e.toString());
        }
    }

    /**
     * Retrieve {@link com.opensymphony.module.sitemesh.Decorator} based on
     * 'pattern' tag.
     */
    public Decorator getDecorator(HttpServletRequest request, Page page) {
        String thisPath = request.getRequestURI();
        String contextPath = request.getContextPath();
        if (thisPath.startsWith(contextPath)) {
            thisPath = thisPath.substring(contextPath.length());
        }
        String name = null;
        try {
            name = configLoader.getMappedName(thisPath);
        } catch (ServletException e) {
            e.printStackTrace();
        }
        Decorator result = getNamedDecorator(request, name);
        return result == null ? super.getDecorator(request, page) : result;
    }

    /**
     * Retrieve Decorator named in 'name' attribute. Checks the role if
     * specified.
     */
    public Decorator getNamedDecorator(HttpServletRequest request, String name) {
        Decorator result = null;
        try {
            result = configLoader.getDecoratorByName(name);
        } catch (ServletException e) {
            e.printStackTrace();
        }

        if (result == null
                || (result.getRole() != null && !request.isUserInRole(result
                        .getRole()))) {
            // if the result is null or the user is not in the role
            return super.getNamedDecorator(request, name);
        } else {
            return result;
        }
    }

}

sitemesh.xml 파일 설정에서 커스텀 DecoratorMapper 사용

sitemesh.xml 파일에서는 아래 코드와 같이 앞서 구현한 DecoratorMapper를 사용하도록 설정한다.

<sitemesh>
    <property name="decorators-file" value="/WEB-INF/decorators.xml"/>
    <excludes file="${decorators-file}"/>

    <page-parsers>
        <parser content-type="text/html" class="com.opensymphony.module.sitemesh.parser.HTMLPageParser" />
    </page-parsers>
    <decorator-mappers>
        <mapper class="com.opensymphony.module.sitemesh.mapper.PageDecoratorMapper">
            <param name="property.1" value="meta.decorator" />
            <param name="property.2" value="decorator" />
        </mapper>
        <mapper class="com.opensymphony.module.sitemesh.mapper.FrameSetDecoratorMapper"/>
        <mapper class="com.opensymphony.module.sitemesh.mapper.PrintableDecoratorMapper">
            <param name="decorator" value="printable" />
            <param name="parameter.name" value="printable" />
            <param name="parameter.value" value="true" />
        </mapper>
        <mapper class="com.opensymphony.module.sitemesh.mapper.FileDecoratorMapper"/>
        <mapper class="com.wemade.sitemesh.WemadeConfigDecoratorMapper">
            <param name="config" value="${decorators-file}" />
        </mapper>
    </decorator-mappers>
</sitemesh>

web.xml 파일 및 decorator.xml 파일 설정

web.xml 파일에서 다음과 같이 경로 기반의 패턴을 사용하고 있다고 해 보자.

<web-app ...>
    ...
    <servlet-mapping>
        <servlet-name>ControllerServlet</servlet-name>
        <url-pattern>/my/*</url-pattern>
        <url-pattern>/data/*</url-pattern>
    </servlet-mapping>

    <filter>
        <filter-name>sitemesh</filter-name>
        <filter-class>com.opensymphony.module.sitemesh.filter.PageFilter</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>sitemesh</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

</web-app>

위 코드에서 ControllerServlet은 경로 기반의 <url-pattern>을 사용하고 있는데, 앞서 구현한 커스텀 DecoratorMapper를 사용함으로써 다음과 같이 데코레이터 파일에서 URL 패턴을 이용해서 매칭을 할 수 있게 된다.

<decorators defaultdir="/decorators">

    <decorator name="my" page="/WEB-INF/view/common/decorator/my.jsp">
        <url-pattern>/my/*</url-pattern>
    </decorator>

    <decorator name="data" page="/WEB-INF/view/common/decorator/data.jsp">
        <url-pattern>/data/*</url-pattern>
    </decorator>

</decorators>

그 동안 경로 기반의 서블릿 매핑을 사용할 때 SiteMesh 때문에 섭섭함이 있었던 개발자에게 본 글이 조금이나마 도움이 되길 바란다.

 

반응형

SiteMesh 설정 및 사용법

2013. 7. 16. 18:12
반응형
SiteMesh를 이용한 웹 페이지 레이아웃 설정

SiteMesh를 이용하여 웹 페이지의 레이아웃을 처리하는 방법을 살펴본다.

SiteMesh의 동작 방식과 설치

웹 어플리케이션을 구성하고 있는 웹 페이지들은 대부분은 페이지 레이아웃이 동일하게 구성되어 있다. 예를 들어, 미디어 다음의 스포츠 게시판을 보면, 각 페이지는 아래 그림과 동일한 형태로 구성되어 있는 것을 확인할 수 있다.


위 그림에서 내용 부분을 제외한 나머지 헤더, 푸터, 좌측 메뉴, 그리고 우측 주요기사는 모든 페이지에서 동일한 위치에 나타낸다. 즉, 게시글 목록 페이지와 게시글 쓰기 페이지는 모두 위 그림과 동일한 레이아웃을 갖는 것이다.

이렇게 동일한 레이아웃을 여러 페이지에 적용해야 할 때, 가장 쉽게 사용할 수 있는 방법이 <jsp:include>나 <%@ include %>를 사용하는 것이다. 하지만, 이는 중복된 코드를 발생시킬 가능성이 높기 때문에, Tiles나 Velocity가 제공하는 레이아웃 기능을 사용하여 구현하게 된다. 추가적으로 SiteMesh를 사용하여 레이아웃을 여러 페이지에 적용할 수 있다.

Tiles나 Velocity 또는 <jsp:include>를 사용하는 방식이 전체 페이지 중 내용 부분에 해당하는 코드만을 생성하는 방식이라면, SiteMesh는 완전한 HTML 페이지를 생성한 뒤 Decorator 패턴을 사용하여 HTML 페이지에 레이아웃을 입히는 방식이다. 본 글에서는 SiteMesh의 동작방식에 대해서 살펴보고, SiteMesh를 사용하여 여러 웹 페이지에 레이아웃을 동일하게 적용하는 방법을 살펴볼 것이다.

SiteMesh의 동작 방식

SiteMesh는 Tiles와 같은 프레임워크와 달리 완전한 HTML 코드로부터 레이아웃이 적용된 새로운 HTML 코드를 생성해낸다. 아래 그림은 SiteMesh의 동작방식을 설명한 것이다.


위 그림에서 데코레이터에 전달되는 HTML 페이지는 <html>, <head>, <body> 등을 포함한 완전한 HTML 페이지이다. 이때 데코레이터에 전달되는 HTML 페이지는 레이아웃과 관련된 내용은 포함되지 않는다. 데코레이터는 레이아웃 정보를 담고 있는 JSP 페이지로서, 앞서 생성한 HTML 페이지에 저장된 (<title> 등의) 메타 정보와 <body> 태그에 포함된 내용을 추출한 뒤, 레이아웃의 알맞은 위치에 추출한 내용을 삽입하여 최종 결과를 생성하게 된다.

예를 들어, 앞서 그림에서 welcome.jsp의 경우를 살펴보자. welcome.jsp는 레이아웃과 관련된 코드를 생성하지 않고 단지 메타 정보와 내용 부분에 들어가는 정보만을 생성하게 된다. welcome.jsp가 생성한 HTML 페이지는 데코레이터에 전달된다. 데코레이터는 welcome.jsp가 생성한 내용으로부터 메타 정보와 BODY 부분을 추출한 뒤 데코레이터의 알맞은 위치에 삽입하여 최종 결과를 생성한다.

SiteMesh 설치

SiteMesh는 서블릿 환경에서 동작하며, http://www.opensymphony.com/sitemesh/download.action 사이트에서 최신 버전을 다운로드 받을 수 있다. 이 글을 쓰는 시점에서 최신 버전은 2.3 버전으로서 sitemesh-2.3.jar 파일을 다운로드 받은 뒤, 웹 어플리케이션 콘텍스트의 WEB-INF/lib 디렉토리에 복사하면 설치가 완료된다.

SiteMesh를 이용한 레이아웃 적용

SiteMesh를 사용하여 웹 페이지에 레이아웃을 적용하기 위해서는 다음의 두 가지를 필요로 한다.

  • SiteMesh 설정 파일
  • 데코레이터

SiteMesh 설정 1, web.xml

SiteMesh를 설정하기 위해서는 먼저 SiteMesh가 제공하는 PageFilter(서블릿 필터)를 설정해주어야 한다.
아래 코드는 설정 예이다.

<?xml version="1.0" encoding="UTF-8"?>
< web-app id="WebApp_ID" version="2.4"
    xmlns="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee 
                      http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
    
    <filter>
        <filter-name>sitemesh</filter-name>
        <filter-class>
            com.opensymphony.module.sitemesh.filter.PageFilter
        </filter-class>
    </filter>

    <filter-mapping>
        <filter-name>sitemesh</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
</web-app>


위 코드는 / 로 들어오는 모든 요청에 대해서 PageFilter를 적용한다고 설정하였다. PageFilter는 요청 URL과 매칭되는 데코레이터를 검색한 뒤, 데코레이터가 발견될 경우 결과 HTML에 매칭되는 데코레이터를 적용한다. 따라서, 데코레이터가 적용되어야 하는 URL의 경우 반드시 PageFilter에 매핑시켜주어야 한다.

SiteMesh 설정 2, decorators.xml 작성

web.xml 파일에 PageFilter 매핑을 설정한 다음에는, 실제 데코레이터에 대한 정보를 담고 있는 decorators.xml 파일을 작성해주어야 한다. decorators.xml 파일은 데코레이터에 대한 설정 정보를 담게 된다.

decorators.xml 파일은 다음과 같은 형태로 데코레이터 목록을 기술한다.

<decorators defaultdir="/decorators">
    <decorator name="submenu" page="submenu_decorator.jsp">
        <pattern>/sub/*</pattern>
    </decorator>

    <decorator name="main" page="main_decorator.jsp">
        <pattern>/*</pattern>
    </decorator>

</decorators>


위 코드에서 <decorators> 태그의 defaultdir 속성은 데코레이터 JSP가 위치할 경로를 의미한다. 이 경로는 웹 어플리케이션 콘텍스트 내에서의 경로를 의미한다.

<decorator> 태그는 한 개의 데코레이터를 설정한다. <decorator> 태그의 두 속성은 다음과 같다.

  • name - 데코레이터의 이름
  • page - 데코레이터로 사용될 JSP 페이지

<pattern> 태그는 데코레이터를 적용할 패턴을 의미한다. 이 패턴은 서블릿 매핑에서의 패턴과 비슷하다. 예를 들어, /sub/submain1.jsp 나 /sub/menu/submenu1.jsp 로 요청이 들어올 경우 'submenu' 데코레이터가 적용되며, 그 외 /main.jsp나 /another/another1.jsp와 같이 /sub/* 에 포함되지 않는 요청의 경우는 'main' 데코레이터가 적용된다.

만약 정확하게 일치하는 <pattern> 값이 존재할 경우 해당 데코레이터를 사용한다. 예를 들어, 아래의 설정을 보자.

<decorator name="submenu" page="submenu_decorator.jsp">
    <pattern>/sub/*</pattern>
</decorator>
    
<decorator name="submain" page="submain_decorator.jsp">
    <pattern>/sub/submain1.jsp</pattern>
</decorator>


이 경우 /sub/submain1.jsp는 submenu 데코레이터와 submain 데코레이터에 모두 매핑되지만, 좀더 정확하게 일치하는 submain 데코레이터가 사용된다.

한 개의 <decorator> 태그는 0개 이상의 <pattern> 태그를 포함할 수 있다.

서블릿 매핑 시 주의 사항

서블릿 매핑을 사용할 경우 <pattern> 값은 서블릿의 경로를 따른다. 예를 들어, 다음과 같이 서블릿 매핑을 설정했다고 하자.

<servlet-mapping>
    <servlet-name>content</servlet-name>
    <url-pattern>/catalog/*</url-pattern>
< /servlet-mapping>


이 경우, 지정한 서블릿 매핑에 해당되는 요청에 데코레이터를 적용하고자 한다면, 다음과 같이decorators.xml의 <pattern> 태그의 값으로 서블릿 경로명을 지정해주어야 한다.

<decorator name="catalog" page="catalog_decorator.jsp">
	<pattern>/catalog</pattern>
</decorator>


만약 서블릿 경로명이 아닌 /catalog/* 를 <pattern> 태그의 값으로 지정할 경우 해당 데코레이터가 적용되지 않는다.

데코레이터 작성

SiteMesh의 데코레이터는 JSP 페이지로서, SiteMesh가 제공하는 커스텀 태그를 사용하여 결과 HTML 페이지를 데코레이션하게 된다. 아래 코드는 간단하게 작성해본 SiteMesh의 데코레이터 코드이다.

<%@ page contentType="text/html; charset=UTF-8" %>
< %@ taglib prefix="decorator" uri="http://www.opensymphony.com/sitemesh/decorator" %>
< html>
    <head>
        <title><decorator:title default="테크리포트" /></title>
        <decorator:head />
    </head>
    <body>
    <div>헤더</div>
    <hr/>
    
    <decorator:body />
    
    <hr/>
    <div>푸터</div>
    </body>
< /html>


위 코드에서 눈여겨 볼 부분은 decorator로 시작하는 커스텀 태그이다. 사용자의 요청을 처리한 결과 페이지는 데코레이터에 전달되는데, 이때 커스텀 태그를 사용하여 전달된 페이지의 내용을 사용할 수 있게 된다. 예를 들어, <decorator:title> 커스텀 태그는 전달된 페이지의 <title> 태그의 값을 구하게 된다. 사용가능한 커스텀 태그는 다음과 같다.

<decorator:head />

HTML의 <head> 태그의 내용을 삽입한다.

<decorator:body />

<body> 태그의 내용을 삽입한다.

<body> 태그에 명시된 프로퍼티의 값을 데코레이터 JSP에 삽입하고 싶다면 다음과 같이 <decorator:getProperty> 커스텀 태그를 사용하면 된다.

<body onload="<decorator:getProperty property="body.onload" />">
…
   <decorator:body />
…
</body>


<decorator:title [ default="..." ] />

<title> 태그에 명시된 타이틀을 삽입한다. 만약 <title> 태그의 값이 발견되지 않을 경우 default 속성에 명시한 값을 삽입한다.

<decorator:getProperty property="." [default="."] [writeEntireProperty="." ]/>

원본 HTML 페이지의 프로퍼티를 삽입한다. 이때 사용가능한 프로퍼티는 다음과 같이 생성된다.

  • HTML Tag:
    < html> 태그의 모든 속성이 프로퍼티로 추가된다.
  • TITLE Tag:
    < title> 태그의 내용이 'title' 프로퍼티로 추가된다.
  • META Tags:
    이름과 내용을 갖는 모든 <meta> 태그는 'meta.이름' 프로퍼티로 추가된다.
  • BODY Tag:
    모든 <body> 태그의 속성이 'body.속성이름' 프로퍼티로 추가된다.

<decorator:getProperty> 커스텀 태그에서 사용가능한 속성은 다음과 같다.

  • property (필수) - 삽입할 프로퍼티의 이름(키)
  • default (선택) - 프로퍼티가 존재하지 않을 경우 삽입할 값
  • writeEntireProperty (선택) - 프로퍼티의 이름 및 이름 앞의 공백을 함께 삽입할 지의 여부를 지정한다. 허용되는 값은 'true', 'yes', 또는 '1' 이다.

예를 들어, 원본 페이지에서 다음과 같이 <body> 태그를 작성했다고 하자.

<body onload="document.someform.somefield.focus();">


그리고 데코레이터 JSP에서 다음과 같이 <decorator:getProperty> 커스텀 태그를 사용했다고 하자.

<body bgcolor="White" <decorator:getProperty property="body.onload" 
           writeEntireProperty="true" />>


이 경우 최종적으로 생성되는 코드는 다음과 같다.

<body bgcolor="White" onload="document.someform.somefield.focus();">


테스트 코드

데코레이션 될 JSP 코드

간단하게 SiteMesh의 데코레이터를 통해 레이아웃이 적용될 HTML 페이지를 생성하는 JSP 페이지를 다음과 같이 작성해보자. 이 JSP의 경로는 /sub/submain1.jsp 라고 하자.

<%@ page contentType="text/html; charset=UTF-8" %>
< html>
< head>
    <title>서브 메인 1</title>
    <script type="text/javascript">
    window.onload = function() {
    }
    </script>
< /head>
< body>
    서브 메인 1
< /body>
< /html>


데코레이터 JSP

데코레이터 JSP인 /decorators/submenu_decorator.jsp를 아래와 같이 작성해보았다.

<%@ page contentType="text/html; charset=UTF-8" %>
< %@ taglib prefix="decorator" uri="http://www.opensymphony.com/sitemesh/decorator" %>
< html>
    <head>
        <title><decorator:title default="테크리포트" /></title>
        <decorator:head />
    </head>
    <body>
    <div>공통 헤더</div>
    <hr/>
    <decorator:body />
    <hr/>
    <div>공통 푸터</div>
    </body>
< /html>


데코레이터 JSP를 작성했으면 decorators.xml 파일에 등록해주어야 한다. 아래 코드는 등록 예이다. 앞서 원본 JSP의 경로를 /sub/submain1.jsp로 지정하였으므로, 아래 코드에서 <pattern>의 값을 '/sub/*'로 지정하였다.

<decorators defaultdir="/decorators">
    <decorator name="submenu" page="submenu_decorator.jsp">
        <pattern>/sub/*</pattern>
    </decorator>
< /decorators>


테스트 결과

이제 웹 브라우저에서 실제로 출력 결과를 확인해보자. 웹 브라우저에서 http://…/[contextPath]/sub/submain1.jsp를 입력한 뒤, 출력된 결과의 소스 코드는 다음과 같을 것이다.

<html>
    <head>
        <title>서브 메인 1</title>
        
    
    <script type="text/javascript">
    window.onload = function() {
    }
    </script>

    </head>
    <body>
    <div>공통 헤더</div>
    <hr/>
    
    서브 메인 1

    <hr/>
    <div>공통 푸터</div>
    </body>
< /html>


위 코드를 보면 원본 JSP가 출력한 결과가 데코레이터를 통해 알맞은 위치에 삽입된 것을 확인할 수 있다.

[참고]

반응형
반응형

eclipse Tomcat 연동 오류

Target runtime Apache Tomcat v6.0 is not defined 오류 해결방법입니다.

(5.0 6.0 7.0 등 모든 버전 해당)

에러 발생 원인은 과거에 프로젝트 생성/사용 시 톰캣 서버 버전과

현재 설정된 톰캣 서버의 버전이 일치하지 않아 발생하는 에러입니다.

1. Markers 창의 에러 내용을 마우스 우측 버튼 클릭하여 Quick Fix를 클릭합니다.

2. 서버실행환경(Server Runtime Environments) 창의 목록에서 사용할 톰캣 항목을 선택하고 OK버튼을 클릭합니다.

3. 이클립스 상단 Project 메뉴의 Clean을 클릭합니다.

4. Clean projects selected below 버튼을 클릭하여 Clean할 프로젝트를 선택 후 OK 버튼을 클릭합니다.

5. 프로젝트 속성(Project - Properties)으로 이동하여 Project Facets 메뉴를 클릭하고 우측 Runtimes 탭에서 구동할 톰캣 버전을 선택한 후 OK 버튼을 클릭합니다.

반응형
반응형
java.lang.IllegalArgumentException: taglib definition not consistent with specification version 
최신버전에 이클립스를 사용할 경우 나타나는 현상. 
web.xml의 taglib 위 아래로 jsp-config 태그로 감싸준다.

  
    http://java.sun.com/jstl/core
    /WEB-INF/tld/c.tld
  


반응형

+ Recent posts

반응형