I generated SOAP client stub with CXF 3.4.2 codegen Maven plugin.
However, when trying to create the service stub created, I get a bunch of errors like that:
There's no ObjectFactory with an #XmlElementDecl for the element {http://tempuri.org/}travelDocumentNumber.
this problem is related to the following location:
at protected javax.xml.bind.JAXBElement org.tempuri.GetActiveVisasForArrival.travelDocumentNumber
at org.tempuri.GetActiveVisasForArrival
However, there is an object factory containing the following code:
#XmlElementDecl(namespace = "http://tempuri.org/", name = "travelDocumentNumber", scope = GetActiveVisasForArrival.class)
public JAXBElement<String> createGetActiveVisasForArrivalTravelDocumentNumber(String value) {
return new JAXBElement<String>(_GetActiveVisasForArrivalTravelDocumentNumber_QNAME, String.class, GetActiveVisasForArrival.class, value);
}
As I can see, such error comes with every parameter of WS interface method (excluding XMLGregorianCalendar) and every returning value.
How can I get rid of those errors?
I generate the code this way:
<execution>
<id>generate-sources</id>
<phase>generate-sources</phase>
<configuration>
<sourceRoot>./generated/cxf</sourceRoot>
<wsdlOptions>
<wsdlOption>
<wsdl>./src/main/resources/wsdl/evisa.wsdl</wsdl>
<serviceName>BorderManagementSystemService</serviceName>
<extraargs>
<extraarg>-client</extraarg>
<extraarg>-verbose</extraarg>
</extraargs>
</wsdlOption>
</wsdlOptions>
</configuration>
<goals>
<goal>wsdl2java</goal>
</goals>
</execution>
How I initialize the service:
service = (IBorderManagementSystemService) new BorderManagementSystemService(new URL(WSDL_LOCATION)).getBasicHttpBindingIBorderManagementSystemService();
The WSDL file was exposed by some C# web service. I used single WSDL option; however, generating from root WSDL causes same errors.
I have added mapping for namespaces to unique Java packages in the plugin parameters and now things work. Probably there was a conflict with other clients generated code.
<extraarg>-p</extraarg>
<extraarg>http://tempuri.org/=rw.gov.dgie.gk.integration.evisa.client</extraarg>
<extraarg>-p</extraarg>
<extraarg>http://schemas.migration.gov.rw/evisa=rw.gov.dgie.gk.integration.evisa</extraarg>
Related
The EU VIES VAT validation from WSDL is not working when running via java code. But the same is working from some soap API testing tools.
Eg, https://wsdlbrowser.com/soapclient?wsdl_url=https%3A%2F%2Fec.europa.eu%2Ftaxation_customs%2Fvies%2FcheckVatService.wsdl and https://app.boomerangapi.com/?ext
Even its not working when I trid to get source code from wsimport. (C:\Program Files\Java\jdk1.8.0_151\bin>wsimport -keep -verbose http://ec.europa.eu/taxation_customs/vies/checkVatService.wsdl)
Error is “The element type "BR" must be terminated by the matching end-tag "".” The same error is coming when trying to access SOAP service via java code.
Any suggestions on how to use this EU wsdl for validating VAT nos?
Solved this using 'JAX-WS' Maven plugin to parse a WSDL file to generate java classes.
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxws-maven-plugin</artifactId>
<version>1.12</version>
<execution>
<id>wsimportb-from-jdk</id>
<goals>
<goal>wsimport</goal>
</goals>
<configuration>
<wsdlUrls>
<wsdlUrl>
https://ec.europa.eu/taxation_customs/vies/checkVatService.wsdl
</wsdlUrl>
</wsdlUrls>
<keep>true</keep>
<packageName>com.vies</packageName>
<sourceDestDir>target/generatedclasses</sourceDestDir>
</configuration>
</execution>
Then export your com.vies custom package under maven <Export-Package>
Change protocol http:// to https:// in the WSDL URL
I am generating Java classes from the CVENT WSDL file using a maven plugin (see the sample below from my POM file). The code generates successfully.
I then call the code (see below) (the start and end dates passed into the getUpdated call are parameters to my method)
When I run / debug, it connects succesfully, but the getUpdated call fails:
Fault from server: INVALID_CVENT_HEADER_VALUE
In examples online, I can see that I need to set the header on the session - but I don't see any method in V200611Soap that allows me to set it.
Anyone with experience of this, or any sample code?
Thanks in advance.
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxws-maven-plugin</artifactId>
<version>1.12</version>
<configuration>
<wsdlUrls>
<wsdlUrl>https://api.cvent.com/soap/V200611.ASMX?WSDL</wsdlUrl>
</wsdlUrls>
<keep>true</keep>
<sourceDestDir>${basedir}/target/generated/src/main/java</sourceDestDir>
</configuration>
<executions>
<execution>
<goals>
<goal>wsimport</goal>
</goals>
</execution>
</executions>
</plugin>
V200611 aV200611 = new V200611();
V200611Soap soap = aV200611.getV200611Soap();
String accountNumber = "xxxxxx";
String userName = "xxxxxx";
String password = "xxxxxx";
LoginResult logingResult = soap.login(accountNumber, userName, password);
CventSessionHeader header = new CventSessionHeader();
header.setCventSessionValue(logingResult.getCventSessionHeader());
GetUpdatedResult getUpdatedResult = soap.getUpdated(CvObjectType.TRAVEL, startDateXMLGregorianCalendar, endDateXmlGregorianCalendar);
I fixed by changing to use the cxf plugin
Then added the wsdlOption
<extendedSoapHeaders>true</extendedSoapHeaders>
Which puts the arguments that are implicit (in the wsdl:binding but not wsdl:port), into the generated API classes.
I generated my classes with jaxb and now I need to populate some list. What's the best way to do that?
pom.xml:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxb2-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>xjc</goal>
</goals>
</execution>
</executions>
<configuration>
<schemaDirectory>${basedir}/src/main/resources/META-INF/xsd</schemaDirectory>
<packageName>be.structure</packageName>
<outputDirectory>${basedir}/target/generated/java</outputDirectory>
</configuration>
</plugin>
The generated class where the list is located:
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "configuration", propOrder = {
"professions"
})
public class Configuration {
protected List<Profession> professions;
public List<Profession> getProfessions() {
if (professions == null) {
professions = new ArrayList<Profession>();
}
return this.professions;
}
}
but as you can see there is no "addProfession" or "setProfessions()" or something. I know there is a way, but I can't really remember it..
getProfessions().add(profession) should do the trick if the underlying list is mutable, but normally you wouldn't change the contents of JAX-instances since JAXB populates the objects for you based on the XML data it is read from - if you change that lists, its no representation of the XML anymore.
I have a maven project where java stubs are generated from wsdl files using axistools-maven-plugin.
Within pom we have following:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>axistools-maven-plugin</artifactId>
<version>${axistools-maven-plugin.version}</version>
<configuration>
<mappings>
<mapping>
<namespace>xyz</namespace>
<targetPackage>x.y.z</targetPackage>
</mapping>
<mapping>
<namespace>http://time.joda.org</namespace>
<targetPackage>com.org.joda.time</targetPackage>
</mapping>
<mapping>
<namespace>abc</namespace>
<targetPackage>a.b.c</targetPackage>
</mapping>
</mappings>
<testCases>false</testCases>
<serverSide>false</serverSide>
<subPackageByFileName>true</subPackageByFileName>
</configuration>
<executions>
<execution>
<goals>
<goal>wsdl2java</goal>
</goals>
</execution>
</executions>
</plugin>
Now in above setting we just have namespaces mapped to package. I am just not able to get how this setting is able to track where does wsdl reside in order generate stubs?
Maven documentation is not very clear on this. Any ideas on this?
EDIT:
I did some testing on this:
I removed all the mappings of namespaces and packages but still wsdl gets picked up.
Even if i change the wsdl name, it still gets picked up.
This is very surprising to me, it seems axis plugin knows about wsdl location. but how i dont knw.
So finally i solved the mystery.
I ran maven build in debug mode : mvn -X clean insatll
I noticed that maven-axistools-plugin checks the default directory as ${basedir}/src/main/wsdl to search for wsdl and hence it was always able to locate my wsdls.
I want dynamically exchange the webserive targetnamescpace (host) in the cade generated by Apache CXF.
Why? Each customer has its own wsdl file.
The current situation is that there is one project, that depends on wsdl X that is hosted on serverX. That means for each Customer an extra build with he specific wsdl URL.
The wsdl files are always identically, just the server changes.
A fat jar (jar-with-dependencies) will be build and uploaded to our nexus server.
We use Java 7 and Maven 3 to build our projects.
The problem is when deploying to nexus you cannot change the change the name of the artifact that gets deployed. application-1.0-CUSTOMER.jar would be a nice pattern but i didn't found a way to solve that and also the whole process dosen't seem very clean.
The webservice-.java files gets generated by the cxf-codegen-plugin plugin. I am using this configuration:
<!-- CXF wsdl2Java Generation -->
<plugin>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-codegen-plugin</artifactId>
<version>2.7.0</version>
<executions>
<execution>
<id>generate-sources</id>
<phase>generate-sources</phase>
<configuration>
<sourceRoot>${project.build.directory}/generated-sources/cxf/</sourceRoot>
<wsdlOptions>
<wsdlOption>
<wsdl>
http://trunk. ....
</wsdl>
<serviceName>ServiceName</serviceName>
<extraargs>
<extraarg>-impl</extraarg>
<extraarg>-verbose</extraarg>
<!-- override the namespace to have always identical package names -->
<extraarg>-p</extraarg>
<extraarg>de.packagename.wsdl</extraarg>
</extraargs>
</wsdlOption>
</wsdlOptions>
</configuration>
<goals>
<goal>wsdl2java</goal>
</goals>
</execution>
</executions>
</plugin>
Here one of the generated java files:
/**
* This class was generated by Apache CXF 2.7.0
* 2013-11-13T14:35:21.046+01:00
* Generated source version: 2.7.0
*
*/
#WebService(targetNamespace = "http://trunk...", name = "SomeName")
#XmlSeeAlso({ObjectFactory.class})
public interface SomeName {
...
}
My idea was to cut out the whole webservice-client implementation out of that application and put it in another project (one project one customer) -- but how to call the webservice from the original project? Currently one Interface is used by the original project as well as one model class.
I know that there is a hack around the deployment problem by using a artifact version with a variable, but it is highly discouraged, at least in maven 3.
I resolved it.
Its similar to this one: How to create a CXF webservice client with dynamic endpoint? but only after a half day debugging i found my solution.
final QName qname = new QName(Settings.MAIN_SCAN_SERVICE_SOAP_URL.get().toString(), "PortName");
final String wsdlUrl = Settings.MAIN_SCAN_SERVICE_WSDL_URL.get().toString();
final JaxWsProxyFactoryBean jaxWsProxyFactoryBean = new JaxWsProxyFactoryBean();
jaxWsProxyFactoryBean.setAddress(Settings.MAIN_SCAN_SERVICE_SOAP_URL.get().toString());
jaxWsProxyFactoryBean.setEndpointName(qname);
jaxWsProxyFactoryBean.setServiceName(new QName(wsdlUrl, "PortName"));
jaxWsProxyFactoryBean.setWsdlLocation(wsdlUrl);
jaxWsProxyFactoryBean.setServiceClass(PortImpl.class);
this.portImpl = (PortImpl) jaxWsProxyFactoryBean.create();