Whiteship's Note


하이버네이트, 스프링 MVC에서 enum 사용하기 3

분류없음 : 2009.07.03 18:53


1. Character 값을 DB에 저장하는 enum도 지원하도록 구현했고..
2. UserType 생성을 좀 더 간편화 했습니다.

public enum FamillyCate implements PersistentEnum {

    FATHER('f', "부"), MOTHER('m', "모"), BROTHER('b', "형제"), SISTER('s', "자매");
   
    private final Character value;
    private final String descr;
   
    private FamillyCate(Character value, String descr) {
        this.value = value;
        this.descr = descr;
    }
   
    public Character getValue() {
        return value;
    }
    public String getDescr() {
        return descr;
    }
...
}

이렇게.. Character 값을 DB에 저장할 enum을 사용할 수 있습니다. 이 enum에 대한 UserType 생성은 다음과 같습니다.

public class FamillyCateType extends GenericEnumUserType<FamillyCate>{
}

이 enum에 대한 PropertyEditor는?

binder.registerCustomEditor(FamillyCate.class, new GenericEnumPropertyEditor<FamillyCate>(FamillyCate.class));

캬,.. enum에 대한 UserType과 PE를 전부 코드 한 줄로.. 끝낼 수 있습니다. GenericEnumUserType와 GenericEnumPropertyEditor 코드는 비공개입니다. 영원히~

자 그럼 오늘은 이만 하고,, 다음 번엔 enum 목록을 가져올 때 순서를 정해서 가져오는 방법을 마련해보도록 하겠습니다.

ps: 오랜만에 dm 서버나 돌려봐야겠네요. 방명록에 누가 요청하셔서;;
top


PropertyEditor 활용 예제

Spring/Chapter 5 : 2008.11.27 15:46


어제 올린 글에 이어지는 내용으로 스프링이 제공하는 form 태그와 PropertyEditor를 조합하는 방법입니다. PropertyEditor로 할 수 있는 일 중 하나를 스프링 form 태그가 해줍니다. 그게 뭐냐면.. getAsText죠.

<form:checkboxes items="${allRoles}" path="roles" delimiter="<br/>" itemLabel="note"  itemValue="id" /><br/>

여기서 보시면, itemValue에 설정한 id 값을 보고 자바빈 스펙에 따라 getId를 호출하여 해당 값을 각각의 체크박스 아이템의 value로 사용합니다. 편하죠, 대신 다른 반쪽이 없기 때문에 바인딩에러가 발생할 겁니다.

form 태그를 사용하여 값을 바인딩할 속성 roles는 Set<Role> 타입이거든요. id가 실제로는 int 값이지만, 화면에서는 String 값 형태로 전달되겠죠. 그 String 값을 Role 타입으로 캐스팅하려니까 에러가 발생하는 겁니다. 이 에러는 <form:errors path="roles" /> 이런 코드를 화면에 붙여두면 확인할 수 있습니다.

자.. 그럼 어떻게 해야되나요? HttpServletRequest 타입 객체를 메소드 매개변수로 추가해주고 거기서 roles라는 파라미터의 값 빼와서 파싱하고 어쩌구 저쩌구.. @.@ 그렇게 하실건가요? 스프링 2.5 이전 이라면 뭐.. 그럴수도 있겠다 싶지만, 서블릿 API에 의존하지 않은 아주 깔끔한 스프링 2.5 애노테이션 기반 컨트롤러에 저 것 때문에 서블릿 API를 사용할 건가요?? 아니죠. 그러고 싶지 않습니다.

네 그러지 않아도 됩니다. setAsText를 구현한 PropertyEditor를 등록해주면 깔끔하게 해결할 수 있습니다.

public class RolePropertyEditor extends PropertyEditorSupport {

    @Override
    public void setAsText(String text) throws IllegalArgumentException {
        if(!text.isEmpty())
            setValue(new Role(Integer.parseInt(text)));
    }

}

하이버를 사용하고 있으니 불 필요한 쿼리를 날리지 않도록 Fake Association Object를 활용하여 PropertyEditor를 구현합니다. 꼭 실제 객체가 필요하다면 DAO를 이용해서 가져올 수도 있겠죠. OSAF에는 두 종류의 GenericPropertyEditor로 그 두 가지 경우를 모두 지원합니다.

자 그리고 이 프로퍼티에디터를 바인더에 등록해주면 끝납니다.,

   @InitBinder
    public void initBinder(WebDataBinder binder) {
        binder.registerCustomEditor(Role.class, new RolePropertyEditor());
    }

끝~.. 이제 스프링이 Role이라는 도메인 객체를 알아보고 잘 파싱해서 Member의 Set<Role> 타입의 roles라는 속성에다가 잘 설정해 줄 겁니다.


