[Info]Tags categorized posts and contents patterns..

[AJAX] Ajax Code E xamples.. [Book] About the book.. [CSS] CSS Code E xamples.. [DB] Sql Code E xamples.. [DEV] All development stor...

레이블이 Struts2인 게시물을 표시합니다. 모든 게시물 표시
레이블이 Struts2인 게시물을 표시합니다. 모든 게시물 표시

2016년 3월 22일 화요일

[EP]제11회 한국 스프링 사용자 모임 세미나 후기 #1..

출처 : Outsider's Dev Story https://blog.outsider.ne.kr/

지난 13일 명동에서 KSUG가 주최하는 제11회 한국 스프링 사용자 모임 세미나가 열려서 갔다가 왔습니다. 10회 세미나가 4월 17일에 열렸으니 6개월여만이군요.

Keynote
시작은 KSUG의 회장이신 fupfin님이 Keynote(?)로 시작되었습니다. 보통 컴퓨터 사이언스라고 부르는데 이 단어는 약간 이상하게 들립니다. 사이언스라는 것은 무언가 발견해내는 과정인데 프로그래밍은 문제를 해결해 나가는 과정입니다. 


스프링은 스프링이 복잡한 것이 아니고 스프링이 해결하려는 문제가 기존의 스트럿츠가 해결하려고 했던 문제 들에 비해서 훨씬 복잡한 문제를 해결하려고 하기 때문이고 각 문제별로 해결하는 방식을 보면 오히려 아주 단순합니다.

프레임워크를 어떻게 정의하는지 보겠습니다.

프레임워크는 공통적인 고수준의 패턴이고 클래스이다. - Larry Best

문제를 해결하려는 사고방식이고 그것을 코드로 만든 것이다. 그래서 한가지 문제를 여러가지로 해결 할 수 있다. - Kent Beck

애플리케이션의 뼈대를 구축하는 것이다. - Mary Shaw


발표하시는 fupfin님Kent Beck의 Framework에 대한 정의

그러면 아키텍쳐란 무엇일까요? 켄트벡은 패턴으로 문제를 해결하려고 하면서 아키텍쳐가 발현되는 것이고 한번에 나오는 것이 아니라 작은 스텝을 통해서 점점 진화하게 되는 것이라고 했습니다. 초반에 아키텍쳐를 잡아놓은 것이 후반에 변경사항에 대처를 못하게 되고 이것이 개발자를 어렵게 만드는 경우가 많이 있습니다.

스트럿츠2 역시 좋은 프레임워크라고 생각합니다. 여기서 스트럿츠2는 앞에서 얘기한 Larry와 Mary의 생각을 적용하고 있다고 볼 수 있습니다. 이는 총체적으로 문제를 해결하려고 하고 있는 반면에 스프링은 문제해결을 위해서 여러가지 중에 선택해서 사용할 수 있도록 하고 있습니다. 또한 스트럿츠2는 특정 패턴을 적용하려고 하고 이 부분의 문제가 발견되면 다른 패턴으로 변경하는 식으로 대처하고 있지만 스프링은 이렇지 않습니다. 핸들러 같을 것을 보면 그냥 Object이고 내부적으로는 버전이 올라가면서도 거의 달라지지 않았습니다. 스트럿츠가 표준을 잡고 강제하려고 하고 있다면 스프링은 선택권을 개발자에게 주기 때문에 발전 가능성이 많이 있습니다.

Spring Trouble Shooting - 백기선
백기선님의 최근 교육을 진행하면서 받은 여러가지 질문과 트러블 케이스들의 경험을 모아 스프링 트러블 슈팅이라는 주제로 발표를 했습니다.

Spring Trouble Shooting 발표발표하시는 백기선님

@Autowired
같은 타입의 빈이 등록되어 있을 경우 @Autowired하였을 때 의도치 않은 결과가 나오는 트러블 상황을 보여주었습니다. @Autowired의 동작원리를 이해해야 하는데 해당 타입의 빈이 1개있으면 바로 찾고 여러개일 경우에는 같은 이름의 빈이 있어야 동작합니다. 때문에 의도치 않은 장애를 피하려면 같은 타입의 빈이 여러개 일경우 명시적으로 이름을 설정하고 주입받을 곳에서 @Autowired 대신 @Resource를 사용하라고 하였습니다.

