JAXB avoid JAXBElement<?> - jaxb

I want to generate Java classes with JAXB from a XSD file.
The problem is, that I always get a few classes like this one (namespace removed):
public static class Action {
#XmlElementRefs({
#XmlElementRef(name = "ReportStateCanceled", namespace = "http://...", type = JAXBElement.class, required = false),
#XmlElementRef(name = "ReportDate", namespace = "http://...", type = JAXBElement.class, required = false),
#XmlElementRef(name = "ReportStatePreliminary", namespace = "http://...", type = JAXBElement.class, required = false),
#XmlElementRef(name = "DocumentID", namespace = "http://...", type = JAXBElement.class, required = false),
#XmlElementRef(name = "ReportStateNotValidated", namespace = "http://...", type = JAXBElement.class, required = false),
#XmlElementRef(name = "CaseNo", namespace = "http://...", type = JAXBElement.class, required = false),
#XmlElementRef(name = "PatientID", namespace = "http://...", type = JAXBElement.class, required = false),
#XmlElementRef(name = "DocumentKey", namespace = "http://...", type = JAXBElement.class, required = false),
#XmlElementRef(name = "ReportTime", namespace = "http://...", type = JAXBElement.class, required = false),
#XmlElementRef(name = "ReportHeading", namespace = "http://...", type = JAXBElement.class, required = false),
#XmlElementRef(name = "ReportStateComplete", namespace = "http://...", type = JAXBElement.class, required = false)
})
protected List<JAXBElement<?>> documentKeyOrDocumentIDOrPatientID;
#XmlAttribute(name = "name")
protected String name;
#XmlAttribute(name = "Query")
protected String query;
/**
* Gets the value of the documentKeyOrDocumentIDOrPatientID property.
*
* <p>
* This accessor method returns a reference to the live list,
* not a snapshot. Therefore any modification you make to the
* returned list will be present inside the JAXB object.
* This is why there is not a <CODE>set</CODE> method for the documentKeyOrDocumentIDOrPatientID property.
*
* <p>
* For example, to add a new item, do as follows:
* <pre>
* getDocumentKeyOrDocumentIDOrPatientID().add(newItem);
* </pre>
*
*
* <p>
* Objects of the following type(s) are allowed in the list
* {#link JAXBElement }{#code <}{#link Template.Page.Actions.Action.ReportDate }{#code >}
* {#link JAXBElement }{#code <}{#link String }{#code >}
* {#link JAXBElement }{#code <}{#link String }{#code >}
* {#link JAXBElement }{#code <}{#link String }{#code >}
* {#link JAXBElement }{#code <}{#link String }{#code >}
* {#link JAXBElement }{#code <}{#link String }{#code >}
* {#link JAXBElement }{#code <}{#link String }{#code >}
* {#link JAXBElement }{#code <}{#link String }{#code >}
* {#link JAXBElement }{#code <}{#link String }{#code >}
* {#link JAXBElement }{#code <}{#link Template.Page.Actions.Action.ReportTime }{#code >}
* {#link JAXBElement }{#code <}{#link String }{#code >}
*
*
*/
public List<JAXBElement<?>> getDocumentKeyOrDocumentIDOrPatientID() {
if (documentKeyOrDocumentIDOrPatientID == null) {
documentKeyOrDocumentIDOrPatientID = new ArrayList<JAXBElement<?>>();
}
return this.documentKeyOrDocumentIDOrPatientID;
}
/**
* Gets the value of the name property.
*
* #return
* possible object is
* {#link String }
*
*/
public String getName() {
return name;
}
/**
* Sets the value of the name property.
*
* #param value
* allowed object is
* {#link String }
*
*/
public void setName(String value) {
this.name = value;
}
/**
* Gets the value of the query property.
*
* #return
* possible object is
* {#link String }
*
*/
public String getQuery() {
return query;
}
/**
* Sets the value of the query property.
*
* #param value
* allowed object is
* {#link String }
*
*/
public void setQuery(String value) {
this.query = value;
}
/**
* <p>Java class for anonymous complex type.
*
* <p>The following schema fragment specifies the expected content contained within this class.
*
* <pre>
* <complexType>
* <simpleContent>
* <extension base="<http://www.w3.org/2001/XMLSchema>string">
* <attribute name="dateFormat" type="{http://www.w3.org/2001/XMLSchema}string" />
* </extension>
* </simpleContent>
* </complexType>
* </pre>
*
*
*/
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "", propOrder = {
"value"
})
public static class ReportDate {
#XmlValue
protected String value;
#XmlAttribute(name = "dateFormat")
protected String dateFormat;
/**
* Gets the value of the value property.
*
* #return
* possible object is
* {#link String }
*
*/
public String getValue() {
return value;
}
/**
* Sets the value of the value property.
*
* #param value
* allowed object is
* {#link String }
*
*/
public void setValue(String value) {
this.value = value;
}
/**
* Gets the value of the dateFormat property.
*
* #return
* possible object is
* {#link String }
*
*/
public String getDateFormat() {
return dateFormat;
}
/**
* Sets the value of the dateFormat property.
*
* #param value
* allowed object is
* {#link String }
*
*/
public void setDateFormat(String value) {
this.dateFormat = value;
}
}
As you can see JAXB uses JAXBElement. Such classes are unuseable for me.
After some research I found out that JAXB has troubles with nillable="true" and minOccurs="0" together, but I do not use nillable anywhere. Tough I am sure, that the problem is related with the minOccurs and maxOccurs.
Even if I would know the exact problem it would be a problem because I get the XSD from an external person and I am not allowed to modify it.
The XSD snippet:
<xs:element name="Action" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="DocumentKey" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="DocumentID" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="PatientID" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="CaseNo" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="ReportHeading" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="ReportDate" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string" >
<xs:attribute name="dateFormat" type="xs:string" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
<xs:element name="ReportTime" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string" >
<xs:attribute name="timeFormat" type="xs:string" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
<xs:element name="ReportStateNotValidated" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="ReportStatePreliminary" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="ReportStateComplete" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="ReportStateCanceled" type="xs:string" minOccurs="0" maxOccurs="1"/>
</xs:choice>
<xs:attribute name="name" type="xs:string" />
<xs:attribute name="Query" type="xs:string" />
</xs:complexType>
</xs:element>
So I searched for another solution.
I always came to the conclusion that I could solve the problem if add a jaxb-binding.xml when I am generating the classes from the XSD.
I tried some bindings, but it never worked.
With this binding I get less JAXBElements, but I get interfaces instead of classes.
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
jaxb:extensionBindingPrefixes="xjc"
jaxb:version="2.0">
<xs:annotation>
<xs:appinfo>
<jaxb:globalBindings generateValueClass="false" generateElementProperty="false" >
<xjc:simple />
</jaxb:globalBindings>
</xs:appinfo>
</xs:annotation>
</xs:schema>
And now I am asking if anyone knows a solution?
The best solution would be if someone provides me a working jaxb-binding.xml.
I am using version 2.2.4-2 of the xjc compiler.
Thank you in advance!

The Problem
The problem is that your xs:choice element has maxOccurs="unbounded".
<xs:choice minOccurs="0" maxOccurs="unbounded">
JAXB Spec Reference
Because of this JAXB can't generate individual properties for each option in the choice structure. See "6.12.6 Bind a repeating occurrence model group" of the JAXB 2.2 (JSR-222) specification for more details:
https://jcp.org/en/jsr/detail?id=222
Why it's a Problem
The following XML fragment is valid according to your XML schema and needs to be able to be represented in the generated object model.
<Action>
<DocumentID/>
<PatientID/>
<PatientID/>
<DocumentID/>
</Action>
Work Around
If you ever really don't like a class that JAXB generates you can create your own and specify via a bindings file that JAXB should use it instead of creating a new one.
<jxb:bindings schemaLocation="yourSchema.xsd">
<jxb:bindings node="//xs:element[#name='Action']">
<jxb:class ref="com.example.Action"/>
</jxb:bindings>
</jxb:bindings>

I wrote the Simpify plugin exactly for this problem.
<xs:schema ...
xmlns:simplify="http://jaxb2-commons.dev.java.net/basic/simplify"
jaxb:extensionBindingPrefixes="... simplify">
<xs:complexType name="typeWithReferencesProperty">
<xs:choice maxOccurs="unbounded">
<xs:element name="a" type="someType">
<xs:annotation>
<xs:appinfo>
<simplify:as-element-property/>
</xs:appinfo>
</xs:annotation>
</xs:element>
<xs:element name="b" type="someType"/>
</xs:choice>
</xs:complexType>
will give you
#XmlElement(name = "a")
protected List<SomeType> a;
#XmlElement(name = "b")
protected List<SomeType> b;
instead of
#XmlElementRefs({
#XmlElementRef(name = "a", type = JAXBElement.class),
#XmlElementRef(name = "b", type = JAXBElement.class)
})
protected List<JAXBElement<SomeType>> aOrB;
Disclaimer: I'm the author.

Related

JAXB not generating field for redefined attribute

I have an xsd that redefines a complex type to add a sequence:
<xs:redefine>
<xs:complexType name="data-extension.type">
<xs:complexContent mixed="true">
<xs:extension base="data-extension.type">
<xs:sequence>
<xs:any minOccurs="0" maxOccurs="unbounded" processContents="strict"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:redefine>
However when I generate the code for my xsd using JAXB, the DataExtensionType class does not has a field for the sequence.
Am I missing something in the xsd or the JAXB generation parameters?
Edit:
This is the generated Java:
/**
* <p>Java class for data-extension.type complex type.
*
* <p>The following schema fragment specifies the expected content contained within this class.
*
* <pre>
* <complexType name="data-extension.type">
* <complexContent>
* <extension base="{http://graphml.graphdrawing.org/xmlns}data-extension.type">
* <redefine>
* <complexType name="data-extension.type">
* <complexContent>
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* </restriction>
* </complexContent>
* </complexType>
* </redefine>
* <sequence>
* <any processContents='lax' maxOccurs="unbounded" minOccurs="0"/>
* </sequence>
* </extension>
* </complexContent>
* </complexType>
* </pre>
*
*
*/
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "data-extension.type", namespace = "http://graphml.graphdrawing.org/xmlns")
#XmlSeeAlso({
DefaultType.class,
DataType.class
})
#Generated(value = "com.sun.tools.internal.xjc.Driver", date = "2018-03-02T02:29:07+00:00", comments = "JAXB RI v2.2.8-b130911.1802")
public class DataExtensionType
extends OriginalDataExtensionType
{
}
The comment suggest the sequence was found during parsing.
I was expecting to see a List<Object> any (or similar) and its getter to be generated. The supper class has a contents field, but its type is String.
Edit 2:
The OriginalData class:
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "", propOrder = {
"content"
})
#XmlSeeAlso({
DataExtensionType.class
})
#Generated(value = "com.sun.tools.internal.xjc.Driver", date = "2018-03-02T02:29:07+00:00", comments = "JAXB RI v2.2.8-b130911.1802")
public class OriginalDataExtensionType {
#XmlValue
#Generated(value = "com.sun.tools.internal.xjc.Driver", date = "2018-03-02T02:29:07+00:00", comments = "JAXB RI v2.2.8-b130911.1802")
protected String content;
/**
*
* Extension mechanism for the content of <data> and <default>.
* The complex type data-extension.type is empty per default.
* Users may redefine this type in order to add content to
* the complex types data.type and default.type which are
* extensions of data-extension.type.
*
*
* #return
* possible object is
* {#link String }
*
*/
#Generated(value = "com.sun.tools.internal.xjc.Driver", date = "2018-03-02T02:29:07+00:00", comments = "JAXB RI v2.2.8-b130911.1802")
public String getContent() {
return content;
}
/**
* Sets the value of the content property.
*
* #param value
* allowed object is
* {#link String }
*
*/
#Generated(value = "com.sun.tools.internal.xjc.Driver", date = "2018-03-02T02:29:07+00:00", comments = "JAXB RI v2.2.8-b130911.1802")
public void setContent(String value) {
this.content = value;
}
}
At first I also expected that the contents field would be the sequence.

JAXB Unmarshalling X,X*

I am having a problem unmarshalling this class from XML.
The problem is caused by the two elements called 'propertyset'. What actually happens is that the first propertyset is unmarshalled correctly then it is immediately overwritten with the second, if it exists...
Is there any annotation/configuration that I can use to successfully unmarshal this XML?
/**
* <p>Java class for a element declaration.
*
* <p>The following schema fragment specifies the expected content contained within this class.
*
* <pre>
* <element name="a">
* <complexType>
* <complexContent>
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* <sequence>
* <element ref="propertyset"/>
* <element ref="propertyset" minOccurs="0"/>
* </sequence>
* <attribute name="id" type="{http://www.w3.org/2001/XMLSchema}long" />
* <attribute name="description" type="{http://www.w3.org/2001/XMLSchema}string" />
* </restriction>
* </complexContent>
* </complexType>
* </element>
* </pre>
*
*
*/
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "", propOrder = {
"propertyset",
"systempropertyset"
}, factoryMethod = "createAEx", factoryClass = ObjectFactoryEx.class)
#XmlRootElement(name = "a")
public class A
{
#XmlElement(required = true, type = B.class)
protected B propertyset;
#XmlElement(name = "propertyset", type = B.class)
protected B systempropertyset;
...
}
I have now moved on to using Moxy. With this I can use #XmlPath("propertyset[1]") and #XmlPath("propertyset[2]")
This works as advertised!

JAXB schemagen how generate choice for two fields?

I have java class:
public class ActivityAddress {
#XmlElement(name = "Elem1", required = false)
private String elem1;
#XmlElement(name = "Elem2", required = false)
private String elem2;
#XmlElement(name = "PostIndex", required = true)
private String postIndex;
}
I want to get schema like this:
<xs:complexType name="ActivityAddress">
<xs:sequence>
<xs:choice minOccurs="0">
<xs:element name="Elem1" type="xs:string"/>
<xs:element name="Elem2" type="xs:string"/>
</xs:choice>
<xs:element name="PostIndex" type="xs:string"/>
</xs:sequence>
So the two fields "Elem1" and "Elem2" must be in choice.
Decision like this:
#XmlElements({
#XmlElement(name = "Elem1", type = String.class, required = false),
#XmlElement(name = "Elem2", type = String.class, required = false)
})
private String elem;
isn't suitable for me, because in java class i need have both fields.
Ноw i can do it? Can anyone please help?
Generating an XML Schema
For the following Java class:
public class ActivityAddress {
#XmlElement(name = "Elem1", required = false)
private String elem1;
#XmlElement(name = "Elem2", required = false)
private String elem2;
#XmlElement(name = "PostIndex", required = true)
private String postIndex;
}
You are going to get an XML Schema like the following, there isn't a way to generate the choice the way you would like.
<xs:sequence>
<xs:element name="Elem1" type="xs:string" mincOccurs="0"/>
<xs:element name="Elem2" type="xs:string" minOccurs="0"/>
<xs:element name="PostIndex" type="xs:string"/>
</xs:sequence>
Pointing to a Hand Crafted XML Schema
You can however generate an XML Schema and then modify it yourself and then tell JAXB to use it. This is done with the package level #XmlSchema annotation.
package-info.java
#XmlSchema(location="http://www.example.com/foo/mySchema.xsd")
package com.example.foo;

spring integration :SpelEvaluationException: EL1004E:(pos 8): Method call: Method getResponseForSample(javax.xml.bind.JAXBElement)

I am new in Spring integration and facing the issue when unmarshalling the SOAP request. I have the below sample xsd:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema targetNamespace="http://tempuri.org/" xmlns:tns="http://tempuri.org/"
version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="FFSampleRequest">
<xs:complexType>
<xs:sequence>
<xs:element name="Timestamp" type="xs:string" minOccurs="1"
form="qualified" />
<xs:element name="SampleType" type="xs:int" form="qualified" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="FFSampleResponse">
<xs:complexType>
<xs:sequence>
<xs:element name="Timestamp" type="xs:string" minOccurs="1" />
<xs:element name="SampleType" type="xs:int" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="getResponseForSample" type="tns:getResponseForSample" />
<xs:element name="getResponseForSampleResponse" type="tns:getResponseForSampleResponse" />
<xs:complexType name="getResponseForSample">
<xs:sequence>
<xs:element name="arg0" minOccurs="1">
<xs:complexType>
<xs:sequence>
<xs:element name="Timestamp" type="xs:string"
minOccurs="1" form="qualified" />
<xs:element name="SampleType" type="xs:int" form="qualified" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
<xs:complexType name="getResponseForSampleResponse">
<xs:sequence>
<xs:element name="return" minOccurs="1">
<xs:complexType>
<xs:sequence>
<xs:element name="Timestamp" type="xs:string"
minOccurs="1" />
<xs:element name="SampleType" type="xs:int" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:schema>
Now I have created the java files using the jaxbmarshaller xjc compiler, below is objectFactory file.other files generated are FFSampleRequest, FFSampleResponse, GetResponseForSample, GetResponseForSampleResponse, package-info. put all these files at
//
// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.4-2
// See http://java.sun.com/xml/jaxb
// Any modifications to this file will be lost upon recompilation of the source schema.
// Generated on: 2014.07.07 at 06:00:25 PM GST
//
import javax.xml.bind.JAXBElement;
import javax.xml.bind.annotation.XmlElementDecl;
import javax.xml.bind.annotation.XmlRegistry;
import javax.xml.namespace.QName;
#XmlRegistry
public class ObjectFactory {
private final static QName _GetResponseForSample_QNAME = new QName("http://tempuri.org/", "getResponseForSample");
private final static QName _GetResponseForSampleResponse_QNAME = new QName("http://tempuri.org/", "getResponseForSampleResponse");
public ObjectFactory() {
}
/**
* Create an instance of {#link GetResponseForSample }
*
*/
public GetResponseForSample createGetResponseForSample() {
return new GetResponseForSample();
}
/**
* Create an instance of {#link GetResponseForSampleResponse }
*
*/
public GetResponseForSampleResponse createGetResponseForSampleResponse() {
return new GetResponseForSampleResponse();
}
/**
* Create an instance of {#link FFSampleRequest }
*
*/
public FFSampleRequest createFFSampleRequest() {
return new FFSampleRequest();
}
/**
* Create an instance of {#link FFSampleResponse }
*
*/
public FFSampleResponse createFFSampleResponse() {
return new FFSampleResponse();
}
/**
* Create an instance of {#link GetResponseForSample.Arg0 }
*
*/
public GetResponseForSample.Arg0 createGetResponseForSampleArg0() {
return new GetResponseForSample.Arg0();
}
/**
* Create an instance of {#link GetResponseForSampleResponse.Return }
*
*/
public GetResponseForSampleResponse.Return createGetResponseForSampleResponseReturn() {
return new GetResponseForSampleResponse.Return();
}
/**
* Create an instance of {#link JAXBElement }{#code <}{#link GetResponseForSample }{#code >}}
*
*/
#XmlElementDecl(namespace = "http://tempuri.org/", name = "getResponseForSample")
public JAXBElement<GetResponseForSample> createGetResponseForSample(GetResponseForSample value) {
return new JAXBElement<GetResponseForSample>(_GetResponseForSample_QNAME, GetResponseForSample.class, null, value);
}
/**
* Create an instance of {#link JAXBElement }{#code <}{#link GetResponseForSampleResponse }{#code >}}
*
*/
#XmlElementDecl(namespace = "http://tempuri.org/", name = "getResponseForSampleResponse")
public JAXBElement<GetResponseForSampleResponse> createGetResponseForSampleResponse(GetResponseForSampleResponse value) {
return new JAXBElement<GetResponseForSampleResponse>(_GetResponseForSampleResponse_QNAME, GetResponseForSampleResponse.class, null, value);
}
}
web.xml file to handle the soap request:
<servlet>
<servlet-name>spring-ws</servlet-name>
<servlet-class>org.springframework.ws.transport.http.MessageDispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>WEB-INF/spring-ws-config.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>spring-ws</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
and used the below settings in the configuration file for calling the service method for this request:
<int:channel id="FFSampleRequestChannel"/>
<int-ws:inbound-gateway id="ws-ffsample-gateway" request-channel="FFSampleRequestChannel" marshaller="marshaller" unmarshaller="marshaller"/>
<bean id="marshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
<property name="contextPath" value="com.java.MyChannel.model" />
</bean>
<int:service-activator input-channel="FFSampleRequestChannel">
<bean class="com.java.MyChannel.serviceImpl.FFSampleImpl">
<constructor-arg ref = "ffSampleRequest"></constructor-arg>
<bean id="ffSampleRequest" class="com.java.MyChannel.model.FFSampleRequest"></bean>
<bean id="ffSampleResponse" class="com.java.MyChannel.model.FFSampleResponse"></bean>
my soap request hits service class successfully but I am getting the exception.
/**
* #author Vinay Agrawal
*/
#XmlRegistry
public class FFSampleImpl implements FFSampleInterface
{
#Autowired
FFSampleRequest request;
#Autowired
FFSampleJdbc ffSampleJdbc;
public FFSampleImpl() {
}
public FFSampleImpl(FFSampleRequest request) {
super();
this.request = request;
}
#Override
#PayloadRoot(localPart = "getResponseForSample" , namespace = "http://tempuri.org/")
#ResponsePayload
public FFSampleResponse getResponseForSample(#RequestPayload FFSampleRequest request){
List<FFSampleResponse> ffSampleResponse = new ArrayList<FFSampleResponse>();
return ffSampleResponse ;
}
}
Soap request is as below:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ser="http://tempuri.org/">
<soapenv:Header/>
<soapenv:Body>
<ser:getResponseForSample>
<!--Optional:-->
<arg0>
<ser:Timestamp>"100"</ser:Timestamp>
<ser:SampleType>15</ser:SampleType>
</arg0>
</ser:getResponseForSample>
</soapenv:Body>
</soapenv:Envelope>
I receive the below exception as below:
19:20:34.472 WARN [tomcat-http--15][org.springframework.integration.ws.MarshallingWebServiceInboundGateway] failure occurred in gateway sendAndReceive
org.springframework.messaging.MessageHandlingException: org.springframework.expression.spel.SpelEvaluationException: EL1004E:(pos 8): Method call: Method getResponseForSample(javax.xml.bind.JAXBElement) cannot be found on com.java.myChannel.serviceImpl.FFSampleImpl type
at org.springframework.integration.handler.MethodInvokingMessageProcessor.processMessage(MethodInvokingMessageProcessor.java:78)
at org.springframework.integration.handler.ServiceActivatingHandler.handleRequestMessage(ServiceActivatingHandler.java:71)
at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:170)
at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:78)
at org.springframework.integration.dispatcher.AbstractDispatcher.tryOptimizedDispatch(AbstractDispatcher.java:116)
at org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:101)
at org.springframework.integration.dispatcher.UnicastingDispatcher.dispatch(UnicastingDispatcher.java:97)
at org.springframework.integration.channel.AbstractSubscribablmyChannel.doSend(AbstractSubscribablmyChannel.java:77)
at org.springframework.integration.channel.AbstractMessagmyChannel.send(AbstractMessagmyChannel.java:255)
at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:114)
at org.springframework.messaging.core.GenericMessagingTemplate.doSendAndReceive(GenericMessagingTemplate.java:154)
at org.springframework.messaging.core.GenericMessagingTemplate.doSendAndReceive(GenericMessagingTemplate.java:44)
at org.springframework.messaging.core.AbstractMessagingTemplate.sendAndReceive(AbstractMessagingTemplate.java:75)
at org.springframework.integration.gateway.MessagingGatewaySupport.doSendAndReceive(MessagingGatewaySupport.java:250)
at org.springframework.integration.gateway.MessagingGatewaySupport.sendAndReceiveMessage(MessagingGatewaySupport.java:224)
at org.springframework.integration.ws.MarshallingWebServiceInboundGateway.doInvoke(MarshallingWebServiceInboundGateway.java:105)
at org.springframework.integration.ws.AbstractWebServiceInboundGateway.invoke(AbstractWebServiceInboundGateway.java:54)
at org.springframework.ws.server.endpoint.adapter.MessageEndpointAdapter.invoke(MessageEndpointAdapter.java:41)
at org.springframework.ws.server.MessageDispatcher.dispatch(MessageDispatcher.java:233)
at org.springframework.ws.server.MessageDispatcher.receive(MessageDispatcher.java:173)
at org.springframework.ws.transport.support.WebServiceMessageReceiverObjectSupport.handleConnection(WebServiceMessageReceiverObjectSupport.java:88)
at org.springframework.ws.transport.http.WebServiceMessageReceiverHandlerAdapter.handle(WebServiceMessageReceiverHandlerAdapter.java:59)
at org.springframework.ws.transport.http.MessageDispatcherServlet.doService(MessageDispatcherServlet.java:292)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:961)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:863)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:647)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:409)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1044)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:607)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:313)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)
I changed the service method parameter below but when I try to receive the values given in the SOAP message is not binding and I am getting null values for the "SampleType" and "Timestamp".
public class FFSampleImpl implements FFSampleInterface
{
#Autowired
FFSampleRequest request;
public FFSampleImpl() {
}
public FFSampleImpl(FFSampleRequest request) {
super();
this.request = request;
}
#Override
#PayloadRoot(localPart = "getResponseForSample" , namespace = "http://tempuri.org/")
#ResponsePayload
public FFSampleResponse getResponseForSample(#RequestPayload JAXBElement<FFSampleRequest> ffreq){
FFSampleResponse ffSampleResponse2 = new FFSampleResponse();
return ffSampleResponse2;
/* return FFSampleResponse;*/
}
I am suspecting that the entries that created in the object factory is not correct because feels that I am facing the challenge due to these entries only(below entries). Please let me know if we have any limitations to use jAXBMARSHALLER and xjc compiler also with the spring integration for marshalling/unmarshalling purpose, because I am facing lot of challenges with the soap mapping from xjc generated java objects. Please provide your inpur and let me know where I am missing for the binding of my soap parameters.
/**
* Create an instance of {#link JAXBElement }{#code <}{#link GetResponseForSample }{#code >}}
*
*/
#XmlElementDecl(namespace = "http://tempuri.org/", name = "getResponseForSample")
public JAXBElement<FFSampleRequest> createGetResponseForSample(FFSampleRequest value) {
return new JAXBElement<FFSampleRequest>(_GetResponseForSample_QNAME, FFSampleRequest.class, null, value);
}
/**
* Create an instance of {#link JAXBElement }{#code <}{#link GetResponseForSampleResponse }{#code >}}
*
*/
#XmlElementDecl(namespace = "http://tempuri.org/", name = "getResponseForSampleResponse")
public JAXBElement<GetResponseForSampleResponse> createGetResponseForSampleResponse(GetResponseForSampleResponse value) {
return new JAXBElement<GetResponseForSampleResponse>(_GetResponseForSampleResponse_QNAME, GetResponseForSampleResponse.class, null, value);
}
I have never used JAXBElement, however it might be usefull.
I generate classes for XSD and mark them as JaxB elements, e.g.:
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "feeRequest", propOrder = {
"billerId",
"amount"
})
#XmlRootElement(name = "feeRequest")
public class FeeReqData {
#XmlElement(required = true)
protected Long billerId;
#XmlElement(required = true)
protected Double amount;
}
And use ObjectFactory only manually and don't rely on that JaxB magic.
This is enough for me to get correct model object based on inbound XML.
From other side, if you use FFSampleImpl as a Spring Integration <service-activator> there is no reason to mark its methods with Spring-WS annotations.

xjc not generating corresponding class member for <xsd:any>

Here is the part of schema that I am using:
<xsd:complexType name="ContentType" mixed="true">
<xsd:annotation>
<xsd:documentation><![CDATA[
The content type is a broad base type allowing any content.
]]></xsd:documentation>
</xsd:annotation>
<xsd:complexContent>
<xsd:extension base="BaseContentType">
<xsd:sequence>
<xsd:any minOccurs="0" maxOccurs="unbounded" namespace="##any" processContents="lax"
/>
</xsd:sequence>
<xsd:attribute name="orientation" type="OrientationEnum" use="optional"
default="portrait">
<xsd:annotation>
<xsd:documentation><![CDATA[
The #orientation attribute is used to specify a "landscape"
orientation for the published form. This is primarily used
for schedules or for tables.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
And the binding file:
<jxb:bindings xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
version="2.1">
<jxb:bindings schemaLocation="../xsd/USLM-1.0.xsd">
<jxb:bindings
node="//xsd:group[#name='NoteStructure']">
<jxb:property name="NoteStructure3" />
</jxb:bindings>
</jxb:bindings>
</jxb:bindings>
And the xjc command to convert the schema to java objects:
xjc -d out -p test -b binding.xml schema.xsd
But the class generated for ContentType doesn't have class member for any. The generated class is below:
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "ContentType")
#XmlSeeAlso({
HeadingType.class,
NoteType.class,
QuotedContentType.class,
ColumnType.class,
PType.class
})
public class ContentType
extends BaseContentType
{
#XmlAttribute(name = "orientation")
protected OrientationEnum orientation;
/**
* Gets the value of the orientation property.
*
* #return
* possible object is
* {#link OrientationEnum }
*
*/
public OrientationEnum getOrientation() {
if (orientation == null) {
return OrientationEnum.PORTRAIT;
} else {
return orientation;
}
}
/**
* Sets the value of the orientation property.
*
* #param value
* allowed object is
* {#link OrientationEnum }
*
*/
public void setOrientation(OrientationEnum value) {
this.orientation = value;
}
}
What am I doing wrong?

Resources