http://tutorials.jenkov.com/java-xml/stax-xmleventwriter.html에서 가져옴


The XMLEventWriter class in the Java StAX API allows you to write StAX XMLEvent's either to aWriter, an OutputStream, or a Result (special JAXP object).

Here is a simple example that writes a series of events to disk, using a FileWriter:

XMLOutputFactory factory      = XMLOutputFactory.newInstance();
XMLEventFactory  eventFactory = XMLEventFactory.newInstance();

try {
    XMLEventWriter writer =
            factory.createXMLEventWriter(
                    new FileWriter("data\\output.xml"));

    XMLEvent event = eventFactory.createStartDocument();
    writer.add(event);

    event = eventFactory.createStartElement(
            "jenkov", "http://jenkov.com", "document");
    writer.add(event);

    event = eventFactory.createNamespace(
            "jenkov", "http://jenkov.com");
    writer.add(event);

    event = eventFactory.createAttribute
            ("attribute", "value");
    writer.add(event);

    event = eventFactory.createEndElement(
            "jenkov", "http://jenkov.com", "document");
    writer.add(event);

    writer.flush();
    writer.close();
} catch (XMLStreamException e) {
    e.printStackTrace();
} catch (IOException e) {
    e.printStackTrace();
}

The result of executing this code is the following XML file (line breaks inserted for readability):

<?xml version='1.0' encoding='UTF-8'?>
<jenkov:document xmlns:jenkov="http://jenkov.com" attribute="value">
</jenkov:document>

As you can see, it is possible to generate XML using XMLEvent's and the XMLEventWriter. But, if you are looking to just output some quick XML, you might be better off using the XMLStreamWriterinstead. It's API is easier to work with, and results in more dense code.


Chaining XMLEventReader and XMLEventWriter

It is possible to add the XMLEvent's available from an XMLEventReader directly to an XMLEventWriter. In other words, you are pooring the XML events from the reader directly into the writer. You do so using the XMLEventWriter.add(XMLEventReader) method.

http://tutorials.jenkov.com/java-xml/stax-xmleventreader.html에서 가져옴


The XMLEventReader class in Java StAX provides an Iterator style API for parsing XML. In other words, it allows you to move from event to event in the XML, letting you control when to move to the next event. An "event" in this case is for instance the beginning of an element, the end of an element, a group of text etc. In other words, pretty much the same events you would get from a SAX parser.

You create an XMLEventReader via the javax.xml.stream.XMLInputFactory class. Here is how that looks:

XMLInputFactory factory = XMLInputFactory.newInstance();

//get Reader connected to XML input from somewhere..
Reader reader = getXmlReader();

try {

    XMLEventReader eventReader =
        factory.createXMLEventReader(reader);
    
} catch (XMLStreamException e) {
    e.printStackTrace();
}

Once created you can iterate through the XML input from the underlying Reader. Here is how that looks:

while(eventReader.hasNext()){

    XMLEvent event = eventReader.nextEvent();

    if(event.getEventType() == XMLStreamConstants.START_ELEMENT){
        StartElement startElement = event.asStartElement();
        System.out.println(startElement.getName().getLocalPart());
    }
    //handle more event types here...
}

You obtain an XMLEvent object from the XMLStreamReader by calling its nextEvent() method. From the event object you can check what type of event you've got, by calling its getEventType() method. Depending on what type of event you have encountered, you will do different actions.


XML Stream Events

Below is a list of the events you can encounter in an XML stream. There are constants for each of these events in the javax.xml.stream.XMLStreamConstants interface.

  • ATTRIBUTE
  • CDATA
  • CHARACTERS
  • COMMENT
  • DTD
  • END_DOCUMENT
  • END_ELEMENT
  • ENTITY_DECLARATION
  • ENTITY_REFERENCE
  • NAMESPACE
  • NOTATION_DECLARATION
  • PROCESSING_INSTRUCTION
  • SPACE
  • START_DOCUMENT
  • START_ELEMENT

XMLEvent Processing

From the XMLEvent object you can get access to the corresponding XML data. You can also get information about where (line number + column number) in the XML stream the event was encountered.

You can turn the event object into a more specific event type object, by calling one of these 3 methods:

  1. asStartElement()
  2. asEndElement()
  3. asCharacters()

Exactly how that works with events like START_DOCUMENT, NAMESPACE or PROCESSING_INSTRUCTION, I don't yet know. I'll update this text when I do. Luckily, we will most often only need the START_ELEMENT, END_ELEMENT, and CHARACTERS events, so this lack of knowledge isn't crucial.


XMLEvent.asStartElement()

The asStartElement() method returns a java.xml.stream.StartElement object. From this object you can get the name of the element, get the namespaces of the element, and the attributes of the element. See the Java 6 JavaDoc for more detail.


XMLEvent.asEndElement()

The asEndElement() method returns a java.xml.stream.EndElement object. From this object you can get the element name and namespace.


XMLEvent.asCharacters()

The asCharacters() method return a java.xml.stream.Characters object. From this object you can obtain the characters themselves, as well as see if the characters are CDATA, white space, or ignorable white space.

'밤을 지새다 > Java' 카테고리의 다른 글

Java StAX: XMLStreamReader - The Cursor API  (0) 2012.04.30
Java StAX: XMLEventWriter - The Iterator Writer API  (0) 2012.04.30
Java StAX: XMLOutputFactory  (0) 2012.04.30
Java StAX: XMLInputFactory  (0) 2012.04.30
Java StAX  (0) 2012.04.30

http://tutorials.jenkov.com/java-xml/stax-xmloutputfactory.html에서 가져옴


The class javax.xml.stream.XMLOutputFactory is a root component of the Java StAX API. From this class you can create both an XMLStreamWriter and an XMLEventWriter. Here are two examples:

XMLOutputFactory factory = XMLOutputFactory.newInstance();

XMLEventWriter eventWriter =
    factory.createXMLEventWriter(
        new FileWriter("data\\test.xml"));

XMLStreamWriter streamWriter =
    factory.createXMLStreamWriter(
        new FileWriter("data\\test.xml"));

XMLOutputFactory Properties

You can set one property on the XMLOutputFactory instance using the setProperty() method. Here is an example:

factory.setProperty(XMLOutputFactory.IS_REPAIRING_NAMESPACES, true);

For a full list of properties and their meaning, see the official JavaDoc (in Java 6) for the StAX API.

'밤을 지새다 > Java' 카테고리의 다른 글

Java StAX: XMLEventWriter - The Iterator Writer API  (0) 2012.04.30
Java StAX: XMLEventReader - The Iterator API  (0) 2012.04.30
Java StAX: XMLInputFactory  (0) 2012.04.30
Java StAX  (0) 2012.04.30
Exceptions  (0) 2011.09.05

http://tutorials.jenkov.com/java-xml/stax-xmlinputfactory.html에서 가져옴


The class javax.xml.stream.XMLInputFactory is a root component of the Java StAX API. From this class you can create both an XMLStreamReader and an XMLEventReader. Here are two examples:

XMLInputFactory factory = XMLInputFactory.newInstance();

XMLEventReader eventReader =
    factory.createXMLEventReader(
        new FileReader("data\\test.xml"));

XMLStreamReader streamReader =
    factory.createXMLStreamReader(
        new FileReader("data\\test.xml"));

XMLInputFactory Properties

You can set various properties on the XMLInputFactory instance using the setProperty() method. Here is an example:

factory.setProperty(XMLInputFactory.IS_NAMESPACE_AWARE, true);

For a full list of properties and their meaning, see the official JavaDoc (in Java 6) for the StAX API.

'밤을 지새다 > Java' 카테고리의 다른 글

Java StAX: XMLEventReader - The Iterator API  (0) 2012.04.30
Java StAX: XMLOutputFactory  (0) 2012.04.30
Java StAX  (0) 2012.04.30
Exceptions  (0) 2011.09.05
자바. 얼마나 알고 사용하고 계신가요?  (0) 2011.08.25

