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.
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
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.
I'm in a current situations in which I have a REST endpoint that accepts POST of incoming JSON messages.
The thing is that I don't think I can specify the POJO object so Jackson can marshall the JSON into the POJO object. Reason for this is that I don't have control of what comes to that endpoint, and number of fields and type can change over time, thus, defining a POJO before hand seems not an option.
So I guess the question is....can I simply tell Jackson to don't do any marshalling and give the String of the response? I can deal with that later with JSONObject-JSONArray or Gson maybe. Say I'd have a method like this:
#POST
#Path("/callback")
#Produces(MediaType.APPLICATION_JSON)
#Consumes(MediaType.APPLICATION_JSON)
public Response facebookUpdate(String json) {
//Do something with the json response...
}
If this is not feasible with Jersey-JAX...any other alternatives?
Thanks!
Alejandro
The easiest is to simply not inject the json into the method and use the request object instead:
public Response facebookUpdate(#Context request) {
try(InputStream is=request.getEntityInputStream()) {
...
}
}
From the request you can then get an inputstream for the request and parse it whichever way you like.
For parsing I can recommend my own jsonj library, which was written specifically to support open ended scenarios like you describe and uses jackson to deserialize into heavily customised implementations of java.util.Map and java.util.List. Gson is also a very solid choice.
If you want to do this application wide, you can instead write your own #Provider and do the same there. This is how I use my library currently actually.
I have a requirement that I need to send an xml from the restclient addon of firefox browser to the resource by adding that xml in the request body. For that I have written a message body reader implementation class and there I am converting that xml to java object. But I am not able to invoke that message body reader class. how to invoke that?
You don't invoke a MessageBodyReader. You mark it as a #Provider and ensure it's added to your JAX-RS application's classes or singletons. There are many ways to do that, some of which are dependent on which JAX-RS implementation you're using. The MessageBodyReader is invoked by the JAX-RS implementation when needed to convert an HTTP entity to a POJO based on media type.
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.