티스토리 뷰

Dev/Java

JMX 기술이해

마이스토리 2016. 9. 9. 17:18

원문 : http://gamadeus.tistory.com/entry/JMX-%EA%B8%B0%EC%88%A0%EC%9D%B4%ED%95%B4


Enterprise Java Technologies Tech Tips에 오신 여러분을 환영합니다. Java 2 Platform, Enterprise Edition (J2EE)에 기반한 enterprise Java technologies 와 APIs의 사용에 관한 최신 정보를 얻어 가시기 바랍니다. 이 글에서는 Java 2 Java 2, Enterprise Edition, v 1.4 를 사용합니다. 다운로드

이번 호에서는,

JMX 기술 이해하기 
SUN JAVA STREAMING XML PARSER 소개

를 다루게 됩니다.

저자 Robert Eckstein

##########2*

JMX 기술 이해하기

JMX(Java Management Extensions)는 프로그래머들에게 자바 어플리케이션의 모니터링과 관리 기능을 제공한다. 실제로 이 API는 웹서버에서 네트워크 디바이스, 웹폰에 이르기까지 자바로 이용 가능한 것은 어느 것이든 로컬 혹은 원격으로 처리 할 수 있게 한다. JMX 기술은 JCP(Java Community Process)에 의해 개발된 밀접한 관계의 두 스펙, Java Specification Request (JSR) 3: Java Management Extensions (JMX) Specification 와 JSR 160: Java Management Extensions (JMX) Remote API 1.0에 의해 정의된다. 이번 테크팁에서는 JMX 아키텍처를 소개하고 간단한 MBean(Managed Beans)을 생성하는 방법을 소개하기로한다.

JMX 기술을 사용하면 MBean(Managed Bean)으로 알려진 하나 이상의 사용자 JavaBean 오브젝트를 통해 (리소스를 호출하는) 한 기계 안의 애플리케이션, 디바이스, 또는 서비스를 원격으로 제어할 수 있다. 이 MBean들은 그 후 핵심 관리 오브젝트 서버(MBean 서버)에 등록된다. MBean서버는 리소스에 접근하기 원하는 모든 원격 매니저에 대한 관리 에이전트 역할을 한다.

JMX 환경

JMX 스펙은 아키텍처를 세개의 티어(tier)로 정의하고 있다. 먼저 설명할 두 레벨은 JSR 3에서 정의된 instrumentation tier와 agent tier이다.

  • Instrumentation Tier. 어플리케이션, 디바이스, 서비스와 같은 리소스들은 MBean (Managed Bean)이라고 불리는 자바 오브젝트를 이용하여 설치된다. MBean은 원격으로 관리하고 모니터링하는 JMX 에이전트를 통해 속성과 연산으로 구성된 관리 인터페이스를 보여준다.

  • Agent Tier. JMX 에이전트의 주요 컴포넌트는 MBean 서버이며, 이는 Mbean이 등록되는 코어 관리 에이전트 오브젝트 서버이다. JMX 에이전트는 또한 MBean 을 핸들링하기 위한 서비스들을 포함하고 있다. JMX 에이전트는 직접적으로 리소스를 제어하고 관리가 가능하도록 한다.

세 번째 티어인 원격 관리 레벨은 JSR 160에 부분적으로 정의되어있다.

  • Remote Management Tier. 이 티어는 에이전트 JVM(Java Virtual Machine) 외부의 원격 관리 어플리케이션으로부터 접근 가능한 JMX 에이전트를 만드는 프로토콜 어덥터(adaptor)와 커넥터(connector)를 정의한다.(JSR160에는 단지 커넥터만 정의.) 커넥터는 원격 클라이언트가 JMX-aware이고 로컬 클라이언트가 보게될 것과 같은 JMX API를 볼 때 사용된다. 어덥터는 원격 클라이언트가 SNMP (Simple Network Management Protocol)나 CIM/WBEM(Common Information Model and Web Based Enterprise Management) 같은 일반 관리 프로포콜을 이용할 때 사용된다.

