Whiteship's Note

'2009/03'에 해당되는 글 32건

  1. 2009.03.30 기트(Git) 주요 개념 (8)
  2. 2009.03.27 JUnit에서 setUp() 또는 @Before를 사용하는 이유? (2)
  3. 2009.03.27 20090327 GMP
  4. 2009.03.26 20090326 GMP
  5. 2009.03.26 JGit 설치
  6. 2009.03.24 20090324 GMP (6)
  7. 2009.03.23 스프링 프레임워크 트레이닝 갈까말까 (6)
  8. 2009.03.20 Our plans for building OSGi application 요약
  9. 2009.03.20 20090320 GMP
  10. 2009.03.19 프로 스프링 2.5 6장 저자와 번역 합의 메일 (9)
  11. 2009.03.19 20090319 GMP (2)
  12. 2009.03.18 스프링 REST 지원 사용하여 애플리케이션에 Atom 뷰 추가하기
  13. 2009.03.17 스프링 웨비나: Building Twitter with Grails in 40 Minutes
  14. 2009.03.17 20090317 GMP
  15. 2009.03.16 공부할 것 정리 (6)
  16. 2009.03.13 EJ2E Item 20. 태그가 있는 클래스 대신 클래스 계층구조를 선호하라.
  17. 2009.03.11 격조 있는 칼(나이프)질로 방울 토마토 먹기 (6)
  18. 2009.03.11 HTTP ETag
  19. 2009.03.11 Content negotiation
  20. 2009.03.11 STS에서 스프링 DM 서버 실행하기
  21. 2009.03.10 SWF 12장 JSF 통합
  22. 2009.03.09 REST in Spring 3: @MVC (8)
  23. 2009.03.09 보드야 이번 겨울 잘~~ 놀았다! (4)
  24. 2009.03.06 스프링 인티그레이션 샌드박스 예제(town crier) 실행 성공~!
  25. 2009.03.06 스프링 인티그레이션 빌드 실패~
  26. 2009.03.05 SWF 11장 스프링 자바스크립트 퀵 레퍼런스
  27. 2009.03.05 STS(Spring Tool Suite) 2.0 RC 버전의 OSGi 개발 툴 (2)
  28. 2009.03.05 개봉동에서 다시 운동 시작! (6)
  29. 2009.03.04 스프링 3.0 m2 빌드 삽질 중 (4)
  30. 2009.03.04 SWF 10장 스프링 MVC 통합

기트(Git) 주요 개념

Good Tools : 2009.03.30 16:16


참조: http://git.or.cz/course/svn.html

저장소(Repository): 서브버전에서 각각의 프로젝트는 체크아웃하고 커밋하는 중앙에 위치한 단일 저장소에 위치한다. Git는 다르게 동작한다. 각각의 프로젝트 트리(working copy라고 부른다) 복사본을 각자의 저장소에 가지고 있는다. 따라서 로컬과 원격 브랜치를 가질 수 있다. 또한 워킹 카피에 붙어있지 않은 베어 저장소(Bare repository)를 가질 수 있는데, 이 것은 특히 저장소를 공개하고 싶을 때 유용하다.

URL: 서브버전에서 URL은 저장소 위치 식별자와 저장소 내부 경로를 나타낸다. 따라서 저장소의 레이아웃과 그 의미를 구조화 한다. 보통 trunk/, branches/, tags/ 디렉터리를 가지고 있을 것이다. 기트에서 URL은 단순 저장소 위치다. 브랜치와 태그는 항상 내포하고 있다. 브랜치중 하나를 기본으로 사용하고 그 이름이 보통 master다.

리비전(Revision): 서브버전은 리지번을 증가만 하는 정수 id로 식별한다. 대규모 프로젝트에서는 금방 수 백, 수 천이 되는 경향이 있다. Git 같은 분산 시스템에서는 실용적이지 않다. Git는 SHA1 id로 리비전을 식별한다. 16 진수의 기다란 160 비트 숫자다. 처음엔 좀 당황스럽지만 실제로는 그리 방해가 되지 않는다. 최신 리비전을 HEAD로 참조할 수 있고, 그 부모를 HEAD^ 로 참조하고 부모의 부모는 HEAF^^ = HEAD^2 이런식으로 참조할 수 있다. 또한 리비전의 앞 부분 몇 개만으로 참조할 수 있다. 그것으로 식별할 수 있다면 기트가 나머지를 추측할 것이다.

커밋(commit): 각각의 커밋은 author와 committer가 있다. 누가 언제 코드를 변경했고 누가 그것을 커밋했는지 알려주는 정보다.(Git는 메일로 주는 패치를 잘 적용할 수 있도록 설계 했는데, 이런 경우 author와 committer가 다를 수 있다.) git config -I로 이름과 이메일을 확인할 수 있다. 그리고 다음 명령어로 그 정보를 설정할 수 있다.

git config --global user.name "Your Name Comes Here"
git config --global user.email you@yourdomain.example.com

명령어: git command 형태인데, git-command 형태로 사용할 수도 있다.

색상: 다음과 같이 설정하면 컬러풀한 결과를 볼 수 있다. 기본값으로 색상을 사용하지 않는다.

git config --global color.diff auto
git config --global color.status auto
git config --global color.branch auto

비주얼: gitk를 사용해서 저장소를 살펴보면 편리할 것이다. 맥용 gitk 대체 애플리케이션
신고

'Good Tools' 카테고리의 다른 글

기트(Git)와 SVN으로 동시에 버전 관리하기  (4) 2009.04.27
Github 맘에 드네~  (0) 2009.04.25
Github에 pull, push하기  (2) 2009.04.14
기트(git) config  (0) 2009.04.09
기트(git) 주요 명령어  (2) 2009.04.07
기트(Git) 주요 개념  (8) 2009.03.30
JGit 설치  (0) 2009.03.26
아이폰 애플리케이션 iDie  (0) 2009.03.03
구글 토크 사전  (4) 2009.01.05
Word Cloud 만들어보기  (0) 2008.12.08
i구글의 날씨 위젯 좀 짱인듯..  (0) 2008.11.28
top

TAG Git

JUnit에서 setUp() 또는 @Before를 사용하는 이유?

모하니?/Coding : 2009.03.27 11:50


참조: http://stackoverflow.com/questions/512184/best-practice-initialize-junit-class-fields-in-setup-or-at-declaration

JUnit은 각각의 테스트를 독립적으로 테스트하기 위해 테스트 마다 개별적인 객체를 생성합니다. 따라서..

public class SomeTest extends TestCase
{
   private final List list = new ArrayList();

    public void testPopulateList()
   {
       // Add stuff to the list
       // Assert the list contains what I expect
   }
}

이런식으로 테스트를 작성해도

public class SomeTest extends TestCase
{
   private List list;

    @Override
   protected void setUp() throws Exception
   {
       super.setUp();
       this.list = new ArrayList();
   }

    public void testPopulateList()
   {
       // Add stuff to the list
       // Assert the list contains what I expect
   }
}

이렇게 작성한 것과 동일하게 각각의 테스트를 실행하기 전에 초기화 하는 코드를 실행합니다.

그럼 대체 setUp이나 @Before는 왜 사용할까요? 그냥 생성자를 사용하거나 저렇게 필드에 직접 객체를 생성하게 해도 비슷한데 말이죠.

윗 글을 찾아보기 전에는 '그냥 tearDown이랑 균형을 맞출려고 만들었나?', '생성자를 쓰면 안 좋은 뭔가가 있나?' 등등 막연하게 생각하고 있었습니다. 그러다가 도무지 궁금해서 구글신에게 문의했더니 윗 글을 찾을 수 있었습니다.

댓글들을 조사해 본 결과.

1. Exception 발생: setUp()에서 예외를 던지면 JUnit이 유용한 스택 트레이스 정보를 돌려주지만, 생성자에서 예외가 발생하면 그냥 테스트 객체를 못 만드는 것이기 때문에 유용한 정보를 얻을 수 없음.

2. 베스트 프랙티스: 테스트 하려는 클래스의 인스턴스는 테스트 또는 setUp()에서 생성하고, 테스트 대상이 아닌 속성들은 필드에서 직접 new로 생성해도 상관없다.

이 두 가지가 유력해 보이네요.
신고
top


20090327 GMP

모하니?/GMPing : 2009.03.27 11:50


모닝 단어

sign up for a class: 수강 신청하다
elective course: 선택 과목
pre-requisite course: 필수 과목
major in: 전공하다
business administration: 경영학

GER(general education requirement): 교양 과목
enroll in: 수강 신청하다
minor in: 부전공하다
double major: 복수전공
수강취소: drop a class, cancle
청강: seat in a class, monitor

I signed up for five classes in this semester.: 이번 학기 다섯 과목 수강 신청했다.
For each term, you are required to enroll two electives: 한 학기에 선택 과목 두 개씩 들어야해.

스크린 잉글리쉬

I should have done something.(뭐라도 했었어야 했는데)
Hey IQ, you want some?
Scuter, you are alive.
I should kill you.
You and your compulsive(충동적인) eating, you almost got us killed.
Scuter, you gotta go want a diet.
I promise I will.
They are all American flies after all.

팝스 잉글리쉬

브리트니 스피어스-서커스

I'm like the ringleader
I call the shots(명령은 내가 내린다.)
I'm like a firecracker
I make it hot
When I put on a show

Talk Play Learn

Can you give me a hand ~ing?

Can you give me a hand figuring this out?
Can you give me a hand washing my car?
Can you give me a hand setting the table?
Can you give me a hand writing my report?
Can you give me a hand fixing my bicycle?
Can you give me a hand organizing the party?

신고

'모하니? > GMPing' 카테고리의 다른 글

20090327 GMP  (0) 2009.03.27
20090326 GMP  (0) 2009.03.26
20090324 GMP  (6) 2009.03.24
20090320 GMP  (0) 2009.03.20
20090319 GMP  (2) 2009.03.19
20090317 GMP  (0) 2009.03.17
20081224 GMP  (0) 2008.12.24
20081223 GMP  (0) 2008.12.23
20081218 GMP  (4) 2008.12.18
20080829 GMP  (0) 2008.08.29
20080828 GMP  (0) 2008.08.28
top

TAG GMP

20090326 GMP

모하니?/GMPing : 2009.03.26 17:06


모닝 단어

All-nighter: 밤을 새다.
cram: 벼락치기 하다.
credit: 이수 학점
midterms: 중간고사
GPA: Grade Point Average 평균점수

성적, 학점, 학년: grade
낙제점: flunk
쪽지시험: pop quiz
점수를 짜게 주는 선생님: tough grader

벼락치기 해야돼: I need to cram.
I polled on All-nighter to finish my term-end paper.

스크린 잉글리쉬

Huston tranquility(고요한) base, the eagle has landed.
We are on the moon.
Did you hear something?
I thought I did for a moment there.
Never mind.
We did it commander

팝스 잉글리쉬

브리트니 스피어스-서커스

there's only two types of people in the world
the ones that entertain
and the ones that observe

well baby I'm a put-on-a-show kinda girl
(I) don't like the backseat(뒤에 물러나 있는건 싫다.)
gotta be first

Talk Play Learn

Where do you want to ~ ?

Where do you want to go?
Where do you want to seat?
Where do you want to meet?
Where do you want to take a trip?
Where do you want to look around?
Where do you want to go for a beer?
Where do you want to have a party?
신고

'모하니? > GMPing' 카테고리의 다른 글

20090327 GMP  (0) 2009.03.27
20090326 GMP  (0) 2009.03.26
20090324 GMP  (6) 2009.03.24
20090320 GMP  (0) 2009.03.20
20090319 GMP  (2) 2009.03.19
20090317 GMP  (0) 2009.03.17
20081224 GMP  (0) 2008.12.24
20081223 GMP  (0) 2008.12.23
20081218 GMP  (4) 2008.12.18
20080829 GMP  (0) 2008.08.29
20080828 GMP  (0) 2008.08.28
top

TAG GMP

JGit 설치

Good Tools : 2009.03.26 15:41


이클립스 업데이트 사이트: http://www.jgit.org/update-site
위 업데이트 사이트를 이용해서 설치하면 됩니다.

그런 다음 Git로 버전 관리할 프로젝트에서 Team -> Share Project -> Git를 선택합니다. 그럼 이제 Team 메뉴에서 Git 명령어 몇 개를 사용할 수 있습니다.

사용자 삽입 이미지
사용자 삽입 이미지

아직은... 툴 지원이 Subversion에 비해 미약한 듯 합니다. 특히 Git에서 자주 사용할 것 같은 명령어인 Add, Commit, Pull, Push에 대한 단축키가 지정되어 있지 않다는 것이 좀 걸립니다. 물론 수동으로 단축키를 등록하고 사용하는 방법도 있지만... 조금 귀찮죠.