또한 컴포넌트 스캔( <context:component-scan default-package="easy"/> )과 <bean/> 설정을 혼용해서 쓰지 않아야 합니다. 혼용해서 쓸 경우 컴포넌트 스캔뒤에 XML의 DI정보로 덮어쓰기 때문에 XML로 등록할 빈은 @Component를 사용하지 말아야 합니다.

@Transactional
트랜잭션을 사용하기 위해 @Transactional 애노테이션을 붙힌 클래스에 인터페이스를 사용하려고 추가하니까 Bean을 제대로 찾지 못하는 트러블 상황을 보여주었습니다. @Transactional을 사용하면 프록시가 만들어지게 되는데 인터페이스가 없을 경우에는 클래스를 가지고 프록시를 만들지만 인터페이스가 있게 되면 클래스가 아닌 인터페이스로 만들기 때문에 프록시 타입은 인터페이스의 타입이 됩니다.
@Transactional을 사용하면 이미 스프링의 AOP를 사용하고 있는 것이고 <tx:annotation-driven />는 인터페이스가 있으면 JDK프록시를 사용하고 인터페이스가 없으면 CGLib프록시를 사용합니다. 인터페이스를 만들었다면 인터페이스를 사용하고 클래스기반으로 하고 싶다면 클래스기반 프록시를 명시적으로 선언해햐 하지만 별로 권하지는 않습니다.
ApplicationContext의 상속구조는 부모 ApplicationContext는 자식 ApplicationContext에 있는 빈에는 접근할 수 없고 자식 ApplicationContext는 부모 ApplicationContext에 있는 빈에 접근할 수 있습니다. 이때 AOP에 대한 설정과 AOP를 적용할 빈은 같은 ApplicationContext에 있어야 가능합니다. 부모에서 제대로 설정했다고 하더라도 자식 ApplicationContext에더 덮어쓰면 AOP가 되지 않기 때문에 부모에 등록할 것과 자식에 등록할 것을 잘 구분해야 합니다. 만약 패키지로 구분하는 것이 어렵다면 애노테이션으로 구분합니다.