일반적으로 JMX를 사용하는 개발자는 다음의 세 분류로 나누어진다.

  • 리소스를 관리하기 위해 MBean을 작성하는 개발자. 이 때, JMX 기술은 관리를 위해 보여지는 인터페이스를 정의한다. 개발자는 MBean과 리소스 자체 간의 "접착체"책임을 가진다.

  • 에이전트를 생성하고 배치하는 개발자. 다음과 같은 전형적인 몇 개의 태스크를 수행한다:

    • MBean 서버를 생성하거나 플랫폼에 의해 제공되어지는 것을 사용한다.

    • MBean 네이밍 컨벤션을 이용하여 리소스를 나타내는 MBean들을 등록한다.

    • 플랫폼(RMI/SNMP)에 의해 공급된 커넥터와 프로토콜 어뎁터를 형성하거나, 리소스가 원격으로 접근되었을 때는 커스텀 커넥터나 어덥터를 추가한다

  • 원격 매니저를 작성하는 개발자. JMX 에이전트와 상호작용하는 커넥터나 프로토콜을 선택하고, 나타난 MBean을 통해 원격으로 관리되는 리소스의 뷰를 구축한다.

다음은 JMX 스펙에 의해 정의된 MBean의 네가지 타입이다.

  • 표준 Mbean (Standard MBean): 표준 Mbean은 그 메소드의 이름에 나타나듯이 관리 인터페이스이다. 메소드는 인터페이스의 내성에 의해 보여진다다. 표준MBeans은 MBean의 가장 일반적인 타입이다. 대부분의 개발자는 이 외의 MBean 타입을 생성할 필요가 없다.

  • 다이나믹 MBean(Dynamic MBean): 다이나믹 MBean은 메소드 이름의 introspection을 통하는 대신 javax.management. DynamicMBean인터페이스를 이용하여 관리 인터페이스를 프로그램적으로 구현한다. 이를 위해서는 관리를 위해 나타나는 속성과 작용을 표현하는 정보 클래스에 의존한다. Dynamic MBean은 MBean의 관리 인터페이스가 컴파일시 알려지지 않았을 때-예를 들어, XML 파일을 파싱하는데 결정되었을 때-종종 사용된다.

  • 모델 MBean(Model MBean): 모델 MBean은 일반적이고 형성가능한 MBean으로써 어플리케이션이 어떤 리소스든지 다이나믹하게 설치하는 데 사용한다. 본질적으로, 관리 인터페이스와 실제 리소스가 프로그램적으로 설정되도록 구현되어온 것이 다이나믹 MBean이다. 이로인해 Java 다이나믹 관리 에이전트에 연결된 어떤 매니저라도 MBean 모델을 다이나믹하게 실증하고 형성할 수 있다.

  • 오픈 MBean(Open MBean): 오픈 MBean은 데이터 타입에 특정 제한을 가진 다이나믹 MBean이며, 이는 관리 어플리케이션과 이들의 관리자들이 런타임시 발견되는 새로운 관리 오브젝트들을 이해하고 사용할 수 있게 한다. 오픈 MBean은 JMX 스펙에 따르는 넓은 범위의 애플리케이션에 오픈될 필요가 있는 리소스를 설치하는데 있어 유동적인 수단을 제공한다.

JMX 관련 관리 인터페이스를 생성하는 데에는 전형적으로 최소 두 단계의 과정으로 진행된다. 첫번째 단계에서는 Mbean을 MBean 서버와 함께 등록하는 에이전트는 물론, MBean 인터페이스를 생성한다. 두번째 단계는 원격 관리 어플리케이션을 사용하여 MBean을 관리하는 것이다. JMX 스펙은 사용자가 원격 관리 어플리케이션으로부터 JMX 에이전트를 접근하는 것을 허락하는 커넥터들의 표준을 정의한다. 이는 다른 프로토콜을 사용하는 JMX 커넥터들이 같은 관리 인터페이스를 제공하기 때문에 유용하다. 이로써 관리 애플리케이션이 커뮤니케이션 프로토콜의 사용 유무에 관계 없이 투과성있게 리소스를 관리할 수 있다. JMX 에이전트는 또한 JMX 스펙에는 따르지 않으나 JMX 에이전트를 지원하는 시스템 혹은 어플리케이션에 의해 사용될 수 있다.

