I'm trying to create a jax-rs client which posts an xml as object and receives an xml on the response body from the server. The code is as below:
import org.apache.cxf.jaxrs.client.WebClient;
..
TravelRequest tr = ...
..
WebClient client = WebClient.create(url);
client.type(javax.ws.rs.core.MediaType.APPLICATION_XML_TYPE).accept(javax.ws.rs.core.MediaType.APPLICATION_XML_TYPE);
javax.ws.rs.core.Response r = client.post(tr);
Object response = r.getEntity();
The java type of the response object is sun.net.www.protocol.http.HttpURLConnection$HttpInputStream
Is it possible to get an object of TravelRequest type instead of reading the xml from input stream? Someone knows any example of it? I can also use spring to configure my client.
Any help would be appreciated.
This is how it is done.
TravelRequest travelRequest = client.post(tr, TravelRequest.class);
Hope this will help someone.
You are using the WebClient the wrong way. Methods like accept and type dont' alter the WebClient but return the updated Client
So the correct usage is:
WebClient client = WebClient.create(url);
Response response = client.type(...).accept(...).post(tr);
The Response.getEntity() can then be used to extract the response.
CXF supports various forms of data binding that you can use to map the response body to your classes.
Related
I am using spring framework reactive webclient to make a call like below
webClient.post()
.uri("/v/score/$model")
.contentType(MediaType.APPLICATION_JSON)
.bodyValue(gson.toJson(request))
.accept(MediaType.APPLICATION_JSON)
.header("Client-Id", clientId)
.awaitExchange()
.awaitBody<ScoringResponse>()
which is working fine. Now I wan to pass the request as a protobuff object instead of json. How can I do that ?
Set the media type to application/octet-stream and pass your proto model in a byte array form by using the .toByteArray() method. On the receiving end you can use the static method {proto generated class}.parseFrom({your bytes come here}) to rebuild the proto object.
Do not forget the POST method request is basically a body content ;)
I am trying to write a cxf interceptor which will forward all the incoming requests from my app to another app. However for POST requests I am unable to get the body of the request.
The code I am using looks like :
String body = message.getContent(String.class);
However the body comes as null. I looked into cxf code & it looks like you have to specify the exact class (Ex : ArrayList) to get the body. My app has multiple such message classes. I wanted to know if there is a method by which I can avoid writing multiple checks for each of my POJO class & do it in a single if.
You could call message.getContent(InputStream.class) and use CXF IOUtils to read into String. Please refer javatips.net/blog/cxf-interceptor-example for more details
try:
XMLStreamReader body = message.getContent(XMLStreamReader.class);
I'm using Jersey 2.22 to consume a REST api.
The approach is contract-first, a service interface and wrappers are used to call the REST api (using org.glassfish.jersey.client.proxy package).
WebClient webClient = ClientBuilder.newClient();
WebTarget webTarget = webClient.getWebTarget(endPoint);
ServiceClass proxy = WebResourceFactory.newResource(ServiceClass.class, webTarget);
Object returnedObject = proxy.serviceMethod("id1");
The question is: how to get the underlying HTTP response (HTTP status + body)?
When the returnedObject is null, I need to analyze the response to get error message returned for example.
Is there a way to do it?
I saw that we can plug filters and interceptors to catch the response, but that's not exactly what I need.
You should return Response as the result of the interface method instead of the plain DTO.
I'm not sure about the level of control you're expecting (considering your reply to #peeskillet comment), but the Response object will give you the opportunity to fine tune your server's response (headers, cookies, status etc.) and read all of them at the client side - as you might see taking a look at Response's members like getStatus() and getHeaders().
The only gotcha here is how to get the body. For this, I'd tell you to use readEntity(Class<T>) (not the getEntity() method as one might try at first). As long as you have the right media type provider registered, you can extract the entity as your DTO class in a easy way.
For example, if you are using maven, jersey and JSON as media type, you can add the following dependency (and take the provider's registration for granted):
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
</dependency>
Then, get the entity body deserialized using:
Response resp = proxy.serviceMethod("id1");
int status = resp.getStatus();
String statusText = resp.getStatusInfo();
String someHeader = resp.getHeaderString("SOME-HEADER");
YourCustomDTO obj = resp.readEntity(YourCustomDTO.class);
When querying a list of your custom objects (i.e. method returns a JSON array) use the array type to read the body.
Response resp = proxy.serviceMethodThatReturnsCollection();
YourCustomDTO[] obj = resp.readEntity(YourCustomDTO[].class);
Please notice that after reading the body, the stream is closed and trying getEntity() may throw an exception.
Hope it helps.
My first question on this community that has helped me so much already.
I'm using RestEasy and trying to do a POST request to a REST service sending a JSON object. The problem is that my JSON object keeps going as a request parameter and not in the request body, which is what I need.
Here is how I'm doing it.
Invocation inv = target.request().buildPost(Entity.json(shipment));
Response response = inv.invoke();
I've been looking for ours on how to put the JSON object into the request body but found nothing.
Any ideas?
This is resolved. There was a problem on the web service that was receiving my request.
Thanks everyone for your comments!**
I have a Java WebService setup which consumes an xml file and want to be able to produce either xml or json based on what the client requests. I know that this is possible through reading up on Jersey REST methods but it does not show how to extract this information. I have also looked on google all over but can't seem to find any examples of this.
http://wikis.sun.com/display/Jersey/Overview+of+JAX-RS+1.0+Features is the site that I was initially referencing which shows that it is possible, I was just wondering if anyone would be able to help me find out how to actually distinguish the client's request. Is it in the html header? body? And if so what is the proper way to extract it?
This is what my method currently looks like, I do not have any issues with connection, just finding out what the client requests as a return type.
#POST
#Path("getStatisticData")
#Produces ({"application/xml","application/json"})
#Consumes ("application/xml")
public String getStatisticData(#FormParam("xmlCoords") String xmlFile) throws Exception{
Thanks in advance.
You can extract it using the #HeaderParam annotation:
...
public String getStatisticData(#HeaderParam("Accept") String accept,
#FormParam("xmlCoords") String xmlFile) throws Exception {
...
}
The Accept header in the request is used for the client to indicate to the server what methods it supports.
If the client can set HTTP headers, the proper way to do it is to use the Accept header:
http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
IF this is not possible, the type requested could be passed in as an argument.
Alternatively, expose two different web services: one that returns XML, one that returns JSON. Each web service would call the same code but with a parameter specifying which format to use.