如何在使用第三方 Web 服务时使用 PayloadLoggingInterceptor 和 SOAPLoggingInterceptor 拦截器
How to use PayloadLoggingInterceptor and SOAPLoggingInterceptor interceptors while consuming a third party web service
在我的应用程序中,我正在使用由我的客户提供的第三方网络服务。
我已经在 Spring 和 Hibernate 框架上开发了我的应用程序,并且在一个模块中我正在使用这个第三方网络服务 url。我使用
生成了网络服务存根
javab2-maven-plugin
maven 插件在我的 pom.xml 文件中声明如下:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxb2-maven-plugin</artifactId>
<version>1.5</version>
<executions>
<execution>
<id>xjc</id>
<goals>
<goal>xjc</goal>
</goals>
</execution>
</executions>
<configuration>
<!-- Package to store the generated file -->
<packageName>com.equifax.unsolicited.wsdl.stub</packageName>
<!-- Treat the input as WSDL -->
<wsdl>true</wsdl>
<!-- Input is not XML schema -->
<xmlschema>false</xmlschema>
<!-- The WSDL file that you saved earlier -->
<schemaFiles>Duk_CIS_Send_CreditStatus.wsdl</schemaFiles>
<!-- The location of the WSDL file -->
<schemaDirectory>${project.basedir}/src/main/wsdl</schemaDirectory>
<!-- The output directory to store the generated Java files -->
<outputDirectory>${project.basedir}/src/main/java</outputDirectory>
<!-- Don't clear output directory on each run -->
<clearOutputDir>false</clearOutputDir>
</configuration>
</plugin>
我正在使用自动生成的 JAXB java 类 来调用 Web 服务。我创建了一个调用 Web 服务的服务 bean :
@Service("unsolicitResponseService")
public class UnsolicitResponseServiceImpl implements UnsolicitResponseService{
private static final Logger LOGGER = Logger.getLogger(UnsolicitResponseServiceImpl.class);
@Autowired
private WebServiceTemplate webServiceTemplate;
@Override
public void sendUnsolicitResponse() {
LOGGER.debug("Calling Duke Web Service to Send Unsolicit Response ... ");
try{
ObjectFactory objecFactory = new ObjectFactory();
CreditStatusMsgType creditStatusMessage = objecFactory.createCreditStatusMsgType();
creditStatusMessage.setMessageHeader(createMessageHeader(objecFactory));
//WRAP THE CLASS AS THE INSTANCE OF JAXBELEMENT OTHERWISE IT WILL THROW MISSING ROOTELEMENT ERROR
JAXBElement<CreditStatusMsgType> creditStatusMessageJaxbElement = objecFactory.createSendCreditStatus(creditStatusMessage);
//CREATE STRING WRITER TO LOG THE REQUEST
Object response = this.webServiceTemplate.marshalSendAndReceive(creditStatusMessageJaxbElement);
LOGGER.debug("Jumio Web Service Response Reponse :"+response);
LOGGER.debug("Unsolicit Response sent to Duke Successfully.");
}catch(Exception ex){
LOGGER.error("Exception generated while calling Web Service to send unsolicit Response : "+ex.getLocalizedMessage(),ex);
}
}
下面是 xml 配置,我在其中声明了拦截器来记录请求和响应:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:sws="http://www.springframework.org/schema/web-services"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:oxm="http://www.springframework.org/schema/oxm"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/web-services
http://www.springframework.org/schema/web-services/web-services-2.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/oxm http://www.springframework.org/schema/oxm/spring-oxm.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
<!-- DEFINE SOAP VERSION USED BY A WSDL -->
<bean id="soapMessageFactory" class="org.springframework.ws.soap.saaj.SaajSoapMessageFactory">
<property name="soapVersion">
<!-- FOR TEXT/XML -->
<util:constant static-field="org.springframework.ws.soap.SoapVersion.SOAP_11"/>
</property>
</bean>
<!-- LOCATION OF THE GENERATED JAVA FILEs -->
<oxm:jaxb2-marshaller id="marshaller" contextPath="com.equifax.unsolicited.wsdl.stub"/>
<!-- CONFIGURE THE SPRING WEB SERVICE -->
<bean id="webServiceTemplate" class="org.springframework.ws.client.core.WebServiceTemplate">
<constructor-arg ref="soapMessageFactory"/> <property name="marshaller" ref="marshaller"/>
<property name="unmarshaller" ref="marshaller"/>
<property name="defaultUri" value="https://partnerstg.duke-energy.com:4443/DukCISSendCreditStatus?wsdl"/>
</bean>
<sws:interceptors>
<bean id="jumioPeyLoadLoggingInterceptor" class="com.test.datasource.logging.interceptor.PayloadLoggingInterceptor">
</bean>
<bean id="jumioSOAPLoggingInterceptor" class="com.test.datasource.logging.interceptor.SOAPLoggingInterceptor">
</bean>
</sws:interceptors>
</beans>
而且我还添加了新的日志记录类别,以将记录器级别设置为 DEBUG 模式:
以上代码调用网络服务成功。但是拦截器没有被调用。所以我无法记录 XML 请求和响应。
在这里,我假设这些拦截器在使用服务时不会工作。如果我在这里错了,请告诉我。
我指的是来自 HERE 的 Spring Web 服务。本站在发布web-service时对拦截器进行了说明
请告诉我我们应该在使用网络服务时使用这个拦截器吗?或者我应该如何打印 JAXB-ELEMENT 的请求和响应?
我在这里添加我已经实施的解决方案。我们可以通过两种方式实施此解决方案。我已经使用 JAXBContext 和 Marshaller 实现了下面列表中的第二个。
1> 日志 Request/Response 通过拦截器。
我们在使用 Web 服务时不能使用 PayloadLoggingInterceptor 或 SOAPLoggingInterceptor。
我们在使用 Web 服务时需要使用 ClientInterceptor。 ClientInterceptor 由 PayloadValidatingInterceptor class 实现,用于拦截 request/response 并根据 [=45 验证它=] 模式。
为此,我们需要提供如下拦截器参考:
<bean id="MyPayloadValidatingInterceptor" class="com.equifax.ic.datasource.jumio.ws.logging.interceptor.JumioPayloadValidatingInterceptor">
<property name="schema" value="file:WebContent/WEB-INF/schemas/account-balance-service.xsd" />
<property name="validateRequest" value="false" />
<property name="validateResponse" value="false" />
</bean>
<bean id="webServiceTemplate" class="org.springframework.ws.client.core.WebServiceTemplate">
<constructor-arg ref="soapMessageFactory"/> <property name="marshaller" ref="marshaller"/>
<property name="unmarshaller" ref="marshaller"/>
<property name="defaultUri" value="https://partnerstg.duke-energy.com:4443/DukCISSendCreditStatus?wsdl"/>
<property name="interceptors">
<list>
<ref bean="MyPayloadValidatingInterceptor"/>
</list>
</property>
</bean>
2> 使用 JAXBContext
记录 Request/Response
这是我在我的应用程序中实施的解决方案,因为我们不应该只使用 PayloadValidatingInterceptor 来记录 reqeust/response。
private void logJAXBRequest(JAXBElement<CreditStatusMsgType> creditStatusMessageJaxbElement){
LOGGER.debug("Logging Web Service Request ...");
StringWriter writer = null;
StreamResult streamResult = null;
StringBuffer buffer = null;
try{
writer = new StringWriter();
streamResult = new StreamResult(writer);
JAXBContext jaxbContext = JAXBContext.newInstance(CreditStatusMsgType.class);
Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.marshal(creditStatusMessageJaxbElement, streamResult);
buffer = writer.getBuffer();
LOGGER.debug("JAXB Webservice Request : "+ buffer.toString());
writer.close();
}catch(Exception ex){
LOGGER.error("Exception generated while creating XML Logs of JAXB Request :",ex);
}
}
大家好,同事们。
显示 XML 请求/响应的主要方式有两种:
首先,您必须将 log4j
依赖项添加到 pom.xml
文件中:
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
然后您必须将log4j.properties
文件放入应用程序的类路径中。当我开发 SOAP 服务时,我经常使用 Spring WS Maven artefact。不幸的是,usual resources
文件夹不是从头开始创建的,您必须手动创建它。然后你把 log4j.properties
文件放在那里。 log4j 配置的内容取决于您要使用的方法(请参阅下面的项目)。得到的结构如下:
使用标准 Message Logging and Tracing 方法和 log4j.properties
文件。除了 log4j 配置文件内容外,不应配置、开发、编写任何内容。 log4j 配置的内容应该如下(按原样使用这些内容):
log4j.rootCategory=DEBUG, stdout
log4j.logger.org.springframework.ws.client.MessageTracing.sent=TRACE
log4j.logger.org.springframework.ws.client.MessageTracing.received=DEBUG
log4j.logger.org.springframework.ws.server.MessageTracing=DEBUG
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%p [%c{3}] %m%n
使用 PayloadLoggingInterceptor
& log4j.properties
文件。应该应用一些配置更改,但这种方法对我来说更灵活。首先,您必须将 PayloadLoggingInterceptor
添加到 MessageDispatcherServlet
配置文件中:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:sws="http://www.springframework.org/schema/web-services" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/web-services http://www.springframework.org/schema/web-services/web-services-2.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:component-scan base-package="com.ln.springws"/>
<sws:annotation-driven/>
<sws:interceptors>
<bean class="org.springframework.ws.server.endpoint.interceptor.PayloadLoggingInterceptor" />
</sws:interceptors>
<sws:dynamic-wsdl id="holiday" portTypeName="HumanResource" locationUri="http://localhost:8080/holidayService/" targetNamespace="http://spring-ws-holidays.com/hr/definitions">
<sws:xsd location="/WEB-INF/hr.xsd"/>
</sws:dynamic-wsdl>
</beans>
最后将以下内容放入log4j.properties
文件:
log4j.rootLogger=debug, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%-5p [%c] - <%m>%n
由于这两种方法,您将在控制台中看到类似的内容:
在我的应用程序中,我正在使用由我的客户提供的第三方网络服务。
我已经在 Spring 和 Hibernate 框架上开发了我的应用程序,并且在一个模块中我正在使用这个第三方网络服务 url。我使用
生成了网络服务存根javab2-maven-plugin
maven 插件在我的 pom.xml 文件中声明如下:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxb2-maven-plugin</artifactId>
<version>1.5</version>
<executions>
<execution>
<id>xjc</id>
<goals>
<goal>xjc</goal>
</goals>
</execution>
</executions>
<configuration>
<!-- Package to store the generated file -->
<packageName>com.equifax.unsolicited.wsdl.stub</packageName>
<!-- Treat the input as WSDL -->
<wsdl>true</wsdl>
<!-- Input is not XML schema -->
<xmlschema>false</xmlschema>
<!-- The WSDL file that you saved earlier -->
<schemaFiles>Duk_CIS_Send_CreditStatus.wsdl</schemaFiles>
<!-- The location of the WSDL file -->
<schemaDirectory>${project.basedir}/src/main/wsdl</schemaDirectory>
<!-- The output directory to store the generated Java files -->
<outputDirectory>${project.basedir}/src/main/java</outputDirectory>
<!-- Don't clear output directory on each run -->
<clearOutputDir>false</clearOutputDir>
</configuration>
</plugin>
我正在使用自动生成的 JAXB java 类 来调用 Web 服务。我创建了一个调用 Web 服务的服务 bean :
@Service("unsolicitResponseService")
public class UnsolicitResponseServiceImpl implements UnsolicitResponseService{
private static final Logger LOGGER = Logger.getLogger(UnsolicitResponseServiceImpl.class);
@Autowired
private WebServiceTemplate webServiceTemplate;
@Override
public void sendUnsolicitResponse() {
LOGGER.debug("Calling Duke Web Service to Send Unsolicit Response ... ");
try{
ObjectFactory objecFactory = new ObjectFactory();
CreditStatusMsgType creditStatusMessage = objecFactory.createCreditStatusMsgType();
creditStatusMessage.setMessageHeader(createMessageHeader(objecFactory));
//WRAP THE CLASS AS THE INSTANCE OF JAXBELEMENT OTHERWISE IT WILL THROW MISSING ROOTELEMENT ERROR
JAXBElement<CreditStatusMsgType> creditStatusMessageJaxbElement = objecFactory.createSendCreditStatus(creditStatusMessage);
//CREATE STRING WRITER TO LOG THE REQUEST
Object response = this.webServiceTemplate.marshalSendAndReceive(creditStatusMessageJaxbElement);
LOGGER.debug("Jumio Web Service Response Reponse :"+response);
LOGGER.debug("Unsolicit Response sent to Duke Successfully.");
}catch(Exception ex){
LOGGER.error("Exception generated while calling Web Service to send unsolicit Response : "+ex.getLocalizedMessage(),ex);
}
}
下面是 xml 配置,我在其中声明了拦截器来记录请求和响应:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:sws="http://www.springframework.org/schema/web-services"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:oxm="http://www.springframework.org/schema/oxm"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/web-services
http://www.springframework.org/schema/web-services/web-services-2.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/oxm http://www.springframework.org/schema/oxm/spring-oxm.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
<!-- DEFINE SOAP VERSION USED BY A WSDL -->
<bean id="soapMessageFactory" class="org.springframework.ws.soap.saaj.SaajSoapMessageFactory">
<property name="soapVersion">
<!-- FOR TEXT/XML -->
<util:constant static-field="org.springframework.ws.soap.SoapVersion.SOAP_11"/>
</property>
</bean>
<!-- LOCATION OF THE GENERATED JAVA FILEs -->
<oxm:jaxb2-marshaller id="marshaller" contextPath="com.equifax.unsolicited.wsdl.stub"/>
<!-- CONFIGURE THE SPRING WEB SERVICE -->
<bean id="webServiceTemplate" class="org.springframework.ws.client.core.WebServiceTemplate">
<constructor-arg ref="soapMessageFactory"/> <property name="marshaller" ref="marshaller"/>
<property name="unmarshaller" ref="marshaller"/>
<property name="defaultUri" value="https://partnerstg.duke-energy.com:4443/DukCISSendCreditStatus?wsdl"/>
</bean>
<sws:interceptors>
<bean id="jumioPeyLoadLoggingInterceptor" class="com.test.datasource.logging.interceptor.PayloadLoggingInterceptor">
</bean>
<bean id="jumioSOAPLoggingInterceptor" class="com.test.datasource.logging.interceptor.SOAPLoggingInterceptor">
</bean>
</sws:interceptors>
</beans>
而且我还添加了新的日志记录类别,以将记录器级别设置为 DEBUG 模式:
以上代码调用网络服务成功。但是拦截器没有被调用。所以我无法记录 XML 请求和响应。
在这里,我假设这些拦截器在使用服务时不会工作。如果我在这里错了,请告诉我。
我指的是来自 HERE 的 Spring Web 服务。本站在发布web-service时对拦截器进行了说明
请告诉我我们应该在使用网络服务时使用这个拦截器吗?或者我应该如何打印 JAXB-ELEMENT 的请求和响应?
我在这里添加我已经实施的解决方案。我们可以通过两种方式实施此解决方案。我已经使用 JAXBContext 和 Marshaller 实现了下面列表中的第二个。
1> 日志 Request/Response 通过拦截器。
我们在使用 Web 服务时不能使用 PayloadLoggingInterceptor 或 SOAPLoggingInterceptor。
我们在使用 Web 服务时需要使用 ClientInterceptor。 ClientInterceptor 由 PayloadValidatingInterceptor class 实现,用于拦截 request/response 并根据 [=45 验证它=] 模式。
为此,我们需要提供如下拦截器参考:
<bean id="MyPayloadValidatingInterceptor" class="com.equifax.ic.datasource.jumio.ws.logging.interceptor.JumioPayloadValidatingInterceptor">
<property name="schema" value="file:WebContent/WEB-INF/schemas/account-balance-service.xsd" />
<property name="validateRequest" value="false" />
<property name="validateResponse" value="false" />
</bean>
<bean id="webServiceTemplate" class="org.springframework.ws.client.core.WebServiceTemplate">
<constructor-arg ref="soapMessageFactory"/> <property name="marshaller" ref="marshaller"/>
<property name="unmarshaller" ref="marshaller"/>
<property name="defaultUri" value="https://partnerstg.duke-energy.com:4443/DukCISSendCreditStatus?wsdl"/>
<property name="interceptors">
<list>
<ref bean="MyPayloadValidatingInterceptor"/>
</list>
</property>
</bean>
2> 使用 JAXBContext
记录 Request/Response这是我在我的应用程序中实施的解决方案,因为我们不应该只使用 PayloadValidatingInterceptor 来记录 reqeust/response。
private void logJAXBRequest(JAXBElement<CreditStatusMsgType> creditStatusMessageJaxbElement){
LOGGER.debug("Logging Web Service Request ...");
StringWriter writer = null;
StreamResult streamResult = null;
StringBuffer buffer = null;
try{
writer = new StringWriter();
streamResult = new StreamResult(writer);
JAXBContext jaxbContext = JAXBContext.newInstance(CreditStatusMsgType.class);
Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.marshal(creditStatusMessageJaxbElement, streamResult);
buffer = writer.getBuffer();
LOGGER.debug("JAXB Webservice Request : "+ buffer.toString());
writer.close();
}catch(Exception ex){
LOGGER.error("Exception generated while creating XML Logs of JAXB Request :",ex);
}
}
大家好,同事们。 显示 XML 请求/响应的主要方式有两种:
首先,您必须将
log4j
依赖项添加到pom.xml
文件中:<dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency>
然后您必须将
log4j.properties
文件放入应用程序的类路径中。当我开发 SOAP 服务时,我经常使用 Spring WS Maven artefact。不幸的是,usualresources
文件夹不是从头开始创建的,您必须手动创建它。然后你把log4j.properties
文件放在那里。 log4j 配置的内容取决于您要使用的方法(请参阅下面的项目)。得到的结构如下:使用标准 Message Logging and Tracing 方法和
log4j.properties
文件。除了 log4j 配置文件内容外,不应配置、开发、编写任何内容。 log4j 配置的内容应该如下(按原样使用这些内容):log4j.rootCategory=DEBUG, stdout log4j.logger.org.springframework.ws.client.MessageTracing.sent=TRACE log4j.logger.org.springframework.ws.client.MessageTracing.received=DEBUG log4j.logger.org.springframework.ws.server.MessageTracing=DEBUG log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%p [%c{3}] %m%n
使用
PayloadLoggingInterceptor
&log4j.properties
文件。应该应用一些配置更改,但这种方法对我来说更灵活。首先,您必须将PayloadLoggingInterceptor
添加到MessageDispatcherServlet
配置文件中:<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:sws="http://www.springframework.org/schema/web-services" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/web-services http://www.springframework.org/schema/web-services/web-services-2.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <context:component-scan base-package="com.ln.springws"/> <sws:annotation-driven/> <sws:interceptors> <bean class="org.springframework.ws.server.endpoint.interceptor.PayloadLoggingInterceptor" /> </sws:interceptors> <sws:dynamic-wsdl id="holiday" portTypeName="HumanResource" locationUri="http://localhost:8080/holidayService/" targetNamespace="http://spring-ws-holidays.com/hr/definitions"> <sws:xsd location="/WEB-INF/hr.xsd"/> </sws:dynamic-wsdl> </beans>
最后将以下内容放入
log4j.properties
文件:log4j.rootLogger=debug, stdout log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%-5p [%c] - <%m>%n
由于这两种方法,您将在控制台中看到类似的内容: