2007년 2월 26일 월요일

Stripes로 하는 자바 웹 개발

Stripes는 오픈소스로서 웹 개발은 개발자에게 단순하며 생산성 있어야 한다는 원칙에 입각하여 설계된 액션 기반(action-based)의 자바 웹 프레임워크이다. 전통적인 자바 웹 개발이 결합도를 낮추는 것(decoupling)을 통한 융통성에 집중한 나머지 다수의 설정 파일(multiple configuration files), 부수적인 객체(additional object), 그리고 기타 단편화된 자원들(fragmented resources)이 만들어지는 결과를 낳았는데 이러한 문제들로 수많은 개발자들이 더 높은 학습곡선과 낮아진 생산성을 겪게 되었다. 그 결과 일부 자바 개발자들은 Ruby on RailsDjango와 같은 비자바 프레임워크(non-Java Framework)로 옮겨가게 되었다. Stripes와 같은 자바 웹 프레임워크는 개발공정의 능률을 높여주는 대안 프레임워크의 성공으로부터 이제 막 배우기 시작하고 있다. 이 기사는 Stripes이 루비 온 레일즈(Ruby on Rails)에서 가능한 것과 같은 단순성을 제공해 주면서, 자체적으로 어떻게 스트러츠(Struts)와 같은 다른 액션 기반의 자바 웹 프레임워크와 구별되는지에 대해 보여줄 것이다.

[그림 1]은 Stripes로 작성된 애플리케이션에서 전형적으로 나타나는 이벤트와 컴포넌트의 일반적인 흐름을 보여준다.


[그림 1] 전형적인 Stripes의 흐름

여러분도 볼 수 있듯이 이것은 여러분이 MVC 프레임워크에서 볼 수 있는 것과 거의 유사하다. Stripes와 다른 액션 기반의 프레임워크간의 한 가지 주된 차이점은 Stripes는 외부 설정 파일이 없다는 것이다. 앞으로 다루겠지만 Stripes는 어노테이션(annotation)과 ‘설정보다는 관례(convention over configuration)’ 이용하여 좀 더 개발에 집중할 수 있게 해주고 번잡스러움은 피하게 해준다.

첫 번째 Stripe Action 만들기

곧바로 무엇이 어떻게 돌아가는지 이해하기 위해 “Hello World” 예제를 만들어 보면서 Stripes 프레임워크에 뛰어들어 보도록 하자. HelloWorldAction 클래스는 사용자에게 성명을 물어 본 다음 그것을 별도의 뷰(view)에 출력할 것이다. 먼저 컨트롤러 자바 클래스를 작성한다.

public class HelloWorldAction implements ActionBean {   

  @ValidateNestedProperties({
    @Validate(field = "firstName", required = true,
              on = {"hello"}),
    @Validate(field = "age", required = true, minvalue = 13,
              on = {"hello"})
  })
  private Person person;
  private ActionBeanContext context;
   
  @DefaultHandler
  public Resolution index() {
    return new ForwardResolution("Hello.jsp");
  }
       
  public Resolution hello() {
    return new ForwardResolution("SayHello.jsp");
  }

  public void setPerson(String person) {this.person = person;}
  public String getPerson() { return person;}
  public void setContext(ActionBeanContext c) {this.context = c; }
  public ActionBeanContext getContext() {return context; }
}

컨트롤러 클래스는 ActionBean이라 불리는 Stripes에 특정한 인터페이스를 구현하는 POJO(Plain Old Java Object)와 닮았다. 모든 Stripes 액션은 StripesDispatcher 서블릿이 ActionBeanContext 객체를 현재 서비스되고 있는 액션에 주입하도록 이 인터페이스를 구현할 필요가 있다. ActionBeanContext 객체는 여러분이 요청(request), 응답(response), 서블릿 컨텍스트(servlet context)와 같은 API 객체에 접근할 수 있도록 해준다. Stripes 애플리케이션에서는 이러한 저수준 API 객체에 접근할 필요가 거의 없다. 또한 ActionBeanContext 클래스는 여러분이 현재 서비스 되고 있는 액션에 관한 상태 정보를 얻을 수 있도록 해줄 뿐만 아니라 현재 서비스되고 있는 액션으로부터의 통보 메시지(informational message)와 오류 메시지를 추가할 수 있도록 해준다. ActionBeanContext 필드와 접근자(accessor)는 모든 Stripes 액션들이 이 구현 클래스를 필요로 할 것이므로 기반 클래스에 저장될 수도 있다.

