MappingJackson2XmlHttpMessageConverter creates extra/duplicate xml elements during marshalling - spring-boot

i am using xjc to create jaxb binding classes from an xsd... and using MappingJackson2XmlHttpMessageConverter to convert the objects to xml.. but what i am seeing is, when i have a list in the binding file, the converter creates a duplicate xml element..
XSD:
<xs:complexType name="orderSubmitType">
<xs:all>
<xs:element name="orderId" type="xs:string" />
<xs:element name="giftCards" type="giftCards"/>
</xs:all>
</xs:complexType>
<xs:complexType name="giftCards">
<xs:sequence>
<xs:element name="giftCard" type="giftCard" minOccurs="0" maxOccurs="10"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="giftCard">
<xs:all>
<xs:element name="cardNumber" type="xs:string" />
<xs:element name="pinNumber" type="xs:string" />
</xs:all>
</xs:complexType>
JAVA:
public class TestRestTemplateConfiguration {
public static RestTemplate getTestClientRestTemplate() {
if (INSTANCE == null) {
RestTemplate restTemplate = new RestTemplate();
restTemplate.setErrorHandler(new TestClientResponseErrorHandler());
ClientHttpRequestInterceptor loggingInterceptor = new TestClientLoggingInterceptor();
restTemplate.setInterceptors(Collections.singletonList(loggingInterceptor));
restTemplate.setRequestFactory(new BufferingClientHttpRequestFactory(new SimpleClientHttpRequestFactory()));
MappingJackson2HttpMessageConverter jacksonConverter = new MappingJackson2HttpMessageConverter();
MappingJackson2XmlHttpMessageConverter jacksonXmlConverter = new MappingJackson2XmlHttpMessageConverter();
restTemplate.setMessageConverters(Arrays.asList(jacksonConverter,jacksonXmlConverter));
INSTANCE = restTemplate;
}
return INSTANCE;
}
}
final xml that is created is ..
<?xml version="1.0" encoding="UTF-8"?>
<OrderSubmitType>
<orderId>111111</orderId>
<giftCards>
<giftCard>
<giftCard>
<cardNumber>123456790</cardNumber>
<pinNumber>1111</pinNumber>
</giftCard>
</giftCard>
</giftCards>
</OrderSubmitType>
as you can see... there is a extra
<giftcard></giftcard> elements...
can anyone tell me what is the mistake that i am doing...
thanks...

Related

XJC -jaxb2-maven-plugin-Generated Getter Setter methods does not follow Java conventions

I am working on jaxb2-maven-plugin, I am generating Java POJOs from XSD.
I have an XSD like this
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="employee">
<xs:complexType>
<xs:sequence>
<xs:element name="projects">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="unbounded" name="project">
<xs:complexType>
<xs:sequence>
<xs:element name="product" type="xs:string" />
<xs:element name="id" type="xs:unsignedByte" />
<xs:element name="**PRIce**" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
When I generate the POJOs using the above it generated the getters/setters for field PRIce like this.
public class Project {
#XmlElement(name = "PRIce", required = true)
protected String prIce;
public String getPRIce() {
return prIce;
}
public void setPRIce(String value) {
this.prIce = value;
}
}
But we need the output like this.
public class Project {
#XmlElement(name = "PRIce", required = true)
protected String prIce;
public String getPrIce() {
return prIce;
}
public void setPrIce(String value) {
this.prIce = value;
}
}

XJC - Add Lombok Annotation on top of every Generated XSD class and remove Setters Getters

I am working on jaxb2-maven-plugin, I am generating Java POJOs from XSD.
I need to add #Data annotation on top of the class without setters getters.
The output file should look like this.
#Data
public class Employee {
#JsonProperty("name")
private Name name;
#JsonProperty("joindate")
private String joindate;
#JsonProperty("payload")
private String payload;
}
My XSD is like this
<?xml version="1.0" encoding="utf-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="employee">
<xs:complexType>
<xs:sequence>
<xs:element name="name">
<xs:complexType>
<xs:sequence>
<xs:element name="lastname" type="xs:string" />
<xs:element name="firstname" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="hiredate" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
I need to add annotation on Name.java as well. I have around 100 XSDs. I need to do this for all XSDs

What is the meaning of '/' in following TIBCO expression

