I am Using CXF for Developing a rest base web service.and in Get method application type is JSON. Using WADL I have generated code.
Issue 1 - In Data class #XmlRootElement is missing.
Now After adding it manually when I consume the service using generated client I got exception
unexpected element (uri:"", local:"ns2.CustomerData"). Expected elements are <{customerbean}CustomerData>
I have gone through various post and if I remove namespace from my Data class as well as client data class then it works fine. But if namespace is removed than wadl2java doesn't work well.
I guess due to some thin server is not responding with proper namespace in response in case of JSON as the same will work if I change data type to XML
I have removed namespace from #XmlRootElement and added the same into #XmlType, and it started working for me.
Related
I have been exploring on how to consume the web services and I found a good articles on JAX-Rs and it is the way to consume Rest Webservices. my task is to hit the URL which returns the XML as response and should be converted into Object which I have achieved using following code.
client = ClientBuilder.newClient();
//example query params: ?q=Turku&cnt=10&mode=json&units=metric
target = client.target(
"http://api.openweathermap.org/data/2.5/weather")
.queryParam("appid", apikey)
.queryParam("units", "metric")
;
And here is the piece of code which will map my XML response to java object
Example exampleObject = target.request(MediaType.APPLICATION_XML).get(Example.class);
This works fine, but the issue is my lead is saying use JIBX since it's faster.
Question 1 : How does target.request converts the xml response (does it use jibx or jaxb etc ?? )
Question 2 : If I have use JIBX I need to download the response as stream and do the marshalling and unmarshalling which I found not a right way to consume webservices, I am I right??
Please do help on this.
1: JAX-RS uses MessageBodyReaders to convert the HTTP entity stream into an object. By default, all JAX-RS implementations are required to ship a MessageBodyReader (and Writer) that uses JAXB to serialize/deserialize to/from XML when the content type is application/xml.
2: If you want to use something other than JAXB to deserialize XML, you could write your own MessageBodyReader that consumes “application/xml”. That would override the built-in JAXB reader.
An example of how to do this is available here:
https://memorynotfound.com/jax-rs-messagebodyreader/
Hope this helps, Andy
My service is consuming a soap service. The target service could add new fields which shouldnt break our service as long as we receive all the fields we need.
I am using CXF to generate java code from WSDL and it breaks whenever it finds a new field. Is it possible to configure CXF to ignore new fields?
The error is something like
org.apache.cxf.interceptor.Fault: Unmarshalling Error: unexpected element (uri:"http://www.a.com/sed/b/products/2014/03/types", local:"BidOnly"). Expected elements are <{http://www.a.com/sed/b/products/2014/03/types}SaleTeam>,
at org.apache.cxf.jaxb.JAXBEncoderDecoder.unmarshall(JAXBEncoderDecoder.java:905) ~[cxf-rt-databinding-jaxb-3.2.0.jar:3.2.0]
at org.apache.cxf.jaxb.JAXBEncoderDecoder.unmarshall(JAXBEncoderDecoder.java:711) ~[cxf-rt-databinding-jaxb-3.2.0.jar:3.2.0]
at org.apache.cxf.jaxb.io.DataReaderImpl.read(DataReaderImpl.java:172) ~[cxf-rt-databinding-jaxb-3.2.0.jar:3.2.0]
I tried to solve the same problem and stumbled upon this question:
CXF - webservice endpoint has changed, WSDL has not
Apparently if you set "set-jaxb-validation-event-handler" to "false" it disables this validation for the unmarshaler. So in my code I added this:
import org.apache.cxf.jaxws.EndpointImpl;
...
EndpointImpl endpoint = new EndpointImpl(...);
endpoint.getProperties().put("set-jaxb-validation-event-handler", "false");
I know I'm answering an old question, but perhaps it will be useful to someone.
I've got an a client for JAX-WS webservice. The problem that i faced is the exception Unmarshalling Error: Maximum Number of Child Elements limit (50000) Exceeded when response is mapping to Java Objects. So i think about manually SAX parsing response. Is there any kind of hack/interceptor that allows me to use nice JAX-WS method binding with manually SAX parsing(through InputStream) the response?
Actually there's no need to do that, since you can just override the property
org.apache.cxf.stax.maxChildElements
to get rid of the exception. For more information, check it out the official documentation: http://cxf.apache.org/docs/security.html
Consider the following code with JAXB binding,
#XmlRootElement
#XmlAccessorType(XmlAccessType.FIELD)
public class SomeRequest {
#XmlElements(value={#XmlElement(name="objOne", type="ObjectOne.class"),
#XmlElement(name="objTwo", type="ObjectTwo.class")})
private MyObject obj;
}
When I get a request similar to this,
<request>
<objectOne>
<!-- Some Data -->
</objectOne>
<objectTwo>
<!-- Some data -->
</objectTwo>
</request>
Both the values are unmarshalled and processed, but only the last value of objectTwo remains.
I want to avoid this some way, by throwing an exception when both are sent in the request.
Also, I am looking for a way to solve it programmatically, without using wsdl schema validation..
I have tried to use, JAXB XmlAdapter after looking at the following question,
Confused as how to use JAXB XML Adapter for my requirement but there is no way to compare if the object has already a value and throw a soap fault.
I also couldn't think of a way of solving it using Unmarshaller, from the oracle jaxb docs
If you could recommend a solution using some kind of Interceptor or extending some JAXB class and validate and throw an exception, it would be great.
The web service implementation is done using apache cxf on jboss, if it helps. CXF Interceptors are also an option but I would take that only if there is no JAXB related solution.
I have a web service app on Apache Geronimo 2.1.3.
I am using JAX-WS, annotating POJOS, using SOAP 1.1. (using Sun JDK 1.5)
Various clients use the web services without a hitch.
One new client is not working. In working clients, only the child element under soapenv:Body has a namespace declaration, and the child's children elements have no namespace declaration. In the new client, ALL descendents of soapenv:Body, including the child's children, have namespace declarations.
In essence, this works:
<soapenv:Body>
<ns1:Echo>
<Message>Hello world</Message>
...
But this does not:
<ns1:Echo>
<ns1:Message>Hello world</ns1:Message>
...
Logging in the app would show that Message is null, instead of "Hello world"
Is this "bad" request OK? It looks like it confirms to WS-I Basic Profile?
The client program can't change. Is there a way for me to override something, to get both versions of this request to work?
Message and ns1:Message are different types, just like fictional java Classes Message and ns1.Message. The server expects a Message element that is declared in the default namespace (there should be a xmlns="<my.default.namespace.name>" somewhere) but it gets a <ns1:Message> and simply ignores it.
If you can't force the client to send valid xml soap messages (according to the wsdl), you may try to change the server code so that it accepts <Message> elements aswell as <ns1:Message> elements as <ns1:Echo> children. You'd have to declare types for the elements from the ns1 namespace and add a choice element to the <ns1:Echo> declaration.