📄 jaxpsax5.html
字号:
<?xml version="1.0" encoding="ISO-8859-1"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" /> <meta http-equiv="Content-Style-Type" content="text/css" /> <title>Handling Errors with the Nonvalidating Parser</title> <link rel="StyleSheet" href="document.css" type="text/css" media="all" /> <link rel="StyleSheet" href="catalog.css" type="text/css" media="all" /> <link rel="Table of Contents" href="J2EETutorialTOC.html" /> <link rel="Previous" href="JAXPSAX4.html" /> <link rel="Next" href="JAXPSAX6.html" /> <link rel="Index" href="J2EETutorialIX.html" /> </head> <body> <table width="550" summary="layout" id="SummaryNotReq1"> <tr> <td align="left" valign="center"> <font size="-1"> <a href="http://java.sun.com/j2ee/1.4/download.html#tutorial" target="_blank">Download</a> <br> <a href="http://java.sun.com/j2ee/1.4/docs/tutorial/information/faq.html" target="_blank">FAQ</a> <br> <a href="http://java.sun.com/j2ee/1.4/docs/tutorial/information/history.html" target="_blank">History</a> </td> <td align="center" valign="center"><a accesskey="p" href="JAXPSAX4.html"><img id="LongDescNotReq1" src="images/PrevArrow.gif" width="26" height="26" border="0" alt="Prev" /></a><a accesskey="c" href="J2EETutorialFront.html"><img id="LongDescNotReq1" src="images/UpArrow.gif" width="26" height="26" border="0" alt="Home" /></a><a accesskey="n" href="JAXPSAX6.html"><img id="LongDescNotReq3" src="images/NextArrow.gif" width="26" height="26" border="0" alt="Next" /></a><a accesskey="i" href="J2EETutorialIX.html"></a> </td> <td align="right" valign="center"> <font size="-1"> <a href="http://java.sun.com/j2ee/1.4/docs/api/index.html" target="_blank">API</a> <br> <a href="http://java.sun.com/j2ee/1.4/docs/tutorial/information/search.html" target="_blank">Search</a> <br> <a href="http://java.sun.com/j2ee/1.4/docs/tutorial/information/sendusmail.html" target="_blank">Feedback</a></font> </font> </td> </tr> </table> <img src="images/blueline.gif" width="550" height="8" ALIGN="BOTTOM" NATURALSIZEFLAG="3" ALT="Divider"> <blockquote><a name="wp64579"> </a><h2 class="pHeading1">Handling Errors with the Nonvalidating Parser</h2><a name="wp95482"> </a><p class="pBody">The parser can generate one of three kinds of errors: fatal error, error, and warning. In this exercise, you'll how the parser handles a fatal error.</p><a name="wp64580"> </a><p class="pBody">This version of the Echo program uses the nonvalidating parser. So it can't tell if the XML document contains the right tags, or if those tags are in the right sequence. In other words, it can't tell you if the document is valid. It can, however, tell whether or not the document is well-formed. </p><a name="wp64581"> </a><p class="pBody">In this section of the tutorial, you'll modify the slideshow file to generate different kinds of errors and see how the parser handles them. You'll also find out which error conditions are ignored, by default, and see how to handle them. </p><hr><a name="wp95501"> </a><p class="pNote">Note: The XML file used in this exercise is <code class="cCode"><a href="../examples/xml/samples/slideSampleBad1.xml" target="_blank">slideSampleBad1.xml</a></code>, as described in <a href="IntroXML4.html#wp69037">Introducing an Error </a>. The output is in <code class="cCode">Echo05-Bad1.txt</code>. (The browsable versions are <code class="cCode"><a href="../examples/xml/samples/slideSampleBad1-xml.html" target="_blank">slideSampleBad1-xml.html</a></code> and <code class="cCode">Echo05-Bad1.html</code>.)</p><hr><a name="wp64592"> </a><p class="pBody">When you created <code class="cCode">slideSampleBad1.xml</code>, you deliberately created an XML file that was not well-formed. Run the Echo program on that file now. The output now gives you an error message that looks like this (after formatting for readability):</p><div class="pPreformattedRelative"><pre class="pPreformattedRelative"><code class="cCodeBold">org.xml.sax.SAXParseException: The element type "item" must be terminated by the matching end-tag "</item>".</code>...at org.apache.xerces.parsers.AbstractSAXParser......at Echo.main(...)<a name="wp95893"> </a></pre></div><hr><a name="wp70786"> </a><p class="pNote">Note: The message above was generated by the JAXP 1.2 libraries. If you are using a different parser, the error message is likely to be somewhat different.</p><hr><a name="wp64595"> </a><p class="pBody">When a fatal error occurs, the parser is unable to continue. So, if the application does not generate an exception (which you'll see how to do a moment), then the default error-event handler generates one. The stack trace is generated by the <code class="cCode">Throwable</code> exception handler in your main method:</p><div class="pPreformattedRelative"><pre class="pPreformattedRelative"> ...} catch (Throwable t) {<code class="cCodeBold"> t.printStackTrace();</code>}<a name="wp64596"> </a></pre></div><a name="wp64597"> </a><p class="pBody">That stack trace is not too useful, though. Next, you'll see how to generate better diagnostics when an error occurs.</p><a name="wp64599"> </a><h4 class="pHeading3">Handling a SAXParseException</h4><a name="wp64600"> </a><p class="pBody">When the error was encountered, the parser generated a <code class="cCode">SAXParseException</code>--a subclass of <code class="cCode">SAXException</code> that identifies the file and location where the error occurred. </p><hr><a name="wp64601"> </a><p class="pNote">Note: The code you'll create in this exercise is in <code class="cCode"><a href="../examples/jaxp/sax/samples/Echo06.java" target="_blank">Echo06.java</a></code>. The output is in <code class="cCode"><a href="../examples/jaxp/sax/samples/Echo06-Bad1.txt" target="_blank">Echo06-Bad1.txt</a></code>. (The browsable version is<code class="cCode"><a href="../examples/jaxp/sax/samples/Echo06-Bad1.html" target="_blank"> Echo06-Bad1.html</a></code>.)</p><hr><a name="wp64602"> </a><p class="pBody">Add the code highlighted below to generate a better diagnostic message when the exception occurs: </p><div class="pPreformattedRelative"><pre class="pPreformattedRelative"><code class="cCodeBold">...} catch (SAXParseException spe) { // Error generated by the parser System.out.println("\n** Parsing error" + ", line " + spe.getLineNumber() + ", uri " + spe.getSystemId()); System.out.println(" " + spe.getMessage() );</code>} catch (Throwable t) { t.printStackTrace();}<a name="wp64603"> </a></pre></div><a name="wp64604"> </a><p class="pBody">Running this version of the program on <code class="cCode">slideSampleBad1.xml</code> generates an error message which is a bit more helpful, like this:</p><div class="pPreformattedRelative"><pre class="pPreformattedRelative">** Parsing error, line 22, uri file:<path>/slideSampleBad1.xml The element type "item" must be ...<a name="wp64605"> </a></pre></div><hr><a name="wp64606"> </a><p class="pNote">Note: The text of the error message depends on the parser used. This message was generated using JAXP 1.2.</p><a name="wp69569"> </a><p class="pNote">Note: Catching all throwables like this is not generally a great idea for production applications.<span style="font-weight: bold"> </span>We're doing it now so we can build up to full error handling gradually. In addition, it acts as a catch-all for null pointer exceptions that can be thrown when the parser is passed a null value.</p><hr><a name="wp64608"> </a><h4 class="pHeading3">Handling a SAXException</h4><a name="wp64609"> </a><p class="pBody">A more general <code class="cCode">SAXException</code> instance may sometimes be generated by the parser, but it more frequently occurs when an error originates in one of application's event handling methods. For example, the signature of the <code class="cCode">startDocument</code> method in the <code class="cCode">ContentHandler</code> interface is defined as returning a <code class="cCode">SAXException</code>: </p><div class="pPreformattedRelative"><pre class="pPreformattedRelative">public void startDocument() throws SAXException<a name="wp64610"> </a></pre></div><a name="wp64611"> </a><p class="pBody">All of the <code class="cCode">ContentHandler</code> methods (except for <code class="cCode">setDocumentLocator</code>) have that signature declaration.</p><a name="wp64612"> </a><p class="pBody">A <code class="cCode">SAXException</code> can be constructed using a message, another exception, or both. So, for example, when <code class="cCode">Echo.startDocument</code> outputs a string using the <code class="cCode">emit</code> method, any I/O exception that occurs is wrapped in a <code class="cCode">SAXException</code> and sent back to the parser:</p><div class="pPreformattedRelative"><pre class="pPreformattedRelative">private void emit(String s)throws SAXException{ try { out.write(s); out.flush(); } <code class="cCodeBold">catch (IOException e)</code> { <code class="cCodeBold">throw new SAXException("I/O error", e);</code> }}<a name="wp64613"> </a></pre></div><hr><a name="wp64614"> </a><p class="pNote">Note: If you saved the <code class="cCode">Locator</code> object when <code class="cCode">setDocumentLocator</code> was invoked, you could use it to generate a <code class="cCode">SAXParseException</code>, identifying the document and location, instead of generating a <code class="cCode">SAXException</code>.</p><hr><a name="wp64615"> </a><p class="pBody">When the parser delivers the exception back to the code that invoked the parser, it makes sense to use the original exception to generate the stack trace. Add the code highlighted below to do that:</p><div class="pPreformattedRelative"><pre class="pPreformattedRelative"> ...} catch (SAXParseException err) { System.out.println("\n** Parsing error" + ", line " + err.getLineNumber() + ", uri " + err.getSystemId()); System.out.println(" " + err.getMessage());<code class="cCodeBold">} catch (SAXException sxe) { // Error generated by this application // (or a parser-initialization error) Exception x = sxe; if (sxe.getException() != null) x = sxe.getException(); x.printStackTrace();</code>} catch (Throwable t) { t.printStackTrace();}<a name="wp64616"> </a></pre></div><a name="wp64617"> </a><p class="pBody">This code tests to see if the <code class="cCode">SAXException</code> is wrapping another exception. If so, it generates a stack trace originating from where that exception occurred to make it easier to pinpoint the code responsible for the error. If the exception contains only a message, the code prints the stack trace starting from the location where the exception was generated.</p><a name="wp64619"> </a><h4 class="pHeading3">Improving the SAXParseException Handler</h4><a name="wp64620"> </a><p class="pBody">
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -