프로그래밍/Spring Framework 25

추상화, DI

스프링의 3대 핵심 기술 중 "추상화" 라는 것이 있다.. 갑자기 누군가 나에게 추상화에 대해 설명해 보라.. 라고 질문을 한다면 뭐라고 답을 해야할까? 라고 생각을 해보았다. 생각을 해보니, 추상화라는 것은 결국 DI 일 뿐이였다. 예를 하나 들어볼까.. 뭐가 좋을까.. OXM 추상화 를 예로 들어보자 .. 스프링은 OXM 추상화를 제공한다. oxm 기술에는 비슷비슷한 여러가지가 있는데, Castor , JaxB, Xstream 등이 있다. 스프링에선 위 기술들에 대한 추상화 인터페이스로 Unmarshaller 를 제공한다. 그리고 각 기술에 대한 구현체들도 제공한다. 당연히 추상화 인터페이스인 Unmarshaller 를 구현하고 있다. 하여, 개발자는 어떤 OXM 기술을 쓰던 Unmarshaller ..

@ResponseBody , json, jquery 를 이용하여 간단한 검색어 자동완성을 만들어봅시다.

네이버 검색창에서 검색어를 입력하면, 자동완성 된 검색어가 뜨는걸 본 적이 있으실 겁니다. 아래와 같이 말이죠 오늘은 위와 같은 기능을 아~~주 간단한 형태로 만들어 보고자 합니다. 전문적인 검색엔진이나 검색기능에 대한 자료를 참고하시고자 하시는분께서는 잘못 찾아오셨습니다. 위와 같은 기능을 간단히 만들기 위해서 스프링 기반의 웹프로젝트에 JsonConverter 를 등록하고, contentNegotiation 설정을 해준 후, @ResponseBody 와 jquery 의 $.getJSON 을 사용할 것입니다. 디비는 MySQL 을 사용할 것입니다. MySQL 을 사용한 이유는 제가 cloudfoundry를 이용하는데 cloudfoundry 에서 MySQL 을 지원하기 때문입니다 우선 응답을 json 형..

Spring <form:checkboxes> 항목 check