I have following code in Tibco business works module
$ES_GetInfo/root/pfx4:GetInformationAndPropertyDetailsResponse/pfx4:LicenseInfo/pfx4:CoreEnt/pfx4:Ent
[pfx4:Ent/pfx4:EntOfferingCode = $Read_DB_Data/group/ROW/EOC]
/pfx4:EntState = "Disabled"
I can understand it is comparing "EntOfferingCode" with "EOC", but could not get the expression "/pfx4:EntState = 'Disabled'"?
As per the TIBCO, the whole expression returns a boolean value.
What is the meaning of "/pfx4:entState='Disabled'". Is logical or conditional or something else?
The whole expression is logical condition. The '/' is just xml schema elements separator in XPath (XML Path Language) syntax. You can start learning tibco xpath from here https://docs.tibco.com/pub/activematrix_businessworks/6.3.0/doc/html/GUID-D319018B-AA74-428D-A034-E477778AD2B6.html
The expression first filtering all the "Ent" nodes that have EntOfferingCode = $Read_DB_Data/group/ROW/EOC
then check if exists EntState = "Disabled" in filtered result
the expression can be replaced by
not (empty($Start/pfx:GetInformationAndPropertyDetailsResponse/pfx:LicenseInfo/pfx:CoreEnt/pfx:Ent[ pfx:EntOfferingCode= "EOC" and pfx:EntState = "Disabled"]))
For example
if the schema is like
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns="http://www.tibco.com/schemas/TestProcess/Schema/Schema.xsd"
targetNamespace="http://www.tibco.com/schemas/TestProcess/Schema/Schema.xsd"
elementFormDefault="qualified"
attributeFormDefault="unqualified">
<xs:element name="GetInformationAndPropertyDetailsResponse">
<xs:complexType>
<xs:sequence>
<xs:element ref="LicenseInfo" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="LicenseInfo">
<xs:complexType>
<xs:sequence>
<xs:element ref="CoreEnt" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="CoreEnt">
<xs:complexType>
<xs:sequence>
<xs:element ref="Ent" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="Ent">
<xs:complexType>
<xs:sequence>
<xs:element name="EntOfferingCode" type="xs:string"/>
<xs:element name="EntState" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
Expression return true for:
<?xml version = "1.0" encoding = "UTF-8"?>
<GetInformationAndPropertyDetailsResponse xmlns = "http://www.tibco.com/schemas/TestProcess/Schema/Schema.xsd">
<LicenseInfo>
<CoreEnt>
<Ent>
<EntOfferingCode>EOC</EntOfferingCode>
<EntState>Disabled</EntState>
</Ent>
</CoreEnt>
</LicenseInfo>
</GetInformationAndPropertyDetailsResponse>
Expression return false for:
<?xml version = "1.0" encoding = "UTF-8"?>
<GetInformationAndPropertyDetailsResponse xmlns = "http://www.tibco.com/schemas/TestProcess/Schema/Schema.xsd">
<LicenseInfo>
<CoreEnt>
<Ent>
<EntOfferingCode>EOC</EntOfferingCode>
<EntState>Enabled</EntState>
</Ent>
<Ent>
<EntOfferingCode>EOC1</EntOfferingCode>
<EntState>Disabled</EntState>
</Ent>
</CoreEnt>
</LicenseInfo>
</GetInformationAndPropertyDetailsResponse>
if you just use
$ES_GetInfo/root/pfx4:GetInformationAndPropertyDetailsResponse/pfx4:LicenseInfo/pfx4:CoreEnt/pfx4:Ent/pfx4:EntState = "Disabled"
it will return true for both examples
If your question is what does the xslt expression mean, it is basically checking the following:
For all LicenseInfo/CoreEnt/Ent,
where Ent/EntOfferingCode = EOC value from the DB
check if the corresponding Enstate is Disabled or not
if Disabled, output true, else output false.

Spring WS is not generating wsdl operations for all the public methods in the Endpoint class

