Clean Code that Works.

The main interface of the java collection frameworks.


shows the main interfaces of the Java Collections Framework, together with one otherIterablewhich is outside the Framework but is an essential adjunct to it. Its purpose is as follows:


  • Iterable defines the contract that a class has to fulfill for its instances to be usable with the foreach statement.

  • 기본적인 컬렉션 인터페이스로 순차 열람을 지원

And the Framework interfaces have the following purposes:

  • Collection contains the core functionality required of any collection other than a map. It has no direct concrete implementations; the concrete collection classes all implement one of its subinterfaces as well.

  • Set is a collection, without duplicates, in which order is not significant. SortedSet automatically sorts its elements and returns them in order. NavigableSet extends this, adding methods to find the closest matches to a target element.

  • 중복된 원소가 없는 컬렉션.
  • Queue is a collection designed to accept elements at its tail for processing, yielding them up at its head in the order in which they are to be processed. Its subinterface Deque extends this by allowing elements to be added or removed at both head and tail. Queue and Deque have subinterfaces, BlockingQueue and BlockingDeque respectively, that support concurrent access and allow threads to be blocked, indefinitely or for a maximum time, until the requested operation can be carried out.


  • List is a collection in which order is significant, accommodating duplicate elements.

  • 원소의 순서가 정의 되어 있는 컬렉션.
  • Map is a collection which uses key-value associations to store and retrieve elements. It is extended by ConcurrentMap, which provides support for concurrent access, by SortedMap, which guarantees to return its values in ascending key order, by NavigableMap which extends SortedMap to find the closest matches to a target element, and by ConcurrentNavigableMap which extends ConcurrentMap and NavigableMap.

  • 키-값에 의해 원소를 저장하고 접근하는 컬렉션.

스프링에서 MappingJacksonHttpMessageConverter를 사용할 때
Date 포맷은 json값이 "createdAt":1287041156338 이렇게 들어 온다.

이게 멍미!!
하여 포맷을 정해줘야 하는데...

아주 유용한 블로그를 발견 했다.
how-to-serialize-java-util-date-with-jackson-json-processor-spring-3-0
오우 very good!!

하는 방법은
jackson 요녀석이 시리얼 라이즈를 하는데..
Date형식에 대해서는 특정 시리얼라이저(
JsonDateSerializer)를 정해줘서.
이 녀석을 getDate 하는데다가
@JsonSerialize(using=JsonDateSerializer.class) 이렇게 해주는거다.
JsonSerializer<Date>이것을 상속하여 JsonDateSerializer를 구현해서 사용.

그러면 jackson 이것이 시리얼라이즈를 할 때 저것을 사용하려 시리얼 라이즈를 하게 된다.

쭉 살펴보면..
댓글에도 유용한 답변이 있다.
바로 전역적인 dateformat을 사용할 때는 어떻게 하는가.

이때는
MappingJacksonHttpMessageConverter의 ObjectMapper를 구현하여 set 해주면 된다.
org.codehaus.jackson.map.ObjectMapper를 상속하여 CustomObjectMapper 를 만들고,
CustomObjectMapper클래스 안의 메서드에 @PostConstruct 를 붙여 주고
getSerializationConfig().setDateFormat(new SimpleDateFormat(“yyyy-MM-dd’T'HH:mm:ss.SZ”));
이 스타일로 포맷을 지정해 주면 된다.

그다음엔 스프링 설정에서 빈으로 만들고 MappingJacksonHttpMessageConverter에다가 주입!!

<bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
<property name="objectMapper" ref="CustomObjectMapper" />
</bean>

프로퍼티 에디터 등등...

화면에서 값을 변경해서 보여줄 때는 <form:input>으로 사용하던지,
아니면 <spring:bind> 로 해서 보여줘야 한다. 웁스.

이게 폼에서 보여줄 때 이렇게 하면 되는데,

나는 뷰.... 목록으로 보여줄때 컨버팅을 하고 싶었다.
이렇게 저렇게도 해보고 고민해봤는데 도무지 이해가 안되서 KSUG에 질문을 올렸다.

http://groups.google.com/group/ksug/browse_thread/thread/6f4a94d4485de366

토비님 글에도 설명이 되어 있는데.
http://toby.epril.com/?p=989

<spring:eval> 태그를 사용하면 된다고 한다..conversionService를 사용해서
전체적인 설명은 토비님 블로그에 잘 설명이 되어 있고,
사용하는 방법은 아래와 같이 설정 해 주면된다.

<mvc:annotation-driven conversion-service="conversionService"/>


<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
        <property name="converters">
            <list>
                <bean class="springsprout.common.conversion.converter.TimeToWebStringConverter" />
            </list>
        </property>
</bean>

이렇게 설정 해 주면 화면 <spring:eval>은 ConversionServiceExposingInterceptor이녀석이 가로체서 컨버터를 적용 해 준다.

토비님 책 보면서 이쪽 부분은 아직 안 읽었었는데, Type-Conversion 부분이 폼에서 하는 부분과 리스트등 뷰에서 하는 부분이 햇갈려서 시간을 많이 잡아 먹었다. -_-;;;
그래도 덕분에 컨버터에 대해서 좀 볼 수 있었다. ..;;

참 jsp에서는 <spring:eval expression="meeting.openTime?:''"/>
이렇게 적어 주어야 한다.
spring el 에 대해서 잘 몰라서 .. The Elvis Operator라는 방식이라는데..
뭐 널이면 "" 공백 출력하라는거 같은데.. 이부분은 좀 더 살펴봐야겠다.

저 ConversionServiceExposingInterceptor 이게 어떻게 값 변환하는지 궁금하네.


iBatis 사용할 때, xml파일 수정시 재 로딩을 자동으로 해주는(서버리스타트 없이) jar 파일 이다.
JCF DAO

근데 저걸 사용 하면 myBatis(iBatis와 myBatis 둘 다 사용 중, 공부용이니깐~)가 로깅이 안된다.
jcf dao에서는 slf4j를 사용해서 로깅을 하는데, 요곳 때문에 안되는 듯 하다.

하여
slf4j-log4j12.jar을 사용해서 하면 로깅이 잘 된다~

myBatis도 xml 변경시 자동 감지 되게 할려고 수정 해 봤는데, 약간 다른 면이 있어서..
조금더 시간을 가지고 해보도록 해야 겠다.

아직 spring에서는 myBatis는 정식 지원이 되지 않고, 다른 사람이 만들어 놓은 확장으로 적용해서 사용 하는 중~

http://www.eclipse.org/

새 버전이 릴리즈 되었다!!
이번에는 Helios.. 이전 버전이 뭐였더라. -_-;;
STS쓰니깐 이전 버전을 잊어 버렸다..
표시가 안되!!

아무튼 STS도 버전업이 될까 하고 검색 해 봤더니.
http://forum.springsource.org/showthread.php?p=305641
이번달 말에 릴리즈 될 수 있을 거라고 한다.

뭐 바뀐점들을 보면
http://eclipse.org/helios/blogathon/reviews.php
여기 보면 대충 살펴 볼 수 있다.

써보면 알 수 있겠지 !!!

옥히 글 보고 새버전 나온지 알았삼.http://www.okjsp.pe.kr/seq/153263


http://www.ibm.com/developerworks/kr/library/os-lombok/index.html

자바빈 클래스에서 getter, setter, toString(), hashCode(), equals()를 제거하자.

lombok이 자동으로 생성해준다.

아직 안 써봐서 잘 모르겠고. ㅋㅋㅋ

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 이 아닌 ""을 리턴하도록 변경 하여 처리 하였다.

이클립스에서 f3 누르면 소스를 찾아 가는데, 소스가 없다면 표시가 되지 않는다.

그런데!!
메이븐을 사용하고 있다면, 메이븐이 자동으로 소스코드를 찾아서 다운받은 후, 이것을 이클립스가 표시해준다.
오오..
짱좋은데 -ㅁ-

UrlLogging 화면

Java/Spring2010. 3. 30. 13:05
지금 만들고 있는 UrlLogging 화면, 달력은 jQuery UI Datepicker로 했고
그래프는 jquery Float chart 플러그인으로 사용.


UI 조금 더 수정 하고, 그래프 검색 결과도 수정하면 좀더 볼만 해 질듯.



간단한 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을 하면 되겠죵!!