spring - 如何在使用第三方 Web 服务时使用 PayloadLoggingInterceptor 和 SOAPLoggingInterceptor 拦截器

标签 spring maven jaxb webservice-client spring-ws

在我的应用程序中,我正在使用由我的客户提供的第三方网络服务。

我已经在 Spring 和 Hibernate 框架上开发了我的应用程序,并且在一个模块中我正在使用这个第三方网络服务 url。我已经使用

生成了网络服务 stub

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 服务.本网站在发布网络服务时对拦截器进行了说明。

请告诉我我们应该在使用网络服务时使用这个拦截器吗?或者我应该如何打印 JAXB-ELEMENT 的请求和响应?

最佳答案

我在这里添加我已经实现的解决方案。我们可以通过两种方式实现此解决方案。我已经使用 JAXBContext 和 Marshaller 实现了下面列表中的第二个。

1> 通过拦截器记录请求/响应。

当我们使用网络服务时,我们不能使用 PayloadLoggingInterceptorSOAPLoggingInterceptor

当我们使用网络服务时,我们需要使用ClientInterceptorClientInterceptorPayloadValidatingInterceptor 类实现,用于拦截请求/响应并根据 xsd 模式验证它。

为此,我们需要提供如下拦截器引用:

<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 记录请求/响应

这是我在我的应用程序中实现的解决方案,因为我们不应该只使用 PayloadValidatingInterceptor 来记录请求/响应。

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);
        }
    }

关于spring - 如何在使用第三方 Web 服务时使用 PayloadLoggingInterceptor 和 SOAPLoggingInterceptor 拦截器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32006048/

相关文章:

java - 将本地 Java 项目 merge 到现有 git 存储库

java - reCaptcha 在用 Google 验证时总是返回 false

git - 将 Git、Gradle 和 Maven 与 ZScaler 证书一起使用?

java - 如果我们在 Maven 中央存储库中找不到 jar 文件,将其添加到 Maven 项目的最佳方法是什么?

java - 如何解决松散耦合/依赖性注入(inject)与富域模型之间的冲突?

java - 如何从数据库中获取电子邮件和密码?我无法在 Spring security 中验证用户

java - Maven 无法找到 org.springframework.ws :spring-ws:1. 5.8

java - 如何解决java.lang.NoClassDefFoundError : javax/xml/bind/JAXBException

java - 非无状态 JAXB XML 适配器

java - 使用 jaxb 从 xml 元素列表中提取值