Clean Code that Works.

Spring Rest 사용할 때.

Spring2010. 11. 19. 10:20
Ajax 요청으로 Spring Rest 사용할 때 주의 해야 할 점이 있다.
일단 기본적으로 web.xml에 HiddenHttpMethodFilter는 당연히 설정 해야 되고.

만약에 ajax로 DELETE 요청을 날릴 때(ajax가 아닌 경우 method="DELETE"로 해주면 히든 필드(_method)에 DELETE가 담겨서 처리) 파라미터로 _method:'DELETE'를 같이 포함해서 넘겨 줘야 한다.

또, 주의 할 점이 ajax요청의 경우(jquery) 디폴트 type이 GET 이기 때문에 type : 'POST'로 지정을 해 줘야
HiddenHttpMethodFilter가 이를 인식하고 히든 필드에 담긴 method로 바꿔준다.
url : '${study.id}/board/imagePost/' + $this.attr('id'),
data : {_method: 'DELETE'},
type : 'POST',

HiddenHttpMethodFilter 코드를 보면 아래와 같이 POST로 넘어와야지 wrapper에서 메서드를 변경 해 준다.
@_@

@Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {

        String paramValue = request.getParameter(this.methodParam);
        if ("POST".equals(request.getMethod()) && StringUtils.hasLength(paramValue)) {
            String method = paramValue.toUpperCase(Locale.ENGLISH);
            HttpServletRequest wrapper = new HttpMethodRequestWrapper(request, method);
            filterChain.doFilter(wrapper, response);
        }
        else {
            filterChain.doFilter(request, response);
        }
    }


KSUG 세미나.

Java2010. 11. 17. 18:15
이번 세미나는

