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
Related
I have to integrate our j2ee application with a REST webservice. And I wanted to use the RestEasy JAX-RS implementation from JBoss. The webservice returns an array in JSON format. I've this piece of code:
Client client = ClientBuilder.newClient();
WebTarget target = client.target("http://myservices.com/schemes/all");
Response response = target.request().get();
Can I map this "response" object to List<Scheme> using RestEasy? Thanks
Provided that your JSON provider is capable of converting JSON to appropriate entities, then yes. The get method you call in the code has an overloaded version which accepts the class of entity to which the result is to be converted. Since there are problems with serializing certain collections' implementations, your type has to be wrapped in GenericType class, like that:
List<Scheme> schema = [...].get(new GenericType<List<Scheme>>(){});
The above method should work with just about every JAX-RS-compliant implementation.
You can also use Jackson library, which allows you (amongst other things) to pass collections without need of wrapping them.
Having a SOAP based web service with XML payload, how can I grab the XML payload of the service response in JAX-WS >2.0 client?
I can see how this question will be marked as duplicate, but bear with me.
It seems that the options are:
Use Dispatch API. However this would require me to go low(er) level and create the request payload manually, which I want to avoid.
Use handler infrastructure of the JAX-WS to grab the payload and possibly pass it via MessageContext property back to the client, but this will still unmarshall the XML into JAXB Object tree, which I want to avoid.
So, how can I:
Call a web service using SEI - no messing with creating XML request from scratch
Grab the 'RAW' XML response without the JAXB unmarshalling happening
Sounds simple enough, right?
Among the non-goals the JAX-WS 2 specification says that
'Pluggable data binding JAX-WS 2.0 will defer data binding to JAXB[10]; it is not a goal to provide a
plug-in API to allow other types of data binding technologies to be used in place of JAXB. However,
JAX-WS 2.0 will maintain the capability to selectively disable data binding to provide an XML based
fragment suitable for use as input to alternative data binding technologies.'
So, you should be able to have access to the raw payload.
The following example is also in the specification :
4.3.5.5 Asynchronous, Callback, Payload-Oriented
class MyHandler implements AsyncHandler<Source> {
...
public void handleResponse(Response<Source> res) {
Source resMsg = res.get();
// do something with the results
}
}
Source reqMsg = ...;
Service service = ...;
Dispatch<Source> disp = service.createDispatch(portName,
Source.class, PAYLOAD);
MyHandler handler = new MyHandler();
disp.invokeAsync(reqMsg, handler);
Since the specification also states that a Binding has its own HandlerChain (see chapter 9) you should be able to remove the JAXB handler from the chain, so that JAXB marshalling/unmarshalling doesn't get involved.
I am writing a REST client for my REST webservice using apache httpclient (4.x). I am using JAXB (JSON) for the request/response. In one of my webservice, I have a PUT request in which I have send the JSON request which is represented as the JAXB object. I know I have to use any implementation class of HttpEntity. One of the way I can think of is marshalling the JAXB object to json & use StringEntity. Is there any other way of doing it?
Thanks,
Deepesh
The best way to ensure most efficient content generation with HttpClient is to create a custom HttpEntity implementation. You can leave HttpEntity#getContent unimplemented and only provide HttpEntity#writeTo(OutputStream) method, inside which you can write out your JAXB object using JAXB object serialization facilities.
I have a REST server which sends JSON in response body. I have recently started reading about Apache Camel. I use following to send requests to my REST service.
from("direct:start").setHeader("token", simple("234da"))
.to("http://localhost:8088/foo/bar/?foo1=bar1");
Now the response will be a JSON, is there any way I get this JSON directly into a POJO using some method ahead of to() (something like this)?
to("http://localhost:8088/foo/bar/?foo1=bar1").toPOJO();
I would prefer a non Spring solution.
Thanks
Little details from my side - although late
Create jsonFormatter and then unmarshal with class you need
JsonDataFormat jsonDataFormat = new JsonDataFormat(JsonLibrary.Jackson);
this can be used in marshalling
from("direct:consume-rest")
.log("calling bean method...")
.to("http://localhost:8080/greeting?name=baba")
//.process(svProcessor) // any extra process if you want
.unmarshal().json(JsonLibrary.Jackson, Greeting.class)
.bean(GreetingHelper.class, "print")
.log("converted to bean ...")
.end()
;
Helper class method
public void print (#Body Greeting greeting) {
Apache Camel provides a component to marshal and unmarshal POJO to and from JSON.
In your case, it would be :
from("direct:start").setHeader("token", simple("234da"))
.to("http://localhost:8088/foo/bar/?foo1=bar1")
.unmarshal().json();
By the way, you may need to configure your json library to do it and I suggest you take look at the official configuration.
Goal
Java client for Yahoo's HotJobs Resumé Search REST API.
Background
I'm used to writing web-service clients for SOAP APIs, where wsimport generates proxy stubs and you're off and running. But this is a REST API, which is new to me.
Details
REST API
No WADL
No formal XML schema (XSD or DTD files). There are example XML request/response pairs.
No example code provided
Progress
I looked at question Rest clients for Java?, but the automated solutions there assume you are providing both the server and the client, with JAXB invoked on POJOs to generate a schema and a REST API.
Using Jersey (a JAX-RS implementation), I have been able to make a manual HTTP request:
import com.sun.jersey.api.client.*;
...
ClientConfig clientConfig = new DefaultClientConfig();
Client client = Client.create(clientConfig);
WebResource webResource = client.resource("https://hj.yahooapis.com/v1/HJAuthTokens");
webResource.accept("application/xml");
// body is a hard-coded string, with replacements for the variable bits
String response = webResource.post(String.class, body);
// parse response into a org.w3c.dom.Document
// interface with Document via XPATH, or write my own POJO mappings
The response can look like:
<?xml version="1.0" encoding="utf-8"?>
<Response>
<ResponseCode>0</ResponseCode>
<ResponseMessage>Login successful</ResponseMessage>
<Token>NTlEMTdFNjk3Qjg4NUJBNDA3MkJFOTI3NzJEMTdDNDU7bG9jYWxob3N0LmVnbGJwLmNvcnAueWFob28uY29tO0pVNWpzRGRhN3VhSS4yQVRqRi4wWE5jTWl0RHVVYzQyX3luYWd1TjIxaGx6U0lhTXN3LS07NjY2MzM1OzIzNDY3NTsxMjA5MDE2OTE5OzZCM1RBMVNudHdLbl9VdFFKMFEydWctLQ==</Token>
</Response>
Or, it can look like:
<?xml version="1.0" encoding="utf-8"?>
<yahoo:error xmlns:yahoo="http://www.yahooapis.com/v1/base.rng" xml:lang="en-US">
<yahoo:description>description</yahoo:description>
<yahoo:detail>
<ErrorCode>errorCode</ErrorCode>
</yahoo:detail>
</yahoo:error>
Questions
Is there a way to auto-generate POJOs which can be marshalled/unmarshalled without a formal schema?
Should I attempt to generate those POJOs by hand, with JAXB annotations?
Is there some tool I should be leveraging so I don't have to do all this manually?
It's interesting that they provide an HTTP URL as the namespace URI for the schema, but don't actually save their schema there. That could be an oversight on their part, which an email or discussion-list posting could correct.
One approach is to create your own schema, but this seems like a lot of work for little return. Given how simple the messages are, I wonder if you even need a POJO to wrap them? Why not just have a handler that extracts the data you need using XPath?
Edit: blast from the past, but I saw the comment, reread the question, and realized that the first sentence was hard to understand. So, clarification:
One very good habit, if you're going to write a publicly accessible web service, is to make your schema document available at the same URL that you use for the schema's namespace URI -- or better, have that URL be a link to complete documentation (the W3C XSD namespace is itself a good example: http://www.w3.org/2001/XMLSchema).
I would suggest writing beans by hand, and only annotating with JAXB annotations if you have to. For most accessors/mutators (getters/setters) you do not have to; by default all public bean accessors and fields are considered, name is derived using bean convention, and default is to use elements instead of attributes (so attributes need to be annotated).
Alternatively you can of course write schema by hand, generate beans using JAXB, if you like W3C Schema a lot. And just use resulting code, not schema, for data binding.
As to POJO: that can be very simple. Something like:
#XmlRootElement("Response")
class Response {
public int responseCode;
public String responseMessage;
public String token; // or perhaps byte[] works for automated base64?
}
and similarly for other ones. Or, use getters/setters if you like them and don't mind bit more verbosity. These are just data containers, no need to get too fancy.
And if you must auto-detect type from content, consider using Stax parser to see what the root element, and then bind using JAXB Unmarshaller, handing XMLStreamReader that points to that root element. That way you can pass different object type to bind to.
And finally: sending/receiving requests: plain old HttpURLConnection works ok for GET and POST requests (construct using, say, URL.openConnection()). Jakarta HttpClient has more features if need be. So oftentimes you don't really need a separate REST client -- they may come in handy, but generally build on simple http client pieces.
I find HTTP4E very useful for making REST calls. It is an awesome Eclipse plugin, it has tabs, syntax coloring, auto suggest, code generation, REST HTTP call replay, etc.. It does a great job of HTTP debugging, HTTP tampering, hacking. I am having so much fun with it.
http://www.ywebb.com/
Try JdkRequest from jcabi-http (I'm a developer). This is how it works:
String body = new JdkRequest("http://www.google.com")
.header("User-Agent", "it's me")
.fetch()
.body()
Check this blog post for more details: http://www.yegor256.com/2014/04/11/jcabi-http-intro.html