Whiteship's Note

'2009/08'에 해당되는 글 27건

  1. 2009.08.31 쓰리좝 시작인가... (6)
  2. 2009.08.31 9월에 할 일 정리 (10)
  3. 2009.08.27 [봄싹 오픈] springsprout.org (20)
  4. 2009.08.27 [봄싹] D-day 오후 10시에 오픈하겠습니다. (4)
  5. 2009.08.26 [봄싹] 시즌 2 오픈 D-1 (2)
  6. 2009.08.23 [스프링 시큐리티 3.0] @PostAuthorize
  7. 2009.08.23 [스프링 시큐리티 3.0] @PreAuthorize
  8. 2009.08.21 [스프링 배치 2.0] 걸음마 떼기 (2)
  9. 2009.08.20 [스프링 3.0 OXM] 14. Marshalling XML using O/X Mappers 4
  10. 2009.08.19 [스프링 3.0 OXM] 14. Marshalling XML using O/X Mappers 3
  11. 2009.08.17 [봄싹] 시즌2 다음 주 오픈 예정 (2)
  12. 2009.08.17 [잡담] 예비군 4년차 훈련 시간 (10)
  13. 2009.08.14 [테스트] 커스텀 MimeMessageHelper 테스트하기
  14. 2009.08.14 [스프링 이메일] MimeMessageHelper 초간단히 사용하기
  15. 2009.08.13 [스프링 3.0 OXM] 14. Marshalling XML using O/X Mappers 2
  16. 2009.08.13 [스프링 3.0 OXM] 14. Marshalling XML using O/X Mappers 1
  17. 2009.08.13 허경영의 콜미
  18. 2009.08.11 제주도 또 가겠구나~ (10)
  19. 2009.08.11 [파이어폭스 플러그인] 파이어버그 짱인듯... (4)
  20. 2009.08.11 [EGIU] Unit 13, 14 정리
  21. 2009.08.11 [봄싹] 간단하지 않은 회원 관리 (4)
  22. 2009.08.10 [파이어폭스 플러그인] 구글 리더 왓처 (2)
  23. 2009.08.07 맥용 STS가 달라졌다!! (2)
  24. 2009.08.07 [EGIU] 20090807 Unit 9, 10 정리
  25. 2009.08.07 [하이버네이트] 애매한 에러 메시지 때문에 삽질.. @_@ (6)
  26. 2009.08.06 [봄싹]기트 도입 실패 사례 (6)
  27. 2009.08.01 20090801 Unit 7, 8 정리 (2)

쓰리좝 시작인가...

모하니?/Thinking : 2009.08.31 16:44


고등학생 수학 과외를 봐주기로 했습니다. 생업은 지금 다니는 회사에서 ERP(보다는 쉬워보이는)라고 할까나.. 암튼 제품을 보다 효율적으로 관리할 수 있는 시스템을 개발 및 유지보수를 하는 일이고, 두 번째 업은 번역인데 한 번 해보고 난 뒤 사기가 많이 떨어졌습니다. 이제는 세 번째 업인 과외를 시작하기로 했습니다.

과외는 세금도 안 떼고 시간당 페이도 괜찮기 때문에 적극적으로 하고 싶은데 개발과 관련된 분야가 아니라는 것이 좀 문제입니다. 고등학생 수학을 봐주기로 했는데 어쩌면 수학 공부를 해가면서 가르쳐야 할지도 모르겠습니다. 수학에서 손뗀지 10년이 다 되가는군요. 뭐.. 동생이 수학과를 나왔으니 모르는걸 물어볼 사람은 있어서 다행입니다.

예전에도 몇 번 과외를 해본적은 있지만, 제가 갈쳤던 학생들은 전부 공부를 하기 싫어했던 학생입니다. 잘하고 싶다는 생각도 없고, 숙제도 하기 싫어하고~ 지금 가르치려는 학생도 이미 전에 한 번 실험삼아(?) 갈쳐봤던 학생인데 공부에 맘이 없는 듯 하여 한 달만 하고 말았었습니다. 그런데 최근에 다시 연락이 왔네요. 애가 다시 공부를 하고 싶어한다고... 과연.. 공부가하고 싶은건지.. 상담 선생이 필요한 건지는 가봐야 알겠지만...

이번에도 공부에 맘이 없다면 금방 끝날 일인 듯 하네요.

흠.. 이왕 하는거 목동에 전단지 막 뿌리고 해볼까나...

"개발자로 키워드려요~ 이제 영어는 기본이다.
누구나 하지 못하는 코딩 조기 교육으로 특기자 전형을 노리세요~"

ㅋㅋㅋㅋ
신고
top


9월에 할 일 정리

모하니?/Planning : 2009.08.31 12:28


1. 봄싹 스터디 및 사이트 개발
- 몇일 전 오픈한 봄싹 사이트 유지 보수를 한 달 간 진행하고, 스터디를 본격적으로 시작할 계획입니다.
- 하이버네이트 스터디가 유력하며..
- 스프링 DM 스터디도 유력하고..
- 스프링 Roo 역시 유력합니다.

2. 하이버네이트 번역
- 너무 많이 미뤄뒀네요. 이제는 다시 열을 올려서 끝내야겠습니다.
- 다음달까지 맡은 부분 번역을 다 끝내는 것이 목표입니다.

3. 회사일
- 당분간 인천 남동공단으로 출퇴근 해야 할지도 모르겠습니다.
- 이럴 땐 운전도 못하고 차도 없는게 아쉽지만, 걍 전철하고 버스 타고 가다보면 어떻게든 다닐 수 있겠죠.

4. 스윙댄스 졸업공연 준비
- 얼마있음 졸업 공연이라는데 안무와 음악을 전부 와이프한테 위임할 생각입니다.
- 신경쓸 겨를이 없는데.. 모여서 다른 커플들과 모여서 준비를 해야 되네요.
- 아마도 다다음주가 마지막일 듯.

5. 보라카이 여행 준비
- 엊그제 제주도에 다녀왔는데 이번에는 한 달 뒤에 보라카이를 갑니다.
- 가지고갈 짐, 비행기 호텔 예약 확인, 현지 물가 확인, 환전 등
- 오늘밤에 대충 끝내야겠네요.

보라카이는 3시간만 빡쎄게 조사하면 끝날테고..
스윙댄스는 집에서 하루 한 시간씩만 하고..
하이버네이트 번역은 출퇴근 시간에 하던 집에서 스윙 연습 끝내고 하던 꾸준히 해야될테고..
회사일은 인천으로 출퇴근하면서 피곤해지고 깨지고 들들 볶이면 되는거고..
봄싹 개발은 이제 주말에만 해야겠군요.
이러면서 평소에도 꾸준히 영어와 스프링 공부도 하고 피아노도 쳐야하는.. 9월 이로군요.

신고

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