http://tutorials.jenkov.com/java-xml/stax.html에서 가져옴


The StAX Java API for XML processing is designed for parsing XML streams, just like the SAX API's. The main differences between the StAX and SAX API's are:

  • StAX is a "pull" API. SAX is a "push" API.
  • StAX can do both XML reading and writing. SAX can only do XML reading.

It is pretty obvious what the difference between a "read + write" capable API vs. a "read" capable API is. But the difference between a "pull" and a "push" style API is less obvious, so I'll talk a little about that. For a more feature-by-feature type comparison of SAX and StAX, see the text SAX vs. StAX.

NOTE: This text uses SVG (Scalable Vector Graphics) diagrams. If you are using Internet Explorer you will need the Adobe SVG Plugin do display these diagrams. Firefox 3.0.5+ users and Google Chrome users should have no problems.


"Pull" vs. "Push" Style API

SAX is a push style API. This means that the SAX parser iterates through the XML and calls methods on the handler object provided by you. For instance, when the SAX parser encounters the beginning of an XML element, it calls the startElement on your handler object. It "pushes" the information from the XML into your object. Hence the name "push" style API. This is also referred to as an "event driven" API. Your handler object is notified with event-calls when something interesting is found in the XML document ("interesting" = elements, texts, comments etc.).

The SAX parser push style parsing is illustrated here:

StAX is a pull style API. This means that you have to move the StAX parser from item to item in the XML file yourself, just like you do with a standard Iterator or JDBC ResultSet. You can then access the XML information via the StAX parser for each such "item" encountered in the XML file ("item" = elements, texts, comments etc.).

The StAX parser pull style parsing is illustrated here:

In fact, StAX has two different reader API's. One that looks most like using an Iterator and one that looks most like using a ResultSet. These are called the "iterator" and "cursor" readers.

So, what is the difference between these two readers?

The iterator reader returns an XML event object from it's nextEvent() calls. From this event object you can see what type of event you had encountered (element, text, comment etc.). This event element is immutable, and can be parsed around to other parts of your application. You can also hang on to earlier event objects when iterating to the next event. As you can see, this works very much like how you use an ordinary Iterator when iterating over a collection. Here, you are just iterating over XML events. Here's a sketch:

XMLEventReader reader = ...;

while(reader.hasNext()){
    XMLEvent event = reader.nextEvent();

    if(event.getEventType() == XMLEvent.START_ELEMENT){
        StartElement startElement = event.asStartElement();
        System.out.println(startElement.getName().getLocalPart());
    }
    //... more event types handled here...
}

The cursor reader does not return events from it's next() call. Rather this call moves the cursor to the next "event" in the XML. You can then call methods directly on the cursor to obtain more information about the current event. This is very similar to how you iterate the records of a JDBCResultSet, and call methods like getString() or getLong() to get values from the current record pointed to by the ResultSet. Here is a sketch:

XMLStreamReader streamReader = ...;

while(streamReader.hasNext()){
    int eventType = streamReader.next();

    if(eventType == XMLStreamReader.START_ELEMENT){
        System.out.println(streamReader.getLocalName());
    }

    //... more event types handled here...
}

So, one of the main differences is, that you can hang on to earlier XML event objects when using the iterator style API. You cannot do this when using the cursor style API. Once you move the cursor to the next event in the XML stream, you have no information about the previous event. This speaks in favour of using the iterator style API.

However, the cursor style API is said to be more memory-efficient than the iterator style API. So, if your application needs absolute top-performance, use the cursor style API.

Both of these two StAX API's will be covered in more detail in later texts. See the table of contents in the right side of this page.


Java StAX Implementation

At the time of writing (Java 6) only the StAX interfaces are bundled with the JDK. There is no StAX implementation built into Java. But, there is a standard implementation which can be found here:

http://stax.codehaus.org/

자주 보게 되는 예외를 정리해 봤습니다. 이유 모를 예외나 모르는 예외가 있을 때 댓글로 달아주세요.