새로 추가한 파일은 관리 대상이 아니라는 표시가 나오고 관리 중인 코드를 변경하고 아직 commit 하지 않았을 경우 not updated라고 표시해줍니다. 이 상태에서 commit을 하면 not updated인 코드만 commit하고 새로 추가한 파일은 commit하지 않습니다.

오른쪽 조그만 빨간색은 JUnit Max인데 저장하는 순간 바로 테스트를 하고 그 결과를 알려주기 때문에 굉장히 유용한 툴인것 같습니다. 손수 테스트를 돌리지 않아도 되기 때문에 코딩 흐름을 빠르게 이어 나갈 수 있습니다.
신고

'Good Tools' 카테고리의 다른 글

Github 맘에 드네~  (0) 2009.04.25
Github에 pull, push하기  (2) 2009.04.14
기트(git) config  (0) 2009.04.09
기트(git) 주요 명령어  (2) 2009.04.07
기트(Git) 주요 개념  (8) 2009.03.30
JGit 설치  (0) 2009.03.26
아이폰 애플리케이션 iDie  (0) 2009.03.03
구글 토크 사전  (4) 2009.01.05
Word Cloud 만들어보기  (0) 2008.12.08
i구글의 날씨 위젯 좀 짱인듯..  (0) 2008.11.28
IntelliJ도 좋아보이는데.. 상용인게 안타깝네요  (4) 2008.11.10
top


20090324 GMP

모하니?/GMPing : 2009.03.24 12:25


모닝 단어

office supplies: 사무 용품
stationery: 문구류, 편지지
envelope: 동봉하다
highlighter: 형광펜
organizer: 다이어리

내일 비품을 주문해야 돼: We need to order office supplies
스테이플로 종이를 박았습니다.: I stapled papers.

스크린 잉글리쉬

This breaking news just in(방금 들어온 소식이다).
We now have photos from American space mission.
American astronout has made it to(~까지 가다) the moon before Russia.
Klemlin very embrassed.

How (did) happen this to us? Someone tell me about this.
I want anwser not yesterday today.
I'll explain comlade.
I'm waiting.

Hi grandma grandfa we did it.
We are headed for the moon.

팝스 잉글리쉬

This sea of heartbreak. lost love and lonelyness.
Memories of your caress so devined.
I wish that you were mine again my deer.
I'm on the sea of tears sea of heartbreak.

Talk Play Learn

How soon can you ~ ?(얼마나 빨리~할 수 있니?)

How soon can you finish this?
How soon can you deliver it?
How soon can you get it back?

신고

'모하니? > GMPing' 카테고리의 다른 글

20090327 GMP  (0) 2009.03.27
20090326 GMP  (0) 2009.03.26
20090324 GMP  (6) 2009.03.24
20090320 GMP  (0) 2009.03.20
20090319 GMP  (2) 2009.03.19
20090317 GMP  (0) 2009.03.17
20081224 GMP  (0) 2008.12.24
20081223 GMP  (0) 2008.12.23
20081218 GMP  (4) 2008.12.18
20080829 GMP  (0) 2008.08.29
20080828 GMP  (0) 2008.08.28
top

TAG GMP

스프링 프레임워크 트레이닝 갈까말까

Spring/etc : 2009.03.23 10:56


참조: http://www.springsource.com/training/spr001/icn20090525

고민되네요. 참석하고 싶은데 걸리는게 조금 있습니다.

일단 돈이 문제입니다. 호주 달러로 거의 3000달러인데 그것도 4월 24일 전에 등록해야 2995달러고, 그 뒤에는 3230달러입니다. 세일 가격에 등록한다고 했을 때 한화로 300만원이 필요합니다.

일정이 문제입니다. 결혼식이 5월 30일인데 교육 일정이 25~28일입니다. 결혼식에 한참 신경써야 할 시기인데 색시가 서운하거나 내가 교육에 집중하지 못 할 일이 생기지는 않을지 걱정입니다.

그래도 가고 싶은 이유는 일단 실습 교육이라는 겁니다. 스프링소스 직원은 어떤 스타일로 스프링을 사용하는지 볼 수 있는 절호의 기회인 듯 합니다.

두 번째는 영어 실력 테스트입니다. 지난 번 스프링 컨퍼런스에 가서 느낀점은 스프링 보다는 영어가 중요하다는 거였습니다. 스프링은 영어를 마스터 하고 나서 해도 늦지 않겠다고 느꼈습니다. 그런데 게을러지다 보니까 쉬운거만 하게 되고 영어 공부보다는 스프링 공부가 쉬우니까 나태해졌는데.. 그런 제 자신에 경각심을 줄겸 영어 열공에 목표도 줄겸.. 여러모로 영어 학습에 기름을 부울 수 있는 계기가 될 것 같습니다.

세 번째는 스프링 자격증입니다. 스프링 자격증이 있다는 걸 모르시는 분들도 많을텐데요. 스프링 자격증을 따려면 교육 과정에 참여해야 합니다. 예외도 있긴 하지만 극히 드문 경우 같구요. 이번 교육에 참요하면 자격증 시험 등록비를 깍아 준다고 합니다. 보통 150$를 깍아 준다고 하니까 괜찮은 떡밥이라고 생각됩니다.

네 번째는 희소성입니다. 이번이 아니면 언제 또 한국에 와서 교육을 해줄지 모르기 때문에 오히려 이번에 교육을 받는게 낫지 않을까 하는 생각입니다.

시간과 돈에 여유가 있으신 분들은 참석하시면 좋을 듯합니다. 아웅~~~ 가고 싶다!!
신고
top


Our plans for building OSGi application 요약

Spring DM/etc : 2009.03.20 20:51


참조 및 요약: Our plans for building OSGi application

OSGi 빌드 요구 사항

- 의존성 메타 데이터 중복 제거: 사용하는 빌드에 따라 pom.xml, ivy.xml에도 의존성을 정의하고 MANIFEST.MF 파일에도 의존성을 정의하는데 그러지 말고 한 곳에서 의존성을 정의하는 방법이 필요하다.

- 기존의 빌드 시스템 활용: 사용자들은 기존의 방식대로 메이븐 또는 Ant 빌드를 사용하고 싶어한다.

- 자동으로 MANIFEST.MF 파일 생성하기

- OSGi MANIFEST.MF 파일에서 의존성 가져오기: MANIFEST.MF 파일을 중심으로 의존성을 해결할 때 필요하다.

시나리오

1. 메이븐 + 이클립스 - pom.xml-주도: OSGi Manifest 파일은 메이븐 또는 이클립스 플러그인을 사용하여 자동생성한다. Manifest 생성에 필요한 대부분의 정보는 자바 코드에서 얻을 수 있지만 버전 정보는 그렇지 않다.  버전 정보는 pom.xml에서 그 정보를 가져올 수 있겠다. Manifest 템플릿을 통해서 그런 일을 할 수 있고 OSGi 속성이나 커스텀 헤더를 추가할 수 있겠다.

2. Ant + Ivy + 이클립스 - ivy.xml-주도: Ant 태스크로 manifest 파일을 생성한다. 위의 방법과 비슷하지만 단점으로 아직 이클립스에서 Ivy 2를 지원하는 플러그인이 없다. 개발자가 ivy.xml 파일을 작성하면 이클립스 플러긴을 사용해서 manifest를 만들고 이클립스 클래스패스를 자동으로 수정해주도록 한다.

3. 메이븐 + 이클립스 - MANIFEST.MF-주도: 개발자가 MANIFEST.MF 파일을 직접 또는 플러그인을 통해서 작성하면 그 파일을 기반으로 의존성을 처리한다. 이때 이클립스의 클래스패스 컨테이너를 이용한다. 테스트를 지원하기 위해 TEST.MF 파일에는 테스트에 필요한 의존성을 정의할 수 있게한다. 여기에 정의한 의존성은 테스트할 떄에만 가져온다. 남은 부분은 이것을 메이븐에 어떻게 적용하느냐 인데 현재 두 가지 옵션을 고려중이다. 하나는 pom.xml을 생성하는 것이고 다른 한 방법은 메이븐의 의존성 처리와 연동 또는 그것을 교체하는 것이다.

4. Ant + Ivy + 이클립스 - MANIFEST.MF-주도: 3번 방법과 비슷하고 2번의 단점인 Ivy 2 이클립스 플러긴 지원이 필요없어진다. Manifest-주도 이클립스 클래스패스 컨테이너를 사용할 것이기 때문이다.

OSGi 빌드 툴

- Bundlor: spring build 프로젝트에서 개발 중이며 몇 주후에 첫 번째 버전을 공개할 예정. 번들을 만들어 주며, manifest.mf 파일을 만들어 준다. http://www.springsource.com/repository/app/ 이곳에 있는 대부분의 번들을 이 툴로 만들었다. manifest 템플릿을 제공하여 커스터마이징 할 수 있게 해준다.

- BundlorEclipse: 이클립스 플러그인으로 Bundlor 기능을 이클립스에서 직접 사용할 수 있다. 소스 코드를 저장 버튼을 눌러 저장할 떄마다 manifest를 계속해서 수정해준다.

- 오프라인 의존성 리졸버

- Manifest 클래스패스 컨테이너

- 메이븐/Ivy 의존성 리졸버/pom.xml/ivy.xml  생성기

왜 bnd를 사용하지 않고 Bundlor를 만들었나?

처음에는 spring dm 프로젝트에서는 bnd를 사용했지만 다음의 부가 기능이 필요해서 만들었다.
- JDT-기반 코드 스캐닝
- 일부(Partial) 코드 처리하기
- 계속적인 manifest 생성

이클립스가 아닌 다른 IDE 활용하기

이클립스 말고 IntelliJ나 NetBeans 사용자를 위해 그쪽 팀에 Bundlor 핵심 라이브러리를 커밋했다. 그 결과 어떤 IDE 에서도 OSGi 개발 툴을 사용할 수 있게 됐다.

추가 요구사항

- 벌크 번들 생성

- 저장소-기반 코드 완성: dm 서버 저장소를 기반으로 소스 코드에서 자동 완성을 하면 자동으로 import 문을 추가해주고 Manifest에도 import 문을 추가해준다.
신고
top


20090320 GMP

모하니?/GMPing : 2009.03.20 17:50


모닝 단어

laundry mat: 빨래방
detergent: 세제
stain: 얼룩
fabric: 옷감
bleach: 표백제

세탁하다: do the laundry
천이 줄어들다: shrink
옷을 개다: folding clothes
작은 얼룩: spot

친환경 세제를 찾고 있어요: i'm looking for a detergent environmently friendly.
빨래하는 것도 질력이 나: I'm sick of doing the laundry.

스크린 잉글리쉬

Wow, That was close.(아슬 아슬 했다.)
He almost got me.
Where is Scuter?
I didn't see him.
There he is. What is he doing?
Oh no Scuter
What's up guys?
Oh I thought that you were down there.

팝스 잉글리쉬

When a man loves a woman

When a man loves a woman,
I give you everything I've got.
Trying to hold on your precious love.
Baby baby please don't treat me bad.

Talk Play Learn

Would you call me when you ~?

Would you call me when you arrive?
Would you call me when you leave?
Would you call me when you start?
Would you call me when you finish?
Would you call me when you see her?
Would you call me when you need help?
Would you call me when you have time?
Would you call me when you get this message?


신고

'모하니? > GMPing' 카테고리의 다른 글

20090327 GMP  (0) 2009.03.27
20090326 GMP  (0) 2009.03.26
20090324 GMP  (6) 2009.03.24
20090320 GMP  (0) 2009.03.20
20090319 GMP  (2) 2009.03.19
20090317 GMP  (0) 2009.03.17
20081224 GMP  (0) 2008.12.24
20081223 GMP  (0) 2008.12.23
20081218 GMP  (4) 2008.12.18
20080829 GMP  (0) 2008.08.29
20080828 GMP  (0) 2008.08.28
top

TAG GMP

프로 스프링 2.5 6장 저자와 번역 합의 메일



봄싹스터디에서 베타리딩 중인 프로 스프링 2.5 6장 AOP 관련 내용 중에 이상한 부분이 있다는 글이 올라온적이 있습니다. 성윤님이 올린 글 @Aspect는 누구의 것?이라는 글인데 저 부분을 번역한 것이 바로 접니다. 번역하면서도 저 부분이 뭔가 맘에 걸렸지만 일단은 번역 자체가 급해서 걍 넘어갔었는데 다행히도 베타리딩에서 잘 걸렸네요.

몇 일 미루다가 오늘 아침 저자에게 메일을 보냈습니다.

사용자 삽입 이미지

대충 @AspectJ 애스팩트가 AspectJ에 의존하는데 왜 의존하지 않는다고 썼느냐.. 라고 보냈습니다. 그랬더니 답장이 왔는데..

사용자 삽입 이미지

