I'm trying to use the InMemoryClientExecutor to call services on my local JVM which return javax.ws.rs.core.Response objects. I can get this to work but only by specifying the String type like so:
String response = new ClientRequest("/myService", executor)
.get(String.class)
.getEntity();
Since the signature of the service is like so:
#GET
#Path("/myService")
public Response getSomeData(#Form MyFormBean bean) {
//...blah...
}
However I would like to get the actual Response objects back so that I can get the entities out and return those objects in my new "aggregate" response. When I just return the string the Jackson Parser doesn't see this as JSON, just a regular string so it does things like encoding line breaks into \n, etc.
Whenever I do something like:
String response = new ClientRequest("/myService",executor)
.get(Response.class)
.getEntity();
or even this to just get the plain request object:
String response = new ClientRequest("/myService", executor).get().getEntity();
I get the following Exception:
Exception Occured: org.jboss.resteasy.client.ClientResponseFailure: Unable to find a MessageBodyReader of content-type application/json and type null
at org.jboss.resteasy.client.core.BaseClientResponse.createResponseFailure(BaseClientResponse.java:523)
at org.jboss.resteasy.client.core.BaseClientResponse.createResponseFailure(BaseClientResponse.java:514)
at org.jboss.resteasy.client.core.BaseClientResponse.readFrom(BaseClientResponse.java:415)
at org.jboss.resteasy.client.core.BaseClientResponse.getEntity(BaseClientResponse.java:377)
at org.jboss.resteasy.client.core.BaseClientResponse.getEntity(BaseClientResponse.java:338)
Also present further down is:
Servlet.service() for servlet Resteasy threw exception: org.jboss.resteasy.spi.LoggableFailure: Unable to find contextual data of type: javax.servlet.http.HttpServletRequest
at org.jboss.resteasy.core.ContextParameterInjector$GenericDelegatingProxy.invoke(ContextParameterInjector.java:56)
at $Proxy210.getScheme(Unknown Source)
Where am I going wrong?
There is no Response object being returned from the server, just a data stream that, in your case, is the representation of some entity, in JSON format. Trying to deserialize this data back into a Response object on the client side will not work, because effectively you are saying the JSON represents a Response object, which it doesn't (it represents the entity that *used to be contained in the Response).
Good news is, there are other ways to obtain the entity, which do not require trying to back-spin it into a Response. You will need to have the entities on the classpath of your client:
MyEntity response = new ClientRequest("/myService", executor)
.get(MyEntity.class)
.getEntity();
Replace MyEntity with the type of the actual entity you are expecting to receive.
Related
I am calling an external API (on which I do not have a control to make any change) using Spring's RestTemplate. The API returns response with an array as response body if the results are found and if not it returns response with String as response body stating "No records found". I am getting an exception when I am getting the no company found message because I typecasted the RestTemplate call to the custom object
ResponseEntity<Student[]> studentDetails = restTemplate.getForEntity(studentUrl, Student[].class);
The above code throws exception when the API returns String message "No records found".
What is the best way to deal with such a scenario?
In that case, you probably may use it like that
ResponseEntity<Object> studentDetails = restTemplate.getForEntity(studentUrl, Object.class);
And then check for the response type and cast the result.
I have a Java Spring API which expects 2 params, a simple String and a object:
#RequestMapping(value = "list", method = RequestMethod.GET)
public ResponseEntity<ListResource> getList(#RequestParam("agentName") String agentName,
#RequestParam("paginationInfo") PaginationInfoList paginationInfo {
//After http request i expect to have here my java Object PaginationInfoList ready to use
}
I'm, trying to send http GET request with Postman but i get this error, then i suppose that i'm not sending the data object "paginationInfo" in the correct way.
"Failed to convert value of type 'java.lang.String' to required type 'com.pippo.prova.test.model.in.PaginationInfoList'; nested exception is java.lang.IllegalStateException: Cannot convert value of type 'java.lang.String' to required type 'com.pippo.prova.test.model.in.PaginationInfoList': no matching editors or conversion strategy found"
Since i can't change the way of sending, infact must be GET and i have to use #ReuqestParam, i don't know how to send json data in postman parameters. I'm trying this and also other options but i always get error.
You can bind The request params to an object. In postman you will have 3 params ("agentName", "pageSize" and "pageNumber") and your controller will receive 2 objects
public ResponseEntity<ListResource> getList(#RequestParam("agentName") String agentName,
#Valid PaginationInfoList paginationInfo)
http://dolszewski.com/spring/how-to-bind-requestparam-to-object/
I have a response which produces #Produces(MediaType.APPLICATION_JSON) like this:
return Response.status(200).entity(product).entity("some message").build();
why postman shows me unexpected s in json view result and some message in xml view
For the Response.ResponseBuilder.entity(Object)` you can see
public abstract Response.ResponseBuilder entity(Object entity)
Set the response entity in the builder.
Any Java type instance for a response entity, that is supported by the runtime can be passed. It is the callers responsibility to wrap the actual entity with GenericEntity if preservation of its generic type is required. Note that the entity can be also set as an input stream.
A specific entity media type can be set using one of the type(...) methods.
Since you call this method twice, only the last value is saved.
Since "some message" is not at all a JSON syntax, it is saying that the s (from some) is unexpected, it is expecting a {
Lets say I have the following REST method:
#GET
#Path("get/{id}")
#Produces({"application/json", "application/xml"})
public Entity getEntity(#PathParam("id") int id) {
//do stuff
Entity entity = find(id);
return entity;
}
When I hit the rest endpoint with any browser by default I get back XML. Is there a way I can specify at the request which media type I want returned? or must I somehow include that information in the path?
You have to specify the Accept header with the media type you want in addition to the Content-Type header that states what is the content type of your request.
So use the Accept header instead of Content-Type header:
Accept: application/xml
You should manually prepare your response. For example if you want JSON answer, you should convert your Entity class to Json and return String.
You can use https://code.google.com/p/google-gson/ for conversion.
In fact it is your decision and your work to prepare the answer. The only thing to take in consideration that Rest works on top of HTTP, so some sort of text(JSON, XML, Plain text) is the most "friendly" format of information.
May be this example can help
RestClientWithAcceptHeader
RestClient client = new RestClient();
ClientResponse response = client.resource("http://example.com/resources/resource1").header("Accept", "application/json;q=1.0, application/xml;q=0.8").get();
// find what format was sent back
String contentType = response.getHeaders().getFirst("Content-Type");
if (contentType.contains("application/json")) {
JSONObject entity = response.getEntity(JSONObject.class); /* or use a String, InputStream, or other provider that supports the entity media type */
} else if (contentType.contains("application/xml") {
String entity = response.getEntity(String.class); /* or use a JAXB class, InputStream, etc. */
More here and here
I am using cxf as a webservice.It supports xml and json format output of the requested data.I want to know that if some exception has occured in my code then i want to return him back the error code either in xml or json format.But i dont know when to give json and xml ,it depends on the requested url that user has asked.
example
#Path("/reports/ad-view/loginId/{loginId}/publisher/")
PublisherReports getPublisherReportsAdView(
#PathParam("loginId") String loginId,
#QueryParam("fromDate") String fromDate,
#QueryParam("toDate") String toDate,
#QueryParam("filterValue") String filterValue);
If you mean you want to detect the mime type used to make the request, then you can use the #Consumes annotation to dictate which method handles which type of request. So you could write:
// Called when an XML request is made
#Path("/reports/ad-view/loginId/{loginId}/publisher/")
#Consumes("application/xml")
PublisherReports getPublisherReportsAdViewXml(...
and:
// Called when a JSON request is made
#Path("/reports/ad-view/loginId/{loginId}/publisher/")
#Consumes("application/json")
PublisherReports getPublisherReportsAdViewJson(...
Then have each variant of the getPublisherReportsAdView() method call a common method to perform the actual processing logic but still handle exceptions differently depending on the method that gets called.
An alternative approach, which doesn't require additional methods, would be to add a parameter which is annotated with the #HeaderParam annotation and use that to hold the value of the 'Content-Type' request header.
e.g.:
PublisherReports getPublisherReportsAdView(
#PathParam("loginId") String loginId,
#QueryParam("fromDate") String fromDate,
#QueryParam("toDate") String toDate,
#QueryParam("filterValue") String filterValue,
#HeaderParam("Content-Type") String contentType)
{
...
The value of contentType will likely also include charset information, for example: application/json; charset=UTF-8 so you'll need to ignore that when working out if the request contained JSON or XML.