자바 애플리케이션에서 SAX 파서를 이용해 XML 문서를 파싱하다가 다양한 예외를 만나게된다. 이번 포스트에서 설명할 예외는 "[Fatal Error] :1:1: Premature end of file." 혹은 "[Fatal Error] :1:1: 예기치 않은 파일의 끝입니다."라는 Exception이다.
말 그대로 SAX 파서의 입력 스트림이 예상하지 갑작스레 끝났을 경우에 발생한다. 가장 흔한 예외 케이스는 SAX 파서에 빈 문자열이 입력되면 발생한다.
다음 예제 코드르 보자.
import java.io.StringReader;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.xml.sax.InputSource;
public class Test {
public static void main(String []args) throws Exception {
String xml = "";
StringReader reader = new StringReader(xml);
InputSource inputSource = new InputSource(reader);
DocumentBuilderFactory facotry = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = facotry.newDocumentBuilder();
try {
Document doc = builder.parse(inputSource);
} catch (Exception e) {
/* no-op */
e.printStackTrace();
}
}
}
DocumentBuilder의 parse() 메소드에 빈 문자열로부터 만들어진 InputSource 객체가 입력되었다. 결국 예외가 발생한다. 코드에서는 try-catch 구문을 이용해서 예외를 잘 잡아 처리했다. 따라서 상위 스택으로 예외가 전파되지는 않는다.
하지만 stderr로 예외에 대한 내용이 출력되어 버린다. SAX 파서를 이용해서 라이브러리를 만드는 경우 빈문자열의 입력같이 대처할 수 있는 상황을 예외처리해서 넘어갈 수 있는데 stderr로 에러 메시지가 출력되어 버려서 문의를 받는 경우가 있다.
DocumentBuilder의 parse() 메소드를 따라 들어가면 SAX 파서가 문자열을 읽어 들이다가 문제가 발생했을 때, Error 핸들러를 호출하는 것을 확인할 수 있다. 사용자가 별도의 Error 핸들러를 등록하지 않으면 DefaultErrorHandler가 호출 된다. DefaultErrorHandler의 동작이 바로 System.err 스트림으로 메시지를 출력하는 것이다.
이를 방지하기 위해서 org.xml.sax.ErrorHandler 인터페이스를 구현한 클래스를 만들고, builder.setErrorHandler() 메소드로 에러 핸들러를 등록해두면 된다.
그게 싫다면 빈문자열등을 미리 확인하여 builder.parse() 메소드가 호출되지 않도록 처리하면 된다.
댓글