Spring 2.5 버전서부터 추간된 기능중에 Annotation(어노테이션)의 기능이 있다.
실제로 사용해본결과 이전의 xml에서 설정하여 사용하는것보단 훨씬 개발하기 편해진것은 확실하다.
( 솔찍히 Spring은 이번에 처음 써보는것나 마찮가지다. )
아직 많은 사용법을 모르지만  간단하게 정리를 해보고자 한다.

* 참고로 이문서는 어디까지나 어노테이션의 사용에 대한 것이지 Spring에 기본적인 내용은 필자도 잘아지 못한다.
( 필자도 앞으로 공부해나가야할 부분이다. )
즉, 간단하게 이미 spring 2.5 이전 버전을 쓰시는 분들은 그냥 "어노테이션을 이렇게 쓰는구나" 정도로 이해해 주시고
Spring을 안쓰시다 2.5를 처음 쓰시는 분들은 Spring의 이전 버전도 어느정도 지식을 쌓으시는 것이 좋을것으로 판단 된다.

Spring 2.5( 중에서도 Spring MVC) 에서 annotation을 사용하기 위해서는 dispatcher-servlet.xml 에 다음의 설정을 추가해야한다.
그래야만 어노테이션이 적용된 class( @Controller, @Service, @Repository 를 포함한 class )를 로딩할수가 있다.

- dispatcher-servlet.xml -
<context:component-scan base-package="kr.pe.jabsiri" /> 가존 작성중 틀린것


2009-06-26 수정내용
dispactcher-servlet.xml에는 아래와 같이해서 Controller의 어노테이션만 로딩을 하고
<context:component-scan base-package="com.enz.adnad" use-default-filters="false">	<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"></context:include-filter>
</context:component-scan>
applicationContext.xml에는 아래와 같이해서 Controller를 제외한 어노테이션만 로딩을 해야한다.
<context:component-scan base-package="com.enz.adnad">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"></context:exclude-filter>
</context:component-scan>


아래는 dispactcher-servlet.xml 에 설정하는 ViewResolver 로써 /WEB-INF/spring/ 로 시작하고 .jsp 로 끝나는 파일을 찾아 옵니다.
controller에서 return "hello/hello_jabsiri"; 와 같이 하면 /WEB-INF/spring/hello/hello_jabsiri.jsp 파일을 찾습니다.
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" p:prefix="/WEB-INF/spring/" p:suffix=".jsp">

1. @Controller
위에서 설정한 컴포넌트 스캔을 통하여 로딩된( <bean> tag를 써서 일일이 등록된 class도 )@Controller를 적용한 Class는 DefaultAnnotationHandlerMapping을 통해 컨트롤로 사용된다.
( DefaultAnnotationHandlerMapping을 통해 컨트롤러로 등록이 되는지 어쩐지는 나도 잘 모른다 그냥그렇다고 한다. 즉, 기본적인 Spring에 대한 공부는 각자의 몫이고 필자 또한 나중에 정리를 할 것이다. )

다음은 사용의 예이다.
@Controller
public class HelloJabsiri {
@RequestMapping(value="/hello/hello_jabsiri.jab")
public String helloJabsiri(){
return "hello/hello_jabsiri"; //리턴값은 .jsp 확장자를 뺀 경로
}
}
return 값의 "hello/hello_jabsiri" 는 dispatcher-servlet.xml 에서 정의한viewResolver 의  p:suffix=".jsp" p:prefix="/WEB-INF/spring/" 내용에 해당하는곳에서 jsp를 찾는다.
/WEB-INF/spring/[ return 값].jsp 의 패턴에 해당하는 jsp를 찾는다.

여기서 잠시 주목할 사항은 helloJabsiri() 메소드는 아무런 파라미터도 받지 않는다는 것이다.
맞다 아무것도 안받아도된다.!!
Spring MVC에서 MultiController ( 명칭이 맞나;? )는 파라미터를 받아도되고 않받아도 되고, 받되 순서가 뒤죽 박죽이어도 된다.

다음과 같이 Member bean을 받을수 있는데 이는 html상의 form input type의 id와 Member 객체들의 맴버변수가 같은것을 알아서 매핑시켜 값을 넘겨주기도 한다.

@RequestMapping("member.do")
public String member(Member member, ModelMap modelMap){
modelMap.put("member", member);
return "member/member";
}
이것외에 @RequestParam과 메소드의 파라미터를 받는 방법등은 첨부파일을 받아서 꼭!!! 보길 바란다.


2. @RequestMapping
위의 HelloJabsiri의 Controller에 보면 @RequestMapping(value="/hello/hello_jabsiri.jab") 이 보일 것이다.
이는 @RequestMapping의 value 형태의 url이 들어오면 helloJabsiri method를 호출 하겠다는 것이다.
위의 코드는 다음과 같이 바뀔수 있다.

@Controller
@RequestMapping("/hello/*")
public class HelloJabsiri {
@RequestMapping(value="hello_jabsiri.jab")
public String helloJabsiri(){
return "hello/hello_jabsiri";
}
}

3. @Autowired
@Autowired 어노테이션은 Spring에서 의존관계를 자동으로 설정할때 사용된다.
이 어노테이션은 생성자, 필드, 메서드 세곳에 적용이 가능하다.

아래와 같이 설정해주면 사용할수 있지만 위에서처럼 scan으로 등록했으므로 안해도 된다.
<bean class=org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor />

(필자는 그냥  <context:component-scan base-package="kr.pe.jabsiri" /> 설정후 아무것도 하지 않는다. 뭐 몰라서 그런것도 있다. )

사용 코드는는 다음과 같다.
@Controller
public class HelloJabsiriController {
@Autowired
private HelloJabsiriService helloJabsiriService;
...........
}

@Service("helloJabsiriService")
public class HelloJabsiriServiceImpl implements HelloJabsiriService {
@Autowired
private HelloJabsiriDao helloJabsiriDao;
...........
}
위의 코드는 Controller에서 HelloJabsiriServiceImpl 의 interface인 HelloJabsiriService를 의존관계로 등록 한것이다.
자세히 보면 @Autowired를 적용한 변수명과 @Service 안에있는 String 값이 같다는걸 눈치챌수 있다.

4. @Service("xxxService")
@Service를 적용한 Class는 비지니스 로직이 들어가는 Service로 등록이 된다.
@Service("helloJabsiriService")
public class HelloJabsiriServiceImpl implements HelloJabsiriService {
@Autowired
private HelloJabsiriDao helloJabsiriDao;
public void helloJabsiri() {
System.out.println( "HelloJabsiriServiceImpl :: helloJabsiri()");
helloJabsiriDao.selectHelloJabsiri();
}
}
helloJabsiriDao.selectHelloJabsiri(); 와 같이 @Autowired를 이용한 객체를 이용하여 Dao 객체를 호출한다.

 
5. @Repository("xxxDao")
@Repository를 적용한 Class는 DataBaseAccess를 할수 있는 Dao로 등록된다.
@Repository("helloJabsiriDao")
public class HelloJabsiriDaoImpl implements HelloJabsiriDao {
public void selectHelloJabsiri() {
System.out.println("HelloJabsiriDaoImpl :: selectHelloJabsiri()");
}
}


Controller에 있는 @Autowired는 @Service("xxxService")에 등록된 xxxService와 변수명이 같아야 하며
Service에 있는 @Autowired는 @Repository("xxxDao")에 등로된 xxDao와 변수명이 같아야 한다.



6. @Transactional (이건 추후 작성 하겠음 )

'Program > Java' 카테고리의 다른 글

Spring3.0 @MVC REST  (0) 2009.12.27
Spring MVC - Annotation Base HandlerInterceptor  (0) 2009.12.27
Annotation (since tiger / 1.5)  (0) 2009.12.27
About JAXB  (0) 2009.12.27
StringUtils  (0) 2009.12.22
* Annotation
코드에 관한 데이터를 제공하며, 효용성으로는 문서화, 컴파일러 체크, 코드분석에서 사용한다.

annotation은 데코레이션, 클래스, 인터페이스, 필드에 적용되어 툴과 라이브러리를 활용할 수 있게 함으로써, 코드에 명시적 프로그래밍을 줄이고 좀 더 많은 선언문을 제공한다.   annotation은 프로그램의 의미적인 부분에 직접 영향을 주지 않고, 툴이 프로그램을 어떻게 다루어야 하는지에 알려준다. 툴이 실행 중인 프로그램의 의미적인 부분에 영향을 줄 수 있다.
annotation은 런타임에 소스 파일 또는 클래스 파일 등에서 읽을 수 있다. annotation은 javadoc 태그의 기능을 보안하고 있다. 마크업을 문서 생성시 필요한 정보를 제공하기 위해 사용하고자 할 경우, javadoc 태크 또는 annotation을 사용해야 한다. 일반적으로 어플리케이션 프로그래머는 annotation 타입을 정의하는 경우가 거의 없지만, annotation 타입을 정의하는작업은 어렵지 않다.

  1. 컴파일러가 에러를 탐지하거나 경고등을 무시하는 등등의 용도
  2. 컴파일 또는 설치시에 소프트웨어 도구가 코드, XML 파일 등을 처리하기 위한 용도
  3. 실행시 별도의 처리 루틴이 필요한 경우(실행 루틴 점검 등과 같은)


* Annotation의 종류
  Marker Annotation : 이름으로 구분하기 위하여 사용하며 추가적인 데이터를 필요하지 않음
  Single-Value Annotation : 간단한 신텍스를 사용하며 단일 데이터를 필요로 함
  Full Annotation : 복잡한 신텍스이며, 다중 데이터를 사용하며 name=value 형태를 취함
   --> 데이터가 Array 인 경우 "{ }"를 이용


* Annotation Type의 정의
  1. Annotation 타입 선언은 인터페이스를 선언하는 방법과 유사하다.
  2. Annotation 타입 선언 시에는 interface 키워드 앞에 @ 기호를 붙인다.
  3. 메소드는 파라메터를 가질 수 없다.
  4. 메소드는 throws 절을 가질 수 없다.
  5. 메소드의 리턴 타입 : 프리미티브(Primitive), String, Class, 열거형(Enum), annotation, 앞에서 열거한 타입들의 배열
  6. 메소드는 기본값(Default Value)를 가질 수 있다.


* 기본 Annotation
  @Deprecated : 더 이상 사용하지 말아야할 메소드를 알림 (비추천 메소드)
  @Documented
  @Retention(RetentionPolicy.RUNTIME)
  public @interface Deprecated {

   }

  @Override : 상위 요소를 오버라이드 할 것임을 알림
  @Target(ElementType.METHOD)
  @Retention(RetentionPolicy.SOURCE)
   public @interface Override {

   }


  @SuppressWarnings : 경고를 하지 않도록 억제 시킴
     - unchecked : 비확인
     - deprecate : 비사용


   @Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
   @Retention(RetentionPolicy.SOURCE)
   public @interface SuppressWarnings {
       String[] value();
   }



