wal*_*mon 6 java soap web-services spring-ws
我有一个SOAP服务,如果我为XML元素指定了错误的输入,请求和响应按预期工作,输入良好
在请求正文中:
...
<ns:myIntegerElement>asdf</ns:myIntegerElement>
...
Run Code Online (Sandbox Code Playgroud)
我的异常解析器被调用,这个解析器只是异常解析器的一个实现,因此它没有异常映射,只是抽象方法中的一些System.out
<bean id="exceptionResolver" class="com.mycompany.ws.MyExceptionResolver">
Run Code Online (Sandbox Code Playgroud)
但是,如果我发送的请求看起来更像这样:
...
<ns:myIntegSOMETHINGGOTTOTALLYMESSUP!!!ent>asdf</ns:myIntegerElement>
...
Run Code Online (Sandbox Code Playgroud)
我的解析器根本没有执行
我将log4j设置为具有根调试级别并查看此输出:
2010-08-09 10:30:01,900 [主题:http-8080-2] DEBUG [org.springframework.ws.transport.http.WebServiceMessageReceiverHandlerAdapter] - 接受传入[org.springframework.ws.transport.http.HttpServletConnection@c46dcf ]到[ http:// localhost:8080/myws/MyWebServices /] 错误:'元素类型"ns:MESSEDUPELEMENT"必须由匹配的结束标记""终止." 2010-08-09 10:30:01,920 [主题:http-8080-2] DEBUG [org.springframework.ws.transport.http.MessageDispatcherServlet] - 无法完成请求org.springframework.ws.soap.saaj.SaajSoapMessageException:无法访问信封:无法从给定来源创建信封:; 嵌套异常是com.sun.xml.internal.messaging.saaj.SOAPExceptionImpl:无法从给定的源创建信封:org.springframework.ws.soap.saaj.support.SaajUtils.getSaajVersion(SaajUtils.java:162)at org .springframework.ws.soap.saaj.SaajSoapMessage.getImplementation(SaajSoapMessage.java:251)org.springframework.ws.soap.saaj.SaajSoapMessage.(SaajSoapMessage.java:位于org.springframework.ws.soap.saaj.support.SaajUtils.getSaajVersion的com.sun.xml.internal.messaging.saaj.soap.SOAPPartImpl.getEnvelope(SOAPPartImpl.java:122)中的createEnvelopeFromSource(SOAPPart1_1Impl.java:70)( SaajUtils.java:159)... 24更多引起:javax.xml.transform.TransformerException:org.xml.sax.SAXParseException:元素类型"smm:smm-aid"必须由匹配的结束标记终止" ".在com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform(TransformerImpl.java:719)的com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform(TransformerImpl. java:313)在com.sun.xml的com.sun.xml.internal.messaging.saaj.util.transform.EfficientStreamingTransformer.transform(EfficientStreamingTransformer.java:393).internal.messaging.saaj.soap.EnvelopeFactory.createEnvelope(EnvelopeFactory.java:102)... 27更多引起:org.xml.sax.SAXParseException:元素类型"smm:smm-aid"必须由匹配终止结束标记"".at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1231)at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl $ JAXPSAXParser.parse(SAXParserImpl.java: 522)在com的com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transformIdentity(TransformerImpl.java:636)的org.xml.sax.helpers.XMLFilterImpl.parse(XMLFilterImpl.java:333) .sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform(TransformerImpl.java:707)... 30更多 createEnvelope(EnvelopeFactory.java:102)... 27更多引起:org.xml.sax.SAXParseException:元素类型"smm:smm-aid"必须由匹配的结束标记""终止.at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1231)at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl $ JAXPSAXParser.parse(SAXParserImpl.java: 522)在com的com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transformIdentity(TransformerImpl.java:636)的org.xml.sax.helpers.XMLFilterImpl.parse(XMLFilterImpl.java:333) .sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform(TransformerImpl.java:707)... 30更多 createEnvelope(EnvelopeFactory.java:102)... 27更多引起:org.xml.sax.SAXParseException:元素类型"smm:smm-aid"必须由匹配的结束标记""终止.at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1231)at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl $ JAXPSAXParser.parse(SAXParserImpl.java: 522)在com的com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transformIdentity(TransformerImpl.java:636)的org.xml.sax.helpers.XMLFilterImpl.parse(XMLFilterImpl.java:333) .sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform(TransformerImpl.java:707)... 30更多 元素类型"smm:smm-aid"必须由匹配的结束标记""终止.at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1231)at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl $ JAXPSAXParser.parse(SAXParserImpl.java: 522)在com的com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transformIdentity(TransformerImpl.java:636)的org.xml.sax.helpers.XMLFilterImpl.parse(XMLFilterImpl.java:333) .sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform(TransformerImpl.java:707)... 30更多 元素类型"smm:smm-aid"必须由匹配的结束标记""终止.at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1231)at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl $ JAXPSAXParser.parse(SAXParserImpl.java: 522)在com的com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transformIdentity(TransformerImpl.java:636)的org.xml.sax.helpers.XMLFilterImpl.parse(XMLFilterImpl.java:333) .sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform(TransformerImpl.java:707)... 30更多
看来spring在这里缺少一个可能的异常,并没有包装它,但是这样一个基本的错误条件没有被捕获似乎不太可能.任何人都可以帮我找到这个问题的根源吗?
我也将包含web.xml和servlet.xml:
web.xml中:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<servlet>
<servlet-name>ws</servlet-name>
<servlet-class>org.springframework.ws.transport.http.MessageDispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
<init-param>
<param-name>transformWsdlLocations</param-name>
<param-value>true</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>ws</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
Run Code Online (Sandbox Code Playgroud)
servlet上下文:
<context:component-scan base-package="com.mycomp.proj.ws" />
<bean id="smmService" class="com.mycomp.proj.ws.SMMRequestHandlingServiceStubImpl"/>
<bean class="org.springframework.ws.server.endpoint.mapping.PayloadRootAnnotationMethodEndpointMapping"/>
<bean class="org.springframework.ws.server.endpoint.adapter.MarshallingMethodEndpointAdapter">
<constructor-arg ref="marshaller"/>
</bean>
<bean id="marshaller" class="org.springframework.oxm.castor.CastorMarshaller">
<property name="mappingLocations">
<list>
<value>classpath:mapping.xml</value>
<value>classpath:hoursOfOperationMapping.xml</value>
</list>
</property>
</bean>
<bean id="smmws" class="org.springframework.ws.wsdl.wsdl11.DefaultWsdl11Definition">
<property name="schema" ref="schema" />
<property name="portTypeName" value="SMM" />
<property name="locationUri" value="/SMMWebServices/"/>
<property name="targetNamespace" value="http://mycomp.proj.com" />
</bean>
<bean id="exceptionResolver" class="com.wdp.smm.ws.MyExceptionResolver"/>
<bean id="schema" class="org.springframework.xml.xsd.SimpleXsdSchema">
<property name="xsd" value="/WEB-INF/ws.xsd" />
</bean>
Run Code Online (Sandbox Code Playgroud)
MessageDispatcherServlet默认创建自己的两个EnpointExceptionResolver实例,即SoapFaultAnnotationExceptionResolver @ 1和SimpleSoapExceptionResolver @ 2
当它解决异常时,SimpleSoapExceptionResolver @ 2将停止任何其他已注册的EnpointExceptionResolver来处理异常.
我花了很长时间才弄清楚,但答案很简单,在你的servlet上下文中你必须这样做:
<bean id="exceptionResolver" class="com.wdp.smm.ws.MyExceptionResolver">
<property name="order" value="1"/>
</bean>
Run Code Online (Sandbox Code Playgroud)
我更仔细地看了你的问题,我想我知道发生了什么。不会调用您的异常处理程序,因为它在soap 处理中处于较高级别。您会看到,WebServiceMessageReceiverHandlerAdapter 尝试将传入的字符串解码为 XML,然后再将其发送到编组器进行处理。由于 XML 无效,调用失败。由于 WebServiceMessageReceiverHandlerAdapter 不支持异常处理程序,它只是重新抛出异常“SaajSoapMessageException”。
现在您可以做的是创建一个扩展 WebServiceMessageReceiverHandlerAdapter 的新类,但它也将 handleConnection() 包装在 try/catch 中,该类在抛出异常时使用您的异常处理程序。
顺便说一下,在调试此类问题时,我的方法是在 log4j 中输出方法名称和行号。以及下载Spring源。