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!**
Related
I am calling a SOAP webservice in a Spring Boot project using Spring WebserviceTemplate. My client class extends WebServiceGatewaySupport. I cannot post the actual code, but this is a sample.
Response response = (Response) getWebServiceTemplate().marshalSendAndReceive(request, new SoapActionCallback("http://tempuri.org/rpc/Gateway/"));
When this request is sent, I am getting response code 400. I enabled trace logging for Spring and found that an empty request is sent.
TRACE o.s.ws.client.MessageTracing.sent.sendRequest - Sent request []
When I tried to create a simpler web service client using the same components - Spring Boot project using Spring WebserviceTemplate, I can see that it sends a valid XML payload and it works.
I have now found that this error happens only as part of a larger existing project - the request object being marshaled as an empty string. It is just sending an empty payload. There are no errors in the log before the call is made to webservice.
The request and response POJO are generated by maven-jaxb2-plugin & I have verified that the package and schema are correct.
I have verified that the Marshaller (Jaxb2Marshaller) and its context path are set correctly, and it marshals the request object when called separately.
How can I debug this? Please give your suggestions.
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 have a JAX-RS client that's making a simple GET request. I'm using the CXF implementation and Spring for DI. The call is successfull and I get a response code of 200 back. But I'm getting an error when reading the response into my POJO.
Exception:
[2015-05-08 16:11:55,457][ERROR][org.apache.cxf.jaxrs.utils.JAXRSUtils]: No message body reader has been found for class com.voya.refapp.domain.Customer, ContentType: application/json
[2015-05-08 16:11:55,468][ERROR][com.voya.refapp.service.CustomerServiceImpl]: filterByName() - Exception occurred
javax.ws.rs.client.ResponseProcessingException: No message body reader has been found for class com.voya.refapp.domain.Customer, ContentType: application/json
at org.apache.cxf.jaxrs.impl.ResponseImpl.reportMessageHandlerProblem(ResponseImpl.java:433) ~[cxf-rt-frontend-jaxrs-3.0.4.jar:3.0.4]
at org.apache.cxf.jaxrs.impl.ResponseImpl.doReadEntity(ResponseImpl.java:384) ~[cxf-rt-frontend-jaxrs-3.0.4.jar:3.0.4]
Code:
Client client = ClientBuilder.newClient();
WebTarget target = client.target("http://localhost:8080/rest").path("customers/1");
Invocation.Builder builder = target.request(MediaType.APPLICATION_JSON_TYPE);
Response response = builder.get(); // Successful
Customer customer = response.readEntity(Customer.class); // Fails
I have the below dependency as suggested in this answer in my classpath, it doesn't seem to be picked up automatically.
<dependency>
<groupId>com.fasterxml.jackson.jaxrs</groupId>
<artifactId>jackson-jaxrs-json-provider</artifactId>
</dependency>
I also tried registering the json provider when creating the client:
Client client = ClientBuilder.newClient().register(new JacsksonJsonProvider());
and
Client client = ClientBuilder.newClient().register(JacsksonJsonProvider.class);
But none of these options worked too. I got a different exception when I registered the json provider using one of the options above:
javax.ws.rs.client.ResponseProcessingException: Problem with reading the data
Update:
Registering the json provider worked fine using ClientBuilder.newClient().register(JacsksonJsonProvider.class). The issue was with the data (like the exception above clearly states.. I feel silly now :(). I had boolean field in the json named "active", but it was called "isActive" in the POJO. Once I added the annotation #JsonProperty("active") to the field in POJO, it started working fine
AFAIK CXF does not support autodiscovery of MessageBodyReader classes. But registering manually JacksonJsonProvider should work for you.
Please check my example that works perfectly well. It is almost exactly the same as yours, I just used different service. Maybe you can spot a difference that prevents your version from working correctly.
Client client = ClientBuilder.newClient().register(JacksonJsonProvider.class);
WebTarget target = client.target("http://jsonplaceholder.typicode.com").path("posts/1");
Invocation.Builder builder = target.request(MediaType.APPLICATION_JSON_TYPE);
Response response = builder.get(); // Successful
Post post = response.readEntity(Post.class);
I have a JSONArray that I am creating by iterating through a database using the cursor(Java). The JASONArray I am creating looks like this:
[{"transID":"1001","shiftID":"1","transType":"test","transDateTime":"2013-02-22 15:30:374:021"},
"transID":"1002","shiftID":"2","transType":"ghy","transDateTime":"2013-02-25 11:56:926:020"},
"transID":"1003","shiftID":"3","transType":"ghfm","transDateTime":"2013-02-25 11:56:248:026"}]
I am trying to post the JSONArray above to a RESTful service. I have the URL, UserID and Token, I am having a hard time understanding how to create HTTP post and have looked at the following links:
How to send a JSONObject to a REST service?
Posting a File and Associated Data to a RESTful WebService preferably as JSON
Posting a JSONArray to WCF Service from android
I understand how the first link worked, but I am unclear on how I should implement the userID and token before posting to the REST service.
This is new to me and if anyone could lead me in the right direction it would be appreciated.
Thank you in advance.
Take a look at Jersey's REST client library. There is a class called WebResource. In order to post to a RESTful service, you can invoke the post method. Note that the second argument in the post method contains the POST request entity, which you can encapsulate your JSONArray entity in your request. Alternatively you can use entity method to specify the MediaType (APPLICATION_JSON) of request entity.
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.