WLI transform xQuery null node - java

I'm using a WLI SOA Application with Hibernate.
I have the following class:
class PersonDB implements Serializable {
Integer id;
String name;
Date dob;
/** getters and setters **/
}
In the ModelPerson JPD, I have the following transform:
PersonDB personDB;
ModelDocument modelXML;
void transformModelXMLToPersonDBModel throws Exception {
this.personDB = transformTransactioModel.transformModelXMLToPersonDBModel(this.modelXML);
}
In the Transform Abstract Class I have the following tranformation:
#com.bea.wli.transform.XQueryTransform(transformType = com.bea.wli.transform.XQueryTransform.TransformMethodType.XQUERY_REF, value = "transformModelXMLToPersonDBModel.xq", schemaValidate = #com.bea.wli.transform.XQueryTransform.SchemaValidate(returnValue = false, parameters = false))
public abstract PersonDB transformModelXMLToPersonDBModel(ModelDocument object);
And the xQuery transformModelXMLToPersonDBModel.xq is:
declare namespace xf = "http://tempuri.org/Dominio/src/com/process/transformations/transformModelXMLToPersonDBModel/";
declare namespace ns-1 = "person.model.tempuri.com";
declare function xf:transformModelXMLToPersonDBModel($object as element(ns-1:Model)) as element() {
for $o in $object return (
<PersonDB>
{
for $code in $o/code
return
<id?>{ data($code) }</id>
}
{
for $nameOfPerson in $o/nameOfPerson
return
<name?>{ data($nameOfPerson)}</name>
}
{
for $date in $o/date
return
<dob?>{ data($date) }</dob>
}
</PersonDB>
)
};
declare variable $object as element(ns-1:Model) external;
xf:transformModelXMLToPersonDBModel($object)
Later, when I test an operation through SoapUI, I try with the following request in the first time:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:open="http://www.openuri.org/" xmlns:pers="person.model.tempuri.com">
<soapenv:Header/>
<soapenv:Body>
<open:find>
<pers:Model>
<!--Optional:-->
<code>100</code>
<!--Optional:-->
<nameOfPerson>John</nameOfPerson>
<!--Optional:-->
<date>1985-11-23T12:44:07</date>
</pers:Model>
</open:find>
</soapenv:Body>
</soapenv:Envelope>
This response is ok.
At the second time, I test the following request to return all persons:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:open="http://www.openuri.org/" xmlns:pers="person.model.tempuri.com">
<soapenv:Header/>
<soapenv:Body>
<open:find>
<pers:Model>
</pers:Model>
</open:find>
</soapenv:Body>
</soapenv:Envelope>
This response logs the following error in SoapUI response:
fc:JWSError
Unhandled process exception
com.bea.wli.bpm.runtime.UnhandledProcessException:
Unhandled process exception [ServiceException] at
com.bea.wli.bpm.runtime.JpdContainer.preInvoke(JpdContainer.java:1043)
at
com.bea.wli.knex.runtime.core.container.Invocable.invoke(Invocable.java:248)
at com.bea.wli.bpm.runtime.JpdContainer.invoke(JpdContainer.java:814)
at
com.bea.wli.knex.runtime.core.bean.BaseContainerBean.invokeBase(BaseContainerBean.java:224)
at
com.bea.wli.knex.runtime.core.bean.SLSBContainerBean.invoke(SLSBContainerBean.java:136)
at
com.bea.wlwgen.StatelessContainer_2hozgx_ELOImpl.invoke(StatelessContainer_2hozgx_ELOImpl.java:137)
at com.bea.wlwgen.SLSBContAdpt.invokeOnBean(SLSBContAdpt.java:29) at
com.bea.wli.knex.runtime.core.bean.BaseDispatcherBean.runAsInvoke(BaseDispatcherBean.java:185)
at
com.bea.wli.knex.runtime.core.bean.BaseDispatcherBean.invoke(BaseDispatcherBean.java:54)
at
com.bea.wli.knex.runtime.core.bean.SyncDispatcherBean.invoke(SyncDispatcherBean.java:168)
at
com.bea.wli.knex.runtime.core.bean.SyncDispatcher_k1mrl8_EOImpl.invoke(SyncDispatcher_k1mrl8_EOImpl.java:133)
at
com.bea.wli.knex.runtime.core.dispatcher.Dispatcher.remoteDispatch(Dispatcher.java:165)
at
com.bea.wli.knex.runtime.core.dispatcher.Dispatcher.dispatch(Dispatcher.java:49)
at
com.bea.wli.knex.runtime.core.dispatcher.HttpServerHelper.executePostRequest(HttpServerHelper.java:711)
at
com.bea.wli.knex.runtime.core.dispatcher.HttpServer.doPost(HttpServer.java:33)
at com.bea.wli.bpm.runtime.JpdServlet.doPost(JpdServlet.java:253) at
javax.servlet.http.HttpServlet.service(HttpServlet.java:763) at
javax.servlet.http.HttpServlet.service(HttpServlet.java:856) at
weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:227)
at
weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:125)
at
weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:283)
at
weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:175)
at
weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:3231)
at
weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321)
at
weblogic.security.service.SecurityManager.runAs(SecurityManager.java:121)
at
weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:2002)
at
weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:1908)
at
weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1362)
at weblogic.work.ExecuteThread.execute(ExecuteThread.java:209) at
weblogic.work.ExecuteThread.run(ExecuteThread.java:181) Caused by:
com.bea.wli.bpm.runtime.UnhandledProcessException: Unhandled process
exception at
com.bea.wli.bpm.runtime.Activity.processException(Activity.java:380)
at com.bea.wli.bpm.runtime.OnException.rethrow(OnException.java:101)
at com.bea.wli.bpm.runtime.OnException.execute(OnException.java:198)
at
com.bea.wli.bpm.runtime.SyncReceive.messageDelivery(SyncReceive.java:63)
at
com.bea.wli.bpm.runtime.ProcessState.processMessage(ProcessState.java:217)
at
com.bea.wli.bpm.runtime.ProcessState.dispatchRequest(ProcessState.java:241)
at
com.bea.wli.bpm.runtime.JpdContainer.dispatchProcessRequest(JpdContainer.java:1077)
at
com.bea.wli.bpm.runtime.JpdContainer.preInvoke(JpdContainer.java:1041)
... 29 more Caused by: com.bea.transform.TransformException:
Unexpected error in transformation - please look at the log for
details. at
com.bea.wli.transform.TransformExecutor.executeXQ2004(TransformExecutor.java:245)
at
com.bea.wli.transform.TransformExecutor.execute(TransformExecutor.java:94)
at
com.bea.wli.transform.runtime.DtfDispMethod.invoke(DtfDispMethod.java:393)
at
com.bea.wli.knex.runtime.core.container.Invocable.invoke(Invocable.java:503)
at
com.bea.wli.knex.runtime.core.container.Invocable.invoke(Invocable.java:476)
at
com.bea.wli.transform.runtime.DtfHandler.invoke(DtfHandler.java:112)
at
com.process.transformations.TransaformTransactionModelImpl.transformModelXMLToPersonDBModel(TransaformTransactionModelImpl.java:436)
at
com.process.ModeloPerson.transformModelXMLToPersonDBModel(ModeloPerson.java:163)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585) at
com.bea.wli.bpm.runtime.Perform.invoke(Perform.java:39) at
com.bea.wli.bpm.runtime.Perform.execute(Perform.java:50) ... 34 more
Caused by: java.lang.NullPointerException at
com.bea.wli.xquery.marshall.xq2004.ClassUnmarshaller.isFullNode(ClassUnmarshaller.java:225)
at
com.bea.wli.xquery.marshall.xq2004.ClassUnmarshaller.unmarshall(ClassUnmarshaller.java:78)
at
com.bea.wli.xquery.marshall.xq2004.PlanUnmarshaller.unmarshall(PlanUnmarshaller.java:13)
at
com.bea.wli.transform.TransformExecutor.executeXQ2004(TransformExecutor.java:231)
... 47 more
I think that the problem is when I send a empty $object in xQuery but I don't know how to validate this parameter if is null.

This is just a guess but you could try changing your types to indicate the element is optional. e.g.
declare function xf:transformModelXMLToPersonDBModel($object as element(ns-1:Model)?) as element()? {
....
};
declare variable $object as element(ns-1:Model)? external;
xf:transformModelXMLToPersonDBModel($object)
Notice I added the optional indicator '?' after the item types.

Related

How do I call a request that has entity in it?

(1) The class I described below includes three strings and one entity.
(2) The text I sent as a call is as follows.
(3) But I'm making the mistake.
1:
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "", propOrder = {"tesisatKod", "islemGuid", "islemTutari", "islemTuru"})
#XmlRootElement(name = "secondStageRequest")
public class SecondStageRequest {
protected String tesisatKod;
protected String islemGuid;
// protected Date sorguSaatTarih;
protected String islemTutari;
protected IslemTuru islemTuru;
}
2:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xc="http://xml.cinigaz.com.tr">
<soapenv:Header>
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" wsse:mustUnderstand="1">
<wsse:UsernameToken>
<wsse:Username>admin</wsse:Username>
<wsse:Password>pwd1234</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
</soapenv:Header>
<soapenv:Body>
<xc:secondStageRequest>
<xc:tesisatKod>bbb</xc:tesisatKod>
<xc:islemGuid>bbb</xc:islemGuid>
<xc:islemTutari>bbb</xc:islemTutari>
<xc:islemTuru>
<xc:islemTuruId> 1</xc:islemTuruId>
<xc:islemTuruAdi> aaa</xc:islemTuruAdi>
</xc:islemTuru>
</xc:secondStageRequest>
</soapenv:Body>
</soapenv:Envelope>
3:
WARN 20148 --- [nio-9020-exec-2] s.w.s.s.e.i.PayloadValidatingInterceptor : XML validation error on request: cvc-type.3.1.2: Element 'xc:islemTuru' is a simple type, so it must have no element information item [children].

