2014-01-08 4 views
1

xml을 받고 변환하고 WSO2 데이터 서비스로 전달하고 결과를 변환하여 요청자에게 돌려주는 WSO2 ESB에 프록시를 구축했습니다.DataService 결과를 변환하려고 할 때 NPE

결과 XML이 인쇄되므로 DataService가 올바르게 호출되고 있습니다.

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:xs="http://ws.wso2.org/dataservice" version="2.0" 
    xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" 
    xpath-default-namespace="http://www.algartelecom.com.br/SOA/Service/GetAppointmentSchedulePortalReqCS"> 
    <xsl:output method="xml" indent="yes" /> 
    <xsl:template match="//xs:GetAppointmentResponse"> 
     <AppointmentRequest> 
      <serviceOrderID> 
       <xsl:value-of select="xs:NewAppointment" /> 
      </serviceOrderID> 
      <opportunityID> 
       <xsl:value-of select="xs:ServiceTOA" /> 
      </opportunityID> 
      <customerOrderID> 
       <xsl:value-of select="xs:MinimalTime" /> 
      </customerOrderID> 
     </AppointmentRequest> 
    </xsl:template> 
</xsl:transform> 

그리고 DataService에 의해 반환 된 XML은 다음과 같습니다 :

ERROR - XSLTMediator Unable to perform XSLT transformation using : Value {name ='null', keyValue ='GetAppointmentSchedulePortalReqCS_Response'} against source XPath : s11:Body/child::*[position()=1] | s12:Body/child::*[position()=1] 
java.lang.NullPointerException 
    at org.apache.synapse.util.jaxp.StreamSourceBuilder.getSource(StreamSourceBuilder.java:55) 
    at org.apache.synapse.mediators.transform.XSLTMediator.performXSLT(XSLTMediator.java:289) 
    at org.apache.synapse.mediators.transform.XSLTMediator.mediate(XSLTMediator.java:191) 
    at org.apache.synapse.mediators.AbstractListMediator.mediate(AbstractListMediator.java:71) 
    at org.apache.synapse.mediators.base.SequenceMediator.mediate(SequenceMediator.java:114) 
    at org.apache.synapse.core.axis2.Axis2SynapseEnvironment.injectMessage(Axis2SynapseEnvironment.java:230) 
    at org.apache.synapse.core.axis2.SynapseCallbackReceiver.handleMessage(SynapseCallbackReceiver.java:443) 
    at org.apache.synapse.core.axis2.SynapseCallbackReceiver.receive(SynapseCallbackReceiver.java:166) 
    at org.apache.axis2.engine.AxisEngine.receive(AxisEngine.java:180) 
    at org.apache.synapse.transport.passthru.ClientWorker.run(ClientWorker.java:217) 
    at org.apache.axis2.transport.base.threads.NativeWorkerPool$1.run(NativeWorkerPool.java:172) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918) 
    at java.lang.Thread.run(Thread.java:662) 

XLST 파일은 다음과 같습니다

<?xml version='1.0' encoding='utf-8'?> 
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> 
    <soapenv:Body> 
     <GetAppointmentResponse xmlns="http://ws.wso2.org/dataservice"> 
      <NewAppointment>147</NewAppointment> 
      <ServiceTOA>TT_P</ServiceTOA> 
      <MinimalTime>1</MinimalTime> 
      <ReturnCode>0</ReturnCode> 
      <ErrorMessage>SUCESSO</ErrorMessage> 
     </GetAppointmentResponse> 
    </soapenv:Body> 
</soapenv:Envelope> 

난 문제는 이런 결과의 변형에 다른 도구에서 XML을 사용하여 XSLT를 테스트 한 결과 tranformation이 작동합니다! =/

나는 GetAppointmentResponse 태그에 DSS에 의해 추가 된 인라인 네임 스페이스 때문에 발생할 수 있다고 생각합니다. JRE1.6.0_43, ESB 4.6.0 및 DSS 3.1.0 사용. 도와주세요.

편집

나는 @Kallja가 언급 한 바와 같이이 문제가 정말 응답에 빈 몸으로 인해 발생 것으로 나타났습니다.

다시 시작, 나는 다음과 같은 시나리오가 :

 PROXY1   ->   PROXY2  ->  PROXY3  ->  ENDPOINT 
in xslt->log1->header->send log2->header->send xslt->log3  address web service 
out log6->xslt->send   log5->send   xslt->log4->send 

이 soapUI를 통해 직접 PROXY3 호출을의 웹 서비스가 제대로 호출되고 응답이 수신됩니다. PROXY2를 호출
하지만, 로그 시퀀스는 다음과 같은 순서로 나타납니다 log2log3, log5log4

그것은 PROXY2PROXY3에 대한 비동기 호출을 의미합니다. 답변을 soapUI로 반환하기 전에 응답의 XML을 기다리지 않습니다. 빈 몸체를 생성합니다.

그런 다음 동기화하는 방법은 무엇입니까? Call mediator로 Send 중재자를 대체하려고했지만 그 결과는 같습니다.

+0

변환도 색슨 9.5와 함께 작동 - 단지 정보. –

+0

변환이 코드 외부와 Saxon에서 작동하면 XSLT가 아닌 Java 코드의 잠재적 인 문제점을 알 수 있습니다. 그걸 보여줄 수 있어요? 오류 메시지는'GetAppointmentSchedulePortalReqCS_Response'와's11 : Body/child :: * [position() = 1] | s12 : Body/child :: * [position() = 1]', 어느 쪽도 우리에게 제공 한 코드의 어느 부분도 아닙니다. 이것들이 무엇을 말하는지 아십니까? – JLRishe

+0

'GetAppointmentSchedulePortalReqCS_Response'은 설명 된 xsl 파일입니다. WSO2 ESB에서 실행되기 때문에 코드가 없습니다. – elias

답변

1

변환하려는 데이터를 가리키는 XPath 표현식 (이 경우에는 WSO2 ESB 기본값)이 null을 반환한다는 것을 나타내는 것으로 보이는 것 같습니다. 이 경우 빈 SOAP 본문이 있음을 의미합니다.

시퀀스 구성을 게시하지 않았으므로 함께 작업 할 필요가 없습니다.

내 제안은 전체 SOAP 봉투를 몇 가지 속성과 함께 ESB 콘솔과 카본 로그 파일, 즉 XSLT 조정자 바로 앞에 실제로 포함되어 있는지 확인하기 위해 전체 로그 (아래)를 추가하는 것입니다 귀하의 페이로드에있는 콘텐츠.

<log category="INFO" level="full" separator=","/> 

변환을 다음 구성으로 테스트 한 결과 무결점으로 수행되었습니다.스타일 요소를 당신의 XSLT 출력에서 ​​불필요한 SOAP의 xmlns 선언을 제거하기 위해 : 나는 당신이 당신의 XSL에 다음 속성을 추가 좋을 것 보조 노트로

<?xml version="1.0" encoding="UTF-8"?> 
<proxy xmlns="http://ws.apache.org/ns/synapse" 
     name="XsltTestProxy" 
     transports="https,http" 
     statistics="disable" 
     trace="disable" 
     startOnLoad="true"> 
    <target> 
     <inSequence> 
     <payloadFactory> 
      <format> 
       <GetAppointmentResponse xmlns="http://ws.wso2.org/dataservice"> 
        <NewAppointment>147</NewAppointment> 
        <ServiceTOA>TT_P</ServiceTOA> 
        <MinimalTime>1</MinimalTime> 
        <ReturnCode>0</ReturnCode> 
        <ErrorMessage>SUCESSO</ErrorMessage> 
       </GetAppointmentResponse> 
      </format> 
      <args/> 
     </payloadFactory> 
     <log level="custom"> 
      <property name="message" value="Before XSLT transformation"/> 
      <property name="payload" expression="$body"/> 
     </log> 
     <xslt key="gov:GetAppointmentSchedulePortalReqCS_Response"/> 
     <log level="custom"> 
      <property name="message" value="After XSLT transformation"/> 
      <property name="payload" expression="$body"/> 
     </log> 
     <property name="RESPONSE" value="true"/> 
     <header name="To" action="remove"/> 
     <send/> 
     </inSequence> 
    </target> 
    <description/> 
</proxy> 

.

exclude-result-prefixes="soapenv" 

EDIT
이 간단한 샘플의 구성은 질문 편집 실행 흐름의 설명에 기초한다. 문제의 흐름을 올바르게 구현하는 방법을 보여줍니다. Proxy1이 호출되면 로그 문은 예상대로 순서대로 나타납니다.

<definitions xmlns="http://ws.apache.org/ns/synapse"> 
<proxy name="Proxy1" statistics="disable" trace="disable"> 
    <target endpoint="Proxy2Endpoint"> 
     <inSequence> 
      <!-- Do some XSLT here --> 
      <log category="INFO" level="custom" separator=","> 
       <property name="message" value="Proxy1 in (1)"/> 
       <property expression="$body" name="body"/> 
      </log> 
      <!-- Do some header magic here --> 
      <!-- Implicit send to the endpoint specified in the target element --> 
     </inSequence> 
     <outSequence> 
      <log category="INFO" level="custom" separator=","> 
       <property name="message" value="Proxy1 out (6)"/> 
       <property expression="/*" name="body"/> 
      </log> 
      <!-- Do some more XSLT here --> 
      <send/> 
     </outSequence> 
    </target> 
</proxy> 
<proxy name="Proxy2" statistics="disable" trace="disable" transports="https http"> 
    <target endpoint="Proxy3Endpoint"> 
     <inSequence> 
      <log category="INFO" level="custom" separator=","> 
       <property name="message" value="Proxy2 in (2)"/> 
       <property expression="$body" name="body"/> 
      </log> 
      <!-- Do some header magic here --> 
      <!-- Implicit send to the endpoint specified in the target element --> 
     </inSequence> 
     <outSequence> 
      <log category="INFO" level="custom" separator=","> 
       <property name="message" value="Proxy2 out (5)"/> 
       <property expression="/*" name="body"/> 
      </log> 
      <send/> 
     </outSequence> 
    </target> 
</proxy> 
<proxy name="Proxy3" statistics="disable" trace="disable"> 
    <target endpoint="ImaginaryWebServiceEndpoint"> 
     <inSequence> 
      <!-- Do some XSLT here --> 
      <log category="INFO" level="custom" separator=","> 
       <property name="message" value="Proxy3 in (3)"/> 
       <property expression="$body" name="body"/> 
      </log> 
     </inSequence> 
     <outSequence> 
      <!-- Do some more XSLT here --> 
      <log category="INFO" level="custom" separator=","> 
       <property name="message" value="Proxy3 out (4)"/> 
       <property expression="/*" name="body"/> 
      </log> 
      <send/> 
     </outSequence> 
    </target> 
</proxy> 
<proxy name="ImaginaryWebService" statistics="disable" trace="disable"> 
    <target> 
     <inSequence> 
      <log category="INFO" level="custom" separator=","> 
       <property name="message" value="Imaginary WebService in"/> 
       <property expression="$body" name="body"/> 
      </log> 
      <payloadFactory> 
       <format> 
        <proxy3Response xmlns="">This is the response from the Imaginary WebService</proxy3Response> 
       </format> 
       <args/> 
      </payloadFactory> 
      <log category="INFO" level="custom" separator=","> 
       <property name="message" value="Imaginary WebService out"/> 
       <property expression="/*" name="body"/> 
      </log> 
      <header action="remove" name="To"/> 
      <property action="set" name="RESPONSE" scope="default" 
       type="STRING" value="true"/> 
      <send/> 
     </inSequence> 
    </target> 
</proxy> 
<endpoint name="Proxy2Endpoint"> 
    <address statistics="disable" trace="disable" uri="http://localhost:8280/services/Proxy2" /> 
</endpoint> 
<endpoint name="Proxy3Endpoint"> 
    <address statistics="disable" trace="disable" uri="http://localhost:8280/services/Proxy3" /> 
</endpoint> 
<endpoint name="ImaginaryWebServiceEndpoint"> 
    <address statistics="disable" trace="disable" uri="http://localhost:8280/services/ImaginaryWebService" /> 
</endpoint> 

+0

답변 주셔서 감사합니다. 문제는 실제로 빈 몸입니다. 나는 그 질문을 편집했다. – elias

관련 문제