DispatcherServlet 매핑
최근에는 DispatcherServlet의 URL 패턴에 /app/*를 사용합니다.
DispatcherServlet에 아무것도 등록하지 않으면 기본전략 빈들이 모두 등록 되지만 명시적으로 하나를 등록하게 되면 나머지 빈들은 등록이 되지 않게 됩니다. 때문에 기본 전략에 의지하다가 추가등록을 하게 되면 잘 돌아가던 서비스가 제대로 돌아가지 않는 문제가 생길수 있기 때문에 기본전략에 의지하기 보다는 필요한 전략을 등록하는 것이 좋습니다.

발표가 끝나고 깜짝 이벤트(?)로 토비의 스프링3의 저자이신 Toby님과의 iChat연결을 통한 질답시간이 있었습니다.

토스3을 공부하면 스프링을 잘할수 있는가에 대한 질문에 Toby님은 스프링을 공부하는데는 여러가지 방법이 있는데 개별 기술을 따로 공부하게 되면 새로운 것이 나올때마다 서로 연결이 안되서 어렵게 느껴질 수 있는데 오히려 전체를 이해하면 더 나을 수 있다고 하셨습니다. 스프링으로 만들어 놓은 것을 가져다가 쓰는 수준이 아니라 스프링의 개념과 철학을 이해하고 개발할 수 있도록 하는 것을 목적으로 쓴 책입니다. 중요한 것은 스프링 전문가가 되는 것이 아니라 스프링의 개념과 철학을 이용해서 자신이 개발하는 애플리케이션을 잘 구축하는 것이 더 중요하고 스프링보다 애플리케이션에 더 초점을 맞추어야 합니다.

분책에 대한 질문에 대해서는 분책을 하게되면 지금과 같은 종이를 사용할 수 없기 때문에 기대처럼 얇아지지 않아서 소용이 없을것 같다고 하셨고 후속책에 대한 질문에는 현재는 구체적인 것은 없고 당초 스프링의 이해, 실제로 어떻게 사용하고 선택하는가, 어떻게 확장하는가의 3부작으로 생각했었는데 마지막 확장에 대한 부분은 쓰지 못했다고 얘기하셨습니다.


간디 코스프레(?)도 하는 쇼맨쉽과 Head First시리즈가 생각나는 PPT가 상당히 인상적이었습니다. 저는 현재 스프링으로 업무를 하고 있지는 않기 때문에 트러블슈팅부분에 대해서는 바로바로 와닿지는 않았지만 트러블 슈팅으로 인한 스프링 개발의 권장사항을 미리 염두에 두고 있어도 충분히 도움이 될 만한 부분이라고 생각했습니다. 특정기술에 대한 설명같은 부분도 좋지만 이렇게 실제 개발할때의 실용적인 부분도 참 유용한것 같습니다.

Rich Domain Model - 조영호
리치 도메인을 이해하려면 리치도메인의 반대되는 개념을 먼저 이해하는 것이 쉽습니다.

Rich Domain Model 발표발표하시는 조영호님

1. 온라인 영화 예매 시스템
이해를 돕기위해 영화 예매시에 여러자기 조건에 따라 할인율이 적용되는 온라인 영화 예매 시스템을 구축하는 시나리오를 준비하셨습니다.
영화(Movie)가 첫번째 도메인 컨셉이며 상영(Showing)정보가 두번째 도메인 컨셉입니다. 세번째로는 할인정책(Discount)가 있는데 절대가격으로 할인하는 Amount Discount와 비율로 할인을 하는 Percent Discount가 있으며 할인규칙(Rule)이 네번째로 몇회차 영화에 할인해 줄것인가 하는 Sequence Rule과 무슨 요일 몇시에 할인할 것인가에 대한 Time Rule이 있습니다.
이 도메인들을 가지고 영화 예매를 할때 적당한 룰을 찾아 할인을 적용하여 그 결과로 예매(Reservation)을 생성하게 됩니다.

2. 데이터 - 지향 설계
데이터를 먼저 생각하고 무엇을 저장할 것인가를 생각하게 됩니다. 그러면 자연스럽게 ERD를 그리게 되는데 이것은 Anemic Domain Model이라고 부르며 테이블의 컬럼과 1:1매핑되는 클래스를 만들게 됩니다 이 클래스는 속성만 가지고 있고 getter/setter만 노출하게 됩니다. 그 후에 이 객체들이 어떻게 동작하는 가(프로세스)에 대해서 고민하게 됩니다. ReservationService를 만들고 예약정보를 보여주는 메서드를 만들고 구현체에서 데이터를 끌어오기 위해서 DAO를 만들게 됩니다. Movie와 Showing정보를 가져오고 Rule정보를 가져와서 적용여부를 판단하고 어떤 할인이 적용되는지 찾아서 적용한뒤 Reservation을 생성해서 디비에 저장하게 됩니다.

데이터 모델에 대한 ERD중앙집중식 제어 스타일의 흐름도

이게 일반적으로 개발하는 방식이고 데이터와 프로세스를 분리하게 되어 프로세스는 모두 서비스레이어에 몰아넣게 됩니다. 이걸 아키텍쳐 패턴으로 보면 Transaction Script 패턴이라고 부르며 실무에서 가장 많이 사용하는 아키텍쳐 패턴입니다.

3. 책임 - 주도 설계
우리가 처음 OOP를 공부할 때 배웠던 "상태와 상태를 처리하는 로직을 같이 두는 것이 OOP이다"라는 개념을 적용한 것이 Rich Domain Model입니다. 이는 데이터 기반이 아닌 책임기반(Responsible Driven)개발입니다. 데이터 - 지향 설계의 중앙집중식에서는 책임이 서비스에 모두 몰려있지만 책임주도에서는 책임이 분산되어 있으며 설계의 관점이 데이터와 프로세스가 아니라 책임기반으로 설계를 하게 됩니다. 그리고 보통 얘기하는 캡슐화는 책임기반으로 설계할 때 달성할 수 있습니다.

책임에 대한 CRC카드위임식, 분식식 제어스타일의 흐름도Rich Domain Model에 새로운 할인 객체를 추가한 모습

책임기반으로 설계할 때는 데이터와 프로세스는 생각하지 않고 이 시스템에 어떤 책임이 있는가를 고민해야 합니다. 시스템의 책임을 결정한 뒤에 어떤 도메인 컨셉에 할당할지를 고민하는 것입니다.
위 예제에서는 예매를 생성할 책임이 있는데 이는 Showing이 상영정보를 알고 있기 때문에 Showing에 할당합니다.(이때 CRC카드를 사용하는데 상단에는 클래스명을 적고 좌측에는 책임을 오른쪽에는 연관클래스를 적습니다.) 여기서 예매정보를 생성하려고 하니 가격을 알아야 하는데 가격을 가장 많이 알고 있는 Movie에 할당하고 필요한 할인율을 위한 책임을 위해 전략개체를 추가해서 DiscountStrategy로 전략패턴을 Movie에 적용하고 Rule을 추가해서 할인여부를 판단하게 됩니다.

설계는 What을 결정하고 구현은 How를 결정하는 것이라고 봤을 때 이 단계는 What을 결정하는 단계입니다. 클래스를 어떻게 만들고 데이터는 어떻게 가져올 것인가 하는 데이터에 대한 생각은 일단 여기서는 하지 않습니다. Anemic Domain Model은 실제적으로 보면 객체지향 설계는 아니고 객체지향 언어를 사용할 뿐입니다. Transaction Script의 단점은 수정이 어렵기 때문에 새로운 할인율이 추가되면 기존 코드를 수정해야 하며 그때문에 if-else구문이 많이 생기게 됩니다. Rich Domain Model의 장점은 OOP의 다형성의 활용이 가능하기 때문에 객체를 추가하고 구성을 바꾸는 것만으로 가능해지게 되고 이것이 Open Closed Principle입니다.

4. 아키텍쳐 & 프레임워크
Rich Domain Model로 설계했을 때 어떻게 구현을 해야하는 가는 프레임워크에 도움을 받을 수 있습니다. 레이어는 정해진 것은 없고 시스템마다 다르지만 앞서 얘기한 부분은 Domain 레이어에 대한 부분입니다. 여기서 중요한 점은 Domain 레이어는 최대한 캡슐화시키고 고립시켜야만 하고 그렇게 해야 POJO기반으로 할 수 있기 때문에 Domian레이어를 바로 노출하지 않고 그 위에 Service레이어를 두어 Service 레이어가 노출되도록 합니다. 여기서 서비스레이어는 Anemic Domain Model에 비해어 아주 간단해 지며 이 경우에는 Operation Script방식으로 코딩하는 것을 선호합니다. 당연히 레이어는 한방향으로만 의존성을 가지도록 해야하며 도메인레이어는 서비스레이어에는 의존하지 않고 하위의 Infrastructure에도 제한적으로만 의존하도록 합니다.

우리가 프레임워크를 쓰는 이유는 POJO로 개발할수 있어서 쓴다고 해도 과언이 아니며 POJO의 3대요소는 DI, AOP, Annotation입니다. 이 3가지 요소를 적용하면 비침투적인 프레임워크를 만들수 있으며 Lightweight 프레임워크라고도 부릅니다.(EJB는 아주 침투적입니다.) DI는 객체간의 의존성 관리이슈로부터 도메인 레이어를 보호하고 수성-사용의 분리 원칙을 적용한 것이며 스프링은 이를 지원하고 있습니다.

POJO의 3대 요소Data Mapper로 DB스키마와 객체모델을 연결한 화면

Rich Domain Model을 적용했을 때 객체모델과 DB스키마간의 불일치를 Impedance Mismatch라고 부르는데 이건 디비 설계과 객체지향 설계의 포커스는 완전히 다르기 때문에 당연한 결과입니다. 디비는 중복의 제거가 목적이고 객체지향은 행위의 효율성에 목적이 있습니다. 이 Impedance Mismatch를 해결하는 것은 아주 어렵기 때문에 데이터지향 설계를 주로 하게 되는 것입니다. 보통 Data Mapper를 사용해서 중간역할을 하도록 하는데 직접만들지는 않고 프레임워크를 사용하는 것이 일반적이며 Data Mapper를 가장 많이 사용하는 것이 Hibernate입니다.

결론
Rich Domain Model은 기술관점이 아닌 설계관점입니다. 자신이 정말 OOP로 설계를 하고 있는가를 먼저 생각하고 그 다음에 기술이 나와야 합니다. 물론 그렇다고 기술이 중요하지 않은 것은 아니며 비침투적인 프레임워크를 사용하지 않고 POJO를 사용하는 것은 거의 불가능합니다. Rich Domain Model을 자제해야 하는 경우는 비즈니스 로직이 단순하고 개발기간이 짧은 경우, 비침투적 프레임워크를 사용할 수 없는 경우, 개발 경험이 부족한 경우, O/R매퍼를 사용할 수 없는 경우나 OOP 설계 경험이 없다면 시도하지 않는 것이 좋습니다. Rich Domain Model을 적용하기 전에 이런 부분에 대한 학습이 필요하며 무조건 좋다는 것은 아니지만 Rich Domain Model이 실무적인 관점(Be Progmatic)에서 어느 경우에 유용할 수 있는 역략을 가질수 있도록 연마해야 합니다.

Q & A
실무에서 팀으로 할때는 어떻게 적용해야 합니까?

회사에서는 주로 성능위주로 많이 하게 되기 때문에 실무에서는 프로토타입정도로만 해봤습니다. 현실적으로는 팀원들의 지식 수준이 어느정도 유사할 경우에는 개발이 좀 빨라지게 됩니다.

관련해서 도움될 만한 책을 추천해 주세요.

객체 지향 - Applying UML and Patterns, 소프트웨어개발의 지혜(Robert C. Martin, Agile Software Development, Principles, Patterns, and Practices)
패턴 - Patterns of Enterprise Application Architecture(Martin Fowler)


저한테는 이번 세미나에서 가장 인상깊었던 세션이었습니다. Rich Domain Model이라는 저한테는 어렵게만 느껴지던 개념을 너무나 쉽고 논리정연하게 설명해 주셨던것 같습니다. 전해 주시는 내용들도 그 내용의 깊이를 알 수 있을 정도로 알찼지만 개념을 이해하기 위한 간단한 예시부터 Rich Domain까지 이어지는 흐름이 너무 자연스러워서 Rich Domain에 대해서 전혀 모르고 있던 저도 그 개념을 이해하기에 너무 좋았던 것 같습니다.
물론 저는 내공이 안되서 Rich Domain을 당장 쓰거나 하지는 못하겠지만 이 개념을 항상 염두에 두고 있는 것 만으로도 큰 도움이 될것 같다는 생각입니다. 언젠가는 Rich Domain Model을 적용해서 개발해 봐야겠지요 ㅎㅎ

2016년 2월 23일 화요일

[JAVA]Eclipse에 Struts 2 셋팅하기..

출처 : Outsider's Dev Story https://blog.outsider.ne.kr/

Struts 2는 MVC Model 2에 기반한 Web Application Framework(WAF)이다. 국내 SI업계에서는 거의 장악한 Struts의 후속 프레임워크이다. 머 스트럿츠2에 대해서 소개하는 건 아니라서(사실 잘 모르기 때문에 은근슬쩍...) 생략하기로 하고 자세한 내용은 다른 루트를 통해서 검색해 보시길....

사용자 삽입 이미지

Struts2를 사용하려면 기본적인 셋팅을 약간 해야되기 때문에 Eclipse에서 셋팅하는 법을 보자. 일단 프로젝트를 만들자 프로젝트를 만드는 것은 기본적인 자바프로젝트랑 동일하다.

사용자 삽입 이미지

웹어플리케이션이므로 Dynamic Web Project으로 만든다.

사용자 삽입 이미지

여기서는 Server를 Tomcat 5.5를 사용한다. 이클립스의 톰캣설정에 대한 부분은 여기서는 생략하고 넘어간다. (서버설정이 되어 있다는 전제하에서.....) 프로젝트를 만들었으면 이제 Struts2를 올려야 한다.Struts2는 다운로드 페이지에서 받을 수 있다. 다운로드 받은 파일의 압축을 풀고 안에 lib안에 보면 스트럿츠2에서 필요한 jar들이 들어 있다.

사용자 삽입 이미지

많은 jar파일들이 있는데 스트럿츠2를 구동하는데 이 모든 jar가 다 필요한 것은 아니다. 기본적으로 필요한 파일들은 다음과 같고 나머지는 다른 플러인등을 위한 파일들이다.

  • antlr-2.7.2.jar
  • commons-beanutils-1.6.jar
  • commons-chain-1.1.jar
  • commons-logging-1.0.4.jar
  • commons-logging-api-1.1.jar
  • commons-validator-1.3.0.jar
  • freemarker-2.3.8.jar
  • ognl-2.6.11.jar
  • oro-2.0.8.jar
  • struts2-core-2.0.11.2.jar
  • struts-core-1.3.5.jar
  • xwork-2.0.5.jar
위의 파일들을 WebContent/WEB-INF/lib 에 복사를 한다.

WebContent/WEB-INF/에 있는 web.xml 을 다음과 같이 수정한다.
Xml

<?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">
    <display-name>
    Struts2Setting</display-name>
    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
        <welcome-file>index.htm</welcome-file>
        <welcome-file>index.jsp</welcome-file>
        <welcome-file>default.html</welcome-file>
        <welcome-file>default.htm</welcome-file>
        <welcome-file>default.jsp</welcome-file>
    </welcome-file-list>
    
    <filter>
        <filter-name>struts</filter-name>
        <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
    </filter>
    
    <filter-mapping>
        <filter-name>struts</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
</web-app>

이제 struts.xml과 struts.properties 2개의 파일이 필요하다. 만들어진 웹어플리케이션이 배포될 때의 이 2개의 파일의 위치는 WebContent/WEB-INF/classes/ 이다. 이클립스에 src폴더 아래 있는 것은 자동으로 classes로 배포하기 때문에 src폴더 안에 넣으면 된다. 이클립스의 Project뷰에서는 java파일 말고는 생성되지 않기 때문에 Navigator뷰에서 만들어 넣으면 된다.(이걸 어디다 넣어야 되는지 몰라서 어찌나 고생했는지....)

사용자 삽입 이미지

struts.xml
Xml

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

<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd">

<struts>
    <package name="default" extends="struts-default" namespace="">
    </package>
</struts> 


struts.properties
Xml

struts.i18n.reload=true
struts.devMode = false
struts.configuration.xml.reload=true
struts.continuations.package = org.apache.struts2.showcase
struts.custom.i18n.resources=globalMessages
#struts.action.extension=jspa
struts.url.http.port = 8080
#struts.freemarker.manager.classname=customFreemarkerManager
struts.serve.static=true
struts.serve.static.browserCache=false
struts.multipart.maxSize=2097252

이렇게 하면 스트럿츠2를 구동하기 위한 셋팅은 완료되었다. (아~ 글 길다... ㅡ..ㅡ) 그럼 이제 돌려보자... 셋팅이 잘 되었는지 봐야되니까...

다음과 같은 PrintStringAction.java 파일을 만든다.(팩키지생성같은 설명을 생략한다.) 이 파일이 비즈니스로직을 담당한다.
Java

package ex.struts;

public class PrintStringAction {
    private String greetings;
    
    public String execute() throws Exception {
        greetings = "Hello World!";
        return "success";
    }
    
    public String getGreetings() { return greetings; }
    public void setGreetings(String greetings) {
        this.greetings = greetings;
    }
}

그리고 WebContent/ 아래에 printString.jsp를 만들어 준다. 이 jsp파일이 뷰단을 담당한다.
Html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<%@ page contentType="text/html; charset=utf-8" %>
<% request.setCharacterEncoding("utf-8"); %>
<% response.setContentType("text/html; charset=utf-8"); %>
<%@ taglib prefix="s" uri="/struts-tags" %>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ko" lang="ko">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>pringtString</title>
  </head>
    
  <body>    
    <s:property value="greetings" />
  </body>
</html>

이제 struts.xml파일에 위 2파일에 대한 맵핑을 추가한다.
Xml

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

<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd">

<struts>
  <package name="default" extends="struts-default" namespace="">
        <action name="printString" class="ex.struts.PrintStringAction">
            <result>/printString.jsp</result>
        </action>
  </package>
</struts> 

이제 프로젝트를 실행하면 된다. Run As. > Run on Server를 실행하고 주소에 printString.action을 실행한다.

사용자 삽입 이미지

위처럼 Hello World! 가 찍히면 struts 셋팅이 완료된거다.

셋팅에만 집중했기 때문에 다른 부분에 대한 설명은 거의 하지 않았다. 다른것들은 나중에...

[Book] 스트럿츠 2 프로그래밍..

출처 : Outsider's Dev Story https://blog.outsider.ne.kr/

스트럿츠 2 프로그래밍 - 8점
현철주.민상기.정광선 지음/에이콘출판


내가 꿈에도 그리던(?) WAF(Web Application Framework)에 드디어 발을 디밀었다. 스프링이냐 스트럿츠2냐는 어려운 선택이지만 일단 스트럿츠2를 택했다. 국내에 아직 스트럿츠2에 대한 책은 별로 나오지 않았다. 이 책과 다른책 2권인 것으로 알고 있다(현재로서는...) MVC Model 2에 대한 전반적인 개념이해는 충분히 가지고 있었고 최근 프로젝트에서 MVC Model 1으로 진행하면서 어떤게 필요하고 불편한지도 어느정도 느끼고 있던 터였다. 내가 있는 환경에서는 프레임워크를 거의 사용하지 않고 몇몇 사업에서 사용한다고 하더라도 그냥 얹어만 놨지 그 프레임웍에서 제공하고 있는 것을 이용해서 개발하지는 않기 때문에 난 아직 프레임워크를 접할 기회를 갖지 못했었다.

그러다 이번에 진행하는 사업에서 얘기가 진행되다가 "스트럿츠2 올릴까?"해서 주저없이 "예"하고 그 담날부터 이 책을 봤다. 보고난 후의 느낌이라면 "이걸 왜 안써!!" 정도???  아주 대략적인 개념만 가지고 있었지만 보면서 내내 "그래 이렇게 개발해야지"하는 생각이 계속 났다. (물론 이 얘기는 책 얘기가 아니라 스트럿츠2 얘기다.) 처음에는 익숙하지 않아서 좀 해맬수도 있지만 MVC의 완전한 분리, 그리고 가장 좋게 느껴진것은 인터셉터와 예외처리들... 프레임워크라면 당연히 개발방법을 어느 정도 강제함으로써 사람이라면 어쩔수 없이 할수 밖에 없는 실수를 줄여주고 개발의 속도를 높여준다. 

난 실수를 줄여주는 부분에 훨씬 관심이 갔다. 따로 모듈을 만든다고 하더라도 보안처리, 예외처 등을 처리하다보면 개발하는 것 만큼 복잡해지고 또 한번에 하지 못하고 지적받을때마다 하다보면 어딘 추가되고 어딘 안되고 나중엔 어디가 어디까지 처리됐는지도 헷갈려버리는 상황에 처하기 일쑤고 그러면 자연히 누락된 부분이 생길수 밖에 없다. 안생기는게 더 신기할 정도다... 그런 부분을 프레임워크안에서 제공해주는 기능으로 전체관리를 해준다는 것은 정말 매력적으로 보였다.(실제 해보면 또 장점이 있고 단점이 있겠지만... 아~ 그리고 물론 프레임워크 안써도 필터를 쓸수 있기는 하지만.....)


이제 책 얘기를 좀 해볼까? 책의 목차는 상당히 잘 되어 있는 편이다. 대부분 스크린샷을 제공하고 있고 세세한 부분까지 설명해 주기 때문에 개념을 잡고 이해하는데 큰 도움이 된다. 아주 간단한 예제를 통해서 스트럿츠2가 어떤식으로 동작되는 지를 가르쳐준다음 각 고급기능에 대해서 상세하게 설명해 주는 것도 상당히 괜찮았다. 난 책을 읽으면서는 왠만하면 코딩을 잘하지 않는 편인데 이번에는 바로 실무에 써먹어야 되기도 했고 나에겐 새로운 영역이었기 때문에 상당히 많은 예제들을 따라해 보았다. 설명하려고 하는 부분에 대한 이해만 도울수 있는 정도의 적절한 예제가 제공되고 있는 느낌이고 처음엔 무슨 소린가 하더라도 한번 예제를 따라해 보면 대부분 이해를 할 수가 있었다. 백문이불여일타라고 하지 않는가... ㅎㅎㅎ

거의 모든 설명의 패턴이 동일하다 처음에 어떤 기능인지를 대략적으로 설명한뒤에 거기에 필요한 부연설명들을 한다. 그리고 이걸 위해서 어떻게 동작할 예제를 만들것인지를 말해주고 동작구조에 대한 그림과 함께 동작방식을 얘기하고 따라할 수 있는 소스를 제공한다. 그리고 그 뒤에 소스에 대한 설명을 한다. 이걸 죽~ 따라하면 이해하는데 전혀 무리가 없을 정도로 자세하다.

각 기능별로 설명과 예제가 함께 있기 때문에 레퍼런스로 활용하기에도 괜찮을듯 하고 많이 쓰는 Ajax, 파일처리, 유효성검사, i18n, 로깅등에 대해서도 자세하게 다루고 있기 때문에 스트럿츠2를 사용하는데 필요한 것은 거의 대부분 담고 있는듯 하다. 그리고 사업들에는 많이 필요할듯한 대표적인 플러그인들도 간단히 예제와 함께 설명해 주고 있다. 물론 플러그인들 부분은 실제로 활용을 하려면 별도의 자료를 찾아봐야 할듯 하다.(이건 뭐 양이 많으니 단점이라고 얘기한것은 아니다.)


이렇게 몇권 나오지 않은 것중에서 고를때는 선택권은 없지만 과연 이중에 좋은 책이 있을가 하는 생각에 망설이게 되는데 스트럿츠2를 입문하기에 적절한 책이라고 생각한다. 다만 아쉬운 점은 이렇게 각 기능을 죽~ 설명한 다음에 대부분의 책에서 마지막으로 나와야 할 종합예제. 더 구체적으로 말하면 서버사이드쪽에서 설명하기도 좋고 이해하는 쪽에서도 좋다고 생각하는 게시판예제!!! 이게 없다. 단편적으로는 거의 이해를 하고 책보면 따라할 수 있을텐데 보는 내내 계속 찜찜하던 것은 개발을 하면 한 페이지에도 수많은 기능들이 필요한데 이렇게 됐을때 이런 것들이 어떻게 유기적으로 구성되어야 하는지가 머릿속에 잘 그려지지가 않았다. 마지막에 게시판 예제같은 것이 하나 제공됐으면 딱 이해됐을텐데....

그 리고 이 책은 마치 매뉴얼처럼 아주 객관적으로만 설명하고 있다. 이게 있지만 이거보단 이렇게 하는게 더 좋다고 생각한다든가 하는 등의 저자의 주관적인(?) 얘기는 거의 들어있지 않다. 그러다 보니 스트럿츠2의 태그라이브러리를 이용하면 Ajax등도 간단하게 쓸 수 있는데 나같이 의심많은 놈은 복잡한 코드를 이렇게 자동으로 찍어주는게 별로 신용이 가지 않았고 결과물을 어느정도까지 커스터마이징이 가능할 지도 감이 잘 오질 않았다. 처음 접하는 입장으로써 이걸 써야되나 말아야 되나 하는 고민들..... 특히 나같은 경우는 prototype.js를 사용하는데 스트럿츠2에서 제공하는 것은 Dojo를 이용하고 있었다. ㅡ..ㅡ

Ajax 에서 많이 사용하는 첫 셀렉트박스를 선택하면 두번째 셀렉트박스의 옵션값이 설정되는 것도 아주 간단히 <s:doubleselect />태그를 이용해서 만들수 있는데 자바스크립트를 직접 다루는 것을 더 좋아하는 나로써는 그냥 이걸 이용하는게 좋을지 하는 등의 고민은 직접 해야한다. ㅡ..ㅡ (물론 책이 모든 고민을 해결해 주는 것은 아니지만...ㅎㅎㅎ)

My Comment..
이 책 표지를 보니 생각이 어렴풋이 난다.. 나도 아마 플젝때문이었을 텐데..
스트럿츠2 프레임워크를 쓴다고 해서.. 개념이라도 확인해봐야겠다고 해서..
찾던 중.. 햄이 책을 읽고 있었던가.. 책이 햄 옆에있었던가 해서.. 보게 되었던..
문제는 조금 보다가.. 인터넷으로 찾아서.. 예제를 돌려보고.. 그 패턴 자체를..
이해하고 넘어갔던 기억이.. ㅋㅋㅋ..