9.11 SOAP处理程序
为了拦截SOAP消息,Web服务架构提供了称为处理程序或拦截器的概念。处理程序可以在入站或出站SOAP消息从服务请求者传递到服务提供者时对它们进行处理。拦截器有两种类型:SOAP拦截器和逻辑拦截器。逻辑处理程序处理SOAP消息的消息体的有效负载,而SOAP处理程序既可以处理消息体,也可以处理消息头。要成为处理程序,Java类只需要实现SOAPHandler接口。
9.11.1 使用XFire测试SOAP处理程序(1)
本节将介绍如何测试服务器SOAP处理程序(PhotoAppSoapAuthnticationHandler),这个处理程序在Web服务调用以前由XFire架构调用。创建一个Web服务客户端,这个客户端使用客户端SOAP处理程序(SOAPClientAuthenticationHandler)来拦截客户端SOAP消息及设置SOAP消息头中的用户证书。PhotoAppSoapAuthenticationHandler拦截引入的SOAP消息,从该SOAP消息中提取用户证书,并验证证书。如果证书无效,则抛出一个异常,此时Web服务操作不会执行。
XFire运行库调用PhotoAppSoapAuthenticationHandler SOAP处理程序来正常处理入站SOAP消息。为了对此进行测试,需要创建一个添加SOAP消息头中的证书信息和调用AffiliateManagement Web服务的操作Web服务客户端。XFire运行库(已配置的XFireExporter)接收Web服务请求并调用PhotoAppSoapAuthenticationHandler。PhotoAppSoapAuthenticationHandler验证证书,成功执行该操作之后,XFire容器会执行必要的Web服务操作。如果PhotoAppSoapAuthenticationHandler抛出异常,那么Web服务操作不会执行,而异常消息会被发送回客户端。
将使用与"调用Web服务"一节中相同的Web服务客户端,只是这里把客户端处理程序连接到了webservice-tent.xml文件中。
(1) 对webservice-client.xml做出以下改动,从而将客户端处理程序SOAPClientAuthenticationHandler引用与XFireClientFactoryBean定义中的outHandler属性连接起来。在affiliateSoapAuthenticationHandler bean定义中连接了一个调试标记。把这个标记设为true以查看控制台打印的出站SOAP消息(将在下一小节分析SOAPClientAuthenticationHandler)。
<bean id="affiliateSoapAuthenticationHandler" class="com.wrox.beginspring.pix.webservice.SOAPClientAuthenticationHandler"> <property name="debug"> <value>false</value> </property> </bean> <bean id="affiliateWebServiceClient" class="org.codehaus.xfire.spring.remoting.XFireClientFactoryBean" lazy-init="true"> <property name="serviceClass"> <value>com.wrox.beginspring.pix.service.AffiliateManagementService</value> </property> <property name="wsdlDocumentUrl"> <value>http://localhost:8080/pix/services/AffilateManagement?wsdl</value> </property> <property name="outHandlers"> <ref bean="affiliateSoapAuthenticationHandler"/> </property> </bean>
(2) 切换到下载的代码的wrox-pix-web部分,输入mvn clean install来构建代码。
(3) 切换到下载的代码的wrox-pix-web部分,运行AffiliateManagementWebServiceTest类:
mvn exec:java -Dexec.mainClass=com.wrox.beginspring.pix.webservice .AffiliateManagementWebServiceTest
看到的输出应该与下面的内容类似。在每个Web服务操作被调用以前,控制台打印SOAP请求。从下面的代码中可以看到,SOAP消息头包含PixCredentials元素,这个元素包含用户ID和密码信息。
[INFO] ..... [INFO]... Retrieving document at 'null'. <?xml version="1.0" encoding="UTF-8" standalone="no"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <soap:Header> <PixCredentials> <userid>webaffiliate1</userid> <password>password1</password> </PixCredentials> </soap:Header> <soap:Body> <persistAffiliate xmlns="http://service.pix.beginspring.wrox.com"> <!-- Commented out. --> </persistAffiliate> </soap:Body> </soap:Envelope> persistAffiliate executed for - > webaffiliate1 <! --- Soap Message --> getAffiliate executed for - > webaffiliate1 <! --- Soap Message --> enrollUserViaAffiliateWebSite executed for - > webaffiliate1 <! --- Soap Message --> changePassword executed for - > webaffiliate1 <! --- Soap Message --> removeAffiliate executed for - > webaffiliate1 org.codehaus.xfire.XFireRuntimeException: Could not invoke service.. Nested exception is org.codehaus.xfire.fault.XFireFault: Authentication Failed org.codehaus.xfire.fault.XFireFault: Authentication Failed [INFO]…