How do we handle exceptions (specially Parsing exceptions) in Spring Web Services?
1. For example, Spring WS distribution has a sample application called 'pox'.
2. If the POX request send to the 'ContactCountEndpoint' has a syntax error, it will got thrown as SAXParse exception and client will get something like this:
3. Now to prevent this kind of response being sent to the client, I wrote aHTML Code:<html> <head> <title>Apache Tomcat/6.0.16 - Error report</title> <style> <!--H1 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:22px;} H2 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:16px;} H3 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:14px;} BODY {font-family:Tahoma,Arial,sans-serif;color:black;background-color:white;} B {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;} P {font-family:Tahoma,Arial,sans-serif;background:white;color:black;font-size:12px;}A {color : black;}A.name {color : black;}HR {color : #525D76;}--></style> </head> <body> <h1>HTTP Status 500 - </h1> <HR size="1" noshade="noshade"> <p> <b>type</b> Exception report </p> <p> <b>message</b> <u></u> </p> <p> <b>description</b> <u>The server encountered an internal error () that prevented it from fulfilling this request.</u> </p> <p> <b>exception</b> <pre>org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.ws.pox.dom.DomPoxMessageException: Could not parse request message; nested exception is org.xml.sax.SAXParseException: The element type "contact" must be terminated by the matching end-tag "</contact>". org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:583) org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:511) javax.servlet.http.HttpServlet.service(HttpServlet.java:710) javax.servlet.http.HttpServlet.service(HttpServlet.java:803)</pre> </p> <p> <b>root cause</b> <pre>org.springframework.ws.pox.dom.DomPoxMessageException: Could not parse request message; nested exception is org.xml.sax.SAXParseException: The element type "contact" must be terminated by the matching end-tag "</contact>". org.springframework.ws.pox.dom.DomPoxMessageFactory.createWebServiceMessage(DomPoxMessageFactory.java:94) org.springframework.ws.transport.AbstractWebServiceConnection.receive(AbstractWebServiceConnection.java:86) org.springframework.ws.transport.support.WebServiceMessageReceiverObjectSupport.handleConnection(WebServiceMessageReceiverObjectSupport.java:86) org.springframework.ws.transport.http.WebServiceMessageReceiverHandlerAdapter.handle(WebServiceMessageReceiverHandlerAdapter.java:57) org.springframework.ws.transport.http.MessageDispatcherServlet.doService(MessageDispatcherServlet.java:197) org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:571) org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:511) javax.servlet.http.HttpServlet.service(HttpServlet.java:710) javax.servlet.http.HttpServlet.service(HttpServlet.java:803)</pre> </p> <p> <b>root cause</b> <pre>org.xml.sax.SAXParseException: The element type "contact" must be terminated by the matching end-tag "</contact>". com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(Unknown Source) com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(Unknown Source) javax.xml.parsers.DocumentBuilder.parse(Unknown Source) org.springframework.ws.pox.dom.DomPoxMessageFactory.createWebServiceMessage(DomPoxMessageFactory.java:87) org.springframework.ws.transport.AbstractWebServiceConnection.receive(AbstractWebServiceConnection.java:86) org.springframework.ws.transport.support.WebServiceMessageReceiverObjectSupport.handleConnection(WebServiceMessageReceiverObjectSupport.java:86) org.springframework.ws.transport.http.WebServiceMessageReceiverHandlerAdapter.handle(WebServiceMessageReceiverHandlerAdapter.java:57) org.springframework.ws.transport.http.MessageDispatcherServlet.doService(MessageDispatcherServlet.java:197) org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:571) org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:511) javax.servlet.http.HttpServlet.service(HttpServlet.java:710) javax.servlet.http.HttpServlet.service(HttpServlet.java:803) </pre> </p> <p> <b>note</b> <u>The full stack trace of the root cause is available in the Apache Tomcat/6.0.16 logs.</u> </p> <HR size="1" noshade="noshade"> <h3>Apache Tomcat/6.0.16</h3> </body> </html>
4. And we declare this class in the application context:Code:public class ResolveParsingException extends AbstractEndpointExceptionResolver private DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); protected final boolean resolveExceptionInternal(MessageContext messageContext, Object endpoint, Exception ex) { }
5. But the problem is SAXParse exception is not handed over to this class, it still gets thrown as shown in #2. If we throw a new 'java.lang.Exception' from 'ContactCountEndpoint', then this 'ResolveParsingException' get sthe chance to resolve it.HTML Code:<bean id="exceptionResolver" class="ResolveParsingException "> </bean>
6. Unfortunately there is not enough information available in Spring WS about handling exceptions, so couldn't resolve this issue based on the available information in reference documentation.
7. Would appreciate if some one could give a pointer, how to catch these 'SAXParse' exceptions nicely and return a XML response back to client, e.g.,
8. Also how do we set this response message in exception resolver?HTML Code:<contacts> <error>Invalid XML</error> </contacts>
i. We create a DOMPoxMesasge
ii. and set it as a response to MessageContext?
messageContext.setResponse(domPoxMessage);
9. A small sample exception resolver class which shows how to handle, this will be of great help and also useful for future help for other people.
Thanks!


Reply With Quote