봄싹을 알리러 갑니다.  (6) 2009.11.24
[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
top


[봄싹 오픈] springsprout.org

모하니?/Coding : 2009.08.27 22:08


www.springsprout.org

드디어 봄싹 스터디 새로운 시즌을 시작합니다.


스터디에 가입 하지 않으셔도 어느 정도 구경은 하실 수 있습니다. 어느 정도만~
아직 미흡한 부분이 많지만, 분명히 점차 개선될 겁니다.

1차 오픈을 할 수 있었던 건 전부 봄싹 개발에 참여해주신 열 분의 개발자들 덕분입니다.

이것 저것 프로젝트 하느랴 바빴을텐데 가장 열정적으로 참여해준 성윤이.
스터디쪽 미흡하다고 한 마디 했더니 몇 일만에 모든 기능을 다 만들어버린 재진이.
깔끔한 개인화면 만들어준 막내.
다소 늦게 개발에 참여했지만, 그래도 저와 함께 회원 모듈을 당당하고 파일 업로드를 담당하고 계신 종봉이형
Ajax, 시큐리티, 제이쿼리, 맵 오픈 API 등 두루 두루 담당하고 개발해주신 정우형.
오프라인에서는 못 봤지만, 어느새 온라인에서 혼자 세미나를 전부 만들어준 명수형.
오프라인에도 자주 참석해주신 소내기형. 역시 혼자 위키를 전부 만들어주셨습니다. 아주 든든해요. 캬~
개발에는 직접 참여해주시지 않았지만, 메일링 통해서 여러 조언을 해주신 성철형님
그리고 마지막으로 약속을 지켜낸 저까지.

현재는 이렇게 10명이 만들고 가꾸고 있습니다. 앞으로 더 여러 개발자들과 함께 가꿔나가고 싶네요.
신고
top


[봄싹] D-day 오후 10시에 오픈하겠습니다.

모하니?/Coding : 2009.08.27 15:58


현재 피튀기게 개발 중입니다. 몸이 10개였으면 좋겠어요. 안 믿으실까봐.. 증거자료 재출합니다.


보세요.. 불과 1시간전에 올린 글인데.. 댓글이 장난 아니죠. @_@ 결국은 명수형이 태그파일 만드는 걸로 결론이 났군요. 캬...

1차로 css로 간단하게 적용하고
2차로 스프링이 제공하는 HTMLUtils를 써보고
3차로 그것을 태그파일로 다듬고
4차는 다시 1~3차를 엎어버리고, 에디터를 적용하는 것..

이 중에서 3차까지는 한 다음 오픈을 할 것 같습니다. 따끈따근한 봄싹 개발 현장이었습니다. ㅎㅎ

불량사원으로 찍히실까봐.. 닉넴은 대충 모자이크 처리했습니다.
봄싹의 에이스 개발자들이 불량 사원으로 찍히는 이것이 바로 "봄싹 딜레마"

신고
top


[봄싹] 시즌 2 오픈 D-1

모하니?/Coding : 2009.08.26 07:18


내일 오픈 합니다. 이번 주 월요일부터 예비군 동미참훈련? 때문에 월.화,수를 교장으로 출퇴근하고 있습니다. 막바지에 소중한 시간을 뺏겨서 아쉽긴하지만, 다른 봄싹 에이스분들께서 많이 신경써 주셔서 무사히 원했던 일정에 맞춰서 오픈할 수 있게 됐습니다.

봄싹 프로젝트와 관련해서는 하고 싶은 이야기들이 상당히 많은데, 그 중 몇 가지 주제들만 뽑아 보면 다음과 같습니다.

- 각종 프레임워크 및 개발환경 도입 성공 사례(하이버네이트, 시큐리티 3.0, 메이븐, CI 툴, 테스트 등)
- 기트 도입 실패 사례(이전에 공유한바 있습니다.)
- 봄싹 개발 프로세스
- 자율적이고 자연스러웠던 작업 세분화
- 데드라인
- 메일링 리스트 활용

이 것들은 제가 느낀점들이고, 다른 봄싹 에이스 분들께서 느낀 주제들도 잘 정리해서 공유할 날이 있을 것 같습니다.

드디어.. 마음대로 주무를 수 있는 홈 페이지가 생겨서 정말 기쁩니다. 비록 몇 달간은 베타 버전으로 공개하겠지만, 차차 스터디에 필요한 기능들을 더 다듬고 추가하면서 꾸준히 발전할 겁니다. 봄싹 파이팅~!!
신고
top


[스프링 시큐리티 3.0] @PostAuthorize

분류없음 : 2009.08.23 15:27


이 녀석도 아주 유용한 애노테이션입니다. @PreAuthorize랑 비슷하게 권한을 확인하지만, 차이점은 메서드를 일단 실행한 뒤에 권한을 확인한다는 것입니다. 처음에는.. 이런 생각을 했었습니다.

이게 뭐야.. @_@.. 이미 실행 한 뒤에 권한을 체크하면... 무슨 소용이지??

그런데 막상 보안관련 코드를 작성하다 보면 그럴 일이 생기더군요. 예를 들어, 봄싹 프로젝트에서 개인 정보 수정 기능이 있는데, 이 때, springsprout.org/member/update/{id}.do 이런 URL 구조를 사용합니다. 이 기능은 컨트롤러에서 GET, POST 2단으로 나눠서 처리합니다. 아주 일반적인 경우죠.

    @RequestMapping(value = "/member/update/{id}.do", method = RequestMethod.GET)
    public String updateForm(@PathVariable int id, Model model)
            throws ServletRequestBindingException {
        model.addAttribute(service.getMemberById(id));
        return "member/update";
    }


    @RequestMapping(value = "/member/update/{id}.do", method = RequestMethod.POST)
    public String updateForm(@PathVariable int id, Member member, BindingResult result,
            SessionStatus status, HttpSession session) throws ServletRequestBindingException {
        validator.validate(member, result);
        if (result.hasErrors()) {
            return "member/update";
        } else {
            service.update(member);
            status.isComplete();
            session.setAttribute("SESSION_FLASH_MSG", "회원정보가 수정되었습니다.");
            return "mypage/index";
        }
    }

시큐리티 보안 기능 중 하나인 메서드 보안 말고, URL 보안으로 MEMBER나 ADMIN 권한이 있는지 정도는 확인할 수 있습니다.

그러나.. GET 요청일 때, 만약 다른 회원 정보를 보기 위해 URL에서 자신의 id 가 아닌 다른 id를 입력한다면 어떻게 될까요? URL 보안은 못 막습니다. 아마도 getMember() 앞쪽에 이런 코드가 들어갈 겁니다.

    public boolean isCurrentUserOrAdmin(int id) {
        if(!isCurrentMembersInfo(id) && !isAdmin())
            throw new AccessDeniedException("다른 회원의 정보에 접근을 시도할 경우 계정이 차단 됩니다.");
        return true;
    }
   
    private boolean isCurrentMembersInfo(int id) {
        return getCurrentMemberId() == id;
    }

isCurrentUserOrAdmin 같은 걸 호출해서 확인을 거친 다음에 getMember()를 호출할 수 있게 해야합니다.

POST 요청은 어떤가요? 누군가 POST 요청을 임의로 만들어서 접근을 시도한다면?? 그 경우도 막기 위해 위와 같은 코드를 update 하기 전에 실행해야 합니다. 이 경우는 이전 글에서 살펴보았던, @PreAuthorize가 적당하기 때문에 쉽게 바꿀 수 있습니다.

    @PreAuthorize("hasRole('ROLE_ADMIN') or (#member.email == principal.Username)")
    public void update(Member member) {
        member.loadAvatar();
        repository.update(member);
    }

이렇게 말이죠. 굳이 컨트롤러에 시큐리티 관련 코드를 삽입할 필요가 없습니다. 그럼 GET 요청 처리는 어떻게 할까요??

    @PostAuthorize("(returnObject.email == principal.Username) or hasRole('ROLE_ADMIN')")
    public Member getMemberById(int id) {
        return repository.getMemberById(id);
    }

이렇게 getMember() 위에 @PostAuthrize를 붙여서 해결할 수 있습니다. 현재 상요자가 화면에 보여주려는 객체에 대한 권한이 있는지 혹은 관리자인지 확인해 보는 것이죠.

결론은.. @PostAuthorize도 매우 유용하답니다.

그런데 참고할만한 자료가 너무 없네요. 애노테이션 API에서 EL에서 자주 쓰일만한 기본 내장 객체 이름 (principal 이나 returnObject) 들을 알려줬으면 하는데 그런 내용이 없습니다.

거의 유일한 참고 자료는 예전에 번역/편역/요역해서 올렸었던 글 하나 뿐..

http://blog.springsource.com/2009/06/03/spring-security-300m1-released/
http://whiteship.me/2257

신고
top


[스프링 시큐리티 3.0] @PreAuthorize

Spring Security/etc : 2009.08.23 14:38


    <global-method-security secured-annotations="enabled"
        jsr250-annotations="enabled" pre-post-annotations="enabled" />

시큐리티 설정 파일에 위와 같이 설정하면 @PreAuthorize, @PostAuthorize, @PreFilter, @PostFilter를 사용할 수 있습니다.

이들 애노테이션에서는 스프링 EL을 사용해서 현재 사용자 정보에 접근하거나, (pre 인 경우)메서드의 인자값 또는 (post 인 경우)메서드의 반환값의 정보에 접근할 수 있습니다.

    @PreAuthorize("(#study.manager.email == principal.Username) or hasRole('ROLE_ADMIN')")
    public void updateStudy(Study study) {
        repository.update(study);
    }

위 예제는 다음 주에 오픈 할 봄싹 프로젝트에서 사용하고 있는 코드입니다. Study를 수정하려는 사람이 관리자이거나, 스터디를 만든 사람인지 확인한 뒤에 메서드를 실행합니다. 만약 해당 EL이 false로 판단되면 Access Dinied 에러를 던져줍니다.

애노테이션을 메서드에만 붙이지 않고 클래스에도 붙여서 클래스에 정의한 모든 메서드에 적용할 수도 있습니다. 이런식으로요.

@Service
@Transactional
@PreAuthorize("hasRole('ROLE_USER')")
public class StudyService {

...

}





신고
top


[스프링 배치 2.0] 걸음마 떼기

Spring Batch/etc : 2009.08.21 00:26


1. 라이브러리 추가.

pom.xml에 스프링 번들 저장소에서 제공하는 스프링 배치 가장 최신 버전을 추가해줍니다

프로젝트가 세 개로 나눠져 있더군요. test 모듈은 테스트 용이니까 test scope으로 설정하는 것이 좋겠네요.

<dependency>
<groupId>org.springframework.batch</groupId>
<artifactId>org.springframework.batch.core</artifactId>
<version>2.0.2.RELEASE</version>
</dependency>

<dependency>
<groupId>org.springframework.batch</groupId> <artifactId>org.springframework.batch.infrastructure</artifactId> <version>2.0.2.RELEASE</version>
</dependency>

<dependency>
<groupId>org.springframework.batch</groupId> <artifactId>org.springframework.batch.test</artifactId>
<version>2.0.2.RELEASE</version>
</dependency>

2. 배치를 Job와 Step으로 표현합니다.

하나의 Job이 하나의 배치 작업이라고 생각하면 될 듯 하고, 배치 작업의 세세한 단계들을 여러 개의 Step으로 표현할 수 있습니다. 하나의 Step은 ItemReader, ItemProcessor, ItemWriter를 각각 가질 수 있는데, 이 것들 다 필요 없이 Tasklet을 구현해서 통짜로 Step을 구현할 수도 있습니다. 그러나 저는 최대한 IR, IP, IW 구조를 이용해 보려고 한 번 써봤습니다.

할 일은 DB에서 특정 데이터들을 읽어와서 이메일로 뿌려주고, 배치가 끝나면 그 결과를 로깅할 것.

2-1. XML 스키마 설정.

batch 네임스페이스를 기본 네임스페이스로 설정한 XML 스키마를 사용합니다.

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/batch"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
        http://www.springframework.org/schema/batch http://www.springframework.org/schema/batch/spring-batch-2.0.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.5.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd"
    xmlns:beans="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
    xmlns:tx="http://www.springframework.org/schema/tx">

// 여기에 job 설정.

</beans:beans>

job 하나 당 하나의 XML 설정 파일로 만드는걸 기본으로 하고, 공통으로 쓸 녀석들은 별도의 XML로 뺀 다음 각각의 job XML에서 import 해서 쓰는 것이 좋을 듯 합니다.

2-2. Job 설정.

본격적으로 job을 설정 파일로 만들어야 합니다. 배치 2.0에서는 개별 아이템들이 아니라 아이템 뭉탱이(chunk) 단위로 배치 작업을 설정할 수 있습니다.

    <job id="itemCouningJob" job-repository="jobRepository">
        <step id="itemCouningStep">
            <tasklet>
                <chunk reader="komaItemReader" writer="emailWriter"
                    commit-interval="100" />
                <listeners>
                    <listener ref="stepResultListener" />
                </listeners>
            </tasklet>
        </step>
        <listeners>
            <listener ref="jobResultListener"/>
        </listeners>
    </job>

이게 끝입니다. 하나의 job 내부에. 하나의 step이 있고, 하나의 listerner(jobResultListener)를 등록해 뒀습니다. job 내부에 여러 개의 step을 설정할 수 있고, 여러 개의 리스너도 등록할 수 있습니다.

하나의 step 에는 리더, 프로세서, 라이터를 등록할 수 있는데, 제가 개념 잡기 힘들었던 부분은 하나의 item을 읽어와서 처리하고 바로 쓴다고??? 였습니다. 그러나 그게 아니더군요. 뭉탱이던 개별 Item이던 읽어온 다음 개별적으로 처리를 하는 것 까진 맞는데, 그것들을 하나 하나 라이터가 처리하는게 아니라, 모든 프로세싱이 끝난 아이템 전체 목록을 라이터가 받아서 작업 합니다.

따라서, 제가 할 일이었던 모든 아이템 목록을 읽어오는 것은 리더에게 맡기면 되고, 별도의 프로세싱 작업이 필요 없는 듯 하니 프로세서는 설정하지 않고, 모든 목록을 읽어온 뒤 이메일로 보내야 하니까 emailWriter라는 걸 하나 등록했습니다.

그리고 Step에도 리스너 하나를 등록해 두었습니다. 이 녀석은 Job에 등록한 것과는 달리 한 Step의 결과, 이름, 시작 시간, 끝난 시간, 수행 시간 등을 알 수 있는 여긴한 녀석입니다.; Job에 등록한 리스너는 모든 Step..즉 Job에 대한 내용을 알 수 있지요.

만약, 정의해야 하는 작업이 step의 리더, 프로세서, 라이터 개념과 잘 맞지 않다면..  Tasklet 자체를 구현한 다음 <tasklet ref=""/> 에 등록해주면 됩니다.

2-3. Job 에서 필요한 빈 정의 및 설정.

이제 위에서 설정한 job에 필요한 빈들을 등록합니다. 우선 리파지토리를 등록합니다.

    <job-repository id="jobRepository" data-source="dataSource"
        transaction-manager="transactionManager" isolation-level-for-create="SERIALIZABLE"
        table-prefix="BATCH_" />

레퍼런스에 있는 것을 그대로 썼습니다. 실제 DB를 이용하도록 했습니다. 다음은 리더 입니다.

    <beans:bean id="komaItemReader"
        class="org.springframework.batch.item.database.HibernateCursorItemReader"
        p:queryString="from Item" p:sessionFactory-ref="sessionFactory" />

하이버네이트 커서 아이템 리더로.. 스프링 배치에서 기본으로 제공해주는 클래스입니다. HQL과 세션 팩토리만 설정하면 됩니다. 다음은 라이터 입니다. 이 녀석은 별도로 구현해 주었습니다.

    <beans:bean id="emailWriter" class="sandbox.batch.writer.EmailWriter"/>

public class EmailWriter implements ItemWriter {

    @Override
    public void write(List items) throws Exception {
        sendEmail(items);
    }

    private void sendEmail(List items) {
        System.out.println("Mailing : " + items);
    }

}

구현이라고 해봤자.. 그냥 저렇게 좀 허접하게 해뒀습니다. 주요 관심사는 아니기 때문에 저렇게 했습니다. 마지막으로 리스너 두개를 구현하는데 이 녀석들은 뭐 간단하니까 패스하죠.

3. 배치 실행하기.

배치 실행은 JobLauncher를 사용하는데 이 녀석은 jobRepository를 필요로 합니다. 따라서 이 녀석도 스프링 DI를 사용하도록 빈으로 등록해 줍니다.

    <beans:bean id="jobLauncher"
        class="org.springframework.batch.core.launch.support.SimpleJobLauncher" p:jobRepository-ref="jobRepository" />

자 이제 드디어 자바 코드로 Job을 실행해 줍니다.

jobLauncher.run(job, new JobParameters());

jobLauncher 이 녀석을 applicationContext에서 DL을 하건, Autowiring으로 가져오건 하고, job도 2번 작업에서 등록한 녀석을 가져옵니다. 그리고 JobParameter 객체를 넘겨주면 실행이 안 될 겁니다.

테이블이 없다는 에러가 나오죠. 다음 스키마 파일 중에 사용 중인 DB에 맞는 녀석을 골라서 테이블을 만들어 준 다음에 실행해 봅니다. 그럼 돌아갈 겁니다.


4. 앞으로 할 일

JobParameter가 이전에 사용한 것과 같다면 배치는 다시 돌지 않습니다. JobParameter를 다른 정보를 가지도록 매번 새로 만들어 줘야 하는데, 그 부분을 좀 살펴봐야겠습니다. Incrementer라는 것과 관련이 있어 보이던데 매번 실행할 때마다 자동으로 겹치지 않는 JobParameter를 만들어 주는게 있을 법도 한데 말이죠.

배치 테스트에 대하 알아봐야겠습니다. 어떻게 테스트 할 수 있는지. 스프링 배치가 제공해주는 테스트 방법은 어떤 것인지.

하이버네이트와 스프링 배치 기본 테이블 스키마를 맵핑해줄 자바빈 객체들은 없는지 살펴봐야겠습니다. 이것도 어딘가 있을 법도 한데 말이죠. 테이블 보고서 직접 자바빈 만들어서 맵핑 해주기는 좀 귀찮자나요. 누군가 해놨거나.. 하이버네이트 툴로 스키마에서 자바빈을 만들고 맵핑도 해주는 걸 찾아보던가 해야겠습니다. 하이버 맵핑만 끝나면.. 뭐 배치 정보 가져와서 화면에 뿌려주기만 하면 되니깐.. 식을 죽 먹기겠네요.

음.. 그리고 간간히 레퍼런스 보면서 이론 공부도 좀 해야겠네요. 여러 용어들이랑 개념들 기타 세부 기능들에는 뭐가 있는지 등등등.
신고

'Spring Batch > etc' 카테고리의 다른 글

[스프링 배치 2.0] 걸음마 떼기  (2) 2009.08.21
top


[스프링 3.0 OXM] 14. Marshalling XML using O/X Mappers 4

Spring/3.0 : 2009.08.20 00:00


참고: http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/ch14s04.html

oxm 네임스페이스를 스프링 XML 설정 파일에 추가하여 사용할 수 있다.

<?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:oxm="http://www.springframework.org/schema/oxm"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/oxm
    http://www.springframework.org/schema/oxm/spring-oxm-3.0.xsd">

현재 지원하는 태그는 다음과 같다.
    •    jaxb2-marshaller
    •    xmlbeans-marshaller
    •    jibx-marshaller

각각의 태그는 해당 섹션에서 자세히 설명하겠다. 예를 들어, 다음은 JAXB2 마샬러를 설정한 모습니다.

<oxm:jaxb2-marshaller id="marshaller" contextPath="org.springframework.ws.samples.airline.schema"/>

신고
top


[스프링 3.0 OXM] 14. Marshalling XML using O/X Mappers 3

Spring/3.0 : 2009.08.19 23:52


참조: http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/ch14s03.html

14.3 Marshaller와 Unmarshaller 사용하기

다음은 마샬링, 언마샬링에서 사용할 JavaBean이다.

public class Settings {
    private boolean fooEnabled;

    public boolean isFooEnabled() {
        return fooEnabled;
    }

    public void setFooEnabled(boolean fooEnabled) {
        this.fooEnabled = fooEnabled;
    }
}

다음 Application에서는 위의 객체를 settings.xml로 저장하고 다시 그것을 읽어들인다.

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.oxm.Marshaller;
import org.springframework.oxm.Unmarshaller;

public class Application {
    private static final String FILE_NAME = "settings.xml";
    private Settings settings = new Settings();
    private Marshaller marshaller;
    private Unmarshaller unmarshaller;

    public void setMarshaller(Marshaller marshaller) {
        this.marshaller = marshaller;
    }

    public void setUnmarshaller(Unmarshaller unmarshaller) {
        this.unmarshaller = unmarshaller;
    }

    public void saveSettings() throws IOException {
        FileOutputStream os = null;
        try {
            os = new FileOutputStream(FILE_NAME);
            this.marshaller.marshal(settings, new StreamResult(os));
        } finally {
            if (os != null) {
                os.close();
            }
        }
    }

    public void loadSettings() throws IOException {
        FileInputStream is = null;
        try {
            is = new FileInputStream(FILE_NAME);
            this.settings = (Settings) this.unmarshaller.unmarshal(new StreamSource(is));
        } finally {
            if (is != null) {
                is.close();
            }
        }
    }

    public static void main(String[] args) throws IOException {
        ApplicationContext appContext =
            new ClassPathXmlApplicationContext("applicationContext.xml");
        Application application = (Application) appContext.getBean("application");
        application.saveSettings();
        application.loadSettings();
    }
}

위에서 설정할 Marshaller와 Unmarshaller는 다음 스프링 설정 파일에서 설정한다.

<beans>
    <bean id="application" class="Application">
        <property name="marshaller" ref="castorMarshaller" />
        <property name="unmarshaller" ref="castorMarshaller" />
    </bean>
    <bean id="castorMarshaller" class="org.springframework.oxm.castor.CastorMarshaller"/>
</beans>

위 설정에서 사용한 Marshaller는 Castor 라이브러리인데, 이 것은 부가적인 설정이 필요 없기 때문에 빈 설정이 간단하다. 도한 CastorMarshaller가 스프링의 Mashaller와 Unmashaller를 모두 구현하고 있다. 따라서 이 빈이 Application의 Marshaller와 Unmashaller에 설정된다. 위 애플리케이션은 다음과 같은 XML 파일을 만들어 낸다.

<?xml version="1.0" encoding="UTF-8"?>
<settings foo-enabled="false"/>


신고
top


[봄싹] 시즌2 다음 주 오픈 예정

모하니?/Coding : 2009.08.17 11:08



날짜를 보세요. 이 많은 이메일이 대부분 토요일과 일요일 그리고 월요일에 토론 중인 메일 목록입니다. 캬... 멋지죠.

열심히 달리고 있는 봄싹 개발자는 현재 총 10명입니다.
기선, 재진, 성윤, 정우, 재일, 수진, 대웅, 종봉, 명수, 성철.
모두 정말 감사합니다.

다음주 주말 전에 1차 오픈 준비가 끝나면, 급하게라도 개발자 페이지를 추가하겠습니다.
일주일만 더 불량 사원으로 지내봅시다!! 봄싹 베스트 회원이 되실겁니다!! 파이팅!!!!

신고
top


[잡담] 예비군 4년차 훈련 시간



6, 6, 24(8*3)

주소지를 바꿨더니 그 새 훈련 기간이 끝나버려서 안 받아도 되는 줄 알았건만.. 그게 아니더군요. 지난 번에 6시간 교육을 다녀왔으니 이제 남은 교육 시간은 30시간. 6시간 짜리 교육 하나와 3일간 8시간 교육을 받으러 출퇴근해야 되는 24시간 짜리 교육이 남았습니다.

오늘 저녁 6시부터 자정 12시까지 6시간 짜리 교육을 받으러 갑니다.
다음 주 월, 화, 수 3일간 오전 9시까지 안양박달교장 이라는 곳으로 오라고 합니다.

1년 중에 총 36시간. 일수로는 5일을 잡아먹는 훈련. 혹자는 이걸 휴식이라며 좋아도 하시지만 전 너무 싫어요. 시대가 어느땐데 파씨즘적인 동영상 시청에 산에 올라가서 의미없는 삽질이나 해데고.. @_@ 그럴바엔 하지 말자고요. 콜오브듀티 5로 시뮬레이션을 하자니까... 그럼 내가 40시간에 6일을 가도 흔쾌히 가겠다.

아휴 짜증나!!!! 더워죽겠는데 국방의 의무는 무슨!! 너나 가!!

http://loved.pe.kr/entry/hannara-minjoo
신고
top


[테스트] 커스텀 MimeMessageHelper 테스트하기

모하니?/Coding : 2009.08.14 14:07


MimeMessage를 사용해서 실제로 메일을 보내보고, 메일이 깨지지는 않는지 확인해보고 싶어서 다음과 같은 테스트를 작성했습니다.

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("/testContext.xml")
public class SignupConfirmMimeMessageHelperTest {

    @Autowired
    JavaMailSender mailSender;

    @Test
    public void sendInteface() {
        MimeMessage mimeMessage = mailSender.createMimeMessage();
        Member member = new Member();
        member.setEmail("whiteship2000@gmail.com");
        assertNotNull(mimeMessage);
        SignupConfirmMimeMessageHelper helper = new SignupConfirmMimeMessageHelper(mimeMessage);
        helper.makeMessage(member);
        mailSender.send(mimeMessage);
    }

}

테스트를 만들면서 JavaMailSender와 MimeMessage, SignupConfirmMimeMessageHelper 클래스를 어떻게 사용할지 고민을 했죠. 생성자에 member도 같이 줘봤다가.. 뺏다가.. 했습니다. 결국은 빼냈습니다. 중요했던 건 SignupConfirmMimeMessageHelper 클래스의 생성 방법과 사용방법 이었습니다.

저런식으로 실제 메일을 보내 본 뒤.. 그대로 두면.. 테스트가 돌 때 마다 저한테 메일을 보내줄 겁니다. 상당히 귀찮은 테스트입니다. 그래서 생각을 했습니다. 안 되겠다. 어차피 메일 보내는 것도 확인했고.. 인코딩도 확인했고.. 내가 이 테스트에서 정하고자 했던 건 SignupConfirmMimeMessageHelper 클래스의 생성자 구조랑 사용법이니깐... 단위테스트로 고치자~

@RunWith(MockitoJUnitRunner.class)
public class SignupConfirmMimeMessageHelperTest {

    @Mock JavaMailSender mockSender;
    @Mock MimeMessage mockMessage;

    @Test
    public void sendInteface() {
        assertNotNull(mockSender);
        assertNotNull(mockMessage);
        when(mockSender.createMimeMessage()).thenReturn(mockMessage);
       
        MimeMessage mimeMessage = mockSender.createMimeMessage();
        Member member = new Member();
        member.setEmail("whiteship2000@gmail.com");
        SignupConfirmMimeMessageHelper helper =
            new SignupConfirmMimeMessageHelper(mimeMessage);
        helper.makeMessage(member);
        mockSender.send(mimeMessage);
    }

}

그래서 이렇게 고쳤습니다. 고치고 나니까... 이런 생각이 드네요.


맨 마지막 줄만 지워버릴껄 그랬나.... 허허헐...
신고
top


[스프링 이메일] MimeMessageHelper 초간단히 사용하기

모하니?/Coding : 2009.08.14 12:09


    private MimeMessage makeTestMimeMessage() throws MessagingException,
            AddressException {
        MimeMessage message = javaMailSender.createMimeMessage();
        MimeMessageHelper helper = new MimeMessageHelper(message);
        helper.setTo("whiteship2000@gmail.com");
        helper.setFrom("s2cmailer@gmail.com");
        helper.setSubject("This is the Subject Line!");
        helper.setText("<h1>This is actual message</h1><a href=\"ads\">hi</a>", true);
        return message;
    }

    private MimeMessage makeTestConfirmMimeMessage() throws MessagingException,
            AddressException {
        MimeMessage message = javaMailSender.createMimeMessage();
        message.setFrom(new InternetAddress("s2cmailer@gmail.com"));
        message.addRecipient(Message.RecipientType.TO,
                                 new InternetAddress("whiteship2000@gmail.com"));
        message.setSubject("This is the Subject Line!");
        message.setContent("<h1>This is actual message</h1><a href=\"ads\">hi</a>",
                           "text/html" );
        return message;
    }

둘 중에 어떤 코드를 쓰느냐는 코딩하는 사람 맘이겠지만, 위에 있는 것이 훨씬 깔끔해 보이지 않나요. Helper를 이용해서 좀 더 직관적인 메서드 이름과 편리한 인터페이스로 MimeMessage를 작성할 수 있습니다.

애용하세요~
신고
top


[스프링 3.0 OXM] 14. Marshalling XML using O/X Mappers 2

Spring/3.0 : 2009.08.13 18:18


요약, 번역, 참조: http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/ch14s02.html

14.2 Marshaller와 Unmarshaller

14.2.1. Marshaller

스프링은 모든 마셜링 과정을 org.springframework.oxm.Marshaller 인터페이스로 추상화 시켰다. 주요 메서드는 다음과 같다.

public interface Marshaller {

    /**
     * Marshals the object graph with the given root into the provided Result.
     */
    void marshal(Object graph, Result result)
        throws XmlMappingException, IOException;
}

(실제로는 boolean supports(Class<?> clazz)  이것도 있음.)

메서드에 전달받은 Object graph를 javax.xml.transform.Result 객체로 변환해 준다. Result는 태깅 인터페이스로 기본적으로 XML을 추상화한 것이다. 다음과 같은 다양한 구현체들이 있다.

Result implementation    Wraps XML representation
DOMResult    org.w3c.dom.Node
SAXResult    org.xml.sax.ContentHandler
StreamResult    java.io.File, java.io.OutputStream, or java.io.Writer

노트: marshal 메서드가 Object 타입의 객체를 받긴 하지만, 대부분 임의의 객체를 전달하진 않는다. 맵핑 파일에 맵핑한 객체 또는 애노테이션을 표시해둔 객체, 마샬러에 등록한 객체 또는 임의의 상위 클래스를 지닌 객체를 넘긴다. 자세한 내용은 O/X 기술 선택 챕터를 참조하라.

14.2.2. Unmarshaller

Mashaller와 비슷하게 org.springframework.oxm.Unmarshaller 인터페이스도 있다.

public interface Unmarshaller {

    /**
     * Unmarshals the given provided Source into an object graph.
     */
    Object unmarshal(Source source)
        throws XmlMappingException, IOException;
}

(이 녀석도 boolean supports(Class<?> clazz) 이걸 가지고 있음)

javax.xml.transform.Source 타입의 객체를 넘겨주면 Object를 반환해준다. 다음과 같은 Source 구현체들이 있다.
 
Source implementation    Wraps XML representation
DOMSource    org.w3c.dom.Node
SAXSource    org.xml.sax.InputSource, and org.xml.sax.XMLReader
StreamSource    java.io.File, java.io.InputStream, or java.io.Reader

14.2.3. XmlMappingException

스프링은 사용중인 O/X 맵핑 툴의 예외 계층 구조를 XmlMappingExcpetion 계층 구조로 변환해준다. 사용중인 툴이 마샬링과 언마샬링 예외를 구분하고 있지 않더라도,,. 스프링에서 이것을 구분해 준다.


신고
top


[스프링 3.0 OXM] 14. Marshalling XML using O/X Mappers 1

Spring/3.0 : 2009.08.13 18:06


요약, 번역, 참조: http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/ch14.html

14.1 도입

객체/XML 변환 과정, 즉 XML 마샬링(Marshalling) 또는 XML 직렬화(Serialization)에 대해 다룬다.

marshaller는 객체 그래프를 XML로 변환해주고..
unmarshaller는 반대로 XML을 객체 그래프로 변환해 준다.

스프링 OXM을 사용할 때의 장점
- 간편한 설정: JAXB context나 JiBK bidning factory 없이도 간단하게 설정할 수 있다. XML 설정시 oxm 네임스페이스를 제공해준다.
- 일관된 인터페이스: 스프링이 제공하는 Marshaller와 Unmashaller 인터페이스를 사용하면 된다. 클라이언트 코드 변경 없이 O/X 맵핑 프레임워크를 교체할 수 있다.
- 일관된 예외 구조: 제각각인 예외들을 스프링의 XmlMappingExcption 이하의 계층 구조로 변환해 준다. 런타입 예외로 기존의 예외를 감싸기 때문에 에러 정보를 분실하진 않는다.


신고
top


허경영의 콜미

모하니?/Watching : 2009.08.13 11:24




가수로 데뷔하신다는데.. 가요 프로에서 보면 정말 재밌을 것 같네요.
구라때문에 감방도 다녀오셨는데 오히려 업그레이드(?)되서 오신듯..
'무중력춤'과 '오링춤'도 너무 기대되요!! +_+

ps: 왠지 벨소리로 대박 날 듯 함...

신고
top

TAG 허경영

제주도 또 가겠구나~




신혼여행으로 4박5일을 다녀왔지만, 너무 볼거리가 많아서 아쉬웠는데 다시 가게 되서 신나네요. 캬캬캬.
3만원에 1박 2일! 와이프도 신났네요. 크하하. 여보 내가 이정도야! 음하하하하
신고
top


[파이어폭스 플러그인] 파이어버그 짱인듯...

Good Tools : 2009.08.11 21:15


요즘 봄싹에서 개발을 하다보니(참... 봄싹은 개발 업체가 아니라 스터디입니다.) 재밌는 것이 있는데, 여러 툴 사용법을 익힐 수 있다는 겁니다. 파이어버그가 좋은 줄은 알고 있었지만, 사용법을 제대로 익혀본적이 없어서 어떻게 써먹는 줄 몰랐는데.. 이번 기회에 유용한 기술을 몇 개 습득했습니다.

1. 레이아웃 미리 조정해보기

레이아웃은 float등으로 띄우고 나서 margin, padding, border로 조정할 수 있는데 border야 뭐.. 그렇다 치고.. margin이랑 padding을 주로 사용해서 레이아웃을 조정합니다. 이 때, JSP나 CSS를 조금 바꾼 담에 브라우저에서 릴로딩해서 보고, 다시 또 수정해서 다시 브라우저가서 릴로딩 하고.. 이런 일을 반복하기 일수인데, 파이어버그를 써서 미리 화면이 어떻게 바뀌는지 조정해서 적당한 값을 알아낼 수 있습니다.


오른쪽 아래에 보이는 레이아웃 창에서 숫자를 클릭해서 조정하면 곧바로 화면에 띄워져 있는 박스들의 위치가 바뀝니다. 캬~~ 멋져요 멋져.

2. 자바스크립트 미리 실행해보기


두번째로 유용하게 쓰고 있는 기능은 '콘솔' 너무 막연해서 뭔지 몰랐는데 여개다가 자바스크립트를 입력해서 미리 실행해 볼 수 있었습니다. 위 화면에서는 복잡한 selection을 하는 제이쿼리를 미리 실험해본 화면입니다.

3. net

왔다 갔다 하는 요청/응답 헤더와 내용을 볼 수 있어서 유용합니다. 스샷은 생략~

IE 8부터는 파이어버그 같은 프로그램이 포함되어 있다던데.. 어떨런지 모르겠습니다. 수수료만 안 붙는다면 10달러 정도 기부하고 싶어지네요.

신고
top


[EGIU] Unit 13, 14 정리

모하니?/English : 2009.08.11 18:24


Unit 13. Present perfect and past 1 (I have done and I did)

현재완료
- 현재와 관련이 있다.
- 최근에 새로운 일이 벌어졌을 때 사용한다.

과거
- 과거에 있었던 일이다.
- 새롭거나 최근의 일이 아닐 때 사용한다.

외울 문장
- He has lost his key (지금도 못 찾고 있다.)
- He lost hist key (과거에 잃어버린적이 있다. 지금은 찾았을 수도 있고 못 찾았을 수 도 있다.)
- I've reqaired the TV
- Who invented the telephone??

틀린 문제 2

A: Are you still reading the paper?
B: No __________ (finish) with it. You can have it.
=> I have finished with it.

이미 예전에 읽었다고 하는 걸까봐 finished를 썼지만 질문에서 still로 물어보고 있으니 최근 상황을 얘기하는 것으로 짐작하고 have + p.p를 써주는게 좋을 듯..

When were you born?
수동태 주의 할 것.

Unit 14. Present perfect and past 2 (I have done and I did)

과거
- 끝난 시간(yesterday, ten minutes ago, in 1999)을 이야기 할 떄는 현재완료를 쓰지 않는다.
- When 이나 What time 으로 물어볼 땐 과거형을 쓴다.

현재완료
- today/this week/since ~ 를 사용할 때 현재완료를 사용한다.

외울 문장
- When did your friend arrive?
- I got home late last night.
- Have you seen Tim recently?
- Dod you see Tim on Sunday?

틀린 문제 3

When _______ published?
=> When was this book published?
When으로 물어봤기 때문에 과거형이 와야 함.
수동태 주의 할 것.

A: Where do you live? B: In Boston.
A: How long ________(you/live) there? B: Five years.
A: Where ________(you/live) before that? B: In Chicago.
A: And how long __________(you/live) in Chicago? B: Two years.
=> 첫 번째 것은 현재 완료. 다음 두 개는 모두 과거 형을 써야함.
현재


신고

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

[BBC News] Toyota recall reaches Eupore  (2) 2010.02.22
[BBC News] Baijing hit by record snowfall  (4) 2010.02.19
[BBC News] Naples pizza protected by EU  (5) 2010.02.18
[BBC News] Ukraine and Russia argue about spies  (2) 2010.02.17
[EGIU] Unit 19, 20정리  (0) 2009.09.02
[EGIU] Unit 13, 14 정리  (0) 2009.08.11
[EGIU] 20090807 Unit 9, 10 정리  (0) 2009.08.07
20090801 Unit 7, 8 정리  (2) 2009.08.01
090731 Unit 5, 6 정리  (6) 2009.07.31
090730 Unit 3, 4 정리  (0) 2009.07.30
090729 Unit 1, 2 정리  (6) 2009.07.29
top


[봄싹] 간단하지 않은 회원 관리

모하니?/Coding : 2009.08.11 12:37


봄싹 시즌 2 개발 중에 자연스래 담당하는 모듈이 나뉘어져서 요즘은 주로 회원 관리 모듈만 개발하고 있습니다. 처음엔 뭐 간단하겠지.. 별거 있나.. CRUD만 하면 되겠지.. 라고 생각했었는데 그게 아니더군요.

일단 회원 관리와 더불어 인증/권한까지 같이 담당하게 되었는데, 사용자가 회원 가입과 로그인을 하고 그 사용자에게 권한을 부여하는 관리자 기능까지 생각해보면 할 일이 심심치는 않았습니다.

1. 회원 가입

로그인과 더불어 사용자가 가장 빨리 접하는 기능 중 하나 일 겁니다. 그래서 디자인에도 조금 신경을 써야했습니다. 그리고 스팸 사용자도 막고 싶었습니다. 캡차를 쓸 수도 있겠지만, 이메일 인증 방법을 사용하기로 결정했습니다. 회원 가입을 서브밋 하면 인증 메일을 전송하고, 사용자가 인증 메일의 링크를 클릭하면 사용자 상태를 인증 된 상태로 바꿔주는 겁니다. 그 전에는 로그인이 되지 않습니다.

검증은 2단계로 화면단에서 한 번, 서버 단에서 한 번 그렇게 두 번 걸러집니다. 이때, 클라이언트 쪽 검증은 제이쿼리의 validation 플러긴을 사용했으며, 중요한 검증 작업 중 하나로 email 중복 체크가 있습니다. 이 부분이 제대로 동작하지 않더라도 최종적으로는 DB단에서 unique 제약 위반으로 에러가 나고 해당 회원 정보는 추가되지 않을 겁니다. 하지만, 그 에러 메시지를 만나게 하기 전에 사용자가 email만 입력한 상태에서 검증을 해주고 싶습니다. Ajax가 필요한 시점입니다. 하지만 요청을 너무 자주 보내고 싶진 않기 때문에, 기본적인 email 형태를 갖췄는지 validation을 한 뒤에 해당 검증을 잘 통과 했을 경우에만 ajax로 요청을 보내서 중복 된 email이 아닌지 확인해 줍니다.

이렇게 화면단/서버단 검증이 잘 끝나서 회원 가입을 진행하게 되면 이메일을 전송하느라 3~5초 정도 시간이 걸리는데 이 시간 동안 사용자에게 뭔가 진행중이라는 사실을 알려주고 화면을 블러킹해줍니다. 이 때 아이튠즈의 블러킹 화면과 비슷한 화면을 보여주도록 했습니다.ㅋㅋ 단, IE에서는 모서리가 각져서 보인다는 거... FF나 Safari에서는 잘 보였습니다.

회원 가입 폼 처리가 끝난 뒤, 회원 가입 인증 대기 화면을 보여줍니다.

2. 가입 승인 대기

회원 가입 인증 메일을 전송했기 때문에, 이제 사용자는 해당 메일을 확인하고 그 메일에 들어있는 링크를 클릭하여 회원 가입 인증을 거칠 수 있습니다.

하지만 만약 사용자가 메일을 한 번 받아놓고 다른 일을 하다가 메일이 쌓여서 봄싹이 보낸 메일이 어딨는지 못 찾았다면? 혹은 메일을 실수로 지웠다면? 해당 사용자는 답답해 할 겁니다. 그래서 인증 메일 재전송 기능이 필요했습니다.

또한 현재 페이지에서 회원이 사용중인 메일 서비스로 바로 이동할 수 있는 링크도 유용할 겁니다.

마지막으로 승인을 받은 사용자에게 기본 권한을 설정해줍니다. 기본으로 모든 사용자는 USER라는 role을 가지도록 구현해 줬습니다. 그래야 익명 사용자와 가입한 사용자를 구분할 수 있을테니 말이죠.

스팸 사용자가 발생할 수 있습니다. 인증을 거치지 않고 계속 가입만 한 사용자들이 DB에 쌓일 수 있죠. 그럴 경우에 대비해서 주기적으로 배치를 실행해서 인증을 거치지 않은 사용자 정보를 삭제해 줍니다.

2. 로그인

여차 저차해서 회원 가입 인증까지 끝낸 사용자는 로그인 화면을 보게 될 겁니다. 회원 가입 인증 메일에 들어있던 링크가 로그인 화면으로 보내주면서 내부에서는 인증 작업을 해주는 것이죠.

이제부터는 스프링 시큐리티와 관련이 있는데, 그다지 어렵진 않았습니다. 스프링 시큐리티를 공부하는게 아니라 그냥 간략하게 사용만 하는 것이니까요. 그다지 어려울 것은 없습니다. 인증 방법은 여러가지가 있는데 일단은 가장 흔한 폼 인증 방식을 선택했습니다. 다음에는 OpenID로 지원해볼 생각이지만, 당장은 아닙니다.

아직 가입을 하지 않은 사용자가 로그인 화면에 들어온 경우가 있을 수 있기 때문에 회원 가입 화면으로 가능 링크가 필요합니다.

또한 가입은 했지만 아직 인증을 거치지 않은 사용자가 있을 수 있는데, 그런 경우 가입 승인 대기 화면으로 포워딩을 하고, 이메일 인증을 받도록 합니다.

비밀 번호를 잊어버렸을 수도 있는데, 이런 경우 가입시 입력한 이메일을 다시 입력받아서 해당 이메일로 비밀번호를 전송해 줍니다. 이 떄 입력하는 이메일도 검증 작업이 필요하겠죠.

3. 관리자

다행히(?) 이 부분은 제 담당이 아닙니다. 성윤군이 담당하고 있는데 제이쿼리를 이용해서 드래그앤드랍으로 권한을 변경할 수 있게 해준다니.. 기대중입니다.

회원 전체 목록 조회.

회원 정보/권한 조회.

회원 정보/권한 변경.

회원 삭제.

모든 목록을 뽑아낸 것이 아니라, 지금까지 완료한 작업이나 오늘 내일 처리할 작업까지만 정리한 것입니다. 아마도 생각하지 못한 작업들이 더 있겠지요. 간단해 보였던 회원 관리가 이렇게도 할 일이 많았다니.. 다른 모듈들은 어떨지 걱정입니다. 이번 주 내로 회원 관리를 정리하고 일손이 모자른 스터디 모듈이나 관리자 모듈쪽에 붙어야겠습니다. 그쪽도 아주 재밌을텐데 말이죠.
신고
top


[파이어폭스 플러그인] 구글 리더 왓처

Good Tools : 2009.08.10 17:35


https://addons.mozilla.org/en-US/firefox/addon/4808

구글 리더를 모니터링 해주는 플러긴 입니다. 얼마전 RSS 갱신이 다소 느리고 사이트 차단까지 당해서 접속이 안 되던 한RSS에서 구글 리더로 갈아탔습니다. 그런데도 도무지 사부님 블로그 포스팅을 실시간으로 캐치하지 못하겠더군요.(실시간으로 알아채지 못하면 항상 애정이 식었다고 하시기 떄문에 @_@) 그래서 결국은 이런 플러그인까지 찾아서 설치했습니다. 과연~~ 애정은 어찌될런지... 몇 일 지켜봐야겠습니다.

혹시 매일 인터넷 서핑을 1시간 이상 하시는 분들 중에 아직도 RSS를 모르시거나, RSS 리더기를 사용하지 않으시는 분들이 있다면 사용을 권해드리고 싶습니다. 정보 습득량과 속도가 많이 달라 지실 겁니다.

ps: 그러고보니, 봄싹 RSS를 개발해야하는군요. 음... 스프링 3.0에 AtomView같은게 있었던 것 같은데 사용해 볼 수 있겠네요.ㅎ
신고
top


맥용 STS가 달라졌다!!

Good Tools : 2009.08.07 22:54


2.1.0이 배포됐다길래. 받으러 들어갔더니.. dmg 파일들이 있다. 오호.. 설마 그냥 옮겨 담기?? 아니네! 인스톨러가 뜨네... 이야~~


이전에는 끼워주기(?)로 주는 dm 서버, tc 서버, roo를 덩달아 다운받아 설치하는 수밖에 없었다. 뭐 압축만 풀면 끝이니깐.. 설치라고 하기도 뭐하지만.. 그런데 이번에는 설치할 제품 목록을 선택하는 화면에서 빼내면 설치하지 않을 수도 있다. 설마.. 이것 때문에 이런 installer를 만들었단 말인가!?

암튼 귿!

ps: 맥용으로 carbon, cocoa, cocoa 64 세 가지 버전이 있는데, 아직은 cocoa로 빌드한 버전을 성능 관련 문제로 비추하고 있다.

Mac OS X

Download the STS Mac OS disk image (*.dmg) from the list above. Once downloaded, please mount the disk image by double-clicking the downloaded dmg file. Open the volume named 'SpringSource' and double-click on the installer to launch the installation. Follow the on-screen instructions to finish the installation.

(*) At this time we do not recommend to use any of the Cocoa builds for Mac OS. There a numerous open performance related problems with the Cocoa port reported at Eclipse.org.


신고
top


[EGIU] 20090807 Unit 9, 10 정리

모하니?/English : 2009.08.07 22:21


Unit 9. Present perfect continuous (I have been doing)

현재 완료 진행형.
- have/has been + -ing
- 방금 어떤 행위가 끝났거나 지속되고 있을 때 사용한다.
- how long, for, since와 주로 함께 사용한다.
- 반복적이거나 주기적인 행위를 표현할 때 사용한다.
- 현재 진행형은 그 순간 하고 있는 것을 표현할 때 사용하고, 현재 완료 진행형은 과거부터 지금까지 이어져온 행위를 표현한다.

외울 문장
- I have been looking for you everywhere.
- How long have you been learning English?
- She's been playing tennis since she was eight.

틀린 문제 2개
Why __________ (you/look) at me like that? Stop it!
=> are you looking

have you been looking이라고 써서 틀림. 현재 진행형을 써야 적절한 문맥.

Is Pual on holiday this week? No __________ (he/work).
=> He's working

이것도 역시 현재 완료 진행형을 써서 틀림. 현재 진행형이 적절한 문맥.

Unit 10. Present perfect continuous and simple (I have been doing and I have done)

현재 완료 진행형
- 행위 자체에 관심이 있지. 그것이 끝났는지 지속되고 있는지는 관심이 없다.
- how long ~~
- want와 mean은 현재 완료 진행형에서 사용할 수 있다.

현재 완료형
- 어떤 행위가 끝났다는 것이 중요하다. 행위 그 자체 보다는 그 행위의 결과에 관심이 있다.
- how much ~~, how many times ~~, how much ~~
- 어떤 동사(know/like/believe)는 보통 진행형으로 사용하지 않는다.

외울 문장
- She's been writing letters all day.
- Lisa has written ten letters today.
- I've known about it for a long time.
- I've been meaning to phone Jane, but I keep forgetting.

틀린 문제 7개

오래 기다렸냐?
=> Have you been waiting long?
기다린 행위가 중요한 거니깐... 현재 완료 진행형.

물고기를 몇 마리 잡긴 했니?
=> Have you caught any fish?
물고기를 잡았는지 못 잡았는지 결과가 중요한 거니깐.. 현재 완료.

너 피곤해 보인다. 일을 열심히 헀니?
=> Have you been working hard?
일을 하고 있던 행위가 중요한 거니깐... 현재 완료 진행형.

Liz는 지금 휴가다. 아 그래? 그녀는 어디로 갔니?
=> Where has she gone?
어디론가 이미 갔으니.. 행위보다는 결과. 그래서 현재 완료.

미안해. 내가 늦었다. 괜찮다. 얼마 안 기다렸다.
=> I have not been waiting long
기다린다는 행위가 중요한 거니깐. 현재 완료 진행형.

비가 아직도 오니? 아니 그쳤다.
=> It has stopped
결과가 중요. 현재 완료.

너에게 빌려간 책을 읽고 있다. 하지만 아직 다 읽진 못했다. 매우 재밌더군.
=> I have been reading the book you lent me, but I have not finished it yet.
첫 번째것은 행위. 두 번째 것은 결과가 중요하니까..


신고

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

[BBC News] Baijing hit by record snowfall  (4) 2010.02.19
[BBC News] Naples pizza protected by EU  (5) 2010.02.18
[BBC News] Ukraine and Russia argue about spies  (2) 2010.02.17
[EGIU] Unit 19, 20정리  (0) 2009.09.02
[EGIU] Unit 13, 14 정리  (0) 2009.08.11
[EGIU] 20090807 Unit 9, 10 정리  (0) 2009.08.07
20090801 Unit 7, 8 정리  (2) 2009.08.01
090731 Unit 5, 6 정리  (6) 2009.07.31
090730 Unit 3, 4 정리  (0) 2009.07.30
090729 Unit 1, 2 정리  (6) 2009.07.29
영어 공부 계획  (2) 2009.07.28
top


[하이버네이트] 애매한 에러 메시지 때문에 삽질.. @_@

Hibernate/etc : 2009.08.07 21:50


DEBUG - OpenSessionInViewFilter.doFilterInternal(207) | Closing single Hibernate Session in OpenSessionInViewFilter
DEBUG - SessionFactoryUtils.closeSession(784) | Closing Hibernate Session
2009. 8. 7 오후 9:30:52 org.apache.catalina.core.StandardWrapperValve invoke
심각: Servlet.service() for servlet springsprout threw exception
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: springsprout.domain.Member.studies, no session or session was closed
    at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:358)
    at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected(AbstractPersistentCollection.java:350)
    at org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:343)
    at org.hibernate.collection.PersistentSet.add(PersistentSet.java:189)
    at springsprout.domain.Member.addManegedStudy(Member.java:154)
    at springsprout.modules.study.StudyService.add(StudyService.java:24)
    at springsprout.modules.study.StudyService$$FastClassByCGLIB$$6d06dbc0.invoke(<generated>)
    at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:149)
