I've inherited a project that communicates with a SOAP-based web service. I'm a total noob at this, although have been doing Java for many years and have done a good bit with XML.
We have a WSDL file for the service, which contains the schema at the top and all the message definition stuff below. At the core of the problem, when I try to connect to the service through our code, I get the dreaded unable to marshal type "https.api_blah_com.services.v4.Product" as an element because it is missing an #XmlRootElement annotation]
My project already has a jaxws binding file:
<jaxws:bindings wsdlLocation="../resources/wsdl/BlahAPI.wsdl"
xmlns:jaxws="http://java.sun.com/xml/ns/jaxws" xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
<jaxws:enableWrapperStyle>false</jaxws:enableWrapperStyle>
<jaxws:bindings
node="wsdl:definitions/wsdl:types/xs:schema[#targetNamespace='https:api.blah.com/services/v4']">
<jxb:globalBindings xmlns:jxb="http://java.sun.com/xml/ns/jaxb" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xjc:generateElementProperty>true</xjc:generateElementProperty>
</jxb:globalBindings>`
</jaxws:bindings>
</jaxws:bindings>
Now I've read that in order to get all my Java classes generated with #XmlRootElement, I need to add a jaxb:globalBinding turning on simple mode.
I've tried adding to my local copy of the WSDL this:
<xs:annotation>
<xs:appinfo>
<jaxb:globalBindings>
<xjc:simple />
</jaxb:globalBindings>
</xs:appinfo>
</xs:annotation>
But the JAXB compiler complains that it cannot honor this globalBindings customization because it's attached to a wrong place or is inconsistent with other bindings.
So I tried adding another bindings file, just for jaxb, like so:
<?xml version="1.0" encoding="UTF-8"?>
<jaxb:bindings version="1.0" xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<jaxb:bindings schemaLocation="../resources/wsdl/blah.wsdl">
<jaxb:globalBindings>
<xjc:simple />
</jaxb:globalBindings>
</jaxb:bindings>
</jaxb:bindings>
But then I get an error that blah.wsdl is not part of this compilation.
I am so close to calling this service...I just cannot get past this one thing, and it's all new to me so I'm not sure what else to try.
I could split out their WSDL into an XSD and a WSDL? Is that required to make this work?
I think you have to bind the xsd file not wsdl at this location. <jaxb:bindings schemaLocation="../resources/wsdl/blah.wsdl">. Please refer to section "External Binding Customization Files" at link.
Not sure if JAXB Binding is configured correctly. The #XmlRootElement required if class forms the root of your element structure. However in SOAP, SOAP element would form root of the XML, Hence check if your ObjectFacory.java class is generated, if generated verify if a method is created for the class type which returns an instance of the class type for example you have class Foo an method `public Foo createFoo() which returns instance of Foo should be present in your ObjectFoacory.java
However I would suggest you to use CXF provided WSDL2java this with client option enabled. It takes few minutes to configure a client code
Related
I'm trying to generate Java sources for a Web Service with Apache CXF wsdl2java executable (I've tried 2.7.8 and 3.2.0 versions).
My wsdl file come from an external agency (TMDD), so I assume is well generated
When I tried to generate files first time, a "Non-unique body parts" error occur:
org.apache.cxf.tools.common.ToolException: Non-unique body parts! In a port, operations must have unique operation signatures on the wire for successful dispatching. In port {http://www.tmdd.org/303/dialogs}tmddOCSoapHttpServicePort, operations "{http://www.tmdd.org/303/dialogs}dlVideoSwitchStatusRequest" and "{http://www.tmdd.org/303/dialogs}dlIntersectionSignalStatusRequest" have the same request body block {http://www.tmdd.org/303/messages}deviceInformationRequestMsg
at org.apache.cxf.tools.wsdlto.WSDLToJavaContainer.validate(WSDLToJavaContainer.java:735)
at org.apache.cxf.tools.wsdlto.WSDLToJavaContainer.processWsdl(WSDLToJavaContainer.java:276)
at org.apache.cxf.tools.wsdlto.WSDLToJavaContainer.execute(WSDLToJavaContainer.java:164)
at org.apache.cxf.tools.wsdlto.WSDLToJavaContainer.execute(WSDLToJavaContainer.java:412)
at org.apache.cxf.tools.common.toolspec.ToolRunner.runTool(ToolRunner.java:105)
at org.apache.cxf.tools.wsdlto.WSDLToJava.run(WSDLToJava.java:113)
at org.apache.cxf.tools.wsdlto.WSDLToJava.run(WSDLToJava.java:86)
at org.apache.cxf.tools.wsdlto.WSDLToJava.main(WSDLToJava.java:185)
I solved it creating a new input message type in dlVideoSwitchStatusRequest operation to avoid this. My steps were:
Create a new message type
<message name="MSG_VideoSwitchStatusRequest">
<part name="message" element="tmdd:videoSwitchStatusRequestMsg"/>
</message>
Declare videoSwitchStatusRequestMsg
<xs:element name="videoSwitchStatusRequestMsg" type="VideoSwitchStatusRequest">
<xs:annotation>
<xs:documentation>
<objectClass>VideoSwitch</objectClass>
<requirement>REQ1109</requirement>
</xs:documentation>
</xs:annotation>
</xs:element>
This one is defined in .xsd file as similar ones for other operations.
Modify input type for that operation
<operation name="dlVideoSwitchStatusRequest">
<documentation><objectClass>VideoSwitch</objectClass><objectClass>ExternalCenter</objectClass><objectClass>OwnerCenter</objectClass><msgPattern>R-R</msgPattern><requirement>REQ538</requirement></documentation>
<input message="tns:MSG_VideoSwitchStatusRequest"/> <!-- This is the new type -->
<!--<input message="tns:MSG_DeviceInformationRequest"/> This is the old one -->
<output message="tns:MSG_VideoSwitchStatus"/>
<fault name="errorReport" message="tns:MSG_ErrorReport"/>
</operation>
With this, that error was solved (i think), but now i get another error
Exception in thread "main" java.lang.InternalError: unresolved reference
at com.sun.xml.xsom.impl.parser.DelayedRef._get(DelayedRef.java:103)
at com.sun.xml.xsom.impl.parser.DelayedRef$Type.getType(DelayedRef.java:148)
at com.sun.xml.xsom.impl.ElementDecl.getType(ElementDecl.java:110)
at com.sun.xml.xsom.impl.ElementDecl.updateSubstitutabilityMap(ElementDecl.java:174)
at com.sun.xml.xsom.impl.parser.ParserContext.getResult(ParserContext.java:141)
at com.sun.xml.xsom.parser.XSOMParser.getResult(XSOMParser.java:214)
at com.sun.tools.xjc.ModelLoader.createXSOM(ModelLoader.java:538)
at com.sun.tools.xjc.api.impl.s2j.SchemaCompilerImpl.bind(SchemaCompilerImpl.java:269)
at com.sun.tools.xjc.api.impl.s2j.SchemaCompilerImpl.bind(SchemaCompilerImpl.java:95)
at org.apache.cxf.tools.wsdlto.databinding.jaxb.JAXBDataBinding.initialize(JAXBDataBinding.java:459)
at org.apache.cxf.tools.wsdlto.WSDLToJavaContainer.generateTypes(WSDLToJavaContainer.java:723)
at org.apache.cxf.tools.wsdlto.WSDLToJavaContainer.processWsdl(WSDLToJavaContainer.java:267)
at org.apache.cxf.tools.wsdlto.WSDLToJavaContainer.execute(WSDLToJavaContainer.java:164)
at org.apache.cxf.tools.wsdlto.WSDLToJavaContainer.execute(WSDLToJavaContainer.java:412)
at org.apache.cxf.tools.common.toolspec.ToolRunner.runTool(ToolRunner.java:105)
at org.apache.cxf.tools.wsdlto.WSDLToJava.run(WSDLToJava.java:113)
at org.apache.cxf.tools.wsdlto.WSDLToJava.run(WSDLToJava.java:86)
at org.apache.cxf.tools.wsdlto.WSDLToJava.main(WSDLToJava.java:185)
This one is too generic and I didn't found any info or doc from Apache site.
First, you must no assume the TMDD wsdl is well generated. I worked with it some time ago and is plenty of errors.
I recommend you to re-create your own version of TMDD.wsdl file, limiting it only to those items you're going to use.
Try that and tell us what you got.
Well, as B. Leal suggest, i drop old tmdd.wsdl and re-do my wsdl files with separate files for each device i will need data for.
As most work has been re-done, i'm not 100% sure about where that error came from, but i'm pretty sure that it was related with some types used in the old wsdl that wasn't declared properly in xsd files.
I know this is not a big help, but if someone falls in this same error, i think you only have two choices:
Re-do your wsdl files, as i did. (I recommend this one, it's easier than it seems)
Check if every single type used in wsdl are present in xsd files and if they're correct.
Thanks for help.
I had the same problem and mine was in XSD. Forgot to add namespace before type. tns and targetNamespace are the same url.
Before:
<xs:element name="getRequest" type="Request">
After
<xs:element name="getRequest" type="tns:Request">
This simple change in all elements using complexType/simpleType fixed the problem.
I'm making raw SOAP requests to Office365 and trying to get a list of contacts for specified AddressListId I successfully get a list of contacts, but it does not include all additional information I need. Once I add some additional properties (e.g. PhoneNumber) to my request, the server returns Invalid shape error.
Here is my request:
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types"
xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages">
<soap:Header>
<t:RequestServerVersion Version="Exchange2013" />
</soap:Header>
<soap:Body >
<m:FindPeople>
<m:PersonaShape>
<t:BaseShape>IdOnly</t:BaseShape>
<t:AdditionalProperties>
<t:FieldURI FieldURI="persona:DisplayName"/>
<t:FieldURI FieldURI="persona:PhoneNumber"/>
</t:AdditionalProperties>
</m:PersonaShape>
<m:IndexedPageItemView BasePoint="Beginning" MaxEntriesReturned="100" Offset="0"/>
<m:ParentFolderId>
<t:AddressListId Id="###-####-####-####"/>
</m:ParentFolderId>
</m:FindPeople>
</soap:Body>
</soap:Envelope>
How can I get all additional information for each persona?
I am using EWS Managed API, so you will have to search for the raw SOAP calls on MSDN, I can only direct your search a bit:
I had a similar problem, because the very same is applicable for FindAppointments(). Asking for AppointmentSchema.RequiredAttendees will raise the Invalid Shape error, and AppointmentSchema.Organizer won't contain the email address, only the name of the organizer, after using FindAppointments().
The solution was to do TWO requests to Exchange Server.
var appointments = calendarFolder.FindAppointments(BasePropertySet.FirstClassProperties);
exchangeService.LoadPropertiesForItems(appointments, MyAdvancedProperties);
I think that the same "workaround" is possible with FindPeople(), as well as every other Find%Itemtype%() EWS may support, I am not sure, though.
EDIT: I just found http://social.technet.microsoft.com/Forums/exchange/en-US/e83abfb1-37a8-48fe-9579-4e120fb77746/ews-managed-api-loadpropertiesforitems-returns-unexpected-end-of-xml-document?forum=exchangesvrdevelopment where it is stated that LoadPropertiesForItems does a call to raw soap GetItem with multiple ItemIDs.
I'm using jibx2wsdl plugin to convert wsdl from java.
But for java collection list, i am getting same name for all the lists.
Everytime i generate jibx i manually rename the lists.
Is there a solution for it.
Also let me know if this prob is not there with some other libraries(cxf,xmlbeans,watever..).
Here is one sample i attached of my wsdl for java list.
<collection field="reportingYearList" usage="optional" create-type="java.util.ArrayList">
<value name="**string**" type="java.lang.String">
<collection>
I'd like to implement some before and after method advisors in Coldspring 2.0, and I'd like to use the new schema for AOP and the new autoproxying feature. Unfortunently, the Narwhal documentation for AOP is currently a cliffhanger. Can anyone give me an example of a Coldspring 2.0 configuration file that uses the AOP schema?
I just finished off 1 more section in the AOP documentation, but in the mean time, here are a few examples to get the ball rolling.
This is an example of setting up around advice. It calls the method timeMethod on the object timer, that matches the pointcut of execution(public * *(..)), which translated to: a method execution, that is public, that returns anything, that is named anything, and takes any arguments, of any types. Essentially, it matches everything.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.coldspringframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.coldspringframework.org/schema/aop"
xsi:schemaLocation="http://www.coldspringframework.org/schema/beans http://coldspringframework.org/schema/coldspring-beans-2.0.xsd
http://www.coldspringframework.org/schema/aop http://www.coldspringframework.org/schema/coldspring-aop-2.0.xsd"
>
<!-- AOP configuration -->
<aop:config>
<aop:aspect ref="timer">
<aop:around method="timeMethod"
pointcut="execution(public * *(..))"/>
</aop:aspect>
</aop:config>
<bean name="timer" class="05_AOP.Timer" />
<bean name="longTime" class="05_AOP.LongTime" />
</beans>
The important piece to note, is that while Time.cfc is just a plain ol' CFC, for it to do the around advice, the method that is being used has to take a MethodInvocation as an argument, like so:
public any function timeMethod(required MethodInvocation invocation)
{
...
}
But there you go, there is an example of using AOP in CS2.
You can still use MethodInterceptors and the like as well, but you will be using <aop:advisor> rather than <aop:aspect>.
But overall, I'm working on the CS2 AOP documentation right now, so it should get filled out in the next day or so.
DOC RELEASED! http://sourceforge.net/apps/trac/coldspring/
An error was discovered processing the <wsse:Security> header
This is a WS-Security question btw...
I can't see anything wrong with my WS endpoint (apart from the fact that it's running in a TIBCO BW engine!). Does someone have any 'prior' with this kind of error? I realise that the WS-Security Header could be broken anywhere presumably to get this error but, there's GOT to be a 90% percentile on some kind of common error.
Here's the secured SOAP - the client is standalone java (WSS4J 1.5.0) performing signing only at this stage.
<soapenv:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header>
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" soapenv:mustUnderstand="1">
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#" Id="Signature-20237898">
<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
<ds:Reference URI="#id-18414151">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<ds:DigestValue>DvjhvAtEVxwntL/RjMCNhId57cg=</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>
YbOB3FRduCr5rutpIvch9sDZfZToy3pjm+Kyl/Oqz6cAPqMVKqvKBb4P7ebnzP/3SVjm+PfLqlE5
BGgcT3Vz93apyg+eY1rAIYUs7K1Zt9F5ejMmij6HQpQTGpyM9BUXJi1x5bt9GuMtD0SK939bIIE2
ZUyZ0jPJp/wUhMonskw=
</ds:SignatureValue>
<ds:KeyInfo Id="KeyId-15734641">
<wsse:SecurityTokenReference xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="STRId-3852606">
<ds:X509Data>
<ds:X509IssuerSerial>
<ds:X509IssuerName>CN=Mark Hesketh,OU=asdf,O=DVA,L=Canberra,ST=ACT,C=AU</ds:X509IssuerName>
<ds:X509SerialNumber>1231310305</ds:X509SerialNumber>
</ds:X509IssuerSerial>
</ds:X509Data>
</wsse:SecurityTokenReference>
</ds:KeyInfo>
</ds:Signature>
</wsse:Security>
</soapenv:Header>
<soapenv:Body xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="id-18414151">
<message xmlns="http://www.tibco.com/schemas/CertificateWork/Resources/Schema.xsd" text="Sample msg with SHA1 signature"/>
</soapenv:Body>
</soapenv:Envelope>
Wow... if you're still having this problem, you have more patience than I... but just in case, here's my thoughts:
http://schemas.xmlsoap.org/specs/ws-security/ws-security.htm#ws-security__toc6201567 - suggests that this is a problem reading the tag.
One thing that sticks out to me is that I don't see a reference connecting the signature to the key info. Certainly, I would assume that the KeyInfo element is describing the certificate that used a private key to make the SignatureValue, but I don't see a peice of the XML that is telling the software that. I don't think including the KeyInfo is enough, there may have to be a link to it.
If not that, I'd double check this against the schema, and maybe an independant schema verifying source. An error at the header level makes me think format rather than content.
That's my first guess at this one, and it's just a guess without getting hands on with your system and trying a bunch of different things. If that doesn't work, this my general logical chain for this type of error:
Format - the XML correct according to the schema?
Signature - the signature needs three things: data, a key, a set of algorithms for making it. Check all three - is the data correct, is the key correct, are the algorithms appropriate for the key and for how the message will be handled? Also, are the key and data items referenced properly and being found by your library?
External sources of info - in this case, your key info references a certificate that presumably is pulled from somewhere else - like an LDAP cert store. So.. can your code get to that external source, is the source of data running and network accessible from where you are running the code? etc.
If PKI -- Certificate Validation/Trust - what does the system have to do behind the scenes to trust the signer? OCSP checks? Lookup in LDAP? Chain to trusted root? etc. Is the trust algorithm working properly and does it have everything it needs - ie, access to OCSP responder, properly configured certificate store, etc.
I reorder these steps based upon my guess on what the error means. The errors are not so intuitive -- so I often go through all these steps just in case my interpretation of the error is wrong. Besides, I may then prevent a problem later...
Check your SOAPAction in the Header. The value in the WSDL must be the same as in the call. A wrong value can cause an InvalidSecurity error.
In Java you can get the message as text with
soapMessage.getSOAPPart().getEnvelope();
Here you can check the values and settings.