* Built-in Annotation
  Target : Annotation의 대상을 무엇으로 할 것인지를 기록 (CONSTRUCTOR, FIELD, METHOD, PACKAGE, ...)
   - ANNOTATION_TYPE : annotation 타입(Annotation Type)선언
    - CONSTRUCTOR : 생성자 함수 선언
    - FIELD : 필드 선언(enum 상수 포함)
   - LOCAL_VARIABLE : 로컬 변수 선언
    - METHOD : 메소드 선언
    - PACKAGE : package 선언
    - PARAMETER : parameter 선언
    - TYPE : 클래스, 인터페이스 (annotation타입(AnnotationType)포함), enum선언


   @Documented
   @Retention(RetentionPolicy.RUNTIME)
   @Target(ElementType.ANNOTATION_TYPE)
   public @interface Target {
       ElementType[] value();
   }


  Retention : 어느 과정에서 Annotation을 사용할 것인지를 기록 (여러개의 값 중 선택 가능) (SOURCE, CLASS, RUNTIME)
   - SOURCE : 소스파일에서만 사용하며 컴파일 이후는 사용하지 않음
    - CLASS : 컴파일 과정까지 사용하며 Runtime에서는 사용하지 않음
    - RUNTIME : Runtime에서까지 사용함


   @Documented
   @Retention(RetentionPolicy.RUNTIME)
   @Target(ElementType.ANNOTATION_TYPE)
   public @interface Retention {
      RetentionPolicy value();
   }

  Documented : Javadoc에 포함(문서화)되어야 함을 알리는 Marker Annotation

   @Documented
   @Retention(RetentionPolicy.RUNTIME)
   @Target(ElementType.ANNOTATION_TYPE)
   public @interface Documented {
   }


  Inherited : 하위 클래스에 상속되어야 함을 알리는 Marker Annotation

   @Documented
   @Retention(RetentionPolicy.RUNTIME)
   @Target(ElementType.ANNOTATION_TYPE)
   public @interface Inherited {

   }



* Custom Annotation
  개발자가 정의하는 어노테이션으로 class 형태로 만들어진다. 어노테이션의 선언은 @interface 로 한다.
  이름 앞에 '@'문자가 오는 것 외에는 기본적으로 인터페이스를 선언하는 것과 동일(메소드들의 내용은 없고 형태만 선언)하다.
  default 가 찍히지 않은 메소드는 필수로 입력해야 한다

   @Retention(RetentionPolicy.RUNTIME)
   public @interface Maker {
       int num();
       String id();
       String name();
       String date() default "unsigned";
   }


   @Maker(num=1, id="dryang", name="junsun.yang")
   public class UseMaker {
        ...
   }

'Program > Java' 카테고리의 다른 글

Spring MVC - Annotation Base HandlerInterceptor  (0) 2009.12.27
Spring MVC Annotation 기초  (2) 2009.12.27
About JAXB  (0) 2009.12.27
StringUtils  (0) 2009.12.22
Annotation (since tiger / 1.5)  (0) 2009.12.15
Java Architecture for XML Binding (JAXB)
번역 : 이원찬

Ed Ort and Bhakti Mehta


이 기사는 다음의 주제들을 다룰것입니다.

- JAXB란 무엇인가?
- 예제1 : XML문서 접근
- 스키마 바인딩
- 다큐먼트 언마샬
- 예제2 : XML문서 생성
- 스키마 바인딩
- 내용트리 작성
- 내용트리 마샬
- 예제3 : XML문서 갱신
- 바인딩 커스터마이징
- 별도의 잇점
- 예제 실행

What's JAXB?

Extensable Markup Language(XML)과 자바기술은 개발자가 인터넷을 통해 데이터와 프로그램의 교환을 돕는 자연스러운 파트너이다. 이것은 XML이 이기종 시스템들과 데이터를 교환하기 위한 표준으로 부상했으며 자바기술은 포터블 어플리케이션 플랫폼을 제공하기 때문이다. 이러한 파트너쉽은 특히 웹서비스에 대해 매우 중요하다. 이것은 사용자와 어플리케이션 개발자의 요구에 따른 프로그램의 기능을 어디서, 어디로든지(from anywhere to anywhere) 웹상에서 제공할 수 있다. XML과 자바기술은 웹서비스와 어플리케이션을 구현하기 위한 이상적인 도구로 인정받고 있다.

그러나 실제 이 둘을 어떨게 조합할 것인가? 더 구체적으로 말하자면 어떻게 자바 프로그램으로 XML문서(이것은 XML태그 데이터를 포함한 파일을 말한다) 에 접근하고 이를 이용할 것인가 하는것이다. 이를 구현하기 위한 가장 보편화된 방법중의 하나는 Simple API for XML(SAX)나 Document Object Model(DOM)과 같은 파서의 도움을 받는것이다. 이 파서들은 Java API for XML Processing(JAXP)에 포함되어 제공된다. 자바 개발자는 어플리케이션에서 JAXP API를 통해 SAX나 DOM을 호출하여 파싱된 데이터(이것은 문서를 스캔하고 논리적으로 여러개의 조각으로 나누는것이다.) 를 얻을 수 있다. 파싱된 데이터는 어플리케이션 이용될 수 있다. SAX의 경우는 파서가 문서의 시작점에서 시작된다. 그리고 문서의 각 부분을 순차적으로 어플리케이션에 전달한다. 메모리에는 아무것도 남기지 않는다. 어플리케이션은 파서로부터 데이터를 받을때에는 어떤 액션을 취할 수 있지만 어떤 데이터도 메모리상에 두고 취급 할 수 없다. 예를들어 이것은 데이터를 메모리상에서 갱신하고 갱신된 데이터를 XML파일로 리턴할 수 없다.

DOM접근법으로, 파서는 객체의 트리를 생성한다. 이 트리는 문서상에 존재하는 컨텐츠와 데이터의 정렬을 그대로 표현한다. 이 경우 트리는 메모리상에 존재한다. 어플리케이션은 트리를 이용해 필요한 데이터에 접근하고 적절한 연산을 수행한다.

지금 개발자들은 XML문서를 더 쉽게 이용한 수 있는 또다른 자바API를 만났다.(Java Architecture for XML Binding(JAXB)). 이 API에 대한 구현은 지금 Java Web Services Developer Pack v.1.1(또는 그 이상 버젼)에서 구할 수 있다.