...

에러의 원인이 무엇일까? 에러 로그에서 가장 중요한 부분이라고 생각하는 부분을 진하게 표시했다. 제 1의 단서는 에러 메시지이고, 제 2의 단서는 에러가 발생한 지점 중 내가 코딩을 한 부분이다. 스프링, 하이버는 많은 유저와 테스트 그리고 지속적인 관리를 통해 내가 작성한 코드보다 더 신빙성이 높기 때문이다.

어쨋든.. 생각해보자. 에러 메시지가 뭐라고 하는가?? 세션이 없다고?? 왜??? 난 분명 @Transactional을 사용했다. 트랜잭션이 없을리 없는데.. 왜 그럴까.. 이해가 되지 않는다. 세션이 닫혔다고?? 왜??? 이해가 되지 않는다. 이런 일이 발생한 적은 없었다.

혹시나해서 DEBUG 모드로 스프링 로그를 찍어보았다. 해당 에러가 나기 직전에 이러한 로그를 볼 수 있다.

DEBUG - HibernateTransactionManager.doBegin(504) | Preparing JDBC Connection of Hibernate Session [org.hibernate.impl.SessionImpl@7650bc]
DEBUG - HibernateTransactionManager.doBegin(569) | Exposing Hibernate transaction as JDBC transaction [com.mchange.v2.c3p0.impl.NewProxyConnection@a681c3]
DEBUG - HibernateTransactionManager.doGetTransaction(437) | Found thread-bound Session [org.hibernate.impl.SessionImpl@7650bc] for Hibernate transaction
DEBUG - AbstractPlatformTransactionManager.handleExistingTransaction(468) | Participating in existing transaction

