SOAP via jax-ws: entity classes missing in schema - java

So, I have a soap server-side project. Annotations - #WebService over interface and implementation, #WebMethod over interface' methods, #XmlRootElement over entity-classes that are in return and arguments in web-methods, and #XmlElement over their fields(over getters actually). Tried also partially and fully swap #XmlRootElement with #XmlType, and #XmlElement with #XmlAttribute.
Project is launched via publisher class or via Tomcat(WSServletContextListener), everything's working after weeks of trial and error. In WSDL schema, for instance:
<xsd:element name="Sell_i">
<xsd:complexType>
<xsd:sequence>
<xsd:element minOccurs="0" name="session" nillable="true" type="xsd:string"/>
<xsd:element minOccurs="0" name="terminal" nillable="true" type="xsd:string"/>
<xsd:element minOccurs="0" name="info" nillable="true" type="tns:TransactionSellInfo"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
Represents the Sell_i method. TransactionSellInfo is an input argument here, and tns points to this namespace aka this wsdl. So, it should be described here. It of course has all the annonations. But, it's just missing, as well as every other class. What's the solution?
Worth noting: schema type is RPC(tho changing to Document doesn't cause classes to appear in wsdl). Also, on the same machine wsimport from wsdl creates classes for those missing entities, which is very wierd(didn't test wsimport on other machines tho). But soapUI won't work with that wsdl and rightfully says that it's malformed.
Maybe it's something quite basic that I'm missing, but google gives nothing useful on all my tries. Any help is appreciated!

Related

generate client wsimport miss link between two object