이제부터 실제 JAXB가 어떻게 행동하는지, SAX와 DBM기반 처리와 비교해 보겠다.

An Example : Accessing an XML Document

당신은 books.xml과 같은 XML문서를 접근하고 출력하는 자바 어플리케이션을 개발할 필요가 있다. 이 문서는 책이름, 저자, 요약설명, ISBN과 같은 책에 관한 데이터를 포함하고 있다. 당신은 SAX 또는 DOM으로 XML문서에 접근하여 데이터를 출력할 수 있다. 예를들어, SAX를 사용한다면 다음과 같은 절차를 따르게된다:

먼저 SAX파서를 생성하는 프로그램을 작성하고 그 파서로 XML문서를 파싱한다. SAX파서는 문서의 처음부터 시작한다. 파서가 XML문서의 시작을 알리는 태그와 같은 특정 신호를 받았을때(SAX용어로, 이벤트라 한다) 호출한 프로그램은 해당 데이터를 이용할 수 있다.

컨텐트 핸들러를 생성하라. 이 핸들러는 이벤트가 발생할때마다 파서에 의해 호출되는 메소드를 정의한다. 이러한 콜백 메소드들은 데이터를 받을때 주로 적절한 액션을 수행한다.

예를들어, 여기 JAXP를 이용하여 XML문서를 파싱하고 생성하는 프로그램이 있다. 프로그램은 MyContentHandler라는 컨텐트핸들러를 이용한다. 이 핸들러는 SAX파서를 이용해 전달받은 데이터를 출력한다.

이제 JAXB를 이용하여 어떻게 books.xml과 같은 XML문서를 처리하고 데이터를 출력하는지 살펴보자. JAXB를 이용하여 당신은 다음과 같은 일을 할 수 있다:

* XML문서를 위한 스키마를 바인딩한다.
* 문서를 언마샬하여 자바 객체로 컨텐츠를 생성한다. 자바객체는 컨텐츠를 표현하고 XML문서형태로 정리된다. 이것은 당신의 프로그램에서 직접 이용할 수 있다.

마샬링이 끝나고 프로그램은 XML문서상에 있는 데이터에 접근하고 출력할 수 있다. 이것은 자바 컨텐츠 객체에 접근하여 손쉽게 출력된다. 여기에는 파서를 생성하고나 이용하지 않는다. 그리고, 컨텐츠 핸들러나 콜백 메소드도 사용되지 않는다. 이것은 개발자가 XML또는 XML처리에 대해 알지 못하여도 XML데이터를 처리할 수 있다는 것을 의미한다.

Bind the Schema

JAXB는 XML문서를 자바형식의 프로그램으로 표현하여 자바 프로그램으로 부터 XML문서에 대한 접근을 손쉽게 한다. 이를 위한 첫번째 단계는 XML문서에 해당하는 스키마를 이와 상응하는 자바클래스들로 바인딩 하는것이다.

Schema: 스키마는 XML스펙이다. 이것은 XML문서에 허용가능한 컴퍼넌트화 컴퍼넌트간의 관계를 관리한다. 예를들어, 스키마는 각 요소(element)들을 구분한다. 그것은 XML문서에 표현된다. 이것이 반드시 어떤 순서로 보여져야 한다거나, 어떤 속성(attribute)을 가질 수 있는지, 어떤 요소가 다른 요소로 확장되는지 구분한다. XML문서는 반드시 XML스키마를 가질 필요는 없다. 스키마가 정확한 XML문서 형태를 갖추었는지 확인 하는 절차가 필요하다. JAXB는 당신이 접근하고자 하는 XML문서는 스키마를 가지고 있다. 이 스키마는 W3C XML Schema Language오 생성되었다.

이 예를 가정해 보자. books.xml문서는 books.xsd라는 W3C XML Schema를 가지고 있다. 이 스키마는 이라는 이름의 컴플렉스타입의 요소를 정의한다. 이것은 이 요소가 자식요소를 가진다는 것을 의미한다. 이 경우 요소이다. 각 요소는 , , 등과 같은 자식요소를 가지고 있다.

바인딩: 스키마를 바인딩한다는 말은 스키마를 표현하는 자바 클래스의 집합을 생성한다는 의미이다. 모든 JAXB구현은 바인딩 컴파일러라 불리는 스키마를 바인딩하기 위한 도구를 제공한다. (바인딩 컴파일러의 사용법은 각기 구현에 따라 다르다) 예를들어, JAXB레퍼런스 구현은 스크립트롤 통해 호출되는 바인딩 컴파일러를 제공한다. 당신이 books.xsd 스키마를 JAXB레퍼런스 구현에서 제공하는 바인딩 컴파일러를 이용하여 바인딩 하기를 원한다고 가정하자. 당신이 솔라리스 운영체제 환경에 있다면 당신은 스키마를 바인딩하기 위해 다음과 같이 스크립트를 이용할 수 있다.

xjc.sh -p test.jaxb books.xsd -d work

-p 옵션은 생성된 클래스를 위한 패키지를 구분하고 -d 옵션은 클래스가 저장될 디렉토리를 구분한다. 이 명령으로 클래스들은 test.jaxb. 라고 work 디렉토리 아래에 패키지된다.

바인딩 컴파일러는 인터페이스 집합과 그 인터페이스를 구현하는 클래스들을 생성할 책임을 가지고 있다. 다음은 books.xsd 스키마를 위해 생성된 인터페이스들이다:

- CollectionType.java 요소의 (unnamed)Complex type을 나타낸다.
- Collection.java 요소를 나타낸다.
- BookType.java BookType Complex type을 나타낸다.
- ObjectFactory.java 인터페이스의 인스턴스를 생성하기위한 메소드들을 가지고있다.

다음의 클래스들은 인터페이스를 구현한다. (이 구현들은 impl서브디렉토리에 생성된다.) 이 클래스들은 구현중심이라는 것을 명심하라. 클래스들은 구현 중심이므로 하나의 JAXB구현에서 바인딩 컴파일러에 의해 생성된 클래스들은 또다른 JAXB구현에 대해서는 재대로 작동하지 않을 것이다. 그러므로, 다른 JAXB를 구현하기 위해서는 스키마를 바인딩 컴파일러와 함께 다시 재바인딩 해주어야 한다.

- impl/CollectionTypeImpl.java CollectionType.java에 기술된 CollectionType인터페이스를 구현한다.
- impl/CollectionImpl.java Collection.java에 기술된 Collection을 구현한다.
- impl/BookTypeImpl.java BookType.java에 기술된 BookType을 구현한다.

This compiles all of the interfaces and classes in the test.jaxb package generated by the binding compiler.

생성된 모든 클래스들은 book.xsd스키마 전체를 나타낸다. 클래스의 get과 set메소드는 스키마에 명시된 요소와 속성의 타입에 따라 데이터를 넣거나 가져오는데 사용된다.

이제 당신은 생성된 인터페이스와 클래스들을 컴파일 할 수 있다. 예를들어 :