분명 Session을 잘 가져왔고, 세션이 닫힌다는 얘기도 없다. 이 바로 다음에 에러가 발생한다. 막막하군.. 그럼 이제 내가 작성한 코드를 살펴보자.

    public void add(Study study) {
        Member currentMember = securityService.getCurrentMember();
        currentMember.addManegedStudy(study);
        repository.add(study);
    }

    public void addManegedStudy(Study study) {
        getStudies().add(study);
        study.addMember(this);
        getManagedStudies().add(study);
        study.setManager(this);
    }

빨간색으로 표시한 부분이 에러가 발생하는 지점이고 최종적으로 getStudies()를 호출할 때 발생한다. 모르겠다. 무엇이 문제일까?

테스트를 만들어보자.

    @Test
    public void add() throws Exception {
        Study study = new Study();
        Member member = new Member();
        memberService.addWithoutConfirm(member);
       
        service.add(study, member);

        assertEquals(member, study.getManager());
        assertTrue(study.getMembers().contains(member));
    }

스프링 통합 테스트를 만들어서 테스트해보았다. 이 테스트는 잘 돌아간다. 더 미궁속으로 빠져든다. 그런데, 테스트와 실제 코드가 같지 않다. 테스트를 편하게 하기 위해 조금 다른 코드를 이용했다. 둘의 차이는 무엇일까?

테스트에서의 member 객체 상태는 Persistent다. 그러나... 실제 코드에서 member 객체 상태는 어떨까? 아차차.. 이런.. 문제의 실마리가 보이는 듯 하다.

그렇다. 실제 코드에서 currentMember 객체는 detached 상태인 것이다. 아.. 이런.. 단서에 너무 의존하다가 눈앞에 있는 객체 상태를 보지 못했다. 나의 실수다. 하이버네이트를 다룰 때 가장 중요한 것 중 하나가 바로 객체의 상태인데. 그것을 못 보다니 한심하다는 생각이 밀려온다. 이미 지난 일이다. 어쩔 수 없다. 다음번엔 잘 찾아내야지.

단 하나.. 바라는게 있다면, 세션이 없다는 얼토당토 않은 에러 메시지 말고, detached 객체에서 lazy loading이 발생한다고 메시지를 출력해주면 좋겠다. 그랬다면... 좀 더 쉽게 해결할 수 있었을 법한 문제였다.
신고
top


[봄싹]기트 도입 실패 사례

모하니?/Coding : 2009.08.06 18:59


봄싹 스터디에서 Git라는 분산 VCS를 사용해 보기로 결정하고, 사전 조사를 거친다음, 간단한 사용법을 공유하고, 개발을 시작했다. 그러나 개발은 더뎠다. 얼마전 더디다 못해 거의 진척이 없다시피 하는 모습을 보고 Git에서 SVN으로 버전 관리 시스템을 바꿨다. 그리고 프로젝트의 데드라인도 설정했다. 그러자... 이게 왠일인가..


