Clean Code that Works.

XML 을 JSON으로..2

Java2010. 4. 5. 23:01
이전의 포스트에 이은 2탄.

이전에 XML을 JSON으로 만들었는데...

이것을 Spring MVC에서 @ResposeBody 형태로 해서 리턴을 하게 되면...


org.codehaus.jackson.map.JsonMappingException: null object
위 오류를 찍어 준다.(항상 발생하는것은 아니고)
왜 이럴까. 하고 봤더니..
값이 null인 것이 있었다.. 위의 XML에는 값이 null 인게 없었는데, 값이 널일 경우에는 JSON에 value 쪽에 null이 들어 가게 된다.

하여, 값이 null일 경우에는 다른 값("") 아무 값도 없는 이런 값이 필요하게 되어 net.sf.json 패키지의
XMLSerializer를 살펴 보게 되었다.

로직을 살펴 보면 값이 없는 경우에 null을 표시 하도록 되어 있는 것을 확인 할 수 있었다.

하여 저 부분을 null 이 아닌 ""을 리턴하도록 변경 하여 처리 하였다.


스프링에서는 다양한 방법으로 스케쥴링을 지원 한다.
Task Execution and scheduling

프로젝트 진행을 하다 보면 스케쥴링을 해야 하는 경우가 많은데(조직도 라던지, 트리거 형식으로 라던지)
아무튼 이런 경우에, 현재 작동중인 Job들을 확인 하고 이를 제어 할 수 있는 것을 해보고 싶어서 해 보았다.

어차피 스케쥴링이라는게 쓰레드이기 때문에 쓰레드를 조회 해서 제어할 수도 있지만, (모든 쓰레드가 표시되서 제어가 힘들다)
기선님이 알려주신 쓰레드 리스트 보는 방법
스프링에서 Quartz 가 지원 되기 때문에 이것을 사용해서 하기로 했다.

하여 결과를 보면, 일단 아래와 같이 구현을 하였다.


구조를 살펴보면
스케쥴러 > 트리거 그룹 > 트리거 > 잡 그룹 > 잡
이런 형식으로 되어 있었다.

일단 잡 그룹으로만 나누어서 스케쥴링을 한다고 생각하고 위와같이 구현 하였다.
각 잡 들 마다 정지, 시작 기능이 있고,
이를 총괄하는 스케쥴러에 대한 정지, 시작 기능이 있다.

트리거 그룹이나 트리거 들에 대한 제어도 각각 추가할 수 있다.(세부 구현 내용이 많아진다.)
사이트 환경에 맞추어 하면 될듯 싶다.(보통 잡 그룹을 여러개 두고, 잡으로 나누어서 하면 될것 같다.)


설정 파일에서 보듯이 jobScheduler를 가지고 하위 잡 정보들을 가져와서 이를 가지고 보여줄 데이터를 만들던가, 잡 들을 조작 하면 된다.




간단한 Url Logger를 작성 하기 위해서, 해당 url에 대한 @RequestMapping에 url값이 필요했다.

구글링을 해서 찾아봤었는데.. http://lizdouglass.wordpress.com/2009/12/16/adding-a-spring-aspect/

여튼..
@Before aspect로 할 경우 Joinpoint에서 getClass 한 후
여기서 getMethods[] 한다. 메서드 들 중에서 방금 호출한 메서드를 가져오고
가져온 메서드와 호출한 메서드 정보가 일치 하면 그 메서드에서 어노테이션 정보를 가져오고
어노테이션 정보에서(대부분 url을 첫번째 값이니) 첫번째 값을 가져온다.

@Before(value="execution(* net.study.spring.controller.WelcomeController.index())")
    public void doBeforeProfiling( JoinPoint jp) throws SQLException
    {
        UrlLogger urlLogger = new UrlLogger();
        Method[] methods =  jp.getTarget().getClass().getMethods();
        for ( Method method : methods) {
            if ( method.getName().equals( jp.getSignature().getName()))
            {
                String[] values = method.getAnnotation( RequestMapping.class).value();
                urlLogger.setTargetUrl( values[0]);
            }
        }
        urlLoggerDAO.insert( urlLogger);
    }

더 낳은 방법도 있을 것 같은데..
토비님 책 나오면 다시한번 집중하고 봐야겠다.

추가로..
aspect표현식을 수정 하면. 아래 한줄임!! ..;
@Before(value="execution(* net.study.spring.bbs.controller.*.*(..)) && @annotation(org.springframework.web.bind.annotation.RequestMapping)")

이렇게 된다. controller클래스에 있는 모든 메서드에 걸긴 거는데 거기서 @annotation이 RequestMapping인 것만!!
왜냐.. url로깅이기 때문에 @_@
만약 dao관련 로깅을 하고 싶다면..@Transactional을 하면 되겠죵!!

개인적으로 하면서 햇갈리고 애 먹엇던 내용을 정리 하는 곳.

1. SimpleFormController클래스에서 onSubmit메서드를 override 했는데 submiit을 POST로 날렸는데 onSubmit 메서드를 타지 않는다.
 -> onSubmit 파라미터 중에 BindException 이 java의 것이 아니라 스프링의 import org.springframework.validation.BindException을 사용 하도록 한다.

2. SimpleFormController에서 submit한구 결과 페이지가 표시 되지 않고,
Neither BindingResult nor plain target object for bean name 'commandName' available as request attribute
에러를 뿜어낼 때, formView와 successView의 이름을 다르게 설정 한다. 이 부부은 스펙을 좀 읽어봐야 하겠는데.. -_-;; 너무 귀찮고.. 영어는 어려와~!~!

3. java.lang.IllegalStateException: No WebApplicationContext found: no ContextLoaderListener registered?
이런 오류가 나올 경우.
왜 나왔냐 하면 .jsp 파일에 직접 접근 할 때 스프링 form 태그를 사용할때 발생 하였다.
이것저것 찾아보고, 샘플 파일들에서 설정을 봐보니.

전에는 servlet에서 *-servlet.xml 파일을 로딩하도록 하고 있었으나,
이렇게 하면 안되고 web.xml에서 이런 형식으로 사용을 해야 된다고 한다.

<context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            /WEB-INF/applicationContext.xml
        </param-value>
</context-param>

<listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener
        </listener-class>
</listener>

4. 이클립스 디버깅 안될때.
JDK 버전이 6u14~15는 이클립스에서 디버깅이 잘 안된다.(웹 프로젝트의 경우)
이럴땐 그냥 6u16으로 변경 고고싱 -_-

스프링과 jQuery를 사용하여 파일 업로드 프로그레스바를 구현 하는 방법
업로드 할때 사용하는 CommonsMultipartResolver를 상속해서 리스너를 추가 해준다.

동작 원리는
  1. 파일 업로드, 파일 업로드 진행상황 가져오기(Ajax, 인터벌로 주기적으로 가져오기)
  2. 리스너가 세션에 진행 상황을 기록
  3. 주기적으로 가져온 업로드 진행 상황을 프로그레스바에 기록.
대충 요롷게 돌아 간다.
근대 업로드 끝나도 브라우저가 잠시 멈추는 현상이 발생!!!
크왁!!

왜이렉!!

일단 이거 해결하고
멀티파일 업로드로 바꾸고
좀더 컴포넌트 한 화면으로 변경할 것.