음.. 이건 걍 읽어보시면 좋은 내용입니다. 본래는 어쩌구 저쩌구 하면서 좀 장황하게 얘기를 해주네요. 중요한건 ApsectJ 라이브러리를 참조하기는 하지만 애노테이션을 떄문에 참조하는 것이지 스프링 AOP를 사용할 때는 AspectJ의 compile-time weaving 같은 컴포넌트를 사용하진 않는다는 겁니다. 그런 뜻으로 AspectJ에 의존하지 않는다고 한거라는거죠.

하지만 너무 애매하자나요. 그래서 다시 메일을 보냈습니다.

사용자 삽입 이미지

애매하니까 AspectJ 라이브러리에서 애노테이션만 사용하고 다른 것들은 사용하지 않는다는 식으로 번역하겠다고 보냈습니다.

사용자 삽입 이미지

귿~ 잘 해결됐네요. 그렇게 하랍니다. 번역서에서는 좀 더 분명하게 적어드리겠습니다.


신고
top


20090319 GMP

모하니?/GMPing : 2009.03.19 11:54


모닝 단어

briefcase: 얇은 서류 가방
satchel: 큰 가방, 학생 가방
suitcase: 여행가방
barf bag: 멀미 봉투
pack: 짐을 꾸리다

purse: 장지갑
sudo trolley: 바튀 달린 가방
plastic bag: 비닐 봉지

Did you begin the pack up?: 짐 싸기 시작했니?

in the bag: 매우 확실한
bottom of bag: 최후의 수단
let the cat out of the bag: 비밀이 새어 나가다

스크린 잉글리쉬

They took a rocket to the moon mommy.
What did you say?
Rocket, He clearly said rocket.
I heard moon.
What's today is date?
Please not now.
Today is the day the humans sending a man to the moon.
Let's going to the moon. Let's going to the moon.

오늘이 무슨 요일이야? What day is it today?
오늘이 몇일이야? What's today is date?

팝스 잉글리쉬

When a man loves a woman

When a man loves a woman,
can't keep his mind on nothing else
he'd trade world for a good thing he's found.

Talk Play Learn

He is such a ~.
He is such a pet lover.
He is such a pessimist.
He is such a worker holic.
He is such a people person.(사교적)
He is such a penny pinchur.(구두쇠)

신고

'모하니? > GMPing' 카테고리의 다른 글

20090327 GMP  (0) 2009.03.27
20090326 GMP  (0) 2009.03.26
20090324 GMP  (6) 2009.03.24
20090320 GMP  (0) 2009.03.20
20090319 GMP  (2) 2009.03.19
20090317 GMP  (0) 2009.03.17
20081224 GMP  (0) 2008.12.24
20081223 GMP  (0) 2008.12.23
20081218 GMP  (4) 2008.12.18
20080829 GMP  (0) 2008.08.29
20080828 GMP  (0) 2008.08.28
top

TAG GMP

스프링 REST 지원 사용하여 애플리케이션에 Atom 뷰 추가하기



참조: http://blog.springsource.com/2009/03/16/adding-an-atom-view-to-an-application-using-springs-rest-support/

위 글을 실습해봤습니다. 재밌더군요~


신고
top


스프링 웨비나: Building Twitter with Grails in 40 Minutes

Spring/Webinar : 2009.03.17 22:59


내일 모래 목요일 한국 시간으로 밤 11시에 시작합니다.
https://www1.gotomeeting.com/register/844031096

스프링소스에서 Grails 개발을 담당하고 있는 Graeme Rocher가 직접 40분 안에 Grails를 사용해서 Twitter와 비슷한 애플리케이션을 만드는 데모를 보여준다고 합니다. +_+ 상상만해도 멋지네요.

스프링, JMS, Java Persistence 기술을 사용할 예정이며, Grails 애플리케이션을 Java EE 플랫폼에 배포하는 것과 관련된 고급 팁과 기술을 선보일 예정이라고 합니다.
  • 스프링-기반 도메인 객체를 사용하여 기본적인 Grails 프로젝트를 어떻게 구성하는지
  • Grails 애플리케이션에서 메시징과 영속성을 어떻게 다루는지
  • 애플리케이션에 필요한 기본 설정을 어떻게 하는지
살펴볼 수 있다고 합니다. 목요일은 오랜만에 웨비나에 참석해야겠습니다.

신고
top


20090317 GMP

모하니?/GMPing : 2009.03.17 11:26


모닝 단어

빨래할 때 주의하세요: Be careful when you do the laundry.
쫙 빼입었구나: You all dressed up.
잘 어울린다: goes well
유행이 지났다: old fashion, out of style
옷이 너무 야하다: loud
garment: 의복, 긴 웃옷
outfit: 여성 의상
gear: 기능성 옷
suit: 정장
dress up: 갖춰입다

스크린 잉글리쉬

할아범: tell your old grandfa. What's on your mind~?(무슨 생각하니?) I know somnething is.
꼬마: I want to have a big advanture.
all for(대찬성) <-> against

팝스 잉글리쉬

Duffy – Stepping Stone
they bring you back to my life again.
I put on a face(난 기쁜척 하고 있어요) just like a friend.
But I think you know ~~

Talk Play Learn

Do you remember ~?
Do you remember your first date with her?
Do you remember your first day in Seoul?
Do you remember your neighbors in LA?
Do you remember the recipe for 미역국?

신고

'모하니? > GMPing' 카테고리의 다른 글

20090327 GMP  (0) 2009.03.27
20090326 GMP  (0) 2009.03.26
20090324 GMP  (6) 2009.03.24
20090320 GMP  (0) 2009.03.20
20090319 GMP  (2) 2009.03.19
20090317 GMP  (0) 2009.03.17
20081224 GMP  (0) 2008.12.24
20081223 GMP  (0) 2008.12.23
20081218 GMP  (4) 2008.12.18
20080829 GMP  (0) 2008.08.29
20080828 GMP  (0) 2008.08.28
top

TAG GMP

공부할 것 정리

모하니?/Planning : 2009.03.16 20:10


매일 세 시간
- 오라클 10/11
- 네트워크 프로그래밍

매일 두 시간
- 번역
- 코딩

매일 한 시간
- GMP

격일 두 시간
- 자바스크립트
- CSS

===================
하루 8시간 학습, 나머지 웹 서핑, 기타 학습, 블로깅은 남는 시간에...


신고

'모하니? > Planning' 카테고리의 다른 글

[Atlassian] 이직 계획  (2) 2009.11.02
[ToDo] 20091016  (0) 2009.10.16
[ToDo] 오늘 할 일 - 할일(예상 소요 시간)(실제 소요 시간)  (4) 2009.10.15
2009년 마무리로 할 일  (4) 2009.10.08
9월에 할 일 정리  (10) 2009.08.31
공부할 것 정리  (6) 2009.03.16
요즘 내 우선순위  (2) 2009.01.22
봄싹 3기 TDD 스터디 장소 시간 확정 됐습니다.  (2) 2008.12.30
봄싹 3기 TDD 스터디 계획  (4) 2008.12.29
이번 주 할 일  (0) 2008.12.23
잠깐 정리 좀;;  (2) 2008.12.23
top


EJ2E Item 20. 태그가 있는 클래스 대신 클래스 계층구조를 선호하라.

Java : 2009.03.13 20:09


참조: Effective Java 2nd Edition. Prefer class hierarchies to tageed classes

사용자 삽입 이미지

위와 같은 클래스의 단점:
- enum, switch 문, 태그 필드로 인해 지져분하다.
- 여러 구현체를 하나의 클래스로 합쳐놓았기 때문에 가독성이 떨어진다.
- 불필요한 필드까지 가지고 인스턴스를 만들어야 하기 떄문에 메모리 풋프린트가 증가한다.
- 생성자에서 불필요한 필드까지 초기화하지 않는 이상 필드를 final로 선언할 수 없다.
- 생성자에서 초기화를 잘못했을 때 컴파일 시점에 이것을 알 수 없다.
- 새로운 종류를 추가했을 때 switch문에 case를 추가해야 한다는 것을 기억해야 한다. 안그러면 런타임 에러가 발생한다.
- 인스턴스 데이터 타입이 실제 타입을 알려주지 못한다.
=> 즉 장황하고, 에러가 발생할 여지가 많고, 비효율적이다.

먼저 추상 클래스를 만들어서 일반적인 것들을 이 클래스로 이동시키고,
구체적인 하위 클래스를 정의한다.
해당 하위 클래스에서 추상 매서드를 구현한다.

사용자 삽입 이미지

이렇게 구성하면
- 깨끗하고 간단하다.
- 특정 타입에 관련된 속성은 해다 클래스가 가지게 된다. 따라서 불필요한 필드가 없다.
- 모든 필드를 final로 선언할 수 있다.
- 컴파일 시점에 생성자에서 데이터 필드를 초기화 하는지, 추상 매서드를 구현했는지 확인할 수 있다.

신고
top

Java : 2009.03.13 20:09 Trackback. : Comment.

격조 있는 칼(나이프)질로 방울 토마토 먹기



아내가 어렸을 때 어느 나라 왕자(?)인지.. 누군지.. 격조 있는 집안의 친구에게 배운 칼질과 포크질을 저에게 전수해 주었습니다. 젓가락질만 어려운게 아니더군요. 나이프와 포크 놓는 위치, 방향, 잡는 법, 스프 떠 마시는 법, 포크 사용하는 법 등 @_@... 제대로 칼질 하려면 알아야 할 것들이 많았습니다.


일단 포크로 방울 토마토를 찍어 올 때 나이프로 받쳐서 튀지 않게 합니다. 그런 다음 반을 자를 때는 포크 정 중앙 사이로 나이프를 넣어서 가르고 나이프로 눌러서 포크를 빼냅니다. 여기서 먹어도 되지만 좀 더 칼질을 즐기려면 끄트머리 정리를 합니다. 포크로 찍고 나이프를 기울여서 끄트머리를 정리해 줍니다. 마지막으로 사진에는 나와있지 않은데 포크의 둥근 부분이 하늘을 향한 방향으로 하여 먹는 것이 올바른 포크 사용법이라고 합니다. 그리고 포크의 2/3 이상 입안에 넣으면 야만인 취급을 받는다고 하니.. 영국이나 프랑스에서 식사하실 때 조심하시기 바랍니다. 한국에서도 혹시나 격조 있게 식사하고 싶으신 분들에게는 한 번 해보시길 추천해 드립니다. 나름대로 재밌습니다. 다음에는 스파게티 먹는 법을 배워봐야겠습니다.

격조있는 식사법을 배워서 프랑스의 그럴싸한 식당에서 격조있게 식사를 하고 노트르담드 파리 오리지널 버전을 감상하고 오는 꿈을 꿔 봅니다. 캬~~
신고
top


HTTP ETag

TCP/IP/HTTP : 2009.03.11 13:28


참조: http://en.wikipedia.org/wiki/HTTP_ETag

ETag는 HTTP 1.1 호환 웹 서버가 반환하는 응답 헤더로 리소스가 변경 됐는지 확인하는데 필요한 정보를 제공합니다. 캐싱 기능이 있는 애플리케이션(ex 브라우저)에서 유용하며, 이 태그를 참조하여 이전에 받았던 ETag와 동일하다면 불필요하게 리소스를 다운로드 하는 작업을 줄일 수 있겠습니다. ETag의 값은 파일 크기와 파일을 수정한 날짜를 기반으로 만들거나 체크섬을 이용한다는군요.

HTTP 헤더 목록에서 다음과 같은 예제를 볼 수 있었습니다.

ETag: 737060cd8c284d8af7ad3082f209582d
신고

'TCP/IP > HTTP' 카테고리의 다른 글

HTTP ETag  (0) 2009.03.11
Content negotiation  (0) 2009.03.11
top


Content negotiation

TCP/IP/HTTP : 2009.03.11 12:41


참조: http://en.wikipedia.org/wiki/Content_negotiation

컨텐츠 네고는 사용자가 서버로 어떤 요청을 보낼 때 사용자가 어떤 응답 타입을 선호하는지에 대한 정보도 같이 전달하는 매커니즘입니다. 요청 보낼 때 Accept-Language, Accept-Charset, Accept-Encoding, Accept-Ranges, Accept헤더 정보에 선호하는 응답 관련 정보를 전달하면 됩니다. 서버에서는 이 응답 타입을 보고 해당 형태의 응답을 전달할 수 있습니다.

예1. 불어로 응답을 받고 싶을 때

Accept-Language: fr

예2. 불어와 영어를 모두 받을 수 있지만 불어를 더 선호하며, text/html 형태 응답을 가장 선호하고 모든 text와 image를 받을 수 있다.

Accept-Language: fr; q=1.0, en; q=0.5
Accept: text/html; q=1.0, text/*; q=0.8, image/gif; q=0.6, image/jpeg; q=0.6, image/*; q=0.5, */*; q=0.1

스프링 웹 플로우 레퍼런스 번역 중에 나온 단어인데 모르는 내용이라 정리해 둡니다.
신고

'TCP/IP > HTTP' 카테고리의 다른 글

HTTP ETag  (0) 2009.03.11
Content negotiation  (0) 2009.03.11
top


STS에서 스프링 DM 서버 실행하기





어제 오늘 방명록에 올라온 질문에 대한 피드백입니다. 참고하셔서 부디 OSGi 프로젝트 무사히 마치시기 바랍니다. 잘 되시면 나중에 저에게만 살짝 프로젝트 소스를 공개해주셔도 됩니다.ㅋㅋ
신고
top


SWF 12장 JSF 통합



12.1. 도입

스프링 Faces는 스프링의 JSF 통합 모듈로 스프링에서 JSF 사용을 간편하게 해준다. JSF UI 컴포넌트 모델을 스프링 MVC와 스프링 웹 플로우 컨틀로러와 함께 사용할 수 있게 해준다.

스프링 Faces는 또한 Ajax와 클리이언트쪽 검증 기능을 제공하는 자그마한 Facelets도 제공한다. 이 컴포넌트 라이브러리는 스프링 자바스크립트를 기반으로 만들었다. 스프링 자바스크립트는 Dojo를 기반 UI 툴킷으로 통합한 자바스크립트 추상화 프레임워크드다.

12.2. 스프링-중심 통합 방법

스프링 Faces는 JSF의 UI 컴포넌트 모델 장정을 스프링의 컨트롤러와 설정 모델 장점과 결합해준다. 아무런 약점없이 JSF의 모든 장점을 활용할 수 있다.

스프링 Faces는 표준 JSF 기능에 다음과 같은 강력한 보완재를 제공한다.

  1. managed bean facility
  2. scope management
  3. event handling
  4. navigation rules
  5. easy modularization and packaging of views
  6. cleaner URLs
  7. model-level validation
  8. client-side validation and UI enhancement
  9. Ajax partial page updates and full navigation
  10. progressive enhancement and graceful degradation

이 기능을 사용하면 faces-config.xml에 필요한 설정 분량을 현격하게 줄여줄 것이며 뷰와 컨트롤러 계층을 보다 깔끔하게 분리해주며 애플리케이션의 기능 책임 모듈화를 보다 잘 지원한다. 이 기능들의 사용법은 다음 절에서 살펴보겠다. 이 기능들 대부분은 스프링 웹 플로우의 플로우 정의 언어를 기반으로 한다. 여러분이 플로우 정의하기에 나와있는 기본을 이해하고 있다고 가정한다.

12.3. web.xml 설정하기

스프링 Faces를 사용하는 첫 번째 단계는 요청을 web.xml 파일에 있는 DispatcherServlet으로 라우팅하는 것이다. 이번 예제에서, 우리는 /spring/으로 시작하는 모든 URL을 서블릿으로 맵핑한다. 서블릿을 설정해야 한다. init-param을 사용하여 서블릿에 contextConfigLocation을 넘겨준다. 이 것은 애플리케이션의 스프링 설정 파일 위치다.

<servlet>
    <servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/web-application-config.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>
   
<servlet-mapping>
    <servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
    <url-pattern>/spring/*</url-pattern>
</servlet-mapping>
       
JSF를 적절하게 동작시키려면, FacesServlet을 web.xml에 설정해야 한다. 스프링 Faces를 사용할 때는 그것을 사용하여 요청을 라우팅할 필요가 없다.

<!-- Just here so the JSF implementation can initialize, *not* used at runtime -->
<servlet>
    <servlet-name>Faces Servlet</servlet-name>
    <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>
   
<!-- Just here so the JSF implementation can initialize -->
<servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>*.faces</url-pattern>
</servlet-mapping>
       
스프링 Faces  컴포넌트를 사용할 때에도 스프링 자바스크립트 ResourceServlet을 설정하여 컴포넌트에서 CSS와 자바스크립트 리소스를 제대로 출력할 수 있게 할 필요가 있다. 이 서블릿은 반드시 /resources/*로 맵핑해야 컴포넌트에서 랜더링한 URL에 대해 제대로 동작한다.

<!-- Serves static resource content from .jar files such as spring-faces.jar -->
<servlet>
    <servlet-name>Resource Servlet</servlet-name>
    <servlet-class>org.springframework.js.resource.ResourceServlet</servlet-class>
    <load-on-startup>0</load-on-startup>
</servlet>
       
<!-- Map all /resources requests to the Resource Servlet for handling -->
<servlet-mapping>
    <servlet-name>Resource Servlet</servlet-name>
    <url-pattern>/resources/*</url-pattern>
</servlet-mapping>
       
스프링 Faces 컴포넌트는 JSP 대신에 Facelet을 사용해야 한다. 따라서 이들 컴포넌트를 사용하려면 일반적인 Facelet 설정을 반드시 추가해야 한다.

!-- Use JSF view templates saved as *.xhtml, for use with Facelets -->
<context-param>
    <param-name>javax.faces.DEFAULT_SUFFIX</param-name>
    <param-value>.xhtml</param-value>
</context-param>
       
12.4. JSF 뷰 랜더링 하도록 웹 플로우 설정하기

The next step is to configure Web Flow to render JSF views. To do this, in your Spring Web Flow configuration include the faces namespace and link in the faces flow-builder-services :

다음 단계는 JSF 뷰를 랜더링 하도록 웹 플로우를 설정하는 것이다. 그렇게 하려면 스프링 웹 플로우 설정에 faces 네임스페이스를 추가하고

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:webflow="http://www.springframework.org/schema/webflow-config"
       xmlns:faces="http://www.springframework.org/schema/faces"
       xsi:schemaLocation="
           http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
           http://www.springframework.org/schema/webflow-config
           http://www.springframework.org/schema/webflow-config/spring-webflow-config-2.0.xsd
           http://www.springframework.org/schema/faces
           http://www.springframework.org/schema/faces/spring-faces-2.0.xsd">

    <!-- Executes flows: the central entry point into the Spring Web Flow system -->
    <webflow:flow-executor id="flowExecutor" />

    <!-- The registry of executable flow definitions -->
    <webflow:flow-registry id="flowRegistry" flow-builder-services="facesFlowBuilderServices" base-path="/WEB-INF">
        <webflow:flow-location-pattern value="**/*-flow.xml" />
    </webflow:flow-registry>

    <!-- Configures the Spring Web Flow JSF integration -->
    <faces:flow-builder-services id="facesFlowBuilderServices" />

</beans>
       
faces:flow-builder-services 태그는 JSF 환경에 적절한 다른 기본 값들도 설정한다. 특히 Unified EL을 기본 EL로 설정한다.

완전히 동작하는 예제는 배포판에서 swf-booking-faces 레퍼런스 애플리케이션을 참고하라.

12.5. faces-config.xml 설정하기

faces-config.xml에 유일하게 설정할 필요가 있는 것은 Facelet 사용에 대한 것이다. 만약 스프링 Faces 컴포넌트를 사용하지 않고 JSP를 사용하고 있다면, 어떠한 스프링 Faces 관련 설정도 faces-config.xml에 추가하지 않아도 된다.

<faces-config>
    <application>
        <!-- Enables Facelets -->
        <view-handler>com.sun.facelets.FaceletViewHandler</view-handler> 
    </application>
</faces-config>
       
12.6. JSF가 관리하는 빈 기능 교체하기

스프링 Faces는 JSF가 관리하는 빈 기능을 플로우가 관리하는 변수와 스프링이 관리하는 빈으로 완전히 교체할 수 있게 해준다. 그렇게 하여 여러분이 관리하는 객체를 잘 정의되어 있는 초기화 후크와 도메인 객체 실행 후크로 생명 주기를 보다 잘 관리할 수 있다. 게다가, 여러분이 이미 비즈니스 계층에서 스프링을 사용해봤다는 가정한다면, 두 개의 다른 빈 관리 모델을 유지하는 것에 대한 개념적인 오버헤드를 줄일 수 있다.

순수 JSF 개발을 할 떄는 request 스코프로는 복잡한 이벤트-기반 뷰를 다루는 대화형 모델 객체를 저장하기에는 적당하지 않다는 것을 금방 알 수 있을 것이다. 오직 사용할 수 있는 옵션은 session 스코프에 모든 것들을 넣는 것이다. 애플리케이션의 다른 뷰 또는 기능적인 부분을 처리할 때 객체들을 청소해줘야 한다는 추가 작업이 생긴다. 정말로 필요한 것은 request와 session 스코프 중간 쯤 되는 어떤 스코프가 필요하다. 우누 좋게도 웹 플로우는 그러한 확장 기능을 제공한다.

12.6.1. 플로우 변수 사용하기

가장 간단하고 자연스럽게 모델을 선언하고 관리하는 것은 플로우 변수를 사용하는 것이다. 이 변수들을 플로우 시작시에 선언할 수 있다.

<var name="searchCriteria" class="com.mycompany.myapp.hotels.search.SearchCriteria"/>
           
그런 다음 이 변수를 플로우 중 어떤 JSF 뷰 템플릿에 EL을 통해서 참조한다.

<h:inputText id="searchString" value="#{searchCriteria.searchString}"/>
           
(좀 더 구체적일 필요가 있다면 그렇게 할 수도 있지만)템플릿에서 변수를 참조할 때 그 스코프로 접두어를 붙이지 않아도 된다는 것에 주목하라. 표준 JSF 빈으로 대응하는 변수에 대해 모든 사용 가능한 스코프에서 찾아볼 것이다. 따라서 EL 표현식을 수정하지 않고도 플로우 정의에서 그것을 참조하는 변수의 스코프를 변경할 수 있다.

또한 뷰 인스턴스 변수를 현재 뷰로 범위를 제한하고 다른 뷰로 이동하면 자동으로 비워버리게 정의할 수 있다. 이렇게 하는 것은 보통 페이지 내에서 다른 뷰로 전이하기 전에 여러 여러 요청에 걸쳐 이벤트를 처리하는 JSF 뷰에서 매우 유용하다.

뷰 인스턴스 변수를 정의할때 var 엘리먼트를 view-state 정의 내부에서 사용할 수 있다.

<view-state id="enterSearchCriteria">
    <var name="searchCriteria" class="com.mycompany.myapp.hotels.search.SearchCriteria"/>
</view-state>
           

12.6.2. 스코프를 가진 스프링 빈 사용하기

비록 자동 연결 플로우 인스터스 변수가 괜찮은 모듈화와 가독성을 제공하지만 가끔 여러분은 AOP 같은 스프링 컨테이너의 기능을 활용하고 싶을 수 있다. 그런 경우 여러분은 스프링 애플리케이션컨텍스트 내부에 있는 빈에 특정 웹 플로우 스코프를 줄 수 있다.

<bean id="searchCriteria" class="com.mycompany.myapp.hotels.search.SearchCriteria" scope="flow"/>
           
이런 접근 방법의 가장 큰 차이점은 EL 표현식에 의해 접근될 때 비을 초기화 한다는 것이다. EL을 통한 이런 종류의 생성 지연은 JSF가 관리하는 빈이 할당되는 것과 매우 비슷하다.

12.6.3. 모델 조작하기

뷰 랜터링 하기 전에 (데이터베이스에서 영속 엔티티를 로딩하는 것 같은)모델 초기화가 필요한 것은 매우 흔한 일이지만 JSF 자체로는 이러한 초기화에 사용할 편의성 후크(hook)를 제공하지 않는다. 플로우 정의 언어는 액션(Action)을 통해서 이와 관련된 자연스러운 기능을 제공한다. 스프링 Faces는 액션의 결과를 JSF-관련 데이터 구조로 변경해주는 추가적인 편의성을 제공한다. 예제를 보자.

<on-render>
    <evaluate expression="bookingService.findBookings(currentUser.name)"
              result="viewScope.bookings" result-type="dataModel" />
</on-render>
         
이렇게 하면 bookingService.findBookings 매서드 결과를 취하고 그것을 표준 JSF DataTable 컴포넌트에서 해당 목록을 사용할 수 있도록 커스텀 JSF DataModel로 감싼다.

<h:dataTable id="bookings" styleClass="summary" value="#{bookings}" var="booking"
             rendered="#{bookings.rowCount > 0}">
    <h:column>
        <f:facet name="header">Name</f:facet>
        #{booking.hotel.name}
    </h:column>                  
    <h:column>
    <f:facet name="header">Confirmation number</f:facet>
        #{booking.id}
        </h:column>
    <h:column>
        <f:facet name="header">Action</f:facet>
        <h:commandLink id="cancel" value="Cancel" action="cancelBooking" />
    </h:column>
</h:dataTable>
           
커스텀 DataModel은 request 스코프 외의 저장을 위한 직렬화와 EL에서 현재 선택한 줄에 대한 접근 등 몇몇 추가적인 편의성을 제공한다. 예를 들어, DataTable 내의 컴포넌트에 의해 액션 이벤트가 발생한 뷰에서 포스트백 할 때, 여러분은 선택한 줄의 모델 인스턴스를 가질 수 있다.