1. NullPointerException
Null 객체에 대해 접근했을 때 발생한다.
ex) String str = null;
str.equals("foo");


2. IllegalArgumentException
잘못된 인자값을 전달했을때 발생한다.


3. ArithmeticException
산술적인 오류가 있을 때 발생한다.
ex) int i = 1 / 0; // 0으로 나눌 수 없으므로 예외 발생.


4. ClassCastException
잘못된 형변환을 할 때 발생한다.
ex) Object o = "foo";
char[] str = (char[]) o;


'밤을 지새다 > Java' 카테고리의 다른 글

Java StAX: XMLInputFactory  (0) 2012.04.30
Java StAX  (0) 2012.04.30
자바. 얼마나 알고 사용하고 계신가요?  (0) 2011.08.25
객체를 바이트 배열로, 바이트 배열을 객체로  (0) 2011.08.22
메서드 체인화 기법  (0) 2011.08.17
다음 소스를 실행하면 출력 순서는 어떻게 되는지 맞춰보세요 :D

public class MyClass{

public MyClass(){

System.out.println("(가)");
}

static {
System.out.println("(나)");
}

{
System.out.println("(다)");
}

public static void main(String[] args){
System.out.println("(라)");
new MyClass();
}

'밤을 지새다 > Java' 카테고리의 다른 글

Java StAX: XMLInputFactory  (0) 2012.04.30
Java StAX  (0) 2012.04.30
Exceptions  (0) 2011.09.05
객체를 바이트 배열로, 바이트 배열을 객체로  (0) 2011.08.22
메서드 체인화 기법  (0) 2011.08.17

Object to byte array and byte array to Object in Java

원출처 : http://scr4tchp4d.blogspot.com/2008/07/object-to-byte-array-and-byte-array-to.html

Here how to convert an Object to a byte array, and vice-versa.
요기에 객체를 바이트 배열로, 그 반대로 바꾸는 방법이 있습니다!
역시 구글링이랄까.
 
public byte[] toByteArray (Object obj)
{
  byte[] bytes = null;
  ByteArrayOutputStream bos = new ByteArrayOutputStream();
  try {
    ObjectOutputStream oos = new ObjectOutputStream(bos); 
    oos.writeObject(obj);
    oos.flush(); 
    oos.close(); 
    bos.close();
    bytes = bos.toByteArray ();
  }
  catch (IOException ex) {
    //TODO: Handle the exception
  }
  return bytes;
}
    
public Object toObject (byte[] bytes)
{
  Object obj = null;
  try {
    ByteArrayInputStream bis = new ByteArrayInputStream (bytes);
    ObjectInputStream ois = new ObjectInputStream (bis);
    obj = ois.readObject();
  }
  catch (IOException ex) {
    //TODO: Handle the exception
  }
  catch (ClassNotFoundException ex) {
    //TODO: Handle the exception
  }
  return obj;
}

'밤을 지새다 > Java' 카테고리의 다른 글

Java StAX: XMLInputFactory  (0) 2012.04.30
Java StAX  (0) 2012.04.30
Exceptions  (0) 2011.09.05
자바. 얼마나 알고 사용하고 계신가요?  (0) 2011.08.25
메서드 체인화 기법  (0) 2011.08.17
안드로이드 NFC 예제를 보면서 괜찮은 기법이 있어서 소개할까합니다. (저만 몰랐던 걸 수도 있구요. :D ) 

제가 본 소스의 일부를 쓰자면

BiMap<Byte, String> URI_PREFIX = BiMap.<Byte, String>builder()
            .put((byte) 0x00, "")
            .put((byte) 0x01, "http://www.")
            .put((byte) 0x02, "https://www.")
            .put((byte) 0x03, "http://")
            .put((byte) 0x04, "https://")
            .put((byte) 0x05, "tel:")
            .build();



맵에 요소를 넣으면서 URI_PREFIX에 인스턴스를 할당하는 구문입니다. 

처음 봤을 때는 저게 원래 자바에서 지원하는 문법인가 싶어서  객체 안에 있는 메서드
위처럼 세미콜론 없이 닷만 찍어서 계속 해보려했는데 당연히도 에러가 나더군요. 

위 문장을 보고 저게 뭐? 라고 생각하셨다면 아래에 쓰는 체이닝 기법을 적용하지 않고 작성한 소스를 보고 비교해보세요.

BiMap<Byte, String> URI_PREFIX =
BiMap.<Byte, String>builder().build(); 
URI_PREFIX.put((byte) 0x00, "");
URI_PREFIX.put((byte) 0x01, "http://www.");
URI_PREFIX.put((byte) 0x02, "https://www.");
URI_PREFIX.put((byte) 0x03, "http://");
URI_PREFIX.put((byte) 0x04, "https://");
URI_PREFIX.put((byte) 0x05, "tel:"); 


개인적인 차이일지도 모르겠지만 저는 체이닝 기법을 적용한 소스가 더 깔끔하고 직관적으로 느껴지네요. 서론은 여기까지 하고 실제로 어떻게 체이닝 기법을 적용할 수 있는지 예제를 만들면서 알아봅시다.

만들 클래스는 간단한 학생 정보 클래스입니다. 체이닝 기법을 적용한다고 해서 그리 효율적인 클래스가 되진 않겠지만 간단한 예를 위해서 이 클래스를 씁니다.

/** 학생정보 클래스 */
class Student{
private String name; // 학생이름
private String number; // 학번
private int birthyear; // 생년
private String dept; // 학과 

public void setName(String name){
this.name = name;
}

public void setNumber(String number){
this.number = number;
}

public void setBirthyear(int birthyear){
this.age = age;
}

public void setDept(String dept){
this.dept = dept;
}

/* getter 생략 */ 
}



위 클래스에서 생성자를 두지 않는다고 가정하면 학생 인스턴스에 정보를 넣기위해서는 아래와 같이 코드를 작성하게 되겠죠

Student student = new Student();
student.setName("세종대왕");
student.setNumber("7284910");
student.setBirthyear(1397);
student.setDept("국어국문학과");



체이닝 기법을 적용하기 위해서 뮤테이터(세터) 메서드의 반환형을 void에서 오브젝트를 반환하도록 Student 타입으로 바꿔 줍니다.
그리고 메서드 구현부의 끝에 return this;를 써서 객체를 반환하도록 하구요.
DSL에서는 setName과 같은 메서드 이름도 더 직관적으로 바꾸지만 익숙함을 위해서 그대로 쓰도록 하겠습니다. 위의 Student 클래스를 체이닝 기법을 적용하기 위한 소스로 바꿔보면 아래와 같습니다. 빨간색 글씨가 수정된 부분입니다

/** 학생정보 클래스 */
class Student{
private String name; // 학생이름
private String number; // 학번
private int birthyear; // 생년
private String dept; // 학과 

public Student setName(String name){
this.name = name;
return this;
}

public Student setNumber(String number){
this.number = number;
return this;
}

public Student setBirthyear(int birthyear){
this.age = age;
return this;
}

public Student setDept(String dept){
this.dept = dept;
return this;
}

/* getter 생략 */ 
}



클래스를 바꿨으니 인스턴스를 할당할 때도 바로 적용해 봅시다.

Student student = new Student()
.setName("세종대왕")
.setNumber("7284910")
.setBirthyear(1397)
.setDept("국어국문학과");



네. 이상입니다.
원리는 간단합니다. 계속해서 객체를 반환하니 메서드를 다시 호출해서 쓸 수 있고. 역시 student 변수는 Student 클래스 타입이니 반환한 객체 그대로 받을 수 있게 됩니다.  

'밤을 지새다 > Java' 카테고리의 다른 글

Java StAX: XMLInputFactory  (0) 2012.04.30
Java StAX  (0) 2012.04.30
Exceptions  (0) 2011.09.05
자바. 얼마나 알고 사용하고 계신가요?  (0) 2011.08.25
객체를 바이트 배열로, 바이트 배열을 객체로  (0) 2011.08.22

+ Recent posts