Note For multiple checkboxes, as long as the “path” or “property” value is equal to any of the “checkbox values – ${dynamic-list}“, the matched checkbox will be checked automatically. 위 말이 무슨 뜻인고 하니,,, items 항목과 path 항목의 값이 같으면 자동으로 체크 된다 라는 뜻이다. 간단한 예제를 남긴다.. @RequestMapping(value = "/userlist", method = RequestMethod.GET) public void userlist(@Principal UserDetails userDetails, Model model){ S..

RequestMappingHandlerMapping 의 setDefaultHandler 문제 발견

Spring 3.0 의 DefaultAnnotationHandlerMapping 과 AnnotationMethodHandlerAdapter가 Spring 3.1 에선 @Deprecated 되고, 대신 RequestMappingHandlerMapping과 RequestMappingHandlerAdapter 로 바뀌었다. 이유인즉슨, Controller 의 요청이 메소드 단위로 세분화 되면서 , DefaultAnnotationHandlerMapping 이 AnnotationMethodHandlerAdapter로 handler 를 전달해줄 때, 문제가 생겼기 때문이다 . 문제에 대해 아~~주 간략히 설명하자면 DefaultAnnotationHandlerMapping 은 AnnotationMethodHandle..

DI - strategy pattern, decorator pattern, proxy pattern & AOP

DI 의 끝을 모르겠다 ... DI (Dependency Injection) 는 STRATEGY PATTERN(전략 패턴) 이다.. 스프링 프레임워크의 모든 것의 중심엔 언제나 DI가 있다. DI는 확장 포인트 임과 동시에 DI에 또 다른 패턴을 적용함으로써 동적으로 특정 행동을 추가할 수 도 있고, 변경할 수도 있다. 데코레이터 패턴을 잠깐 생각해보자.. InputStream is = new BufferedReaderInputStream(new FileInputStream()); 이는 일종의 생성자를 이용한 DI라고 이해하면 된다. 생성자를 이용한 DI를 통해 특정 기능을 동적으로 추가해주고 있는 것이다. 프록시 를 살펴보자. class HelloProxy{ Hello hello; public void..

토비의 스프링 느낀점 - 스프링프레임워크 철학에 대해.

토비의 스프링 을 3독째 정독하면서 내가 느낀 점을 간단히 작성한다.. 우선, 이 리뷰는 스프링프레임워크의 기능보다, 개발 철학에 중점을 둔 리뷰임을 밝힌다. 토비의 스프링은 읽으면 읽을수록, 감탄을 자아내게 하는 책이다.. 우선 저자인 이일민 님은 스프링에 대한 깊은 이해 뿐만 아니라, 객체지향적 설계, 테스트주도개발, 리팩토링 뿐만 아니라, 애자일, eXtreme Programming 에도 조예가 깊은 분임을 느낄수 있었다. 책 전반에 걸쳐 객체지향적 설계, 리팩토링, 테스트주도개발 의 중요성에 대해 꾸준히 강조하고 있다. 또한 이 책에는 애자일, eXtreme Programming 개발 방법론에 대해서도 나온다. 딱 애자일, eXtreme Programming 이라고 명시 돼 있진 않지만, 이책의 ..

@Requestmapping produces, @ResponseBody

어떤 요청을 할 때, 응답 형태를 text/html 로 할 수도 있고, application/xml 로 할 수도 있고, application/json 형태로 할 수도 있다. 이런 경우, 지금까지 난 ContentNegotiatingViewResolver 를 통해 ViewResolover와 View를 등록하고 요청 url 끝에 확장자를 붙여서 ContentNegotiatingViewResolver 가 적절한 ViewResolver 를 선택하여 원하는 형태의 View 로 출력하게끔 했었다. 헌데, Model 의 정보를 나타내야할 형태가 고작 html, xml이나 json 을 쓰는게 다 인 경우가 많고, 이런 경우 Model 오브젝트를 xml로 컨버트 해주는 MarshallingHttpMessageConver..

@Cacheable, @CacheEvict

빈번하게 호출돼서 화면에 출력돼야 하는 데이터는 Caching 을 이용하면, 속도가 훨씬 빨라진다.. 아주 간단히 말해, 매번 똑같은 데이터를 굳이 새롭게 호출해야 할 필요 없이 특정 영역에 저장해뒀다가 바로 꺼내쓰는 것이 바로 Caching이다. 스프링에선 역시 Caching을 아주 멋들어지 제공한다. 캐싱 기능을 적용하고 싶은 메소드에 @Cacheable 에노테이션만 붙여주면 이 메소드는 캐싱기능이 적용된다.. @Cacheable 은 여러모로 @Transactional 과 흡사하다.. Manager를 등록해야하는것 마저 동일하다 @Transactional 이 transactionManager를 등록해야하는것과 마찬가지로 @Cacheable 은 cacheManager를 등록해야한다.. @Cacheabl..

MockMvc 파일업로드 테스트

파일 업로드 테스트를 진행 해야하는 상황이 있었다.. 슈퍼맨 같은 MockMvc 에 분명히 있을거란 생각을 했다 ㅎㅎ 찾아보니 역시나 있다. import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.fileUpload; this.mockMvc.perform(fileUpload("/fileupload").file("file", "ABC".getBytes()); 위와 같이 해주면 끝이다.. 너무 심플해서 뭐 딱히 이해도 필요없고, 설명할 것도 없는 듯 하다.

Controller return type void 인 경우,

단순히 model 에 addAttribute 만 하고, jsp 에서 model attribute 를 출력해주고픈 마음에 @RequestMapping(value="/myMethod") public void myMethod(Model model){ model.addAttribute("message", "attribute added"); } 위와 같이 선언을 하면 과연 model에 attribute 만 추가되고 끝일까? 답은 아니오 다. 왜냐하면 스프링에서 자동등록되는 전략 중 RequestToViewNameResolver 를 통해 자동생성되는 뷰 이름이 사용된다.