I have a Spring endpoint class with two public methods. But when Spring is auto-generating the wsdl it doesn't include the second public method. Could you pleas let me know what is wrong and what needs to be done. I am using Spring 4.3 and below are the classes.
Configuration class
#EnableWs
#Configuration
public class SoapServiceConfig extends WsConfigurerAdapter {
#Bean
public ServletRegistrationBean messageDispatcherServlet(ApplicationContext applicationContext) {
MessageDispatcherServlet servlet = new MessageDispatcherServlet();
servlet.setApplicationContext(applicationContext);
servlet.setTransformWsdlLocations(true);
return new ServletRegistrationBean(servlet, "/ws/*");
}
#Bean(name = "policies")
public DefaultWsdl11Definition policyserviceWsdl11Definition(#Autowired #Qualifier("swissSchema") XsdSchema swissSchema) {
DefaultWsdl11Definition wsdl11Definition = new DefaultWsdl11Definition();
wsdl11Definition.setPortTypeName("PoliciesPort");
wsdl11Definition.setLocationUri("/ws");
wsdl11Definition.setTargetNamespace("http://www.testcomp.com/iaworkflow/soapservice");
wsdl11Definition.setSchema(swissSchema);
return wsdl11Definition;
}
#Bean(name = "bankservice")
public DefaultWsdl11Definition bankServiceWsdlDefinition(#Autowired #Qualifier("bankSchema")XsdSchema bankSchema) {
DefaultWsdl11Definition wsdl11Definition = new DefaultWsdl11Definition();
wsdl11Definition.setPortTypeName("BankAPIPort");
wsdl11Definition.setLocationUri("/ws/bankapi");
wsdl11Definition.setTargetNamespace("http://www.testcomp.com/consumer/bankservice/soapservice");
wsdl11Definition.setSchema(bankSchema);
return wsdl11Definition;
}
#Bean
#Qualifier("bankSchema")
public XsdSchema bankSchema() {
return new SimpleXsdSchema(new ClassPathResource("bankservice.xsd"));
}
#Bean
#Qualifier("swissSchema")
public XsdSchema swissSchema() {
return new SimpleXsdSchema(new ClassPathResource("policylookup.xsd"));
}
}
Endpoint
#Endpoint
public class BankingServiceEndpoint {
private static final String NAMESPACE_URI = "http://www.testcomp.com/consumer/bankservice/soapservice";
#PayloadRoot(namespace = NAMESPACE_URI, localPart = "BankInfoSearchRequest")
#ResponsePayload
public BankInfoSearchResponse getBankInfo(#RequestPayload BankInfoSearchRequest request) {
BankInfoSearchResponse response = createDummyResponse(request.getPolicyNumber(),request.getLimit());
return response;
}
#PayloadRoot(namespace = NAMESPACE_URI, localPart = "BankVerificationRequest")
#ResponsePayload
public BankVerificationResponse verifyBankInformation(#RequestPayload BankVerificationRequest request) {
return BankVerificationResponse.builder().build();
}
}
Generated WSDL
<?xml version="1.0" encoding="UTF-8" standalone="no"?><wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:sch="http://www.testcomp.com/consumer/bankservice/soapservice" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://www.testcomp.com/consumer/bankservice/soapservice" targetNamespace="http://www.testcomp.com/consumer/bankservice/soapservice">
<wsdl:types>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="http://www.testcomp.com/consumer/bankservice/soapservice" version="1.0">
<xs:element name="BankInfoSearchRequest">
<xs:complexType>
<xs:sequence>
<xs:element name="policyNumber" type="xs:string"/>
<xs:element name="limit" type="xs:int"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="BankInfoSearchResponse">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="1" name="policyNumber" nillable="false" type="xs:string"/>
<xs:element name="bankdatas" type="tns:BankDatas"/>
<xs:element maxOccurs="1" name="error" nillable="true" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:complexType name="BankDatas">
<xs:sequence>
<xs:element maxOccurs="unbounded" name="bankinfo" type="tns:BankInfo"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="BankInfo">
<xs:sequence>
<xs:element name="AccountNumber" type="xs:string"/>
<xs:element name="RoutingNumber" type="xs:string"/>
<xs:element name="BankName" type="xs:string"/>
<xs:element name="VerificationDescription" type="xs:string"/>
<xs:element name="VerificationCode" type="xs:string"/>
<xs:element name="Verified" type="xs:boolean"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="BankVerificationRequest">
<xs:sequence>
<xs:element maxOccurs="1" name="PolicyOwnerInformation" type="tns:PolicyOwnerInformation"/>
<xs:element maxOccurs="1" name="BankInfo" type="tns:BankInfo"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="PolicyOwnerInformation">
<xs:sequence>
<xs:element name="FirstName" type="xs:string"/>
<xs:element name="MiddleName" type="xs:string"/>
<xs:element name="LastName" type="xs:string"/>
<xs:element name="SSN" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="BankVerificationResponse">
<xs:sequence>
<xs:element maxOccurs="1" name="PolicyOwnerInformation" type="tns:PolicyOwnerInformation"/>
<xs:element maxOccurs="1" name="Bankinfo" type="tns:BankInfo"/>
<xs:element name="BankVerificationTransactionId" type="xs:string"/>
<xs:element name="ItemReferenceId" type="xs:string"/>
<xs:element name="SubmittedBy" type="xs:string"/>
<xs:element name="VerificationResponse" type="xs:string"/>
<xs:element name="VerificationStatus" type="xs:string"/>
<xs:element name="BankVerificationTransactionType" type="xs:string"/>
<xs:element name="Created" type="xs:string"/>
<xs:element name="Success" type="xs:string"/>
<xs:element name="Error" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
</wsdl:types>
<wsdl:message name="BankInfoSearchResponse">
<wsdl:part element="tns:BankInfoSearchResponse" name="BankInfoSearchResponse">
</wsdl:part>
</wsdl:message>
<wsdl:message name="BankInfoSearchRequest">
<wsdl:part element="tns:BankInfoSearchRequest" name="BankInfoSearchRequest">
</wsdl:part>
</wsdl:message>
<wsdl:portType name="BankAPIPort">
<wsdl:operation name="BankInfoSearch">
<wsdl:input message="tns:BankInfoSearchRequest" name="BankInfoSearchRequest">
</wsdl:input>
<wsdl:output message="tns:BankInfoSearchResponse" name="BankInfoSearchResponse">
</wsdl:output>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="BankAPIPortSoap11" type="tns:BankAPIPort">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="BankInfoSearch">
<soap:operation soapAction=""/>
<wsdl:input name="BankInfoSearchRequest">
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output name="BankInfoSearchResponse">
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="BankAPIPortService">
<wsdl:port binding="tns:BankAPIPortSoap11" name="BankAPIPortSoap11">
<soap:address location="http://localhost:9080/workflowintg/ws/bankapi"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
I figured out the issue. There was a problem in the XSD. I declared the root element as xs:complexType instead of xs:element.