I would like to generate client stubs from a wsdl with wsimport maven plugin , this is works well but with one issue : i have two object that should be linked togerther but afetr the generation is donne , it's not perfect
<types>
<xsd:schema elementFormDefault="qualified" targetNamespace="http://www.hello.com/ns/xsd/boba/restitution-restituerCarriereAvecValo.xsd">
<xsd:import namespace="http://www.hello.com/holla/infosRetour.xsd" schemaLocation="xsd/infosRetour.xsd"/>
<xsd:import namespace="http://www.hello.com/ns/wsdl/boba/messageRetourModuleValorisation.xsd" schemaLocation="xsd/messageRetourModuleValorisation.xsd"/>
<xsd:element name="messageIn" type="xsd:anyType"/>
<xsd:element name="messageOut">
<xsd:complexType>
<xsd:complexContent>
<xsd:extension base="ir:infosRetour">
<xsd:choice>
<xsd:element name="messageRetour" type="xsd:anyType"/>
<xsd:element name="rejetControleSyntaxiqueSemantique" type="xsd:anyType"/>
<xsd:element name="rejetControleIdentification" type="xsd:anyType"/>
</xsd:choice>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
</xsd:element>
</xsd:schema>
</types>
here my object messageOut sould have a field messageRetour of type messageRetour class, but when i see my class messageOut this field is set as Object and not the montioned class.
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "", propOrder = {
"messageRetour",
"rejetControleSyntaxiqueSemantique",
"rejetControleIdentification"
})
#XmlRootElement(name = "messageOut")
public class MessageOut
extends InfosRetour
{
protected Object messageRetour;
protected Object rejetControleSyntaxiqueSemantique;
protected Object rejetControleIdentification;
as you can see here here is the sub class generated , you can see that there is a class named messageRetour
HOW CAN I CHANGE THIS TYPE TO BE SET AS A CLASS AND NOT AS OBJECT ?
even when i chnage this line <xsd:element name="messageRetour" type="xsd:anyType"/> to <xsd:element name="messageRetour"/> i got the same issue always Object and not a class
You get Object because of xsd:anyType as type.
You should change the type of <xsd:element name="messageRetour" type="xsd:anyType"/> to the messageRetour type.
This type is probably provided by one of the schemas you import. I'm not sure about the specific name, will be probably MessageRetour or messageRetour or message-retour, something like that. So it will probably be something like:
<xsd:element name="messageRetour" type="ir:messageRetour"/>
If the type is provided by the other imported schema, you may need to declare a namespace prefix first (like xmlns:mrmv="http://www.hello.com/ns/wsdl/boba/messageRetourModuleValorisation.xsd") and then use mrmv:messageRetour as type.

How does JAXB decide which type to create when it marshals XML that can match both types?

I have an XML schema whose topmost element is Document
<xsd:element name="Document" type="Document"/>
It contains one element of type ZZ_Customer which is restriction of Customer.
Both of these elements contain children of the same name but with slightly different types.
<xsd:complexType name="Document">
<xsd:sequence>
<xsd:element name="CstmrCdtTrfInitn" type="ZZ_Customer"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="ZZ_Customer">
<xsd:complexContent>
<xsd:restriction base="Customer">
<xsd:sequence>
<xsd:element name="GrpHdr" type="ZZ_Group"/>
<xsd:element name="PmtInf" type="ZZ_Payment" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:restriction>
</xsd:complexContent>
</xsd:complexType>
<xsd:complexType name="Customer">
<xsd:sequence>
<xsd:element name="GrpHdr" type="Group"/>
<xsd:element name="PmtInf" type="Payment" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
When JAXB unmarshalls an XML file will it create an instance of ZZ_Customer or will it create an instance of Customer? Likewise when will it create an instance of Group or ZZ_Group?
I've noticed is that JAXB will instances of ZZ_* for certain parts of the XML but uses their base counter parts for other parts of the XML.
On what basis does it makes its decisions? It does not appear obvious which criteria that JAXB is using.
Unfortunately I have no control over the schema and its design.
Since Document has a property that corresponds to the sub-type.
The sub-type will be created when unmarshalling. This makes sense since in Java when a property is typed to the subclass you can't set an instance of the super class on it.
If the property had corresponded to the super type, by default JAXB would have unmarshalled it to an instance of the super type. The XML can contain the xsi:type attribute to specify that the subtype is being used.

wsimport bind xsd:int to Integer instead of int

Ok. The title really says it all.
I have a extremely large SOAP server I'm calling in a java application. To make my life easier I've been using wsimport to generate the source and jar for the service. I just ran into a problem. All the xsd:int types in the wsdl are being parsed as int types in the java code when I need them as Integer types. Reason for this is some of the int's i need to set as null, but since int types can't be null I can't do that.
I am currently going through and hand changing the fields, but I want to know if there is a easier way to do it through a agrument to the wsimport command
Here is my current wsimport command. Thanks
wsimport.exe -d E:\ServiceWSBuild -p com.example.wsdl -s E:\Service\src -verbose http://wsdl.example.com/?wsdl
Here is also a example of one of the custom types that does this:
<xsd:complexType name="SubPackageSell">
<xsd:complexContent>
<xsd:extension base="tns:APIObject">
<xsd:sequence>
<xsd:element name="sp" type="tns:SubPackage"/>
<xsd:element name="value" type="xsd:int"/>
<xsd:element name="days" type="xsd:int"/>
<xsd:element name="date" type="xsd:string"/>
<xsd:element name="combine" type="xsd:boolean"/>
</xsd:sequence>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
For elements, specify minOccurs="0" and wsimport should generate a java.lang.Integer instead of a primitive int. The default values for minOccurs and maxOccurs is 1, which is why you are getting primitive ints. For example:
<xsd:element name="value" type="xsd:int" minOccurs="0"/>

some noob wsdl questions

<xsd:element name="loginResponse">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="loginReturn" type="tns:test"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:complexType name="test">
<xsd:sequence>
<xsd:element minOccurs="0" maxOccurs="1" name="tx" type="xsd:int"/>
<xsd:element minOccurs="0" maxOccurs="1" name="result" type="xsd:int"/>
<xsd:element minOccurs="0" maxOccurs="1" name="name_space" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
I just want to ask why is the type tns:test used? How can I get the tx, result, namespace values in complextype name="test", because that's the response should I get based on the api they given to me.
tns is the target namespace prefix, which should be defined at the top of your WSDL or XSD file (which includes test).
You didn't wrote how you do access the values, but I assume that your code is working in a different namespace, so that test cannot be indentified. Most likely there is a method which allows you to get values by element name and namespace. Note that in that case, the namespace isn't tns but rather the URL which is defined at top of source file.
If you're not familiar with namespaces: Each XML element is associated with a namespace, like a class in Java is part of a package. In XML there is no import statement, so you have to name an element by name and namespace. To keep the files readable you can define namespace prefixes (probably as an abbreviation).

JAXB Generation nillable=true

Using JAXB 2.2.4 I am generating Java code with the following binding file:
<bindings xmlns="http://java.sun.com/xml/ns/jaxb" version="2.0"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<globalBindings generateElementProperty="false">
</globalBindings>
Unfortunately, the generated code has a nillable = true annotation. See the following example:
#XmlElement(name = "ArtID", nillable = true)
protected STEBeitrag artID;
This is the definition of STEBeitrag:
<xsd:complexType name="CT_Beitrag">
<xsd:complexContent>
<xsd:extension base="allgemein:CT_Objekt">
<xsd:sequence>
<xsd:element name="ArtID" type="daten:STE_Beitrag" minOccurs="0" maxOccurs="1" nillable="true"/></xsd:element>
</xsd:sequence>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
<xsd:complexType name="STE_Beitrag" abstract="true">
<xsd:simpleContent>
<xsd:extension base="xsd:string"/>
</xsd:simpleContent>
</xsd:complexType>
If I do not set the ArtID in the generated CT_Beitrag object then the unmarshaller produces an output like
<ns:ArtID xsi:nil="true"/>
The element ArtID has an abstract type and therefore this XML output is invalid.
How can I generate code with JAXB that omits the nillable=true in the XmlElement annotation?
By the way, the schema canĀ“t be changed.
I have no solution, but this problem is addressed in bug
http://java.net/jira/browse/JAXB-890
I hope this problem wil be solved.
I don't how to do what you're asking and I'd be surprised if what you're asking is worth the effort.
There are 2 options that jump to my mind:
Change the schema (I know you said you can't but perhaps you can take a local copy of the schema if you can't change it due to it being hosted on a server outside of your control)
Change the generated code... simply change nillable=true to nillable=false

Categories