불과 2주 만에 총 9명의 개발자가 온/오프라인에서 뜨겁게 개발에 참여하고 있다. 현재 이 모습은 내가 봄싹 구글 그룹스를 처음 만들 때 상상하던 모습이다. 이대로만 간다면, 8월 29일 데드라인 안에 사이트 1차 개발을 마칠 수 있을 것 같다.

바뀐 요인은 딱 두 가지. 1. 데드라인 설정. 2. 개발자에게 보다 편리한 개발 환경으로 전환. 어쩌면 2번은 1번으로 인해 불가피 했을지도 모르겠다. 처음에는 느긋하게 기트에 적응해가자면서 개발을 하자고 생각했었다. 하지만 그것은 오산이었다.

기트를 사용하고 있지만, 기트를 사용하는 시나리오는 예전 SVN을 사용하던 때와 별반 다르지 않았다. 수시로 branching/merging을 하지 않을 꺼라면 굳이 Git를 사용할 필요가 없다는 것을 몸소 체험했으며, 중간 관리자를 거쳐야만 하는 대규모 개발도 아니기 때문에 한방에 서버로 바로 커밋/업데이트하는 SVN이 그립기도 했다. 또한 이클립스 툴 지원이 아직도 미약했다. 마지막으로 별도의 기트 서버를 운영하지 않고 GitHub를 이용했는데, 나중에는 사용자가 많아져서 계정 관리하는 것이 어려웠다. 이 부분은 아마도 봄싹에서 GitHub를 잘못이용한 것이 아닌가 하는 생각이 든다. 애초에 내 계정에 다른 개발자들의 공개키를 등록하는것이 아니라, 프로젝트에서 별도의 브랜치를 따다가 자기 계정에서 관리하는 형태로 프로젝트를 진행했어야 하는 듯 하다.