Complex XPaths using EclipseLink MOXy and JAXB

I am currently using EclipseLink MOXy 2.4.1 and trying to update an element's value via XPaths.
The input used is :
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<expenseReport>
<user>
<userName>Sanaulla</userName>
</user>
<items>
<item>
<itemName>Seagate External HDD</itemName>
<purchasedOn>August 24, 2010</purchasedOn>
<amount>6776.5</amount>
</item>
<item>
<itemName>External HDD</itemName>
<purchasedOn>August 24, 2010</purchasedOn>
<amount>677336.5</amount>
</item>
</items>
</expenseReport>
The XSD is
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="expenseReport" type="ExpenseT"/>
<xs:complexType name="ExpenseT">
<xs:sequence>
<xs:element name="user" type="UserT"/>
<xs:element name="items" type="ItemListT"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="UserT">
<xs:sequence>
<xs:element name="userName" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="ItemListT">
<xs:sequence>
<xs:element name="item" type="ItemT" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="ItemT">
<xs:sequence>
<xs:element name="itemName" type="xs:string"/>
<xs:element name="purchasedOn" type="xs:string"/>
<xs:element name="amount" type="xs:decimal"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
And my Java code is :
JAXBContext context = JAXBContext.newInstance("sample.jaxb.xsd");
JAXBElement<ExpenseT> element = (JAXBElement<ExpenseT>)unmarshaller.unmarshal(new File("resources/sample_before.xml"));
ExpenseT expenseReport = element.getValue();
context.setValueByXPath(expenseReport, "items/item[1]/amount/text()", null, "100.11");
/** Marshalling code **/
I have my java classes created from the XSD using Moxy's tool "jaxb-compiler.cmd".
As you can see from the above code, I am trying to set the amount of 1st item to "100.11". But it doesn't set the value, nor does it throw any exception.
I tried setting the username above using XPath like this
context.setValueByXPath(expenseReport, "user/userName/text()", null, "ABC");
And, it does set/update the value properly.
Can you please advise on how can I set values for complex XPaths with Predicates? Something like this :
items/item[itemName='Seagate External HDD']/amount
We recently fixed a bug in our EclipseLink 2.4.2 and 2.5.0 streams related to setting values in which the XPath contains a postional indicator (ie "foo[1]/bar[2]/text()"). You can download a nightly build from the following link:
http://www.eclipse.org/eclipselink/downloads/nightly.php
You can use predicates in mappings with #XmlPath (see: http://blog.bdoughan.com/2011/03/map-to-element-based-on-attribute-value.html), but we currently don't supports this with our setValueByXPath call. Could you open an enhancement

Resources