컨트롤러 클래스의 나머지 부분들은 다른 자바 개발자들에게 친숙할 것이다. Person이라는 객체는 뷰에서 한 사람의 성과 이름을 읽고 기록하는데 사용될 접근자를 포함한다. 이 객체는 단순히 중첩된 객체에 불과하나 Stripes는 자바 컬렉션(Java Collection), 제네릭 지원(generics support), 그리고 색인화된 프로퍼티(indexed propertis)를 통해 좀 더 복잡한 데이터 바인딩도 할 수 있도록 해준다. Stripes가 복잡한 데이터 바인딩을 처리할 수 있으므로 여러분의 도메인 객체를 그것을 필요로 하는 다른 계층에서도 재사용 할 수 있다. 예를 들어 Stripes를 통해 도메인 객체 내에 들어있는 정보들을 수집하여 Hibernate와 같은 다른 POJO 프레임워크나 EJB 3를 이용하여 퍼시스턴스 차원의 변경을 손쉽게 할 수 있다.

hello 메소드 호출시 사용자가 성명을 입력하도록 하는 간단한 Stripes 유효성 검증 어노테이션(validation annotation)이 person 필드에 추가되어 있다. 만일 사용자가 필수 입력란에 내용을 입력하지 않으면 원래 페이지로 되돌아온 다음 이 유효성 검증과 관련된 오류 메시지가 보여질 것이다. 이 유효성 검증은 어노테이션 속성(on = {“hello”})에 지정되어 있는 것과 같이 hello 이벤트가 요청되었을 경우에만 검사될 것이다. 또한 Stripes는 유효성 검증의 유형과 필드명에 근거한 sensible default를 사용하여 오류 메시지를 만들어낼 것이다. 예를 들어 만약 한 Person 객체의 필수 입력필드인 firstName이 폼이 전송될 때 주어지지 않을 경우 사용자는 다음과 같은 오류 메시지를 보게 될 것이다:

Person First Name is a required field.
(Person First Name은 필수 입력필드입니다.)
이 메시지는 Person.firstName에 대한 객체 그래프 컴포넌트(object graph component)를 이용하여 생성되는데 이것은 메시지를 좀 더 사람이 읽기 쉬운 형태로 만들어 준다. 이러한 유효성 검증 오류 메시지는 좀 더 커스터마이즈가 필요할 경우 오버라이드할 수 있다. 또한 Person 객체의 프로퍼티인 age라 불리는 Integer 타입의 필드도 있다. Stripes는 먼저 Integer 필드인 person.age에 대한 요청 파라미터 값의 타입 변환을 수행한 다음 그 값을 Person 객체내의 값에 바인딩할 것이다. 그 값이 Person 객체의 age 필드에 바인딩되고 나면 Stripes는 그 Integer 값이 13보다 작은지에 대한 유효성 검사를 수행할 것이다. 만약 사용자가 정수 대신 문자열을 입력할 경우 사용자는 다음과 같은 메시지를 보게 될 것이다:
The value (Mark) entered in field Person Age must be a valid number.
(Person Age 필드에 입력된 값(표시)은 유효한 숫자여야 합니다.)
만약 사용자가 정수지만 13보다 작은 값을 입력할 경우 다음 메시지를 보게 될 것이다:
The minimum allowed value for Age is 13.
(Age에 허용된 최소값은 13입니다.)
다시 한번 말하지만 우리는 이러한 오류 메시지에 대한 어떠한 외부 설정(external configuration)을 제공할 필요가 없었다. 이러한 유효성 검사를 제공하는 어노테이션이 여러분의 필드에 인라인되어 개발자가 유효성 검사를 위치시키는 것과, 유효성 검사가 수행될 것을 알게되는 것, 그리고 유효성 검사에 대한 유지보수성 변경(maintenance change)을 용이하게 한다.

이 Stripes 액션에는 호출가능한 두 개의 메소드(이벤트라 불리는)도 포함되어 있는데, 이벤트는 ActionBean 클래스에서 다음과 같은 서명을 가진 메소드로서 나타난다:
public Resolution eventName
index 메소드에 @DefaultHandler가 표시되어 있음을 주목하라. 이 액션에는 여러 개의 이벤트가 있으므로 그것들 중 하나는 기본 이벤트로 지정되어 있을 필요가 있다. 만약 이러한 액션을 요청하는 URL에 이벤트가 기입되어 있지 않으면 Stripes는 @DefaultHandler 어노테이션이 지정된 이벤트를 찾아 그것을 실행시킬 것이다.



