일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- PostgreSQL
- JavaScript
- JDBC
- maven
- myBatis
- Eclipse
- jpa
- 설정
- AJAX
- 문서
- Core Java
- IntelliJ
- git
- MySQL
- spring
- oracle
- Python
- Docker
- Open Source
- error
- MSSQL
- ubuntu
- Tomcat
- Thymeleaf
- 오픈소스
- Spring Boot
- Exception
- STS
- Source
- SpringBoot
- Today
- Total
헤르메스 LIFE
[Stripes] Stripes로 하는 자바 웹 개발 - 2 본문
원문 : http://www.hanb.co.kr/network/view.html?bi_id=1333
제공 : 한빛 네트워크
저자 : Mark Eagle
역자 : 이정목
원문 : http://www.onjava.com/pub/a/onjava/2007/01/24/java-web-development-with-stripes.html
[이전 기사 보기]
☞ Stripes로 하는 자바 웹 개발 - 1
설정보다는 관례(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 바인딩으로 변환된다.
- 전체 경로를 포함한 클래스 이름에서 www, web, stripes, action과 일치하는 문자열이 나타나는 부분을 뽑아낸다. 예제에서는 패키지명에서 4개 중 3개가 일치한다. 따라서 “example.HelloWorldAction”만 남게 된다.
- 클래스명의 끝에서부터 "Action"과 " Bean"이 존재할 경우 제거한다. 우리가 작성했던 클래스가 Action으로 끝나기 때문에 “example.HelloWorld”가 된다.
- 이제 마침표(.)를 슬래시(/)로 치환하면 “example/HelloWorld”가 된다.
- 마지막으로 URL 바인딩을 완성시키는 바인딩 접미사(기본값으로 .action)를 마지막에 추가한다. 최종 결과는 “example/HelloWorld.action”가 된다.
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=13hello 요청 파라미터에 대해서는 아무런 값도 지정하지 않았음을 유의하라. 이 경우 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>Srping 통합
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의 수석 소프트웨어 엔지니어이다.
'Spring Framework' 카테고리의 다른 글
[Spring] Eclipse에서 JPetStore 테스트 환경 구축 - Spring Framework 2.5, iBatis (0) | 2012.06.22 |
---|---|
[Log4j] log4J 에서 콘솔창에 두번씩 sql이 나오는 이유 (0) | 2012.06.13 |
[Stripes] Stripes로 하는 자바 웹 개발 - 1 (0) | 2012.06.12 |
[MyBatis] Spring + MyBatis Sample - JPetStore 6.0.1 Bundle (0) | 2012.06.12 |
[MyBatis] MyBatis Wiki (0) | 2012.06.12 |