2009년 07월 24일
UTFDataFormatException 처리
XML 문서를 모 쇼핑몰에서 받아와 파싱하는 과정에서 UTFDataFormatException 이 발생한다.
log : java.io.UTFDataFormatException: Invalid byte 1 of 1-byte UTF-8 sequence
위와 같은 Exception은 처음 보았기에 조금 당황. XML 문서에 영어와 한글이 들어 갔을 때 서로
상이한 에러 메세지가 출력되어 인코딩 문제가 의심이 갔다.
옆에 있는 인도 엔지니어 친구 왈,
"JDK 1.3에서 parsing 방법은 loose parsing 인데 반해서, JDK 1.4의 parsing 방법은 strict parsing이다"
정확한 내용을 바로 알아챌 수는 없었지만, parsing 의 내부 규칙이 보다 엄격해 졌다는 감이 왔다.
(추가 학습 필요 ...)
기존의 소스 코드는 ...
SAXParserFactory parserFactory = SAXParserFactory.newInstance();
SAXParser saxParser = parserFactory.newSAXParser();
//..생략
saxParser.parse(uri, xmlHandler);
코드를 모두 공개하는 건 불가하므로 ...
JDK 1.3 에서는 parser 객체를 받아온 후 바로 parse 메소드 호출로 파싱이 가능했다.
더 이상의 부가 작업이 필요치 않았던 것이다.
setValidating(), setNamespaceAware() 정도의 부가 작업만이 필요했는데, JDK 1.4에서는 위 같은
방법으로 하면 처음에 제시했던 Exception이 떨어 졌다.
일단 인코딩을 지정해주기 위해서 파일 경로를 uri 받는 파싱 대신에 stream으로 받는 파싱 방법을
사용했다.
SAXParserFactory parserFactory = SAXParserFactory.newInstance();
SAXParser saxParser = parserFactory.newSAXParser();
//..생략
FileInputStream stream = new FileInputStream(new File(uri));
InputSource inputSource = new InputSource(stream);
inputSource.setEncoding("euc-kr");
saxParser.parse(inputSource, xmlHandler);
성공적으로 인코딩을 지정해주었다고 생각했는데.. 수 번을 돌려봐도 동일한 에러가 발생했다.
다음 문제는 파일을 읽어 들이는 '방법'에 대한 차이때문에 발생했다.
자바 IO에서는 두 가지 방법을 제공하고 있는데, 하나는 stream 구조로 이는 1byte를 기반으로 하고 있다.
두 번째는 write, reader로 이는 2byte를 기반으로 하고 있다. 두 방법의 각각의 차이점과 사용 목적을
가지고 있는데 이는 차후에 다루기 위해서 미뤄 논다.
해결 방벙은 XML 문서를 읽어 들일 때 stream 기반이 아닌 reader로 읽음으로서 문제 해결.
SAXParserFactory parserFactory = SAXParserFactory.newInstance();
SAXParser saxParser = parserFactory.newSAXParser();
//..생략
FileReader reader= new FileReader(new File(uri));
InputSource inputSource = new InputSource(reader);
inputSource.setEncoding("euc-kr");
saxParser.parse(inputSource, xmlHandler);
출처 : Tong - 삽질만이 살 길이다님의 JSP & ETC통
log : java.io.UTFDataFormatException: Invalid byte 1 of 1-byte UTF-8 sequence
위와 같은 Exception은 처음 보았기에 조금 당황. XML 문서에 영어와 한글이 들어 갔을 때 서로
상이한 에러 메세지가 출력되어 인코딩 문제가 의심이 갔다.
옆에 있는 인도 엔지니어 친구 왈,
"JDK 1.3에서 parsing 방법은 loose parsing 인데 반해서, JDK 1.4의 parsing 방법은 strict parsing이다"
정확한 내용을 바로 알아챌 수는 없었지만, parsing 의 내부 규칙이 보다 엄격해 졌다는 감이 왔다.
(추가 학습 필요 ...)
기존의 소스 코드는 ...
SAXParserFactory parserFactory = SAXParserFactory.newInstance();
SAXParser saxParser = parserFactory.newSAXParser();
//..생략
saxParser.parse(uri, xmlHandler);
코드를 모두 공개하는 건 불가하므로 ...
JDK 1.3 에서는 parser 객체를 받아온 후 바로 parse 메소드 호출로 파싱이 가능했다.
더 이상의 부가 작업이 필요치 않았던 것이다.
setValidating(), setNamespaceAware() 정도의 부가 작업만이 필요했는데, JDK 1.4에서는 위 같은
방법으로 하면 처음에 제시했던 Exception이 떨어 졌다.
일단 인코딩을 지정해주기 위해서 파일 경로를 uri 받는 파싱 대신에 stream으로 받는 파싱 방법을
사용했다.
SAXParserFactory parserFactory = SAXParserFactory.newInstance();
SAXParser saxParser = parserFactory.newSAXParser();
//..생략
FileInputStream stream = new FileInputStream(new File(uri));
InputSource inputSource = new InputSource(stream);
inputSource.setEncoding("euc-kr");
saxParser.parse(inputSource, xmlHandler);
성공적으로 인코딩을 지정해주었다고 생각했는데.. 수 번을 돌려봐도 동일한 에러가 발생했다.
다음 문제는 파일을 읽어 들이는 '방법'에 대한 차이때문에 발생했다.
자바 IO에서는 두 가지 방법을 제공하고 있는데, 하나는 stream 구조로 이는 1byte를 기반으로 하고 있다.
두 번째는 write, reader로 이는 2byte를 기반으로 하고 있다. 두 방법의 각각의 차이점과 사용 목적을
가지고 있는데 이는 차후에 다루기 위해서 미뤄 논다.
해결 방벙은 XML 문서를 읽어 들일 때 stream 기반이 아닌 reader로 읽음으로서 문제 해결.
SAXParserFactory parserFactory = SAXParserFactory.newInstance();
SAXParser saxParser = parserFactory.newSAXParser();
//..생략
FileReader reader= new FileReader(new File(uri));
InputSource inputSource = new InputSource(reader);
inputSource.setEncoding("euc-kr");
saxParser.parse(inputSource, xmlHandler);
출처 : Tong - 삽질만이 살 길이다님의 JSP & ETC통
# by | 2009/07/24 14:01 | 그외... | 트랙백 | 덧글(0)








☞ 내 이글루에 이 글과 관련된 글 쓰기 (트랙백 보내기) [도움말]