이제 Hello World 예제에 뷰 로직을 추가해 보자. 기본적으로 Stripes는 JSP를 표준 뷰 기술로 지원하기는 하나 FreeMarker와 같은 다른 뷰 기술을 사용할 수도 있다. 여기에는 Stripes 태그 라이브러리를 제외하고는 사실 새로이 배워야 할 것이 없다. Hello.jsp라 불리는 첫 번째 뷰는 사용자가 이름을 입력하고 전송할 수 있도록 해줄 것이다.

<%@ taglib prefix="stripes"
          uri="http://stripes.sourceforge.net/stripes.tld" %>
<html>
  <head>
    <title>Stripes Hello World</title>
  </head>
  <body>
    <stripes:errors/>
    <stripes:form
        beanclass="com.
                   myco.
                   web.
                   stripes.
                   action.
                   example.
                   HelloWorldAction">
    Say hello to: <br>
    First name: <stripes:text name="person.firstName"/>
    <br>
    Age:<stripes:text name="person.age"/><br>
    <stripes:submit name="hello" value="Say Hello"/>
    </stripes:form>
  </body>
</html>

이 JSP는 읽고 유지보수 하기에도 간단하다. 폼과 입력 필드에 사용된 Stripes 태그들은 HTML에 그것과 대응되는 태그들과 매우 유사하다. Stripes:form 태그는 beanclass라 불리는 속성을 포함하고 있는데 이것은 앞서 정의하였던 컨트롤러 클래스의 전체 경로를 포함한 이름이다. 우리는 beanclass 속성 대신 stripes:form 태그의 액션 속성을 사용할 수도 있었다. 그러나 beanclass 속성은 여러분이 Stripes 액션에 대한 리팩터링을 수행할 필요가 있을 경우 리팩터링을 더 쉽게 만들어 준다. 아래에는 액션 속성을 사용할 경우 stripes:form 태그를 어떻게 지정해야 하는지 나타나 있다:
<stripes:form action="/example/HelloWorld.action">

stripes:input 태그들 중 하나는 입력 필드의 값을 컨트롤러 내의 Person 객체의 firstName
필드에 저장하는데 사용될 person.firstName의 name 속성을 지정한다.
마지막으로 stripes:submit 태그는 Stripes HelloWorldAction 클래스가 hello 이벤트를
사용하도록 지시하는데 사용될 name 속성을 지정한다.

이제 이름과 성의 값을 HelloWorldAction에 전송하도록 설정할 것이다.
우리가 해야할 일은 오직 별도의 뷰에 그것을 출력하도록 하는 것이다.






<%@ taglib prefix="stripes"
       uri="http://stripes.sourceforge.net/stripes.tld" %>
<html>
  <body>
    <stripes:errors/>
    <h2>Hello ${actionBean.person.firstName} your age is
              ${actionBean.person.age} </h2>
    <p/>
    <stripes:link beanclass="com.myco.web.stripes.action.
                                   example.HelloWorldAction">
      Say Hello Again
    </stripes:link>
  </body>
</html>

이 JSP는 action에 직접 연결된 레퍼런스에 접근하여 사람의 이름과 성 필드의 내용을 출력할 것이다.
이러한 목적으로 Stripes는 자동적으로 actionBean 요청 속성(request attribute)을 포함하는데
그것은 JSTL로 접근가능하다. 마지막으로 stripes:link 태그를 사용하여 HelloWorldAction
클래스로 되돌아가는 링크를 하나 만들어서 다른 이름을 입력하여 출력하게 할 수 있도록 하였다.
뿐만 아니라 이러한 방식으로 stripes:link가 명시적으로 index 이벤트를 참조하도록
만들 수도 있다:
<stripes:link beanclass="com.myco.web.stripes.action.
example.HelloWorldAction"
event="index">Say Hello Again</stripes:link>

index 메소드에 @DefaultHandler 어노테이션을 지정하였으므로 Stripes는 이벤트 속성 없이도
어떤 메소드를 실행할지 알게 된다.



설정보다는 관례(Convention Over Configuration)


이제 자바 컴포넌트들을 작성하였으므로 URL에 액션이 맵핑되도록 설정하고 두 개의 뷰에 그것들을
연결시킬 것이다. 잠깐만 기다려라, 이건 Stripes이므로 아무런 외부 설정파일이 필요하지 않다.