'Spring > Chapter 5' 카테고리의 다른 글

PropertyEditor 활용 예제  (8) 2008.11.27
5. Validation, Data-binding, the BeanWrapper, and PropertyEditors  (0) 2007.03.21
top


스프링 MVC form 태그 써 보셨어요?

Spring/Chapter 13 : 2008.11.26 15:14


귿이에요.

<form:checkboxes items="${allAuthorities}" path="authorities" delimiter="<br/>" itemLabel="name"  itemValue="id" />

단 한 줄로..


저렇게 출력해줍니다. 괜찮죠? EL로 넘겨준 allAuthorities 이 녀석은 List 타입으로 도메인 객체 타입의 객체들을 담고 있죠. 흠... 화면에 보이는 값이 어째 좀 '사용자 비친화적(and 개발자 친화적)'입니다. name 말고 note를 출력하도록 할까요? 아~~주 간단합니다.

<form:checkboxes items="${allAuthorities}" path="authorities" delimiter="<br/>" itemLabel="note"  itemValue="id" />

JSP에서 단어 하나만 바꿔주면 되죠.


짜잔... OSAF의 커스텀 태그는 스프링 form 태그를 기반으로 만들었으며, 정형적인 화면 개발 속도를 극대화 할 수 있도록 만들어 두었습니다.

다음에는 PropertyEditor 활용법을 살펴보겠습니다.
top


8.7. Spring-MVC Integration

Spring DM/Chapter 8 : 2008.06.17 22:00


1.1부터 스프링 DM은 스프링 MVC 프레임워크와 밀접하게 통홥되었다. 이번 섹션에서 어떻게 스프링 MVC 애플리케이션을 OSGi 환경에서 실행할 수 있는지 살펴보겠다.

OSGi 플랫폼에서 제대로 사용되려면, 스프링 MVC를 새로운 환경으로 이전해야 한다. 스프링 DM은 OSGi를 인식하는 application context를 제공한다.(OsgiBundleXmlWebApplicationContext) 이것은 스프링 MVC의 XmlApplicationContext와 동일한 역할을 한다. application context는 웹 애플리케이션 BundleContext를 알고 있고 따라서 OSGi 영역에 있는 자원들을 읽고 OSGi 서비스를 공개하고 BundleContextAware를 지원하고 클래스패스에 포함되어있는 번들들을 컴포넌트스캔할 수 있다.

이 애플리케이션 컨텍스트를 사용하려면 스프링의 ContextLoaderListener의 contextClass라는 파라미터와 DispatcherServlet을 사용하면 된다.

<context-param>
  <param-name>contextClass</param-name>                                                                   (1)
  <param-value>
org.springframework.osgi.web.context.support.OsgiBundleXmlWebApplicationContext
</param-value>    (2)
</context-param>

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

<servlet>
  <servlet-name>petclinic</servlet-name>
  <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>                              (4)
  <load-on-startup>2</load-on-startup>
  <init-param>
    <param-name>contextClass</param-name>                                                             (5)
    <param-value>
org.springframework.osgi.web.context.support.OsgiBundleXmlWebApplicationContext
</param-value>  (2)
  </init-param>
</servlet>

(1) 스프링의 ContextLoaderListner가 최상위 웹 애플리케이션 컨텍스트 타입을 알기 위한
context-param 이름
(2) OSGi를 인식하는 web application context 풀네임
(3) 스프링 설정 읽어들이는 리스너
(4) 스프링 MVC 젤 앞단 컨트롤러
(5) 스프링의 DispatcherServlet이 웹 애플리케이션 컨텍스트 타입을 알기 위한 init-param

위와같이 설정하면,  스프링 DM 번들은 구동중인 BundleContext를 가져다 사용할 수 있으며 OSGi 환경을 인식할 수 있다.

노트

물론 스프링 MVC 애플리케이션에는 적절한 import 문들이 들어가있어야 한다. 즉 WAR도 번들이기 때문에 manifest 파일에 적절하게 설정되어 있지 않으면, 클래스패스가 맞지 않게되고 따라서 제대로 동작하지 않을 것이다.

'Spring DM > Chapter 8' 카테고리의 다른 글

8.7. Spring-MVC Integration  (0) 2008.06.17
8.6. OSGi-ready libraries and web development  (0) 2008.06.17
8.5. Customizing the standard deployers  (0) 2008.06.14
8.4. web extender 설정하기  (0) 2008.06.12
8.3. WAR classpath in OSGi  (0) 2008.06.12
8.2. Web support 사용법  (0) 2008.06.12
8.1. 지원하는 웹 컨테이너  (0) 2008.06.12
Chapter 8. Web Support  (0) 2008.06.12
top