<transition on="cancelBooking">
    <evaluate expression="bookingService.cancelBooking(bookings.selectedRow)" />           
</transition>
           
12.7. 스프링 웹 플로우로 JSF 이벤트 처리하기

스프링 웹 플로우는 낮은 결합도를 유지하면서 JSF 액션 이벤트를 처리할 수 있게 해준다. 자바 코드에서 JSF API에 의존하지 않아도 된다. 이벤트를 커스텀 자바 액션 코드를 전혀 사용하지 않고 플로우 정의 언어를 사용하여 완전하게 처리할 수 있다. 이렇게 하면 (JSF 뷰 템플릿과 SWF 플로우 정의) 이벤트를 연결할 때 만들어지는 구성물들을 전체 애플리케이션을 빌드하고 다시 배포할 필요 없이 즉시 리프래시 되기 때문에 보다 기민한 개발 프로세스가 가능해진다.

12.7.1. JSF In-page 액션 이벤트 처리하기

간단하지만 JSF에서 가장 흔한 경우가 모델을 조작하는 이벤트를 발생시키고 동일한 뷰로 모델의 변경된 상태를 보여주는 것이다. 플로우 정의 언어는 transition 엘리먼트에서 이것을 지원한다.

이 것에 대한 좋은 예제는 페이징 처리를 하는 목록 표다. 거대한 결과 목록 중의 일부만 읽어오고 보여주고 싶다고 가정해보자. 그리고 사용자는 그 결과를 페이징할 수 있다. 목록을 읽어오고 보여주는 초기 view-state 정의는 다음과 같다.
 
<view-state id="reviewHotels">
    <on-render>
        <evaluate expression="bookingService.findHotels(searchCriteria)"
                  result="viewScope.hotels" result-type="dataModel" />
    </on-render>
</view-state>
           

JSF DataTable로 현재 호텔 목록을 보여주도록 할 수 있다. 그런 다음 표 하단에 "More Results" 링크를 제공한다.
 
<h:commandLink id="nextPageLink" value="More Results" action="next"/>
           
이 커맨드링크는 action 속성에서 "next" 이벤트를 보낸다. 그럼 여러분은 이벤트를 view-state 정의에 추가하려 처리할 수 있다.
 
<view-state id="reviewHotels">
    <on-render>
        <evaluate expression="bookingService.findHotels(searchCriteria)"
            result="viewScope.hotels" result-type="dataModel" />
    </on-render>
    <transition on="next">
        <evaluate expression="searchCriteria.nextPage()" />
    </transition>
</view-state>
           
여기서 searchCriteria 인스턴스에서 page 카운트를 증가하여 "next" 이벤트를 처리한다. 그럼 다음 on-render 액션을 변경된 criteria로 호출한다. 그러면 다음 페이지 결과를 DataModel로 로딩해준다. transition  엘리먼트에 to 속성이 없기 때문에 동일한 뷰를 다시 보여준다. 그리고 모델에 변경된 사항을 뷰에 반영해준다.

12.7.2. JSF 액션 이벤트 처리하기

in-page 이벤트 다음 단계는 조작한 모델을 가지고 다른 뷰로 이동하는 이벤트다. 순수 JSF로 이것을 하려면 faces-config.xml에 네비게이션 로직을 추가하고 자바 코드를 JSF가 관리하는 빈에 추가해야 한다.(두 작업 모두 다시 배포해야 한다.) 플로우 정의 언어를 사용하면, in-page 이벤트를 다루던 방식과 매우 비슷하게 한 곳에서 그런 것을 다룰 수 있다.

계속해서 페이징 처리하는 목록을 살펴보자. 보여지는 DataTable의 각각의 row에 row 인스턴스에 대한 자세한 내용 페이지 링크를 가지고 있도록 하고자 한다. 여러분은 테이블에 다음의 commandLink 컴포넌트를 가지고 있는 컬럼을 추가할 수 있다.

<h:commandLink id="viewHotelLink" value="View Hotel" action="select"/>
           
이것은 "select" 이벤트를 발생시킨다. 그다음 기존의 view-state에 또 다른 transition 엘리먼트를 추가하여 이것을 처리할 수 있다.
 
<view-state id="reviewHotels">
    <on-render>
        <evaluate expression="bookingService.findHotels(searchCriteria)"
            result="viewScope.hotels" result-type="dataModel" />
    </on-render>
    <transition on="next">
        <evaluate expression="searchCriteria.nextPage()" />
    </transition>
    <transition on="select" to="reviewHotel">
            <set name="flowScope.hotel" value="hotels.selectedRow" />
    </transition>
</view-state>
           
여기서 "select" 이벤트는 DataTable에서 현재 선택한 hotel 인스턴스를 플로우 스코프에 넣어서 처리하고 있다. 그렇게 하면 "reviewHotel" view-state에서 참조할 것이다.

12.7.3. 모델 검증 수행하기

JSF는 변경 사항을 모델에 반영하기 전에 필드-수준 입력 검증 관련 유용한 기능을 제공한다. 하지만 변경 사항을 적용한 뒤에 모델-수준의 좀 더 복잡한 검증을 수행할 필요가 있다면 여러분은 관리하는 빈의 JSF 액션 매서드에 커스텀 코드를 추가해야 한다. 이런 종류의 검증은 모메인 모델 자체 책임이지만 도메인 모델 계층에 원하지 않던 JSF API 의존성을 추사하지 않고서는 에러 메시지를 뷰에 전달하기가 어렵다.

스프링 Faces를 사용하면 일반적이고 낮은-수준의 MessageContext를 여러분의 비즈니스 코드에서 유용하게 사용할 수 있고 그곳에 추가한 모든 메시지는 랜더링 시에 FacesContext에서 사용할 수 있다.

예를 들어, 사용자가 호텔 예약을 완료하기 위해 필요한 상세 정보를 입력하는 뷰가 있다고 가정하자. 여러분은 거기서 입력받은 체크인 체크아웃 날짜가 비즈니스 규칙에 맞는지 확인해야 한다. transition 엘리먼트에서 그러한 모델-수준 검증을 호출할 수 있다.
 
<view-state id="enterBookingDetails">
    <transition on="proceed" to="reviewBooking">
        <evaluate expression="booking.validateEnterBookingDetails(messageContext)" />
    </transition>
</view-state>
          
여기서 "proceed" 이벤트는 booking 인스턴스의 모델-수준 검증 매서드를 호출하여 처리한다. 매서드를 호출할 때 MessageContext 인스턴스를 넘겨줘서 메시지를 기록할 수 있게 한다. 그런다음 h:messages 컴포넌트를 사용하여 JSF 메시지를 보여줄 수 있다.

12.7.4. Ajax 이벤트 처리하기

스프링 Faces는 표준 JSF 컴포넌트에 Ajax-기반 일부 뷰 수정 기능을 추가한 몇몇 특별한 UICommand 컴포넌트를 제공한다. 이들 컴포넌트는 사용자가 사용하는 브라우져의 기능이 떨어진다면 전체 페이지를 리프래시 하여 모두 잘 동작할 것이다.

[노트] 노드
스프링 Faces의 코어 JSF 지원이 JSF 1.1 호환가능 하지만, 스프링 Faces Ajax 컴포넌트는 JSF 1.2를 필요로 한다.

Revisiting the earlier example with the paged table, you can change the "More Results" link to use an Ajax request by replacing the standard commandButton with the Spring Faces version (note that the Spring Faces command components use Ajax by default, but they can alternately be forced to use a normal form submit by setting ajaxEnabled="false" on the component):

           
<sf:commandLink id="nextPageLink" value="More Results" action="next" />
           

This event is handled just as in the non-Ajax case with the transition element, but now you will add a special render action that specifies which portions of the component tree need to be re-rendered:

<view-state id="reviewHotels">
    <on-render>
        <evaluate expression="bookingService.findHotels(searchCriteria)"
                  result="viewScope.hotels" result-type="dataModel" />
    </on-render>
    <transition on="next">
        <evaluate expression="searchCriteria.nextPage()" />
        <render fragments="hotels:searchResultsFragment" />
    </transition>
</view-state>
           

The fragments="hotels:searchResultsFragment" is an instruction that will be interpreted at render time, such that only the component with the JSF clientId "hotels:searchResultsFragment" will be rendered and returned to the client. This fragment will then be automatically replaced in the page. The fragments attribute can be a comma-delimited list of ids, with each id representing the root node of a subtree (meaning the root node and all of its children) to be rendered. If the "next" event is fired in a non-Ajax request (i.e., if JavaScript is disabled on the client), the render action will be ignored and the full page will be rendered as normal.

In addition to the Spring Faces commandLink component, there is a corresponding commandButton component with the same functionality. There is also a special ajaxEvent component that will raise a JSF action even in response to any client-side DOM event. See the Spring Faces tag library docs for full details.

An additional built-in feature when using the Spring Faces Ajax components is the ability to have the response rendered inside a rich modal popup widget by setting popup="true" on a view-state .

<view-state id="changeSearchCriteria" view="enterSearchCriteria.xhtml" popup="true">
    <on-entry>
        <render fragments="hotelSearchFragment" />
    </on-entry>
    <transition on="search" to="reviewHotels">
        <evaluate expression="searchCriteria.resetPage()"/>
    </transition>
</view-state>
           

If the "changeSearchCriteria" view-state is reached as the result of an Ajax-request, the result will be rendered into a rich popup. If JavaScript is unavailable, the request will be processed with a full browser refresh, and the "changeSearchCriteria" view will be rendered as normal.

신고

'Spring Web Flow > Chapter 12' 카테고리의 다른 글

SWF 12장 JSF 통합  (0) 2009.03.10
top


REST in Spring 3: @MVC

Spring/etc : 2009.03.09 11:10


참고: REST in Spring 3: @MVC

스프링 3.0의 RESTful 기능

- URI 템플릿
@PathVariable 애노테이션으로 URI의 특정 위치의 값을 맵핑해올 수 있음.
@RequestMapping("/hotels/{hotelId}")
public String getHotel(@PathVariable hotelId, ModelMap model) {
  List<Hotel> hotels = hotelService.getHotels();
  model.addAttribute("hotels", hotels);
  return "hotels";
}
이때 /hotels/1 이런 요청이 들어오면 hotelId 매개변수로 1이라는 값을 받아올 수 있음.

두 개 이상 맵핑 할 수도 있고 변수명을 다르게 줄 수도 있음.
@RequestMapping(value="/hotels/{hotel}/bookings/{booking}", method=RequestMethod.GET)
public String getBooking(@PathVariable("hotel") long hotelId, @PathVariable("booking") long bookingId, ModelMap model) {
  Hotel hotel = hotelService.getHotel(hotelId);
  Booking booking = hotel.getBooking(bookingId);
  model.addAttribute("booking", booking);
  return "booking";
}

Ant 스타일 경로를 지정할 수도 있음.
@RequestMapping(value="/hotels/*/bookings/{booking}", method=RequestMethod.GET)
public String getBooking(@PathVariable("booking") long bookingId, ModelMap model) {

}

데이터 바인딩도 사용할 수 있음.
@InitBinder
public void initBinder(WebDataBinder binder) {
  binder.initBeanPropertyAccess();
  SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
  dateFormat.setLenient(false);
  binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, false));
}

@RequestMapping("/hotels/{hotel}/dates/{date}")
public void date(@PathVariable("hotel") String hotel, @PathVariable Date date)
                throws IOException {

}
/hotels/1/dates/2008-12-18 이런 요청을 받으면 2008-12-18 이 부분 문자열을 Date 타입으로 바인딩 해 줌.

- Content Negotiation
Accept HTTP 헤더로 뷰를 판단함. 서버 응답은 Content-Type를 통해 뷰를 전달한다. 이런 과정을 content negotiation이라고 한다.

주요 클래스: ContentNegotiatingViewResolver

- Views
RSS 피드를 만들 때 사용할 수 있는 뷰: AbstractAtomFeedView, AbstractRssFeedView
XML 뷰: MarshallingView
JSON 뷰: JacksonJsonView

- HTTP Method Conversion
HTTP에서는 GET, POST, DELETE, PUT을 제공하지만 HTML은 GET, POST만 지원한다. 따라서 POST를 사용하면서 hidden parameter로 Method를 명시하면 해당 Method로 변환해주는 HiddenHttpMethodFilter 제공.
스프링 form 태그에서 이 기능을 지원하기 때문에 form태그의 method에 delete, put도 사용 가능.
<form:form method="delete">
    <p class="submit"><input type="submit" value="Delete Pet"/></p>
</form:form>

@RequestMapping(method = RequestMethod.DELETE)
public String deletePet(@PathVariable int ownerId, @PathVariable int petId) {
    this.clinic.deletePet(petId);
    return "redirect:/owners/" + ownerId;
}