표준 Mbean 인터페이스 만들기

가상의 온도계 장치를 위한 MBean을 만들어보자. 소스 코드는 이 테크팁의 샘플 아카이브(ttfeb2005jmx.jar)를 참조하기 바란다. 첫번째로 해야할 것은, MBean 인터페이스를 생성하여 리소스를 "설치"하는 것이다. 다시 말하자면, 리소스의 설치에 접근을 구현하기 위해서는 Mbean을 생성해야하는 것이다. 다음은 간단한 MBean의 예제이다.

 public interface ThermometerMBean { // Attributes public double getTemperature(); public double getMaximumTemperature(); public double getMinimumTemperature(); // Operations public void resetMaxAndMin(); } 

MBean의 인터페이스는 일반적으로 읽고 쓸 수 있는(또는 둘다) 이름별, 타입별 속성들과 활성화될 수 있는 이름별, 타입별 작용들로 구성되어있다.

JMX 기술은 또한 Java 이벤트 모델을 기반으로 하는 일반적 노티피케이션 모델을 정의한다. JMX 에이전트와 MBeans는 이 노티피케이션 모델을 사용하여 관리 애플리케이션이나 다른 Mbean들과 같이 필요로하는 곳에 중요한 정보를 전송할 수 있다. 그러나 이 예제에서는 노티피케이션을 사용하지 않는다.

다음 단계는 MBean 인터페이스의 구현을 생성하는 것인데, 이것은 꽤 간단하다. 여기서 우리는 단순하게 가상의 static 싱글톤 접근자를 호출하는 Thermometer 라는 클래스를 생성한다. 접근자는 온도 데이터를 갖고 있는 오브젝트에 대해 레퍼런스를 얻는다. 표준 Mbean을 위해서, 구현 클래스의 이름과 MBean인터페이스의 이름은 마지막 부분의 "MBean"을 빼고는 반드시 같아야한다. (예를 들어 ThermometerMBean은 Thermometer이다.)

 public class Thermometer implements ThermometerMBean { // Attributes public double getTemperature() { return getMyStaticDeviceInterface().getTemperature(); } public double getMaximumTemperature() { return getMyStaticDeviceInterface().getMax(); } public double getMinimumTemperature() { return getMyStaticDeviceInterface().getMin(); } // Operations public void resetMaxAndMin() { getMyStaticDeviceInterface().resetMaxAndMin(); } // ... } 

JMX 에이전트 생성하기

리소스가 MBean에 의해 설치된 후에는 JMX 에이전트를 통해 관리될 수 있다. MBean은 같이 작용하는 JMX 에이전트에 대해 별다른 지식을 필요로 하지 않는다. 이로써 애플리케이션, 시스템, 네트워크의 개발자들은 복잡한 관리 시스템에 대한 이해 필요 없이 표준 방법으로 제품을 관리할 수 있다.

에이전트는 서버에 위치한 서비스들로부터 도움을 받는다. 에이전트 서비스는 MBean 서버에 등록된 Mbean에서의 관리 작용을 수행할 수 있는 오브젝트이다. 에이전트에 관리 지능을 포함시킴으로써, JMX 기술은 좀 더 강력한 관리 어플리케이션을 허용하게 된다.

JMX 에이전트의 핵심 컴포넌트는 MBean 서버이며, Mbean이 등록되는 관리 오브젝트 서버이다. JMX 에이전트는 또한 Mbean을 관리하기 위한 서비스들과 관리 어플리케이션에 의해 접근허락이 되는 적어도 하나의 커뮤니케이션 커넥터를 포함한다. 다음은 간단한 에이전트를 위한 소스 코드이다.

 import java.lang.management.*; import javax.management.*; public class ThermometerAgent { private MBeanServer server = null; public ThermometerAgent() { server = ManagementFactory.getPlatformMBeanServer(); Thermometer tBean = new Thermometer(); ObjectName tBeanName = null; try { tBeanName = new ObjectName( "ThermometerAgent:type=Thermometer"); server.registerMBean(tBean, tBeanName); } catch(Exception e) { e.printStackTrace(); } } public static void main(String argv[]) { ThermometerAgent agent = new ThermometerAgent(); System.out.println( "Agent is ready... Press Enter to close"); try { System.in.read(); } catch (Exception e) { e.printStackTrace(); } } } 

예제 구동하기

예제를 구동하기 위해서는 J2SE 1.5가 필요하다.

  1. 이번 테크팁에 대한 샘플 아카이브(ttfeb2005jmx.jar)를 다운로드한다.

  2. 예제 압축파일을 다운로드 받은 디렉토리를 변경하고, 다음과 같이 샘플 아카이브에 대한 JAR 파일의 압축을 푼다.
     jar xvf ttfeb2005jmx.jar 
    예제를 위한 소스코드가 나타날 것이다.

  3. 표준 javac 컴파일러를 사용하여 클래스들을 컴파일한다.

  4. 다음 명령어를 사용하여 에이전트 클래스를 구동시킨다.
     java -Dcom.sun.management.jmxremote ThermometerAgent 
  5. 새로운 쉘이나 명령 프롬프트의 경우 jconsole 툴(J2SE bin 디렉토리에 있음)을 시작하기 바란다.

에이전트가 등록되면, 다음과 비슷한 화면이 나타난다.

  1. JMX 에이전트에 접속한다. MBeans 탭을 클릭하고 왼쪽에 있는 트리 중 ThermometerAgent 엔트리의 Thermometer MBean을 선택한다. Attributes 탭을 선택하면 최고, 최저, 현재 온도에 대한 온도계 속성이 나타날 것이다.
  1. Operations 탭을 클릭하면 resetMaxAndMin() 버튼을 보게 될것이다.

이 테크팁은 단지 JMX 기술의 표면적인 부분만 다룰 뿐이다. 더 많은 정보는 Getting Started with Java Management Extensions (JMX): Developing Management and Monitoring Solutions 문서를 참고하기 바란다. 이 문서에서는 이 테크팁에서 보여지는 것 같은 비슷한 예제를 생성하지만 커넥터 사용에 있어 좀 더 자세히 설명한다. 또한 JMX technology page 를 참고하고 JMX 스펙(v2.0)의 발전을 보기위해서는 JSR 255를 주시하기 바란다.

##########7*
##########8*

SUN JAVA STREAMING XML PARSER 소개

XML을 사용하는 대부분의 Java 개발자는 SAX (Simple API for XML) 라이브러리와 DOM(Document Object Model) 라이브러리에 익숙할 것이다. SAX는 이벤트 기반의 API이며, 이는 일반적으로 프로그래머가 파서와 몇 개의 리스너를 등록하고, 특정 XML 문법 생성자(예를 들어 요소나 속성)가 도착되면 리스너 메소드가 호출된다는 의미이다. 그 반대로 DOM은 트리 기반의 아케텍처를 가지며, 전체 문서를 스캔하여 마주치는 각각의 문법 생성자의 오브젝트 트리를 구축한다. 프로그래머는 스캔이 완료된 후 오브젝트 트리에 접근하여 수정할 수 있다

이 두 방법 모두 각각의 결점을 가지고 있다: 리스너를 이용하는 이벤트 기반의 API는 일반적으로 다루기 힘들다. 리스너들이 파서에 의해 조종되기 때문이다. 트리 기반의 API는 스캔되는 문서의 양에 비해 과도한 양의 메모리를 소모할 수 있다. 이제 Java 개발자들이 XML 을 스캔하는데 이용할 수 있는 세 번째 API가 등장하였다. StAX (Streaming API for XML parse)가 그것이다.

SJSXP란?

SJSXP(Sun Java Streaming XML Parser)는 StAX를 빠른 속도로 구현한다. 썬마이크로시스템즈와 협력하고 있는 BEA Systems, XML-guru James Clark, Stefan Haustein, Aleksandr Slominski (XmlPull 개발자들), 그리고 JCP의 다른 멤버들은 JSR 173를 구현하는 것으로써 StAX를 개발하였다. StAX은 공유 인터페이스들에 기반하는, 파서(parser) 독립적인 Java API이다.

SJSXP는 Java Web Services Developer Pack v1.5에 포함되어있다. SJSXP에 대해 처음으로 알아차릴만한 것은 이것이 스트림 API에 기반한다는 것이다. 즉, 개발자가 어느 한 노드에 접근하기 위해 전체 문서를 읽을 필요가 없다. 또한, 파서를 시작하여 파서가 데이터를 이벤트 리스너 메소드에 "push"하도록 허용하는 법칙을 따르지 않는다. 대신에 SJSXP는 "pull" 메소드를 구현하며, 이 메소드는 정렬 포인터를 문서에서 현재 스캔되고 있는 지점에 유지한다. 이는 종종 커서(cursor)라고 불린다. 사용자는 단순히 커서가 현재 가리키고 있는 노드에 대한 파서를 요청하면 된다.

XML 문서 파싱에 SJSXP 이용하기

SJSXP를 이용하여 XML 문서를 읽는 것은 아주 쉽다. 대부분의 작업은 javax.xml.stream.XMLStreamReader 인터페이스를 구현하는 오브젝트를 통해 이뤄진다. 이 인터페이스는 XML 문서의 첫 부분에서 마지막까지 이동되는 커서를 나타낸다. 몇 가지 명심해야할 것이 있다. 커서는 항상 하나의 아이템(시작 태그 요소, 진행 명령, DTD 선언 등)만을 가리켜야 한다. 또한 커서는 항상 앞으로 움직여야 하며 (뒤로 움직일 수 없다), 다음에 무엇이 나타나는지 미리 보기를 실행할 수 없다. 다음의 코드 발췌에서 파일로부터 XML을 읽는 XMLStreamReader를 얻을 수 있다.

 URL url = Class.forName("MyClassName").getResource( "sample.xml"); InputStream in = url.openStream(); XMLInputFactory factory = XMLInputFactory.newInstance(); XMLStreamReader parser = factory.createXMLStreamReader(in); 

그 후 다음 코드를 이용하여 XML 파일을 반복할 수 있다.

 while(parser.hasNext()) { eventType = parser.next(); switch (eventType) { case START_ELEMENT: // Do something break; case END_ELEMENT: // Do something break; // And so on ... } } 

XMLStreamReader의 hasNext() 메소드는 XML 파일에서 또다른 유효한 아이템이 있는지 확인한다. 만약 있다면, 커서가 다음 아이템으로 넘어가게하기 위해 next() 메소드를 사용할 수 있다. next() 메소드는 만나게되는 문법상 생성자(아이템)의 타입을 가리키는 인티거 코드를 리턴한다.

XMLInputStreamReader에는 몇 개의 get 메소드가 있어서 커서가 가리키는 XML 아이템의 내용을 얻는 데 사용할 수 있다. 첫번째 메소드는 getEventType()이다:

 public int getEventType() 

메소드는 커서가 있는 곳에서 파서가 찾은 아이템의 타입을 식별하는 integer 코드를 리턴한다. next() 메소드에 의해 리턴되는 것과 같은 코드이다. 아이템은 XMLInputStream 상수 중 하나에 의해 식별된다.

 XMLStreamConstants.START_DOCUMENT XMLStreamConstants.END_DOCUMENT XMLStreamConstants.START_ELEMENT XMLStreamConstants.END_ELEMENT XMLStreamConstants.ATTRIBUTE XMLStreamConstants.CHARACTERS XMLStreamConstants.CDATA XMLStreamConstants.SPACE XMLStreamConstants.COMMENT XMLStreamConstants.DTD XMLStreamConstants.START_ENTITY XMLStreamConstants.END_ENTITY XMLStreamConstants.ENTITY_DECLARATION XMLStreamConstants.ENTITY_REFERENCE XMLStreamConstants.NAMESPACE XMLStreamConstants.NOTATION_DECLARATION XMLStreamConstants.PROCESSING_INSTRUCTION 

만약 아이템에 이름이 있는 경우, getName()과 getLocalName() 메소드를 사용하여 이름을 얻을 수 있다. 후자는 어떤 다른 정보(예; 확인된 네임스페이스가 없는 요소의 이름) 없이 이름 자체를 산출한다.

 public Qname getName() public String getLocalName() 

만약 당신이 현재 아이템의 네임스페이스를 식별하고 싶다면 getNamespaceURI() 메소드를 사용 할 수 있다.

 public String getNamespaceURI() 

만약 DTD 선언 내의 텍스트나 요소 안의 텍스트 등과 같은 동반되는 텍스트가 있을 때에는 다음 메소드들을 사용하여 얻을 수 있다.(후자는 요소를 위해 단독으로 사용 될 수 있다)

 public String getText() public String getElementText() 

만약 요소가 그것과 관계 되는 속성을 가진다면 getAttributeCount() 메소드를 사용하여 현재 요소가 가진 속성들의 갯수를 얻을 수 있다. 그 후 getAttributeName() 와 getAttributeValue() 메소드를 사용하여 각각의 정보를 검색 할 수 있다.

 public int getAttributeCount() public Qname getAttributeName(int index) public String getAttributeValue(int index) 

만약 속성의 로컬 이름과 요소의 네임스페이스 URI를 안다면, 또한 다음의 메소드를 이용하여 속성값을 얻을 수 있다.

 public String getAttributeValue( String elementNamespaceURI, String localAttributeName) 

추측했겠지만, 모든 접근자 메소드가 특정 상태에 적용가능한 것이 아니다. 예를 들어, 현재 DTD를 프로세싱 중이라면getElementText()을 호출할 수 없다. 만약 이를 호출한다면, 파서가 충돌하는 이벤트 타입을 식별했다는 XMLStreamException을 얻게 되거나 메소드가 스스로 널(null) 값을 리턴하게 될 것이다.

XMLInputFactory 클래스의 setProperty() 메소드를 사용하여 몇 가지 파서 속성을 시작할 수 있다. 예를 들어, 다음은 파서와 마주치는 엔티티 레퍼런스는 교체될 것이라고 지정한다.

 factory.setProperty( XMLInputFactory.IS_REPLACING_ENTITY_REFERENCES, Boolean.TRUE); 

파서가 외부 엔티티를 지원하는 것을 막기 위해 다음과 같이 설정한다.

 factory.setProperty( XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, Boolean.FALSE); 

파서가 네임스페이스를 알아차리게하기 위해 다음과 같이 설정한다.

 factory.setProperty( XMLInputFactory.IS_NAMESPACE_AWARE, Boolean.TRUE); 

SJSXP의 현재 버전에서는 다음의 명령은 허용되지만 파서는 확인되지 않는다는 것을 유의하기 바란다.

 factory.setProperty(XMLInputFactory.IS_VALIDATING, Boolean.TRUE); 

만약 이 XMLInputFactory 특성들 중 어느 하나라도 가능하게 된다면 setXMLReporter() 메소드를 사용하여 파서가 만나게되는 오류를 제어할 수 있다. 파서가 만나는 오류의 타입을 가장 빨리 정확하게 결정할 수 있는 방법은 setXMLReporter() 메소드와 상호 작용하는 익명의 이너 클래스를 사용하는 것이다. 이는 다음과 같다.

 factory.setXMLReporter(new XMLReporter() { public void report(String message, String errorType, Object relatedInformation, Location location) { System.err.println("Error in " + location.getLocationURI()); System.err.println("at line " + location.getLineNumber() + ", column " + location.getColumnNumber()); System.err.println(message); } }); 

XML 문서 작성에 SJSXP 사용하기

XML 결과를 작성하는 것은 SJSXP를 이용하면 쉽다. 이 경우, XMLStreamReader 인터페이스 대신에 XMLStreamWriter 인터페이스를 사용할 수 있다. XMLStreamWriter 인터페이스는 작성하는 요소, 속성, 코멘트, 텍스트를 비롯해 XML 문서의 모든 부분을 작성하기 위한 직접적인 메소드를 제공한다. 다음의 예제에서는 어떻게 이 인터페이스를 얻어서 XML 문서를 작성하는데 사용하는지 보여준다.

 XMLOutputFactory xof = XMLOutputFactory.newInstance(); XMLStreamWriter xtw = xof.createXMLStreamWriter(new FileWriter("myFile")); xtw.writeComment( "all elements here are in the HTML namespace"); xtw.writeStartDocument("utf-8","1.0"); xtw.setPrefix("html", "http://www.w3.org/TR/REC-html40"); xtw.writeStartElement( "http://www.w3.org/TR/REC-html40","html"); xtw.writeNamespace( "html", "http://www.w3.org/TR/REC-html40"); xtw.writeStartElement( "http://www.w3.org/TR/REC-html40","head"); xtw.writeStartElement( "http://www.w3.org/TR/REC-html40","title"); xtw.writeCharacters("Java Information"); xtw.writeEndElement(); xtw.writeEndElement(); xtw.writeStartElement( "http://www.w3.org/TR/REC-html40","body"); xtw.writeStartElement("http://www.w3.org/TR/REC-html40","p"); xtw.writeCharacters("Java homepage is "); xtw.writeStartElement("http://www.w3.org/TR/REC-html40","a"); xtw.writeAttribute("href","http://java.sun.com"); xtw.writeCharacters("here"); xtw.writeEndElement(); xtw.writeEndElement(); xtw.writeEndElement(); xtw.writeEndElement(); xtw.writeEndDocument(); xtw.flush(); xtw.close(); 

각 요소를 작성하는 것이 끝나면 사용자는 라이터(writer)를 날려보내고 닫아야한다.

이전의 코드는 다음의 XML로 결과가 나타난다.(여기서는 쉽게 읽을 수 있게 라인 별로 나타내었다.)

 <!--all elements here are explicitly in the HTML namespace--> <?xml version="1.0" encoding="utf-8"?> <html:html xmlns:html="http://www.w3.org/TR/REC-html40"> <html:head> <html:title>Java Information</html:title> </html:head> <html:body> <html:p> Java information is <html:a href="http://frob.com">here</html:a> </html:p> </html:body> </html:html> 

XML 문서 필터링

만약 각각의 아이템 타입을 스캔하고 싶지 않다면 들어오는 XML 문서에 대한 필터를 생성할 수 있다. 이를 위해서는 javax.xml.stream.StreamFilter 인터페이스를 구현하는 클래스를 생성한다. 이 인터페이스는 단지 accept() 메소드만으로 구성된다. 이 메소드는 XMLStreamReader 오브젝트를 허용하고 원시 Boolean을 리턴한다. StreamFilter의 일반적인 구현은 다음과 같다.

 public class MyStreamFilter implements StreamFilter { public boolean accept(XMLStreamReader reader) { if(!reader.isStartElement() && !reader.isEndElement()) return false; else return true; } } 

그 다음으로 XMLInputFactory의 createFilteredReader() 메소드를 호출하여 필터링된 리더(reader)를 생성하고 이를 원래 XML 스트림 리더와 StreamFilter 구현에 모두 전달한다. 다음과 같다.

 factory.createFilteredReader( factory.createXMLStreamReader(in), new MyStreamFilter()); 

SJSXP의 더 자세한 정보는 Sun Java Streaming XML Parser release notes를 참고하기 바란다.

Sun Java Streaming XML Parser 예제 코드 구동하기

  1. 이번 테크팁에 대한 샘플 아카이브(ttfeb2005sjsxp.jar)를 다운로드한다.

  2. Java Web Services Developer Pack Downloads page에서 Java WSDP 1.5를 다운로드, 설치한다.

  3. 예제 압축파일을 다운로드 받은 디렉토리를 변경하고, 다음과 같이 샘플 아카이브에 대한 JAR 파일의 압축을 푼다.
     jar xvf ttfeb2005sjsxp.jar 
  4. 사용자의 classpath가 ttfeb2005sjsxp.jar와 jsr173_api.jar를 포함하도록 설정한다. 이들은 Java WSDP 1.5 installation의 sjsxp/lib 디렉토리에 위치하고 있다.

  5. SJSXPInput를 컴파일하고 구동한다. 

    다음의 각각의 XML 아이템과 유사한 엔트리가 나타날 것이다.
     Event Type (Code=11): DTD Without a Name With Text: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1- transitional.dtd"> ----------------------------- 
  6. SJSXPOutput를 컴파일하고 구동한다. 결과는 XMLOutputFile라는 이름의 파일에 보내지며, 위의 결과 예제에 보여지는 요소들을 포함할 것이다.


댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31