javac test/jaxb/*.java test/jaxb/impl/*.java

이 컴파일은 test.jaxb 패키지에 포함된 모든 클래스들과 인터페이스를 컴파일 한다.

Unmarshal the Document

XML문서를 언마샬 하는것은 컨텐츠객체의 트리를 생성하는 것이다. 이것은 문서의 컨텐츠와 구성을 표현한다. 컨텐츠 트리는 DOM기반의 트리가 아니다. 사실, JAXB를 통해 생성된 컨텐츠 트리는 DOM기반 트리에 비해 더 효율적으로 메모리를 사용한다.

컨텐츠 객체는 바인딩 컴파일러에 의해 컴파일된 클래스들의 인스턴스들이다. 바인딩 컴파일러 외에 JAXB구현은 마샬링과 같은 JAXB와 관현된 구현 런타임API를 제공해야만 한다. API들은 바인딩 프레임웍의 부분으로 제공된다. 바인딩 프레임웍은 세개의 패키지로 구성된다. 기본패키지인 javax.xml.bind 는 마샬링, 언마샬링, 확인(validation)과 같은 기능을 수행한다. 두번째로 javax.xml.bind.util 패키지는 많은 유틸리티 클래스들을 포함한다. 세번째로 javax.xml.bind.helper 패키지는 JAXB구현 제공자(priovider)를 위해 설계되었다. (역자주: JAXB implementation provider는 바인딩 컴파일러로 생성된 JAXB implementation을 말한다)

XML문서를 언마샬하기 위해서는:

- JAXBContext 객체를 생성한다. 이 객체는 JAXB API의 엔트리포인트를 제공한다. 객체를 생성할때는 컨텍스트경로를 명시하여야 한다. 이것은 바인딩 컴파일러에 의해 생성된 인터페이스를 포함한 하나 또는 그 이상의 패키지명의 목록이다. 컨텍스트경로에 여러개의 패키지명을 허용함으로써 JAXB는 서로다른 스키마의 XML데이터요소 조합을 언마샬할 수 있도록 지원한다.

예를들어 다음의 코드는 컨텍스트경로가 test.jaxb인 JAXBContext객체를 생성한다. 이 패키지는 books.xsd스키마를 위한 인터페이스를 포함한다.

import javax.xml.bind.JAXBContext;

JAXBContext jc = JAXBContext.newInstance("test.jaxb");

- 언마샬객체는 언마샬링과정을 제어한다. 이것은 실질적인 언마샬명령을 수행사는 메소드를 포함한다. 예를들어, 다음의 코드는 Unmarshaller 객체를 생성한다.

Import javax.xml.bind.Unmarshaller;

Unmarshaller unmarshaller = jc.createUnmarshaller();

- unmarshal 메소드를 호출하면 실질적인 XML문서의 엄마샬링을 한다. 예를들어 다음의 문장은 books.xml파일의 XML데이터를 언마샬한다.

Collection collection = (Collection)unmarshaller.unmarshal(new File(“books.xml”));

(주의) 여기서 Collection은 java.util.Collection이 아니라 test.jaxb.Collection 이다.

- 스키마에서 파생된 클래스의 get메소드의 사용은 XML데이터에 접근할수있게 한다. JAXB컴파일러가 생성한 클래스는 해당 스키마의 각 속성타입 또는 요소의 데이터를 획득하거나 기술할 수 있는 get, set메소드를 포함하고 있다. 예를들어, 다음의 문장은 books와 book요소의 데이터를 가져온다.

CollectionType.BooksType booksType = collection.getBooks();
List bookList = booksType.getBook();

데이터를 획득한 다음에는 프로그램상에서 직접 이것을 출력할 수 있다. 여기 books.xml파일의 데이터를 언마샬 하고 화면에 출력하는 프로그램 예제가 있다. 이 프로그램을 실행하면 다음의 결과를 보게 될 것이다.

Book details
Item id: 999
Book Name: Learning JAXB
Book ISBN: 123445
Book Price: 34 $
Book category: other
Book promotion: 10% on this book if purchased by March 2003
No of Authors 1
Author Name Jane Doe

Book details
Item id: 129
Book Name: Java Webservices today and Beyond
Book ISBN: 522965
Book Price: 29 $
Book category: magazine
Book promotion: Buy one get Learning webservices Part 1 free
No of Authors 2
Author Name John Brown
Author Name Peter T.

원본데이터의 확인 : 프로그램이 다음의 문장을 포함하고 있는지 확인하라.

unmarshaller.setValidating(true);

이 문장은 JAXB의 중요한 기능을 보여준다: 원본데이터의 무결성 검사는 스키마를 이용해 언마샬과정의 일부로 확인될 수 있다. 이경우, JAXB에게 원본데이터의 무결성을 검사할것인지 묻게된다. 만약 데이터에 문제가 발견되면 JAXB구현은 이것을 기록하거나 다른 행동을 취할 수 있다. JAXB는 여기에 매우 많은 유연성을 제공한다. JAXB스펙은 에러가 발생하였을 시 모든 제공자(Provider)가 validation 에러를 남기도록 명시하고 있다. 그러나, 구현(implementation)은 데이터의 처리를 멈추지 않아도 된다. 어떤 제공자는 첫번째 오류가 발생시 실행을 멈출것이고, 어떤 제공자는 매우 많은 에러가 발견되어도 멈추지 않을 것이다. 다시말해, 이것은 JAXB구현이 올바르지않은 XML문서도 성공적으로 언마샬 하고 자바객체트리를 생성할 수 있음을 말한다. 그러나, 결과는 바뀌지 않을 것이다. 모든 JAXB구현에게 핵심적으로 요구되는 기능은 정상적인 문서를 언마샬 할 수 있는것이다.

당신이 이러한 validation작업을 과부하(Overhead)라고 생각한다면 이러한 validating작업을 언제든지 끌수도 있다.

다른 소스의 언마샬링: 앞서본 예제가 파일로 저장된 XML데이터를 어떻게 언마샬하는지 설명하였지만 이것은 파일 뿐만이 아니라 InputStream객체나 URL, DOM노드와 같은 다른 소스도 언마샬할 수 있다. 예를들어, javax.xml.transform.sax.SAXSource객체는 언마샬할 수 있다. SAX이벤트도 언마샬 할 수 있다. 다시말해, 당신은 다큐먼트의 SAX파싱을 하고 이벤트를 JAXB에 전달하여 언마샬을 할 수 있다.

언마샬링을 하지않고 데이터 다루기: JAXB는 언마샬을 하지 않고도 XML데이터를 다룰수 있도록 한다. 스키마로부터 생성된 클래스들중에 ObjectFactory라는 클래스가 있다. 이것은 각 스키마에서 파생된 인터페이스와 클래스의 객체를 생성하는 메소드를 가지고 있다. 예를들어, books.xsd를 위해 생성된 패키지에는 ObjectFactory클래스가 있고 이 클래스는 createCollection이라는 Collection객체를 생성하기 위한 메소드가 있고 createBookType은 BookType객체를 생성한다. 이 메소드들은 어떤 언마샬과정을 거치지 않고 컨텐츠객체의 트리를 생성할 수 있게 한다. 이런 객체를 생성한 뒤에 컨텐츠를 삽입하기 위해서는 각 객체의 set메소드를 이용하면 된다.

또 다른 예제: XML문서 구축

당신은 XML문서데이터를 직접 제어하는것 보다 자바 어플리케이션을 통해 제어하는것을 필요로 할것이다. 여기 JAXB를 이용한 쉬운예가 있다.

XML문서를 생성하기 위해 DOM식의 접근법을 사용하였을 것이다. 이것은 당신이 문서의 내용을 메모리상에서 생성할 필요가 있기 때문이다. 반면에 SAX는 메모리상에서 데이터를 생성하는 작업을 허용하지 않는다. DOM식의 접근법을 이용할때, 프로그램은 문서를 생성하기 위해 DOM객체와 메소드를 생성하고 사용하게 된다. DOM은 데이터를 정렬하여 트리객체처럼 보여주도록 설계되었다. 당신의 프로그램이 Document 객체의 메소드를 사용하면 트리의 노드와 같은 다른 객체를 생성해 낼 수 있다. 각 노드는 XML문서의 내용을 포함하고 있다. 당신은 트리의 정렬순서에 따라 노드를 추가할 수 있다. 다시말해, DOM객체의 메소드는 루트노드를 만들거나 그 루트노드를 Document객체에 추가한다.

'Program > Java' 카테고리의 다른 글

Spring MVC Annotation 기초  (2) 2009.12.27
Annotation (since tiger / 1.5)  (0) 2009.12.27
StringUtils  (0) 2009.12.22
Annotation (since tiger / 1.5)  (0) 2009.12.15
XML 파싱  (0) 2009.12.15
Commons-Lang
IV. org.apache.commons.lang.StringUtils
java api의 String을 보면 문자열 처리하기에는 제공하는 기능들이 너무 빈약합니다.
그래서 프로그래머들은 자기 나름데로의 독특한 Utils를 만들어 사용하지요.
하지만 Commons-lang에서 제공하는 StringUtils를 사용한다면 더이상 자신만의 Utils를 사용할 필요가 없습니다. 여기 모두 ㄷ ㅏ ~ 있기 때문이지요 ^^
한가지 더 장점이 있다면 String의 null 값때문에 더이상 NullPointerException을 생각하지 않아도 된다는 것입니다. StringUtils에서 ㄷ ㅏ ~ 알아서 해주기 때문입니다.
그럼 어떠한 기능들의 함수가 있는지 알아봅시다
반환값 함수명 파라미터
String abbreviate String str, int maxWidth
"…"를 포함한 지정한 사이즈로 문자열을 축소한다 maxWidth은 4보다 커야한다
String abbreviate String str, int offset, int maxWidth
"…"를 포함한 지정한 사이즈로 문자열을 앞/뒤로 축소한다 offset은 7보다 커야한다
String capitalise String str
deprecated
String capitaliseAllWords String str
deprecated
String capitalize String str
문자열중 첫번째 문자를 대문자로 만든다
String center String str, int size
str의 길이가 size가 되도록 문자열 좌우에 공백문자를 하나씩 추가한다 (우측부터 시작한다)
String center String str, int size, char padChar
str의 길이가 size가 되도록 문자열 좌우에 padChar를 하나씩 추가한다 (우측부터 시작한다)
String center String str, int size, String padStr
str의 길이가 size가 되도록 문자열 좌우에 padStr을 하나씩 추가한다 (우측부터 시작한다)
String chomp String str
문자열 맨 끝에있는 'n' , 'r', 'rn'을 제거한다
String chomp String str, String separator
문자열 맨 끝에 separator가 있으면 이를 제거한다
String chompLast String str
deprecated
String chompLast String str, String sep
deprecated
String chop String str
문자열 맨 끝에있는 문자 하나를 제거한다
String chopNewline String str
deprecated
String clean String str
deprecated
String concatenate Object array[]
deprecated
boolean contains String str, char searchChar
str이 searchChar를 포함하고 있으면 true
boolean contains String str, String searchStr
str이 searchStr을 포함하고 있으면 true
boolean containsNone String str, char invalidChars[]
str이 invalidChars의 각 문자를 모두 포함하고 있지 않으면 true
boolean containsNone String str, String invalidChars
str이 invalidChars를 모두 포함하고 있지 않으면 true
boolean containsOnly String str, char valid[]
str이 valid의 각 문자들만 포함하고 있어야 true
boolean containsOnly String str, String validChars
str이 validChars 들만을 포함하고 있어야 true
int countMatches String str, String sub
str중에 sub가 포함되어있는 갯수를 반환한다
String defaultString String str
str이 null이면 ""를 반환하고 아니면 str을 반환한다
String defaultString String str, String defaultStr
str이 null이면 defaultStr을 반환하고 아니면 str을 반환한다
String deleteSpaces String str
deprecated
String deleteWhitespace String str
문자열중 공백문자가 있으면 모두 제거한다
String difference String str1, String str2
str1과 str2를 비교하여 다른부분을 반환한다 (str2의 부분을 반환)
boolean equals String str1, String str2
str1이 null이면 str2가 null인지 유무를 반환하고 str1이 null이 아니면 str1과 str2의 equals를 반환
boolean equalsIgnoreCase String str1, String str2
equals와 동일하며 대소문자를 무시하고 비교한다
String escape String str
deprecated
String getChomp String str, String sep
deprecated
String getNestedString String str, String tag
deprecated
String getNestedString String str, String open, String close
deprecated
String getPrechomp String str, String sep
deprecated
int indexOf String str, char searchChar
str에서 첫번째 searchChar의 인덱스를 반환한다
int indexOf String str, char searchChar, int startPos
str의 startPos 인덱스부터 첫번째 searchChar의 인덱스를 반환한다
int indexOf String str, String searchStr
str에서 첫번째 searchStr의 인덱스를 반환한다
int indexOf String str, String searchStr, int startPos
str의 startPos 인덱스로부터 첫번째 searchStr의 인덱스를 반환한다
int indexOfAny String str, char searchChars[]
str에서 searchChars중 포함하고 있는 문자의 첫번째 인덱스를 반환한다
int indexOfAny String str String searchChars
str에서 searchChars중 포함하고 있는 문자열의 첫번째 인덱스를 반환한다
int indexOfAny String str, String searchStrs[]
str에서 searchStr중 포함하고 잇는 문자열의 첫번째 인덱스를 반환한다
int indexOfAnyBut String str char searchChars[]
str에서 searchChars중 포함되지 않은 문자 첫번째 인덱스를 반환한다
int indexOfAnyBut String str, String searchChars
str에서 searchChars중 포함되지 않은 문자 첫번째 인덱스를 반환한다
int indexOfDifference String str1, String str2
str1과 str2를 비교하여 문자열이 틀려지기 시작하는 인덱스를 반환한다
boolean isAlpha String str
문자열이 모두 Character.isLetter 이면 true (모두 문자이면 true)
boolean isAlphanumeric String str
문자열이 모두 Character.isLetterOrDigit 이면 true (문자거나 숫자이면 true)
boolean isAlphanumericSpace String str
문자열이 모두 Character.isLetterOrDigit 이거나 공백이면 true
boolean isAlphaSpace String str
문자열이 모두 Character.isLetter 이거나 공백문자이면 true
boolean isBlank String str
문자열이 공백문자이거나 길이가 0이거나 null인경우 true
boolean isEmpty String str
문자열이 길이가 0이거나 null인경우 true
boolean isNotBlank String str
문자열이 공백문자도 아니고 길이가 0도 아니고 null도 아니면 true
boolean isNotEmpty String str
문자열이 길이가 0이 아니고 null도 아니면 true
boolean isNumeric String str
문자열이 모두 Character.isDigit 이면 true (모두 숫자이면 true)
boolean isNumericSpace String str
문자열이 모두 Character.isDigit 이거나 공백문자이면 true
boolean isWhitespace String str
문자열이 모두 Character.isWhitespace 이면 true (모두 공백이면 true)
String join Object array[]
array에서 문자열을 읽어와 모두 연결시킨다
String join Object array[], char separator
array에서 문자열을 읽어와 separator를 구분자로 연결시킨다
String join Object array[], String separator
array에서 문자열을 읽어와 separator를 구분자로 연결시킨다
String join Iterator iterator, char separator
iterator에서 문자열을 읽어와 separator를 구분자로 연결시킨다
String join Iterator iterator, String separator
iterator에서 문자열을 읽어와 separator를 구분자로 연결시킨다
int lastIndexOf String str, char searchChar
str에서 마지막 searchChar의 인덱스를 반환한다
int lastIndexOf String str, char searchChar, int startPos
str의 startPos 인덱스부터 마지막 searchChar의 인덱스를 반환한다
int lastIndexOf String str, String searchStr
str에서 마지막 searchStr의 인덱스를 반환한다
int lastIndexOf String str, String searchStr, int startPos
str의 startPos 인덱스부터 마지막 searchStr의 인덱스를 반환한다
int lastIndexOfAny String str, String searchStrs[]
str에서 searchStr의 문자열들중 포함하고 있는 문자열의 마지막 인덱스를 반환한다
String left String str, int len
str의 좌측에서 len 길이만큼 문자열을 구한다
String leftPad String str, int size
str의 길이가 size가 되도록 문자열 왼쪽에 ' '을 추가한다
String leftPad String str, int size, char padChar
str의 길이가 size가 되도록 문자열 왼쪽에 padChar를 추가한다
String leftPad String str, int size, String padStr
str의 길이가 size가 되도록 문자열 왼쪽에 padStr을 추가한다
String lowerCase String str
str을 소문자로 변환한다
String mid String str, int pos, int len
str의 pos 인덱스부터 len 길이만큼의 문자열을 구한다
String overlay String str, String overlay, int start, int end
str의 start부터 end까지overlay로 변환한다
String overlayString String text, String overlay, int start, int end
deprecated
String prechomp String str, String sep
deprecated
String repeat String str, int repeat
str을 repeat만큼 반복하여 반환한다
String replace String text, String repl, String width
text에서 모든 repl을 width로 변환한다
String replace String text, String repl, String width, int max
text에서 모든 repl을 width로 변환하는데 최대 max개만큼 변환한다
String replaceChars String str, char searchChar, char replaceChar
str에서 searchChar를 replaceChar로 모두 변환한다
String replaceChars String str, String searchChars, String replaceChars
str에서 searchChars를 replaceChars로 모두 변환한다
String replaceOne String text, String repl, String width
text에서 repl를 width로 변환하는데 첫번째 하나만 변환한다
String reverse String str
문자열을 앞뒤 순서를 바꾼다
String reverseDelimited String str, char separatorChar
separatorChar를 구분으로 문자열을 나눈 후 나눠진 단어들을 역순으로 바꾼다
String reverseDelimitedString String str, String separatorChars
deprecated
String right String str, int len
str의 len길이만큼 우측에서 문자열을 구한다
String rightPad String str, int size
str의 길이가 size가 되도록 문자열 오른쪽에 ' '을 추가한다
String rightPad String str, int size, char padChar
str의 길이가 size가 되도록 문자열 오른쪽에 padChar를 추가한다
String rightPad String str, int size, String padStr
str의 길이가 size가 되도록 문자열 오른쪽에 padStr을 추가한다
String[] split String str
공백문자를 구분자로 사용하여 분리한다
String[] split String str, char separatorChar
separatorChar를 구분자로 사용하여 분리한다
String[] split String str, String separatorChars
separatorChars를 구분자로 사용하여 분리한다
String[] split String str, String seperatorChars, int max
separatorChars를 구분자로 사용하여 분리한며 최대 max개 만큼한다. 배열의 크기는 max가 된다
String strip String str
문자열 좌우에 있는 공백문자를 제거한다 trim과 동일하다
String strip String str, String stripChars
문자열 좌우에 stripChars에 존재하는 문자를 제거한다
String[] stripAll String strs[]
배열에 있는 모든 문자열 좌우에 있는 공백문자를 제거한다
String[] stripAll String strs[], String stripChars
배열에 있는 모든 문자열 좌우에 stripChars에 존재하는 문자를 제거한다
String stripEnd String str, String stripChars
문자열 우측에만 strip 한다
String stripStart String str, String stripChars
문자열 좌측에만 strip 한다
String stripToEmpty String str
str이 null이면 ""를 반환하고 아니면 strip 한다
String stripToNull String str
str이 null이면 null을 반환하고 아니면 strip 한다
String substring String str, int start
str의 start 인덱스부터 문자열을 구한다
String substring String str, int start, int end
str의 start 부터 end 인덱스 까지 문자열을 구한다
String substringAfter String str, String separator
str의 처음 separator 부분부터 문자열을 구한다
String substringAfterLast String str, String separator
str의 마지막 separator부분부터 문자열을 구한다
String substringBefore String str, String separator
str의 처음 separator 부분까지 문자열을 구한다
String substringBeforeLast String str, String separator
str의 마지막 separator부분까지 문자열을 구한다
String substringBetween String str, String tag
str에서 tag 사이에 있는 문자열을 구한다
String substringBetween String str, String open, String close
str에서 open부터 close 까지 사이에 있는 문자열을 구한다
String swapCase String str
대문자는 소문자로 변환하고 소문자는 대문자로 변환한다
String trimToNull String str
str이 null이거나 length가 0이면 null을 반환하고 그렇지 않으면 좌우 공백문자를 제거한다
String trim String str
문자열 좌우 공백문자를 제거한다
String trimToEmpty String str
str이 null이면 ""를 반환하고 그렇지 않으면 좌우 공백문자를 제거한다
String uncapitalise String str
deprecated
String uncapitalize String str
문자열의 첫문자를 소문자로 변환한다
String upperCase String str
str을 대문자로 변환한다
사용법
모두 static 함수이기때문에 다음과 같이 사용하면 됩니다.
String text = StringUtils.replace(str, repl, width);
자료만들면서 정리한 엑셀 첨부 합니다 ^^
=============================================
본문서는 자유롭게 배포/복사 할수 있지만
이문서의 저자에 대한 언급을 삭제하시면 안됩니다
저자 : GoodBug (unicorn@jakartaproject.com)
=============================================

'Program > Java' 카테고리의 다른 글

Annotation (since tiger / 1.5)  (0) 2009.12.27
About JAXB  (0) 2009.12.27
Annotation (since tiger / 1.5)  (0) 2009.12.15
XML 파싱  (0) 2009.12.15
아파치 미나  (0) 2009.12.15

+ Recent posts