그래서 모두에게 익숙한 SVN으로 넘어왔다. 결국은 기트 도입이 실패했지만, 프로젝트는 실패하지 않았다. 어쩌면 그로인해 프로젝트 성공의 길로 한 걸음 더 다가간 것 같이 느껴진다. 비록 이번에는 기트 도입이 실패했지만, 다음에 적절한 상황이 오면 다시 시도해 볼 생각이다. 다음에는 기트허브에서 새로운 방식으로 개발을 진행하던지, 별도의 기트 서버 환경을 구축한 뒤에 해볼 생각이다. 그때가 되면 이클립스 툴도 조금은 진전이 있겠지...??

ps: 예상외로 메이븐 도입에 대해서는 다들 잘 수긍하는 편이었다. 처음부터 메이븐 리파지토리, 플러긴, 페이스, 골 등의 개념 설명을 한 적이 없고, 필요한 명령어만 몇개 알려드리고, pom.xml에 의존성 추가하는 것만 알려드렸다. 기트가 워낙 충격적이어서 그랬나...? 아무튼 메이븐은 기트에 비하면 도입이 쉬운편이었다. 봄싹에선 말이다.



신고
top


20090801 Unit 7, 8 정리

모하니?/English : 2009.08.01 23:42


Unit 7, Present perfect(I have done)