How to handle multiple SOAP requests in the same envelope using Java Web Service?

I currently have a web service with the method:
#Override
#WebResult(Name="OIPResponse")
public Map<String, Object> getOIP(#WebParam(name = "invoice") String invoiceNumber,#WebParam(name = "part") String partNumber)
The normal SOAP request I use to call it looks like this:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:oip="http://oip.mycompany.com/">
<soapenv:Header/>
<soapenv:Body>
<oip:getOIP>
<invoice>41587182</invoice>
<part>9ZF2A5-570</part>
</oip:getOIP>
</soapenv:Body>
</soapenv:Envelope>
and the response is something like this:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ns2:getOIPResponse xmlns:ns2="http://oip.mycompany.com/">
<OIPResponse>
<entry>
<key>ERR_CODE</key>
</entry>
<entry>
<key>SELLING_OU</key>
<value xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" xsi:type="xs:string">null</value>
</entry>
...
</OIPResponse>
</ns2:getOIPResponse>
</soap:Body>
</soap:Envelope>
I've tested this and it works fine. Now I am wondering if there is a way to include multiple requests in the same SOAP envelope like this:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:oip="http://oip.mycompany.com/">
<soapenv:Header/>
<soapenv:Body>
<oip:getOIP>
<invoice>41587182</invoice>
<part>9ZF2A5-570</part>
</oip:getOIP>
<oip:getOIP>
<invoice>41587183</invoice>
<part>9ZF2A5-570</part>
</oip:getOIP>
<oip:getOIP>
<invoice>41587184</invoice>
<part>9ZF2A5-570</part>
</oip:getOIP>
<oip:getOIP>
<invoice>41587185</invoice>
<part>9ZF2A5-570</part>
</oip:getOIP>
</soapenv:Body>
</soapenv:Envelope>
and get back something like this:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ns2:getOIPResponse xmlns:ns2="http://oip.mycompany.com/">
<OIPResponse>
...
</OIPResponse>
<OIPResponse>
...
</OIPResponse>
<OIPResponse>
...
</OIPResponse>
...
</ns2:getOIPResponse>
</soap:Body>
</soap:Envelope>
Is there any way to do this?
I ended up creating a POJO called OIPRequest that contained the two parameters I need (invoice and part number) and a new method getOIPMultiple which takes an array of OIPRequests as an input parameter.
import javax.xml.bind.annotation.XmlRootElement;
#XmlRootElement
public class OIPRequest {
public String invoiceNumber, partNumber;
public OIPRequest(String invoice, String part) {
invoiceNumber = invoice;
partNumber = part;
}
public OIPRequest() {
invoiceNumber = "";
partNumber = "";
}
}
This makes the request look like this:
<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/">
<Body>
<getMultipleOIP xmlns="http://oip.mycompany.com/">
<OIPRequest xmlns="">
<invoiceNumber>41587182</invoiceNumber>
<partNumber>9ZF2A5-570</partNumber>
</OIPRequest>
<OIPRequest xmlns="">
<invoiceNumber>41587182</invoiceNumber>
<partNumber>9ZF2A5-570</partNumber>
</OIPRequest>
<OIPRequest xmlns="">
<invoiceNumber>41587182</invoiceNumber>
<partNumber>9ZF2A5-570</partNumber>
</OIPRequest>
</getMultipleOIP>
</Body>
</Envelope>

SOAP request modification

I have a SOAP request like this, it's working fine:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:web="http://com/">
<soapenv:Header/>
<soapenv:Body>
<web:ConversionRate>
<!--Optional:-->
<FromCurrency>?</FromCurrency>
<!--Optional:-->
<ToCurrency>?</ToCurrency>
</web:ConversionRate>
</soapenv:Body>
</soapenv:Envelope>
I was changing the request a litle bit to understand the concepts:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" >
<soapenv:Header/>
<soapenv:Body>
<ConversionRate xmlns="http://com/">>
<!--Optional:-->
<FromCurrency>?</FromCurrency>
<!--Optional:-->
<ToCurrency>?</ToCurrency>
</ConversionRate>
</soapenv:Body>
</soapenv:Envelope>
The second one is not working, throwing a wrong answer.
My service class is
package com;
import javax.jws.WebService;
import javax.jws.WebMethod;
import javax.jws.WebParam;
#WebService (targetNamespace="http://com/")
public class CurrencyConvertor
{
public String ConversionRate (#WebParam(name = "FromCurrency") String FromCurrency, #WebParam(name = "ToCurrency") String ToCurrency)
{
System.out.println("ST\n" + FromCurrency + "\n" + ToCurrency + "\nEnd" );
switch(FromCurrency+","+ToCurrency)
{
case "USD,INR":
return "58";
case "INR,USD":
return "0.017";
default:
return "XXX";
}
}
}
The second request always falling to default case, the thing is, the values are sending as null since I changed the name space. So my Web service should answer for the second request properly, what should cause the issue, how to rectify this.
your namespace is not correct even it looks well.
I have to change com to com.example, because it is not possible to post answer with link to com only.
tns=http://com.example/ is defined in
the WebService, not for the webmethod. Change your method declaration to
public String ConversionRate (
#WebParam(name = "FromCurrency", tagetNamespace = "http://com.example/") String FromCurrency,
#WebParam(name = "ToCurrency", tagetNamespace = "http://com.example/") String ToCurrency) {
...
}
Even I'm not definitely sure if the XML has valid format
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" >
<soapenv:Header/>
<soapenv:Body>
<ConversionRate xmlns="http://com.example/">
<FromCurrency>?</FromCurrency>
<ToCurrency>?</ToCurrency>
</ConversionRate>
</soapenv:Body>
</soapenv:Envelope>
or namespace is required just for parameters
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" >
<soapenv:Header/>
<soapenv:Body>
<ConversionRate>
<FromCurrency xmlns="http://com.example/">?</FromCurrency>
<ToCurrency xmlns="http://com.example/">?</ToCurrency>
</ConversionRate>
</soapenv:Body>
</soapenv:Envelope>

Using JAX-WS to send SOAP request with headers

The request which I want to send is :-
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:idm="http://integration.standardandpoors.com/Schema/IDM">
<soapenv:Header>
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsu:Timestamp xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="Timestamp-23762130">
<wsu:Created>2013-06-09T06:00:44.733Z</wsu:Created>
<wsu:Expires>2013-06-09T08:00:44.733Z</wsu:Expires>
</wsu:Timestamp>
<wsse:BinarySecurityToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" EncodingType="SSHA" ValueType="AccessManagerSSOSecurityToken" wsu:Id="OAMToken">TOKEN HARE</wsse:BinarySecurityToken>
</wsse:Security>
</soapenv:Header>
<soapenv:Body>
<idm:findUserById>
<applicationName>APP ID</applicationName>
<userId>USER ID</userId>
</idm:findUserById>
</soapenv:Body>
</soapenv:Envelope>
My current java code is
public class WsClient{
public static void main(String[] args) throws Exception {
IdmService sis = new IdmService();
IdmWebServicePort si = sis.getIdmWebServiceImplPort();
WSBindingProvider bp = (WSBindingProvider)si;
Element node = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new ByteArrayInputStream("<wsse:Security xmlns:wsse=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd\"> <wsu:Timestamp xmlns:wsu=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd\" wsu:Id=\"Timestamp-23762130\"><wsu:Created>2013-06-09T06:00:44.733Z</wsu:Created> <wsu:Expires>2013-06-09T08:00:44.733Z</wsu:Expires></wsu:Timestamp><wsse:BinarySecurityToken xmlns:wsu=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd\" EncodingType=\"SSHA\" ValueType=\"AccessManagerSSOSecurityToken\" wsu:Id=\"OAMToken\">token here</wsse:BinarySecurityToken></wsse:Security>".getBytes())).getDocumentElement();
bp.setOutboundHeaders(
Headers.create(node)
);
//si.getSecurityChallengeQuestionsAndAnswersForUser("APP NAME", "USER ID");
User u=si.findUserById("MSA", "test100#sandp.com");
System.out.println(u.getFirstName());
}
}
error which I am getting is :-
Exception in thread "main" java.lang.NoSuchMethodError: com.sun.xml.bind.api.JAXBRIContext.newInstance

Setting up an XML response for SOAP

I'm having a real hard time with this issue.
Basically I've built a WebService using Java/JAX-WS, this is my Interface
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
#WebService
public interface OperationsInterface {
#WebResult(name = "result")
LoginResponse Login(#WebParam(name = "login") Login login);
#WebResult(name = "result")
String Purchase(#WebParam(name = "purchase") Purchase purchase);
}
Login is just a POJO that contains 2 strings (username and password)
LoginResponse is another POJO, it has this
String status;
int code;
String message;
SubscriptionTier subscriptionTier;
String accountNumber;
String firstName;
String lastName;
Nothing fancy, pretty simple in fact. The request is something like this
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ott="http://ott.amentum.net/">
<soapenv:Header/>
<soapenv:Body>
<ott:Login>
<login>
<username>USERNAME</username>
<password>1234</password>
</login>
</ott:Login>
</soapenv:Body>
</soapenv:Envelope>
And the response comes like this
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ns2:LoginResponse xmlns:ns2="http://ott.amentum.net/">
<result>
<accountNumber>0110000076</accountNumber>
<code>1</code>
<firstName>JOHN</firstName>
<lastName>DOE</lastName>
<message>Login has been successful.</message>
<status>success</status>
<subscriptionTier>
<tier>TVOD</tier>
<tier>CANAL</tier>
<tier>CATCHUP</tier>
</subscriptionTier>
</result>
</ns2:LoginResponse>
</soap:Body>
</soap:Envelope>
As far as I know, this is correct, however, my customer is expecting something like this
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ns2:LoginResponse xmlns:ns2="http://ott.amentum.net/">
<accountNumber>0410089676</accountNumber>
<code>1</code>
<firstName>MARIA DEL CARMEN</firstName>
<lastName>PADILLA MARTIN</lastName>
<message>Login has been successful.</message>
<status>success</status>
<subscriptionTier>
<tier>TVOD</tier>
<tier>CANAL</tier>
<tier>CATCHUP</tier>
</subscriptionTier>
</ns2:LoginResponse>
</soap:Body>
</soap:Envelope>
They want me to remove the result tag, which is the name of the LoginResponse object I created to return the information.
Is there a way to do this?
Thanks in advance

Categories

Resources