- ETag support
ETga는 HTTP 1.1 호환 응답 헤더로 해당 URL에 있는 컨텐츠가 변경 됐는지 확인할 때 사용.
스프링은 ShallowEtagHeaderFilter를 제공하여 JSP로 랜더링한 결과를 캐싱하고 MD5 해시를 만들고 응답에 ETag를 반환해준다. 다음에도 사용자가 같은 자원을 요청하면 이전에 만든 해시를 If-None-Match 값으로 사용한다. 두 개 해시값을 비교해서 같으면 304(Not Modified)를 반환한다.

차후에 제공할 deep ETag는 모데인 객체나 RDBMS 테이블과 관련되어 있어 좀 더 복잡한데 JPA의 @Version(낙천적-롹킹할 때 사용하는 애노테이션) 기반 또는 ApsectJ의 애스팩트로 지원할 예정~ 이라고 합니다.
신고
top


보드야 이번 겨울 잘~~ 놀았다!



거의 격주 마다 성우리조트로 스노우보드를 타러 다녔습니다. 가서 참한 색시도 만났고 난생 첨 해보는 스포츠도 즐기고 다른 동호회 활동도 살짝 맛보았습니다.

사용자 삽입 이미지


거의 일요일 마다 보드를 타러 다녀왔는데 이젠 날씨도 많이 따뜻해져서 보드를 타기 힘들어보입니다. 다음 종목으로 원래 인라인을 생각했었는데 몸매를 다지기 위해 종목을 바꿔서 수영에 도전합니다. 수영도 첨 배워보는데 색시가 알아서 잘 갈쳐주겠죠?
신고
top

TAG 보드, 수영

스프링 인티그레이션 샌드박스 예제(town crier) 실행 성공~!

Spring Integration : 2009.03.06 19:37


참조 : http://blog.springsource.com/2009/02/27/spring-integration-on-dm-server/

  1. Download and install the SpringSource Tool Suite and dm Server (this is as easy as unzipping the files). You can also use Eclipse with the dm Server tools and Spring IDE if you prefer.
  2. Configure a dm Server under the default name and start it
    1. open the Server view, right click in it and select new
    2. type Spring in the search window and select SpringSource dm Server 1.0
    3. point to the unzipped dm Server directory
  3. Update your bundle repository and install Spring Integration Core 1.0.1 and Commons Logging 1.1.1
    1. double click the newly created server a server management console opens
    2. select the repository tab and click 'Update local bundle and library repository index'
    3. search for Spring Integration and download the core bundle
    4. start the server
  4. Import the projects from the Spring Integration sandbox
    1. check out the projects to a local working directory
    2. From STS select File->Import->Existing projects into workspace and point to the working directory

본문에서 윗 부분을 보고 그대로 따라했더니 됐습니다. 흠.. 간략히 요약하자면

1. STS는 어제 2.0 소식을 접하고 한 번 설치해본터라 쉽게 했고 dm Server는 최신 버전 1.0.2를 새로 받아서 설치했습니다.

2. dm Server를 서버 창에 추가해줍니다.

3. dm Server를 더블클릭하고 Repository 탭에서 spring integration로 검색한 다음 spring integration core 1.0.1 번들을 다운로드 합니다.

4. 서버를 실행합니다.

5. 스프링 인티그레이션 sandbox 예제 소스를 받아옵니다.

svn co https://src.springframework.org/svn/spring-integration/sandbox/si-osgi

6. 위에서 받아온 예제를 이클립스에서 import 합니다.
- 이 때 scribe 프로젝트의 MANIFEST.MF에서 에러가 발생할 수 있는데 스프링 2.5.6 라이브러리가 필요해서 그렇습니다. 그 떄는 에러가 발생한 지점을 클릭하고 퀵픽스를 이용해서 필요한 라이브러리를 다운받으면 됩니다.

7. com.springsource.samples.integration.osgi 프로젝트를 드래그 앤 드랍으로 dm server에 추가해줍니다.

8. 서버 콘솔에서 ss로 설치된 번들을 확인합니다.

사용자 삽입 이미지

자 이렇게 번들이 잘 설치됐는지 확인합니다. 끝났습니다. 이제 스프링 인티그레이션 예제가 잘 돌고 있나 확인해봐야겠죠?? 참고로 이 예제 애플리케이션은 콘솔에 뭔가 출력하는게 없고 전부 로깅을 하기 때문에 콘솔로는 이 애플리케이션이 제대로 돌고 있는지 확인하기 어렵습니다.

town crier가 주기적으로 소리를 지르면 scribe는 그때 그때 메시지를 받아가고 goverment는 주기적으로 메시지를 가져갑니다. 자세한 건 소스 코드를 참조해 보시구요. 이렇게 동작하는지 일단 눈으로 보고 싶다면 dm server를 설치한 곳으로 이동하여 trace.log 파일을 열어봐야 합니다.

사용자 삽입 이미지

저 위치의 파일을 열어 보면 다음과 같이 주요 메시지가 정기적으로 출력되는 걸 볼 수 있습니다.

사용자 삽입 이미지

자~~ 이제 가지고 놀 장난감이 준비 됐네요. 이 녀석하고 놀면서 스프링 인티그레이션, 스프링 dm 서버, 스프링 dm + OSGi 등과 친해져야겠네요. +_+

차후에 프로젝트도 좀 더 분석해서 스크린캐스팅을 제공하겠습니다. 캬캬
신고
top


스프링 인티그레이션 빌드 실패~

Spring Integration : 2009.03.06 18:04


소스 받기: svn co https://src.springframework.org/svn/spring-integration/tags/spring-integration-1.0.1.RELEASE

몇일 전 스프링 프레임워크 3.0 빌드도 실패했는데 이번에도 실패하네요. 스프링 인티그레이션 프로젝트도 스프링 프레임워크와 비슷한 프로젝트 구조를 가지고 있으며 동일한 빌드 방법을 사용합니다. 즉 Ant를 사용하여 라이브러리는 Ivy를 사용해서 가져옵니다.

어쨋거나 이번에도 실패하네요.

사용자 삽입 이미지

이번에는 Tsts failed라는데 아마 Tests Failed 겠죠? 흠;; 뭐 걍 빌드 해준 라이브러리만 써도 관계없기는 한데 빌드가 안되니까 참 찝찝하네요.
신고
top


SWF 11장 스프링 자바스크립트 퀵 레퍼런스



11.1 도입

스프링 자바스크립트(spring-js)는 Dojo 같이 자주 사용하는 자바스크립트 툴킷에 대한 경량 추상화다. 목표는 공통의 클라인트-쪽 프로그래밍 모델을 제공하여 웹 페이지를 리치 위젯과 애이작스 리모팅으로 급격히 개선하는 것이다.

11.2. 자바스크립트 리소스 제공하기

스프링 JS는 웹 애플리케이션 루트 디렉토리와 jar 파일에서 자바스크립트와 CSS 파일 같은 웹 리소스를 서빙하는 ResourceServlet를 제공한다. 이 서블릿은 Spring.js 파일을 여러분 페이지에 공급하는 편리한 방법을 제공한다. 이 서블릿을 배포하려면 web.xml에 다음과 같이 설정하라.

<!-- Serves static resource content from .jar files such as spring-js.jar -->
<servlet>
    <servlet-name>Resource Servlet</servlet-name>
    <servlet-class>org.springframework.js.resource.ResourceServlet</servlet-class>
</servlet>
       