현재완료: have/jas + pp(past participe)
과거분사(pp)는 보통 -ed로 끝나지만, 다수의 중요 동사들이 불규칙 변화를 한다.
'something has happend'는 보통 새로운 정보를 나타낼 때 사용한다.
현재와 연관이 있다. 과거의 결과가 현제까지 지속되는 것이다.
just(조금 전에), already(이미, 벌써), yet(부정, 의문문)과 함께 사용할 수 있다
gone to와 been to의 차이
- gone to는 현재도 가 있는 상태.
- been to는 다녀와서 지금은 돌아온 상태.

외울 문장

The road is closed. There's been (there has been) an accident.
I can't find my bag. Have you seen it?
Have you just arrived?
He's already gone.
Has it stopped raning yet?

틀린 문제 2 개.

- arrive의 과거 분사 arrived

Unit 8. Present perfect 2(I have done)

지금까지 지속된 기간을 나타내는 표현이 올 수 있다.
recently/in the las few days/since breafast
말하는 시점까지도 그 기간이 끝나지 앉았을 때, 현재 완료향과 today/this evening/thie year를 사용한다.

외울 문장

Have you ever eaten caviar?
I've never been to China.
Have you heard from Brian recently?
He has never driven a car before.

틀린 문제 6개

(most beautiful place / visit) What's ________________________
the most beautiful place you have ever visited.


신고

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

[BBC News] Naples pizza protected by EU  (5) 2010.02.18
[BBC News] Ukraine and Russia argue about spies  (2) 2010.02.17
[EGIU] Unit 19, 20정리  (0) 2009.09.02
[EGIU] Unit 13, 14 정리  (0) 2009.08.11
[EGIU] 20090807 Unit 9, 10 정리  (0) 2009.08.07
20090801 Unit 7, 8 정리  (2) 2009.08.01
090731 Unit 5, 6 정리  (6) 2009.07.31
090730 Unit 3, 4 정리  (0) 2009.07.30
090729 Unit 1, 2 정리  (6) 2009.07.29
영어 공부 계획  (2) 2009.07.28
영어 공부하자  (4) 2009.07.21
top







티스토리 툴바