알려진 대로 아래 네가지 순서로 진행되었다.
1. 스프링 트러블 슈팅(http://whiteship.me/?p=12783)
2. 리치 도메인 모델
3. 스프링 원 2010(맞나..;)(http://www.ksug.org/116)
4. 스프링 레스트풀 서비스.

가장 괜찮았던 강의는 3번째 강의 였다.
정상혁님이 2010년 10월에 열렸던 SpringOne2GX 2010에 참가 하였던 후기에 대해서 발표를 하셨는데.
전체적으로 스프링이 앞으로 어떻게 나아갈 것인지에 대해서 들을 수 있어서 좋았다.

기선이형이 했던 스프링 트러블 슈팅은..
순순히 다이아몬드를 옥수수로 교환해 주면 유혈 사태는 발생하지 않는다..는 내용만 생각난다. -_-;;

리치 도메인 모델의 경우는
봄싹의 구조가 일단 DDD 스타일로 개발 되어 있기 때문에 발표 내용과 거의 일치한 다고 볼 수 있어서, 이해하기가 쉬었다.
게시판 설계할때도 도메인 모델을 기준으로 해서 만들고 개발 했었는데,
발표 내용 처럼, CRM 카드등을 통한 좀 더 정확한 설계가 필요할 것 같다.

레스트풀 서비스같은 경우는 좀 더 웹 서비스나 그런 쪽에 특화된 강의를 기대 했었는데 그런 부분이 부족해서 약간 아쉬었다.

이번에도 혹시나 책 증정 이벤트를 할까 해서 정신을 뽀짝 차리고 듣고 있었는데, 아쉽게도 없었다. ㅋ_ㅋ

발표 하신분들 준비 하신분들 모두 수고하셨습니다.
다음에도 좋은 강의 부탁 드려요 '-^




GIT 사용자 설정하기.

Java2010. 11. 16. 14:26
이클립스에서 eGit을 사용하는 경우에,
소스 커밋을 할 때 아래와 같이 Author, Commiter가 등록되어 있지 않은 경우.


Window > preperence > team > git > Configuration 에 등록해 준다.


git Config 파일을 열어보면 아래와 같이 변경 되어 있다.
여기서도 수정 해도 됨 @_@

git 명령어로 추가하는 방법도 있는데 기억이...


요건 일반적인 디좌인


이미지 강조 디자인 @_@


2번 하고 비슷

SRP..

Java/이론..2010. 11. 2. 18:49
클린코드 204쪽..

SRP(Single responsibility principle)는 객체 지향 설계에서 더욱 중요한 개념이다. 또한 이해하고 지키기 수월한 개념이기도 하다. 하지만 이상하게도 SRP는 클래스 설계자가 가장 무시하는 규칙 중 하나다. 우리는 수많은 책임을 떠안은 클래스를 꾸준하게 접한다. 왜일까?

소프트웨어를 돌아가게 만드는 활동과 소프트웨어를 깨끗하게 만다는 활동은 완전히 별개다. 우리들 대다수는 두뇌 용량에 한계가 있어 "깨끗하고 체계적인 소프트웨어"보다 "돌아가는 소프트웨어"에 초점을 맞춘다. 전적으로 올바른 태도다. 관심사를 분리하는 작업은 프로그램만이 아니라 프로그래밍 활동에서도 마찬가지로 중요하다.
문제는 우리들 대다수가 프로그램이 돌아가면 일이 끝났다고 여기는 데 있다. "깨끗하고 체계적인 소프트웨어"라는 다음 관심사로 전환하지 않는다. 프로그램으로 되돌아가 만능 클래스를 단일 책임 클래스 여럿으로 분리하는 대신 다음 문제로 넘어가 버린다.

게다가 많은 개발자는 자잘한 단일 책임 클래스가 많아지면 큰 그림을 이해하기 어려워진다고 우려한다. 큰 그림을 이해하려면 이 클래스 저 클래스 수없이 넘나들어야 한다고 걱정한다. 하지만 작은 클래스가 많은 시스템이든 큰 클래스가 몇 개뿐인 시스템이든 돌아가는 부품은 그 수가 비슷하다. 어느 시스템이든 익힐 내용은 그 양이 유사하다. 그러므로 고민할 질문은 다음과 같다. "도구 상자를 어떻게 관리하고 싶은가?" 작은 서랍을 많이 두고서 기능과 이름이 명확한 컴포넌트를 나눠 넣고 싶은가? 아니면 큰 서랍 몇 개를 두고서 모두를 던져 넣고 싶은가?"

규모가 어느 수준에 익르는 시스템은 논리가 많고도 복잡하다. 이런 복잡성을 다루려면 체계적인 정리가 필수적이다. 그래야 개발자가 무엇이 어디에 있는지 찾는다. 그래야 (변경을 가할 때) 직접 영향이 미치는 컴포넌트만 이애하면 충분하다. 큼직한 다목적 클래스 몇 개로 이뤄진 시스템은 (변경을 가할 때) 당장 알 필요가 없는 사실까지 들이밀어 독자를 방해한다.

강조하는 차원에서 한 번 더 말하겠다. 큰 클래스 몇 개가 아니라 작은 클래스 여럿으로 이뤄진 시스템이 더 바람직하다. 작은 클래스는 각각 책임이 하나이며, 변경할 이유가 하나이며, 다른 작은 클래스와 협력해 시스템에 필요한 동작을 수행한다.

처음에 특정 페이지를 열었을 때, 어떤 url을 요청 했는데 권한이 없을 경우,
로그인 하는 페이지로 이동 해야 하는데 url에 jsessionid가 붙엇 url을 못찾는다는 오류가 생긴다.

간단하게 disable-url-rewriting="true"를 http 태그에 설정 해 주면 발생 하지 않는다.
근데 스프링 문서서도 위 내용은 찾을 수 없다.

http://stackoverflow.com/questions/2291236/how-can-i-prevent-spring-security-from-appending-jsessionidxxx-to-login-redirec

여기서 내용을 찾았는데... 뭐 갸내들이 바빠서 문서 업데이트를 못했나 보다 -_-;;

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.

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

켄트 벡의 구현 패턴 을 읽는 중.

사실 한 1년 반전에.. 그때쯤 나왔나? 책 나왔을 때 다 읽었었는데..
기억이 안났다.. ㄱ-...

하여 기억을 되새겨 볼 겸 해서 다시 읽어 보는중...
특히나 컬렉션 프레임워크 부분은...(면접보는데 질문이었다. 대답을 잘 못했음)
충격 먹고 다시 살펴 보았다.  웁스 -_-;;

잘 좀 하자 ㅋ.

스프링에서 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>


jQGrid에서 jsonData 사용할 경우에 일반적으로 아래와 같은 구조로 데이터가 넘어올 것이라 기대한다.
{"page":"1","total":2,"records":"13",
"rows":[{"id":"13","cell":["13","2007-10-06","Client 3","1000.00","0.00","1000.00",null]}]}

다른 부분은 문제가 없는데 rows에 id와 cell정보가 모델 형식과 맞지 않는 경우가 많아서...
List<Post> 형식으로 rows를 구성하고 싶은데, 이를 가공해 줘야 한다는 말씀... 맵 형식으로 해서 id, cell 방식으로..
게다가 cell 에는 키가 없고 값만 줄줄이 들어 있다.

음 하여 나는 이걸 좀 변경하고 싶다.
아래와 같은 형식으로 키 : value 쌍으로.(jackson 컨버터가 이런형식으로 변환 해 준다.)


그럼 어떻게 하면 되는가..

jQGrid 옵션에다가 이것을 추가 하면 된다.

jsonReader 속성을 보면 응답해주는 json의 값들의 키들을 변경해 줄 수 있다.
root, page, total, records 등등

jQGrid는 글번호를 자동 생성 해 준다.(글번호 관련 column 및 row가 필요 없다.)