너무 좋아서 믿지 않을 수도 있겠지만 이것은 Stripes에서 가장 생산성 있는 기능 중의 하나이다.
Stripes는 설정보다는 관례을 이용하여 액션을 URL에 맵핑시킨다. 또한 기호화된
이름(symbolic names)을 실제 뷰에 맵핑시키기 위하여 외부 설정 파일을 사용할 필요도 없다.
이는 개발자들이 뷰의 실제적인 경로에 이르는 SUCCESS와 같은 기호화된 이름 사이사이를 찾아
다니는 방법을 결정하기 위하여 설정 파일들 사이를 여기저기 헤집고 다닐 필요가 없다는 것을
의미한다. 즉, 자바와 뷰 컴포넌트를 외부적으로 묶을(external wiring) 필요가 없다.
이는 더 나은 유지보수성과 더 높은 생산성으로 우리를 이끌어 준다.

Stripes는 어떻게 각각의 액션을 외부적으로 혹은 다른 어노테이션이 없이 Java 액션 클래스에
대한 묵시적인 URL 맵핑을 제공할까? 이것은 web.xml 파일 안에 들어있는 Stripes 설정과 URL
맵핑을 생성하기 위한 sensible defaults를 이용하는 방법을 가지고 설명할 수 있다.
먼저 StripesFilter라 불리는 Servlet 필터에 대해 논의해볼 필요가 있다.
아래에 web.xml 파일안에 들어있는 StripesFilter의 기본 설정이 나타나 있다:



<filter>
  <display-name>Stripes Filter</display-name>
  <filter-name>StripesFilter</filter-name>
  <filter-class>
    net.sourceforge.stripes.controller.StripesFilter
  </filter-class>
    <init-param>
    <param-name>ActionResolver.UrlFilters</param-name>
    <param-value>/WEB-INF/classes</param-value>
  </init-param>
</filter>

Servlet 컨테이가 구동될 때 StripesFilter는 init-param 요소의 초기화를 수행한다.
가장 중요한 init-param 요소 중 하나는 ActionResolver. UrlFilters 파라미터이다.
이것은 Stripes에게 Stripes와 관계된 클래스를 어디에서 찾아보아야 하는지 알려준다.
이 경우 Stripes는 모든 ActionBean 인터페이스를 구현하는 클래스들을 기본적으로
/WEB-INF/classes 경로에서 찾아보게 될 것이다. 각각의 위치한 ActionBean 클래스는 그러한
클래스에 대한 기본 바인딩 URL과 함께 Map에 추가될 것이다. Stripes가 Hello World 예제
클래스에 어떠한 일을 하는지 예제를 살펴보기로 하자.

HelloWorldAction 클래스가 /WEB-INF/classes 경로 안에 들어있고 ActionBean 인터페이스를
구현하므로 그것은 Stripes 서블릿으로 인식될 것이다. 예제에서 사용된 HelloWorldAction
클래스의 전체 경로를 포함한 이름(fully qualified name)은
com.myco.web.stripes.action.example.HelloWorldAction이다.
전체 경로를 포함한 이름은 이제 다음의 규칙에 따라 URL 바인딩으로 변환된다.
  1. 전체 경로를 포함한 클래스 이름에서 www, web, stripes, action과 일치하는 문자열이 나타나는 부분을 뽑아낸다. 예제에서는 패키지명에서 4개 중 3개가 일치한다. 따라서 “example.HelloWorldAction”만 남게 된다.
  2. 클래스명의 끝에서부터 "Action"과 " Bean"이 존재할 경우 제거한다. 우리가 작성했던 클래스가 Action으로 끝나기 때문에 “example.HelloWorld”가 된다.
  3. 이제 마침표(.)를 슬래시(/)로 치환하면 “example/HelloWorld”가 된다.
  4. 마지막으로 URL 바인딩을 완성시키는 바인딩 접미사(기본값으로 .action)를 마지막에 추가한다. 최종 결과는 “example/HelloWorld.action”가 된다.
이제 Stripes가 ActionBean 클래스를 찾았고 그것에 대한 URL 바인딩을 생성하였으므로 그것들은 URL 바인딩이 키이고 ActionBean을 구현하는 클래스를 값으로 가지는 java.util.Map>에 캐싱될 것이다. 아래에 우리가 작성했던 예제가 Map에 어떻게 저장될 것인지 나타나 있다:

URL 바인딩 ActionBean 클래스
/example/HelloWorld.action com.myco.web.stripes.action.example.HelloWorldAction

논의해볼 필요가 있는 두 번째 사항은 Stripes가 URL 바인딩을 거꾸로 여러분이 구동시키고자 하는 ActionBean 클래스로 변환시키는 방법에 관한 것이다. 이것은 아래와 같이 web.xml 파일안에 설정되어 있는 Stripes 디스패처 서블릿(Stripes dispatcher Servlet)의 책임이다.

<servlet>
     <servlet-name>StripesDispatcher</servlet-name>
     <servlet-class>
        net.sourceforge.stripes.controller.DispatcherServlet
    </servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
  <servlet-name>StripesDispatcher</servlet-name>
  <url-pattern>*.action</url-pattern>
</servlet-mapping>

StripesDispatcher의 책임 중 하나는 URL을 Stripes ActionBean 클래스로 해석(resolve)하는 것이다. 사용자가 http://host/uri/example/HelloWorld.action URL을 요청할 경우 Stripes 디스패처 서블릿은 URL 바인딩 맵 안을 살펴보고 com.myco.web.stripes.action.example.HelloWorldAction 클래스를 찾아서 그것의 인스턴스를 인스턴스화시킬 것이다. 마지막으로 index 메소드가 기본 핸들러로 어노테이션을 통해 정의되어 있고 URL상에 이벤트가 지정되어 있지 않으므로 index 메소드가 호출될 것이다.

그럼 HelloWorldAction의 hello 메소드를 직접 실행시키고자 하면 어떻게 될까? URL은 아래와 같이 요청 파라미터로 이벤트명을 포함할 필요가 있을 것이다:
http://host/uri/example/HelloWorld.action?hello=&firstName=Mark&age=13

hello 요청 파라미터에 대해서는 아무런 값도 지정하지 않았음을 유의하라. 이 경우 StripesDispatcher는 hello 요청 파라미터명과 public Resolution hello()라는 메소드 서명을 가진 HelloWorldAction 클래스 안의 메소드명이 서로 일치하는 것으로 인식할 것이다. 메소드명은 초기화시 성능을 위해 별도의 Map에 캐싱될 것이다.

우리는 지금까지 Stripes의 기본사항들과 간단한 액션을 작성하는 방법, 그리고 몇가지 프레임워크의 작동 방식에 대해 알아보았다. 우리는 web.xml에 몇 가지 초기화 설정을 함으로써 프레젠테이션 컴포넌트에 묶기 위한 별도의 XML 설정파일을 갖는 것을 피할 수 있다. 이는 몇 가지 연유로 중요한 의미를 지닌다. 먼저 어떠한 수정을 해야 할 경우 여러분은 URL을 보고 즉시 우리가 어떤 클래스를 찾아봐야 할지를 알게 된다. 다음으로 설정 파일이 커지고 그것을 관리할 수 없을 지경에 다다랐을 경우에 우리를 보조해줄 별도의 툴도 필요하지 않게 된다. 이러한 설정 파일을 제거함으로써 더 이상 프레임워크에 수많은 메타 데이터를 주입시키지 않아도 된다. 결론적으로 우리는 컴포넌트가 각기 다른 것들과 관계되는 방법을 서술하는 별도의 파일을 계속적으로 유지할 필요가 없어진다.

Ajax

그럼 좀 더 고급스러운 기능은 어떠한가? Stripes가 Ajax를 처리하는 방법을 살펴보도록 하자. 우리는 위의 Hello World 예제에 이미 존재하는 내용을 갱신하는 Ajax 호출을 포함되도록 수정할 것이다. 이 예제는 Stripes 액션에 Ajax 호출을 제공하기 위하여 Prototype을 어떻게 이용하는지 보여줄 것이다. 이 예제의 소스는 리소스에서 참조할 수 있다. 먼저 Hello.jsp가 Prototype 자바스크립트 라이브러리를 포함하도록 수정하자. 또한 Ajax 호출을 위한 자바스크립트 함수를 추가하고 onclick 이벤트를 가진 새로운 버튼을 참조하도록 전송 버튼을 변경할 것이다:

<%@ taglib prefix="stripes"
            uri="http://stripes.sourceforge.net/stripes.tld" %>
<html>
  <head>
    <title>Stripes Hello World</title>
    <script
        src="${pageContext.request.contextPath}/js/prototype.js"
        type="text/javascript"></script>

    <script type="text/javascript">
       function sayHelloAjax() {
          var myAjax = new Ajax.Updater('hello',
          "<stripes:url
               beanclass="com.
                          myco.
                          web.
                          stripes.
                          action.
                          example.
                          HelloWorldAction"
               event="sayHelloAjax"/>",
          {
              method: 'get',
              parameters: Form.serialize('helloForm')
          });
        }
    </script>
  </head>
  <body>
    <stripes:errors/>
    <stripes:form
        beanclass="com.
                   myco.
                   web.
                   stripes.
                   action.
                   example.
                   HelloWorldAction"
        id="helloForm">
        Say hello to: <br>
        First name: <stripes:text
                          name="person.firstName"/><br>

        Age:<stripes:text name="person.age"/><br>

        <stripes:button
                name="helloAjax"
                value="Say Hello"
                onclick="sayHelloAjax()"/>

        <div id="hello"></div>

    </stripes:form>
  </body>
</html>

stripes:button은 onclick 이벤트를 가지는데 이것은 HelloWorldAction 클래스의 sayHelloAjax를 호출하여 그 결과를 hello라 불리는 div 태그안에 리턴할 것이다. 아래에는 HelloWorldAction 클래스 안에 추가해야 할 필요가 있는 새로운 메소드가 나타나 있다:

public Resolution sayHelloAjax(){
  return new ForwardResolution("SayHelloAjax.jsp"); 
}

이름과 성에 대한 바인딩이 Stripes에 의해 처리되기 때문에 이 메소드가 하는 일은 그리 많지는 않다. 따라서 이 메소드의 책임은 오로지 SayHelloAjax.jsp라 불리는 파셜 페이지(partial page)로 포워딩 하는 것 뿐이다. 아래는 SayHelloAjax.jsp의 내용이다:

<h2>Hello ${actionBean.person.firstName} your age is ${actionBean.person.age}!</h2>

Spring 통합


Stripes는 Spring과 통합할 수 있는 기능을 내장하고 있다. 여러분은 Spring의 빈(bean)이나 서비스를 여러분의 Action에 자동으로 주입시킬 수 있다. Stripes 방식에서는 이렇게 하는 것은 Spring 컨텍스트 설정을 제외하고는 외부 설정을 필요로 하지 않는다. Spring 설정에 다음과 같이 정의된 빈이 있다고 가정하자:

<bean id="personService" parent="abstractTxDefinition">
  <property name="target">
    <bean class="com.myco.service.impl.PersonServiceImpl"/>
  </property>
</bean>


person 서비스를 Stripes 액션에 주입시키기 위해서는 Spring 빈의 이름과 일치하는 프로퍼티와 설정자 메소드(setter)를 추가해 준다. Stripes는 적절한 Spring 빈을 액션 클래스에 주입시키기 위하여 @SpringBean 어노테이션을 제공해 준다. 아래에 무엇이 Stripes 액션에 포함되어야 하는지 나타나 있다:

private PersonService personService;

@SpringBean
public void setBlogService(BlogService blogService) {
  this.blogService = blogService;
}

이 기사는 Stripes의 고급 기능에 대해 모두 다루지는 못한다. 그러나 Stripes documentation은 매우 포괄적이므로 필요하면 Stripes documentation을 참조하라. 뿐만 아니라 Stripes은 Tiles과 유사한, 외부 설정을 필요로 하지 않는 레이아웃 관리자를 포함하고 있다. 추가적으로 라이프사이클 이벤트(life-cycle events), 파일 업로드, 그리고 그 이상의 것들에 걸쳐 사용될 수 있는 인터셉터(interceptor)도 사용할 수 있다.

결론

Stripes는 강력하지만 심플한 자바 웹 프레임워크이다. Stripes는 어노테이션과 제네릭과 같은 Java 5의 기능을 이용하는데 이는 자바 개발자가 외부 설정파일을 유지하는 것을 회피할 수 있게 해주며 생산성을 증가시킨다. Stripes는 어려운 웹 개발 작업을 쉽게 만들어 주며 단순한 작업들을 훨씬 더 쉽게 만들어 준다.

리소스

Mark Eagle는 조지아주의 애틀랜타에 위치한 MATRIX Resource, Inc의 수석 소프트웨어 엔지니어이다.

제공 : 한빛 네트워크
저자 : Mark Eagle
역자 : 이정목
원문 : http://www.onjava.com/pub/a/onjava/2007/01/24/java-web-development-with-stripes.html

댓글 없음:

댓글 쓰기