<!-- Map all /resources requests to the Resource Servlet for handling -->
<servlet-mapping>
    <servlet-name>Resource Servlet</servlet-name>
    <url-pattern>/resources/*</url-pattern>
</servlet-mapping>
       
11.3. 스프링 자바스크립트를 페이지에 포함시키기

스프링 JS는 자신의 API 구현체를 유명한 자바스크립트 툴킷으로 빌드 할 수 있게 설계됐다. Spring.js 기본 구현체는 Dojo 툴킷을 기반으로 한다.

스 프링 자바스크립트를 페이지에서 사용하려면 보통 기반으로 하는 툴킷, Spring.js 기반 인터페이스 파일, 스프링-(라이브러리 구현체).js 파일을 포함시킬 필요가 있다. 예를 들어 다음은 ResourceServlet를 사용하여 Dojo 구현체를 가져온다.

<script type="text/javascript" src="<c:url value="/resources/dojo/dojo.js" />"> </script>
<script type="text/javascript" src="<c:url value="/resources/spring/Spring.js" />"> </script>
<script type="text/javascript" src="<c:url value="/resources/spring/Spring-Dojo.js" />"> </script>
       
기 반 라이브러리의 위젯 시스템을 사용하면 보통 여러분은 반드시 원하는 룩앤필(look and feel)을 얻기 위해 CSS 리소스를 포함시킬것이다. booking-mvc 레퍼런스 애플리케이션은 Dojo의 tundra.css를 포함시킨다.

<link type="text/css" rel="stylesheet" href="<c:url value="/resources/dijit/themes/tundra/tundra.css" />" />
       
11.4. 스프링 자바스크립트 데코레이션

스 프링 자바스크립트의 주요 개념은 기존 DOM 노드에 데코레이션을 적용하는 개념이다. 이 기술은 기능이 좋치 않은 브라우저에서도 여전히 동작할 페이지 같은 웹 페이지를 혁신적으로 개선할 때 사용한다. addDecoration 매서드는 데코레이션을 적용할 때 사용한다.

다음 예제는 스프링 MVC의 <form:input> 태그에 풍부한 제안 기능을 가능하게 하는 것을 보여준다.

<form:input id="searchString" path="searchString"/>
<script type="text/javascript">
    Spring.addDecoration(new Spring.ElementDecoration({
        elementId: "searchString",
        widgetType: "dijit.form.ValidationTextBox",
        widgetAttrs: { promptMessage : "Search hotels by name, address, city, or zip." }}));
</script>
       
ElementDecoration 는 리치 위젯 기능을 기존의 DOM 노드에 추가할 때 사용한다. 이 데코레이션 타입은 기반으로 하는 툴킷을 완전히 감추는 것을 목표로 하지 않는다. 따라서 툴킷의 네이티브 위젯 타입과 속성을 직접 사용한다. 이 방법은 공통의 데코레이션 모델을 사용하여 기반하는 툴킷의 모든 위젯을 일관적인 방법으로 통합하기 위한 것이다. booking-mvc 레퍼런스 애플리케이션에서 제안에서 부터 클라이언트쪽 검증까지 데코레이션을 적용하는 많은 예제를 참조하라.

ElementDecoration를 사용하여 리치 검증 기능을 갖춘 위젯을 적용할 때 일반적인 요구 사항은 폼이 검증을 통과하기 전까지는 서브밋하지 않는 것이다. ValidateAllDecoration으로 그것을 할 수 있다.

<input type="submit" id="proceed" name="_eventId_proceed" value="Proceed" />
<script type="text/javascript">
    Spring.addDecoration(new Spring.ValidateAllDecoration({ elementId:'proceed', event:'onclick' }));
</script>
       

이것은 "Proceed" 버튼을 클라이언트 쪽 검증을 하고 성공적으로 패스 할 때 까지 폼 서브밋을 허용하지 않는 특별한 onclick 이벤트 핸들러로 데코레이트한다.

AjaxEventDecoration는 원격 애이작스 요청을 서버로 보내는 클라이언트쪽 이벤트 리스너를 적용한다. 또한 응답할 때 자동으로 콜백 함수를 링크에 등록한다.

<a id="prevLink" href="search?searchString=${criteria.searchString}&page=${criteria.page - 1}">Previous</a>
<script type="text/javascript">
    Spring.addDecoration(new Spring.AjaxEventDecoration({
        elementId: "prevLink",
        event: "onclick",
        params: { fragments: "body" }
    }));
</script>
       
이 것은 "Previous Results" 링크의 onclick 이벤트를 응답시에 특정 조각을 다시 랜더링하도록 특별한 매개변수와 함께 애이작스 호출로 꾸며준다. 이 링크는 클라이언트에서 자바스크립트를 사용할 수 없는 경우에도 여전히 동작한다는 것에 주목하라. (애이작스 요청 다루기에서 서버에 요청을 어떻게 다루는지 자세히 살펴보라.)

또한 하나의 엘리먼트에 여러 개의 데코레이션을 적용하는 것도 가능하다. 다음 예제는 애이작스와 validate-all 서브밋 금지를 같이 적용한 버튼에 대한 예제다.

<input type="submit" id="proceed" name="_eventId_proceed" value="Proceed" /> 
<script type="text/javascript">
    Spring.addDecoration(new Spring.ValidateAllDecoration({elementId:'proceed', event:'onclick'}));
    Spring.addDecoration(new Spring.AjaxEventDecoration({elementId:'proceed', event:'onclick',formId:'booking', params:{fragments:'messages'}}));
</script>
       
Dojo의 쿼리 API를 사용하여 한 줄로 여러 엘리먼트에 하나의 데코레이션을 적용하는 것도 가능하다. 다음 예제는 체크박스 집합을 Dojo Checkbox 위젯으로 꾸민다.

<div id="amenities">
<form:checkbox path="amenities" value="OCEAN_VIEW" label="Ocean View" /></li>
<form:checkbox path="amenities" value="LATE_CHECKOUT" label="Late Checkout" /></li>
<form:checkbox path="amenities" value="MINIBAR" label="Minibar" /></li>
<script type="text/javascript">
    dojo.query("#amenities input[type='checkbox']").forEach(function(element) {
        Spring.addDecoration(new Spring.ElementDecoration({
            elementId: element.id,
            widgetType : "dijit.form.CheckBox",
            widgetAttrs : { checked : element.checked }
        }));
    });
</script>
</div>

11.5. 애이작스 요청 다루기

스프링 자바스크립트의 클라이언트 쪽 애이작스 응답 다루기는 서버에서 "조각" 받기 개념을 기반으로 했다. 이들 조각은 단순한 표준 HTML로 기존 페이지의 일부를 교체할 의도를 가지고 있다. 서버에서 필요한 핵심 조각은 전체 응답 중에서 어떤 조각을 일부만 랜더링 해야 하는지 판단할 때 사용한다.

전체 응답 중에 일부 조각만 랜더링 하려면 전체 응답은 반드시 응답 구성할 때 컴포지션을 사용할 수 있고 그 컴포지션의 구성 요소들은 개별적으로 참조하거나 랜더링 할 수 있는 템플릿 기술을 사용해서 만들어야 한다. 스프링 자바스크립트는 타일즈(Tiles)를 사용하는 간단한 스프링 MVC 확장을 통해 이것을 달성한다. 컴포지션을 지원하는 어떤 템플릿 시스템이든지 이론적으로는 같은 기술로 사용할 수 있다.

스프링 자바스크립트의 애이작스 리모팅 기능은 애이작스 요청을 다루는 코드가 일반 브라우저 요청과 다르지 않아야 한다는 개념을 기반으로 한다. 따라서 애이작스 요청에 대한 별도의 지식은 코드에서 직접적으로 필요하지 않고 동일한 핸들러를 두 가지 스타일의 요청에 모두 사용할 수 있다.

11.5.1. 스프링 MVC 컨트롤러로 애이작스 요청 다루기

애이작스 요청을 스프링 MVC 컨트롤러로 다루려면 스프링 MVC 확장이 제공하는 설정을 여러분의 스프링 애플리케이션 컨텍스트에 일부 응답을 랜더링 하도록 추가하면 된다.

<bean id="tilesViewResolver" class="org.springframework.js.ajax.AjaxUrlBasedViewResolver">
    <property name="viewClass" value="org.springframework.webflow.mvc.view.FlowAjaxTilesView"/>
</bean>
           
이것은 AjaxUrlBasedViewResolver를 설정하여 애이작스 요청을 분석하고 FlowAjaxTilesView 객체를 만들어서 적절한 부분을 랜더링하는 것을 처리하게 한다. FlowAjaxTilesView는 웹 플로우와 순수 스프링 MVC 요청을 모두 랜더링하는 작업을 할 수 있다. 조각은 타일즈 뷰 정의의 개별 속성에 대응한다. 예를 들어, 다음의 타일즈 뷰 정의를 보자.

<definition name="hotels/index" extends="standardLayout">
    <put-attribute name="body" value="index.body" />
</definition>

<definition name="index.body" template="/WEB-INF/hotels/index.jsp">
    <put-attribute name="hotelSearchForm" value="/WEB-INF/hotels/hotelSearchForm.jsp" />
    <put-attribute name="bookingsTable" value="/WEB-INF/hotels/bookingsTable.jsp" />
</definition>
           
애이작스 요청은 "body", "hotelSearchForm", "bookingsTable"를 기술하여 요청에서 일부를 랜더링할 수 있다.

11.5.2. 스프링 MVC + 스프링 웹 플로우에서 애이작스 요청 다루기

스프링 웹 플로우는 조각의 부가적인 랜더리을 플로우 정의 언어에서 render 엘리먼트로 직접 다룬다. 이 방법의 장점은 조각의 선택이 클리이언트 쪽 코드와 완전히 분리 된다는 것이다. 스프링 MVC 컨트롤러 접근 방법에서 사용하듯이 요청에 넘겨주는 별도의 매개변수가 필요 없다. 예를 들어, 만약 앞선 예제 타일즈 뷰를 리치 자바스크립트 팝업으로 "hotelSearchForm" 조각을 랜더링 하고 싶다면 다음과 같이 할 수 있다.

<view-state id="changeSearchCriteria" view="enterSearchCriteria.xhtml" popup="true">
    <on-entry>
        <render fragments="hotelSearchForm" />
    </on-entry>
    <transition on="search" to="reviewHotels">
        <evaluate expression="searchCriteria.resetPage()"/>
    </transition>
</view-state>               
           
       
신고

'Spring Web Flow > Chapter 11' 카테고리의 다른 글

SWF 11장 스프링 자바스크립트 퀵 레퍼런스  (0) 2009.03.05
top


STS(Spring Tool Suite) 2.0 RC 버전의 OSGi 개발 툴

Spring/etc : 2009.03.05 20:29


원문 : OSGi Development Tools in STS 2.0

간단하게 요약만 합니다. 일단 새 제품 다운로드부터 해야겠죠?

기존에 제공하던 툴
  • dm Server Integration: dm 서버를 이클립스 WTP로 통합하여 dm 서버 인스턴스 생명 주기 관리와 OSGi 번들, PAR, 일반 JEE WAR 파일 배포를 할 수 있게 해줌. 또한 dm Server 통합은 설치한 구성물의 코드가 바뀌면 자동으로 업데이트하고 리프레쉬 해줌.
  • 프로젝트 마법사: OSGi 번들과 PAR 프로젝트 생성 마법사 제공.
  • Manifest 편집기와 검증: MANIFEST.MF 파일에서 코드 완성, 하이퍼링크, 검증 기능을 제공.
  • Classpath 관리: OSGi 의존성 메타 데이터를 MANIFEST.MF에서 가져와서 클래스패스 컨테이너를 만든다. 테스트 용 의존성은 테스트 소스 폴더의 META-INF/TEST.MF 사용.
  • 저장소 브라우저: 스프링소스 엔터프라이즈 번들 저장소에 쉽게 접근하게 해준다.
새 기능

STS 2.0은 Import-/Export-Pachage 관계와 서버를 기반으로 번들을 분석하고 그들의 의존성을 가시화하는 기능을 제공한다. OSGi 런타임 콘솔에서 볼 수 있는 텍스트 형태와 비슷한 정보에 접근할 수 있다. 장점은 그런 정보를 IDE에서 쉽게 이요할수 있고 번들 메타 데이터와 연결을 비주얼 툴에서 클릭으로 네비게이션 할 수 있다는 것이다.

서버 편집기에서 Bundle Overview 페이지를 제공한다. 이 페이지에서는 OSGi 런타임에서 접근할 수 있는 모든 연결 정보와 MANIFEST의 번들의 메타 데이터에 접근을 제공하며 설치된 모든 번들을 보여준다.

사용자 삽입 이미지

번들 의존성 그래프를 제공한다. 패키지 또는 서비스 의존성을 보여줄 수 있다. 그래프에서 의존성을 몇 단계까지 보여줄 지 설정할 수 있다.

사용자 삽입 이미지

이퀴녹스 콘솔과 거의 같은 서버 콘솔을 제공한다. 명령 완성과 명령 히스토리 기능을 제공한다.

사용자 삽입 이미지

실행하기

어느덧 다운로드가 끝나고 이제 실행볼 시간이네요. 캬~~ 따끈따끈한 개발 도구를 어디 열어 볼까요~

사용자 삽입 이미지
사용자 삽입 이미지

음~ dm 서버가 잘 들어있군요.  자 일단 서버 만들고 바로 가동시켜 봅니다. 그리고 서버 콘솔에서 ss를 입력해 봤습니다.

사용자 삽입 이미지
다음은 Bundle Information 탭입니다. 와우..

사용자 삽입 이미지
마지막으로 번들 그래프를 보죠.. 캬오~~~~
사용자 삽입 이미지
그림에서 패키지를 더블클릭하면 그래프가 샤샥 바뀌는데 아주 재밌습니다.

이상으로 STS 2.0 리뷰를 마칩니다.
신고
top


개봉동에서 다시 운동 시작!

모하니?/운동해 : 2009.03.05 12:24



아침 5시 반에 일어나서 산책을 다녀옵니다. 이제 이틀째 입니다. 어제는 위로 올라갔었는데 오늘은 아래로 다녀왔습니다. 어제갔던 산책로에 비해서 재미난 시설이 많더군요. 앞으론 이 길로 다니기로 했습니다.

특히 중간에 빨간 동그라미 지점에는 인라인 경주를 할 수 있게 트랙이 있고 농구 골대와 풀코트가 있습니다. 아내랑 둘이 인라인 경주를 해도되고 스케이트 보드를 타고 놀아도 되고 농구를 해도 될 것 같습니다. 해봐야 알겠지만 셋 다 아내가 저보다 잘 한다는군요. 핫핫! 해보자고!!

사용자 삽입 이미지

이런 좋은 곳이 있었다니!! 열심히 살빼야겠습니다~
신고

'모하니? > 운동해' 카테고리의 다른 글

[위핏] 나만의 트레이닝 방법  (0) 2010.02.18
개봉동에서 다시 운동 시작!  (6) 2009.03.05
자전거 타기 시작  (0) 2008.03.21
줄넘기 상황판  (0) 2007.08.02
줄넘기 대만족  (8) 2007.07.25
으윽.. 안돼..  (0) 2007.05.12
top


스프링 3.0 m2 빌드 삽질 중

Spring/etc : 2009.03.04 02:21


http://blog.springsource.com/2009/03/03/building-spring-3/ 윗 글을 보며 삽질 중입니다.

사용자 삽입 이미지

컴파일 에러가 난다며 두 번째 단계에서 막히네요. 자바 1.5라서 그런가 싶어서 kenu 형 블로그보고 1.6으로 바꾼 담에 해봤지만... 그래도 안 되네요. 흠~ 왜 컴파일이 안 되는걸까나.. @_@

readme.txt를 읽어봤더니 javac 1.6 이상, ant 1.7 이상이라길래 다시 한 번 버전을 확인해 봤습니다
사용자 삽입 이미지
흠~~ @_@ 두 시가 넘었네.. 낼 다시 해보자.


신고
top


SWF 10장 스프링 MVC 통합



10.1. 도입

이번 장에서는 웹 플롱를 스프링 MVC 웹 애플리케이션으로 어떻게 통합하는지 살펴보겠다. booking-mvc 예제 애플리케이션은 웹 플로우와 스프링 MVC에 대한 좋은 참고자료다. 이 애플리케이션은 간단하게 만든 여행 사이트로 사용자가 호텔 방을 검색하고 예약할 수 있다.

10.2 web.xml 설정하기

스프링 MVC를 사용하는 첫 번쨰 단계는 DispatcherServlet을 web.xml에 설정하는 것이다. 여러분은 일반적으로 웹 애플리케이션 마다 한 번씩 이 작업을 할 것이다.

아 래 예제는 /spring/ 으로 시작하는 모든 요청을 DispatcherServlet으로 맵핑한다. init-param을 사용하여 contextConfigurationLocation을 제공한다. 이 설정 파일은 웹 애플리케이션에 관한 것이다.

<servlet>
    <servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/web-application-config.xml</param-value>
    </init-param>
</servlet>
   
<servlet-mapping>
    <servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
    <url-pattern>/spring/*</url-pattern>
</servlet-mapping>

10.3. 플로우로 디스패칭하기

DispatcherServlet은 애플리케이션 리소스에 대한 요청을 핸들러에게 전달한다. 플로우는 핸들러 하나의 핸들러 타입니다.

10.3.1. FlowHandlerAdapter 등록하기

요청을 플로우로 디스패칭하는 첫 번째 단계는 스프링 MVC에서 플로우 처리가 가능하게 하는 것이다. 그렇게 하려면 FlowHandlerAdapter를 설치하라.

<!-- Enables FlowHandler URL mapping -->
<bean class="org.springframework.webflow.mvc.servlet.FlowHandlerAdapter">
    <property name="flowExecutor" ref="flowExecutor" />
</bean>
           

10.3.2. 플로우 맵핑 정의하기

플로우 처리를 가능하게 했다면, 다음 단계는 특정 애플리케이션 리소스를 여러분 플로우로 맵핑하는 것이다. 그렇게 하는 가장 간단한 방법은 FlowHandlerMapping를 정의하는 것이다.

<!-- Maps request paths to flows in the flowRegistry;
     e.g. a path of /hotels/booking looks for a flow with id "hotels/booking" -->       
<bean class="org.springframework.webflow.mvc.servlet.FlowHandlerMapping">
    <property name="flowRegistry" ref="flowRegistry"/>
    <property name="order" value="0"/>
</bean>
           
이 맵핑을 설정함으로써 Dispatcher는 애플리케이션 리소스 경로를 플로우 레지스트리에 있는 플로우로 맵핑한다. 예를 들어, /hotels/booking 경로의 리소스에 접근한다면 레지스트리는 hotels/booking id를 가지고 있는 플로우를 찾는다. 만약 해당 id를 가진 플로우를 발경하면 그 플로우가 요청을 처리한다. 만약 플로우를 찾지 못하면 다음 Dispatcher에 있는 (ordered chain)순서에 따라 다음 핸들러 맵핑이 찾아보거나 "noHandlerFound" 응답을 반환한다.

10.3.3. 플로우 처리 워크플로우

유효한 플로우 맵핑을 발견하면, FlowHandlerAdapter는 플로우의 새로운 실행 시작 지점이 어딘지 알아내거나 현재 HTTP 요청 정보를 기반으로 기존의 실행을 다시 시작한다. 어탭터가 적용할 플로우 실행을 새로 시작하거나 다시 시작하는데 관련된 여러 기본 행위가 존재한다.

  • HTTP 요청 매개변수들은 모든 시작 플로우 실행에서 이용할 수 있다.
  • 플로우 실행이 최종 응답 없이 종료되면 기본 핸들러가 동일한 요청을 새로운 실행 시작을 시도한다.
  • 예 외가 NoSuchFlowExecutionException이 아니라면 처리하지 않는 예외를 DispatcherSerlvet에 위임한다. 기본 핸들러는 NoSuchFlowExecutionException를 만나면 새로운 실행을 시작하여 예외를 극복하려고 한다.
보다 자세한 내용은 FlowHandlerAdapter API 문서를 참조하라. 여러분은 이런 기본 행위를 상속 또는 여러분 만의 FlowHandler를 구현하여 재정의 할 수 있다. 다음 절에서 자세히 다루겠다.

10.4. 커스텀 FlowHandler 구현하기

FlowHandler는 HTTP 서블릿 환경에서 플로우를 어떻게 실행할지 커스터마이징 할 때 사용할 수 있는 확장 지점이다. FlowHandler는 FlowHandlerAdapter가 사용하며 다음을 책임진다.
  • 실행할 플로우 정의의 id를 반환한다.
  • 시작할 때 플로우의 새로운 실행에 넘겨줄 입력값을 만든다.
  • 종료할 때 플로우의 실행에서 반환하는 결과를 처리한다.
  • 플로우 실행 중에 발생하는 예외를 처리한다.
이런 책임들은 org.springframework.mvc.servlet.FlowHandler 인터페이스에 정의에 나타나있다.

public interface FlowHandler {

    public String getFlowId();

    public MutableAttributeMap createExecutionInputMap(HttpServletRequest request);

    public String handleExecutionOutcome(FlowExecutionOutcome outcome,
        HttpServletRequest request, HttpServletResponse response);

    public String handleException(FlowException e,
        HttpServletRequest request, HttpServletResponse response);
}               
       
To implement a FlowHandler, subclass AbstractFlowHandler. All these operations are optional, and if not implemented the defaults will apply. You only need to override the methods that you need. Specifically:

FlowHandler를 구현하려면 AbstractFlowHandler를 상속하라. 모든 기능은 부가적인 것이기 떄문에 구현하지 않으면 기본 설정이 적용된다. 여러분은 필요한 매서드만 재정의하면 된다. 특히...
  • 여러분 플로우의 id를 Http 요청에서 직접 가져올 수 없을 때 getFlowId(HttpServletRequest)를 재정의하라. 기본으로 실행할 플로우의 id는 요청 URI의 pathinfo 부분에서 가져온다. 예를 들어 http://localhost/app/hotels/booking?hotelId=1는 기본으로 플로우 id로 hotels/booking를 가져온다.
  • HttpServletRequest에서 플로우 입력 매개변수 추출을 상세하게 제어하고 싶다면 createExecutionInputMap(HttpServletRequest)를 재정의하라. 기본으로 모든 요청 매개변수를 플로우 입력 매개변수로 사용한다.
  • 특정 플로우 실행 결과를 별도 방식으로 처리하고 싶다면 handleExecutionOutcome을 재정의하라 기본 행위는 종료한 플로우의 URL로 리다이렉트하여 플로우의 새로운 실행을 시작한다.
  • unhandled 플로우 예외를 상세하게 제어하고 싶다면 handleException을 재정의하라. 기본 행동은 클라이언트가 종료됐거나 만료된 플로우 실행에 접근하면 플로우 재시작을 시도한다. 그밖의 예외는 스프링 MVC ExceptionResolver 기반 시설에 던져준다.
10.4.1. FlowHandler 예제

스프링 MVC와 웹 플로우 사이에 흔한 협력은 종료했을 때 @Controller로 리다이렉트 하는 것이다. FlowHandler는 특정 컨트롤러 URL로 플로우 정의에 결합하지 않고도 할 수 있게 해준다. 스프링 MVC로 리다이렉트하는 FlowHandler 예제는 아래와 같다.

public class BookingFlowHandler extends AbstractFlowHandler {
    public String handleExecutionOutcome(FlowExecutionOutcome outcome,
                                         HttpServletRequest request, HttpServletResponse response) {
        if (outcome.getId().equals("bookingConfirmed")) {
            return "/booking/show?bookingId=" + outcome.getOutput().get("bookingId");
        } else {
            return "/hotels/index";
        }
    }
}
           
이 핸들러는 오직 플로우 실행 결과를 특정 방법으로 다뤄야 하기 때문에 다른 것은 재정의할 필요가 없다. bookingConfirmed 결과만 새로운 예약을 보여주도록 리다이렉트할 것이다. 그밖에 다른 결과는 호텔 인덱스 페이지로 다시 리다이렉트 한다.

10.4.2. 커스텀 FlowHandler 배포하기

To install a custom FlowHandler, simply deploy it as a bean. The bean name must match the id of the flow the handler should apply to.

커스텀 FlowHandler를 설치하려면 간단하게 빈으로 배포하면 된다. 빈 이름은 반드시 핸들러를 적용할 플로우의 id와 일치해야 한다.

<bean name="hotels/booking" class="org.springframework.webflow.samples.booking.BookingFlowHandler" />
           
이 설정에서 /hotels/booking에 접근하는 것은 커스텀 BookingFlowHandler를 사용하는 /hotels/booking 플로우를 실행하는 것이다. 예약 플로우가 종료되면 FlowHandler는 플로우 실행 결과를 처리하고 적절한 컨트롤러로 리다이렉트 한다.

10.4.3. FlowHandler 리다이렉트

FlowExecutionOutcome 또는 FlowException를 처리하는 FlowHandler는 처리 한 다음 리다이렉트 할 리소스를 가리키는 문자열을 반환한다. 앞선 예제에서 BookingFlowHandler는 bookingConfirmed 결과는 booking/show 리소스 URI로 리다이렉트 하고 그밖에 모든 결과는 hotels/index 리소스로 리다이렉트 했다.

기본으로, 반환된 리소스 위치는 현재 서블릿 맵핑을 기준으로 상대적이다. 이로인해 플로우 핸들러가 상대 경로를 사용하여 애플리케이션의 다른 컨트롤러로 리다이렉트 할 수 있다. 또한 명시적인 리다이렉트 접두어는 좀 더 제어가 필요한 경우에 사용할 수 있다.

지원하는 명시적인 리다이렉트 접두어는 다음과 같다.
  • servletRelative: - 현재 서블릿에서 상대적인 위치의 리소스로 리다이렉트 하라.
  • contextRelative: - 현재 웹 애플리케이션 컨텍스트 경로에 상대적인 위치의 리소스로 리다이렉트 하라.
  • servetRelative: - 서버 루트에 상대적인 위치의 리소스로 리다이렉트 하라.
  • http:// 또는 https://: - 전체를 명시한 리소스 URI로 리다이렉트 하라.
이것과 동일한 접미어를 exteralRedirect를 사용하여 플로우 정의에서 사용할 수 있다. view-state 또는 end-state에서 지시자로 쓸 수 있다. 예를 들어 view="externalRedirect:http://springframework.org" 이렇게 쓸 수 있다.

10.5. View Resolution

웹 플로우 2는 다른 것을 기술하지 않으면 선택한 뷰 식별자를 플로우 작업 디렉토리에 위치한 파일로 맵핑한다. 기존의 스프링 MVC + 웹 플로우 애플리케이션에서는 외부 viewResolver가 이미 이런 맵핑을 다루고 있을 것이다. 따라서 그 리졸버를 계속 하용하고 플로우 뷰를 패키징 하는 방법을 바꾸고 싶지 않다면 웹 플로우를 다음과 같이 설정하라.

<webflow:flow-registry id="flowRegistry" flow-builder-services="flowBuilderServices">
   <webflow:location path="/WEB-INF/hotels/booking/booking.xml" />
</webflow:flow-registry>

<webflow:flow-builder-services id="flowBuilderServices" view-factory-creator="mvcViewFactoryCreator"/>

<bean id="mvcViewFactoryCreator" class="org.springframework.webflow.mvc.builder.MvcViewFactoryCreator">
   <property name="viewResolvers" ref="myExistingViewResolverToUseForFlows"/>
</bean>
      
10.6. 뷰에서 발생한 이벤트 신호보내기

When a flow enters a view-state it pauses, redirects the user to its execution URL, and waits for a user event to resume. Events are generally signaled by activating buttons, links, or other user interface commands. How events are decoded server-side is specific to the view technology in use. This section shows how to trigger events from HTML-based views generated by templating engines such as JSP, Velocity, or Freemarker.

플로우가 멈춘 view-state로 들어가면, 사용자를 실행 URL로 리다이렉트 하고 사용자가 다시 시작 이벤트를 발생할 때까지 기다린다. 이벤트는 보통 활성화 버튼, 링크 또는 다른 사용자 인터페이스 커맨드에 의해 신호가 보내진다. 이벤트가 서버쪽에 어떻게 디코드 되느냐는 사용하는 뷰 기술에 따라 다르다. 이번 절에서 (JSP, Velocity, 또는 Freemarker 같은 템플릿 엔진에 의해 만들어진 뷰를 기반으로) HTML에서 이벤트를 어떻게 발생시키는지 살펴보겠다.

10.6.1. 이름이 있는 HTML 버튼 사용하여 이벤트 신호 보내기

아래 예제는 클릭했을 때 각각 proceed와 cancel 이벤트 신호를 보내는 두 개의 버튼을 보여준다.

<input type="submit" name="_eventId_proceed" value="Proceed" />
<input type="submit" name="_eventId_cancel" value="Cancel" />

버튼이 눌리면 웹 플로우는  _eventId_ 로 시작하는 요청 매개 변수 찾고 나머지 문자열을 이벤트 id로 간주한다. 이 예제에서 _eventId_proceed를 보내면 proceed가 id가 된다. 같은 폼에서 발생할 수 있는 여러 이벤트가 있을 때 이런 스타일을 사용할 수 있겠다.

10.6.2. 감춰진 HTML 폼 매개변수를 사용하여 이벤트 신호 보내기

아래 예제는 서브밋 할 때 proceed 이벤트를 보내는 폼이다.

<input type="submit" value="Proceed" />
<input type="hidden" name="_eventId" value="proceed" />   
          
여기서 웹 플로우는 간단하게 특수한 _eventId 매개변수를 찾고 그 값을 이벤트 id로 사용한다. 이런 스타일은 오직 폼에서 발생하는 이벤트가 한 개 일 때에만 사용하라.

10.6.3. HTML 링크를 사용하여 이벤트 신호 보내기

아래 예제는 활성화 했을 때 cancle 이벤트를 보내는 링크다.

<a href="${flowExecutionUrl}&_eventId=cancel">Cancel</a>       
          
이벤트를 발생시키면 HTTP 요청이 서버로 보내진다. 서버 쪽에서는 플로우가 현재 view-state에서 이벤트를 디코딩한다. 어떻게 이 디코딩 프로세스가 동작하는지는 뷰 구현체에 따라 다르다. 스프링 MVC 뷰 구현체가 간단하게 _eventId 이름을 가지고 있는 요청 매개변수를 찾는 것을 기억하라. 만약 _eventId 매개변수가 없다면 뷰는 _eventId_로 시작하는 매개변수를 찾고 해당 문자열의 남은 부분을 이벤트 id로 사용한다. 만약 둘 다 없는 경우에는 어떤 플로우도 실행하지 않는다.
신고

'Spring Web Flow > Chapter 10' 카테고리의 다른 글

SWF 10장 스프링 MVC 통합  (0) 2009.03.04
top







티스토리 툴바