JAX-RS GET: MessageBodyReader not found for media type=text/plain - jersey

I'm getting following error while trying to do JAX-RS GET request:
MessageBodyReader not found for media type=text/plain, type=class com.intuit.accountant.services.common.cdm.Job, genericType=class com.intuit.accountant.services.common.cdm.Job
Below is my code:
Response response = target("jobs/Hello")
.request()
.header("intuit_offeringid", "testOfferingId")
.header(RequestHeaders.REALM, CommonUtil.DEFAULT_REALM_ID_FOR_INTUIT_EMPLOYEE)
.header(RequestHeaders.AUTH, "002923")
.header(RequestHeaders.TICKET,"00303")
.get(Response.class);
What does this error mean? How can I fix this?

You need to post all the code. The error is almost assuredly not happening in that code sample you posted. The get(Response.class) is converting it to a generic http response where you can see the response payload, status, response headers etc.
What you didn't post would most likely look somemthing like this. response.readEntity(com.intuit.accountant.services.common.cdm.Job)
In this case you don't have a reader registered to convert a text/plain response from the server to an entity. I don't know if the response was supposed to be json/xml and you are receiving text because there was an error of some kind. You should check the response as text like this to see what you are getting. This will probably point you in the right direction. If you are getting text you would have to write an implementation of MessageBodyReader to convert the plain text into an entity.
Try this...
System.out.println("Response body is " + response.getEntity(String.class));

Related

How to Get request body in spring cloud gateway

Is there a way I can extract the request body (JSON) from the spring cloud gateway?. I went through a few approaches like RequestBodyrewrite and all, but as far as I understood it is used for modifying the response body. In my case, I wanted to get the request body and do some logic there and send the data via headers to the underlying microservices. Right now I am getting the request body with the attribute "cachedRequestBodyObject" with the help of the request body predicator.
readBody(SomeClass.class, s-> true)
I don't think I am not fully making use of the request body predicator here. We would also get this as part of the getRequestBody() method but it has a data buffer as a return type, so not sure how to get the JSON details from the data buffer. Is there a way better approach to do this ?..
Thanks in Advance.

generic return type for restemplate.exchange

I am using resttemplate.exchange to invoke a URL and get response. But the issue is the response type varies when I successfully receives the output and if I get some error.
eg.
ResponseEntity<XXX[]> response = restTemplate.exchange(endPoint,HttpMethod.GET,req,
new ParameterizedTypeReference<XXX[]>() {},uriVariables);
If there is no issue with service and then output is in format of list. but if there is error like "NO DATA FOUND" then the response is in MAP. so whenever I have any issue with URL i get "404: null error" because my response type is unable to identify the error which is in MAP.
Could you please suggest what could be done as i can not change the response type of services.
Edit:: http://localhost:9090/data/getDetail?name=XXX
response [{"name":"XXX","Dept":"teaching","createdby":"YYY","createdDt":"06/09/2018"}]
when data not found case::http://localhost:9090/data/getDetail?name=YYY
response
{"response":"DATA NOT FOUND"}

Receiving "Invalid_Request" response from Google-DistanceMatrix api in VBA

I'm sending an XML Request to the google-distancematrix api with a string that looks like:
https://maps.googleapis.com/maps/api/distancematrix/xml?origin=Grafton,+VA&destination=Yorktown,+VA&key=myKey
and am getting the following back:
<DistanceMatrixResponse>
<status>INVALID_REQUEST</status>
</DistanceMatrixResponse>
I'm obviously doing something wrong when formatting the request string, any recommendations?
turns out the syntax should be "origins" and "destinations" (plural) instead of "origin" and "destination"

Jersey: Returning 400 error instead of 500 when given invalid request body

I'm using Jersey's integrated Jackson processing to transform incoming JSON to a POJO, e.g.:
#POST
#Consumes(MediaType.APPLICATION_JSON)
public Response newCustomer( CustomerRepresentation customer)
{
...
}
If a client sends JSON with invalid fields Jersey currently returns a 500 Internal Server Error. Instead, I'd like to return a 400 Bad Request, preferably with some meaningful detail indicating which fields are in error.
Any insight into how this could be accomplished? (At least returning a generic 400 instead of the completely inappropriate 500?)
Update:
Here's the exception being generated server-side, before my handler is invoked:
javax.servlet.ServletException: org.codehaus.jackson.map.exc.UnrecognizedPropertyException:
Unrecognized field "this_isnt_a_known"_field" (Class com.redacted....), not marked as ignorable
I was finally able to work around this problem by implementing an ExceptionMapper to catch the UnrecognizedPropertyException thrown by Jackson and map it to a 400 Bad Request response:
#Provider
public class UnrecognizedPropertyExceptionMapper implements ExceptionMapper<UnrecognizedPropertyException>
{
#Override
public Response toResponse(UnrecognizedPropertyException exception)
{
return Response
.status(Response.Status.BAD_REQUEST)
.entity( "'" + exception.getUnrecognizedPropertyName() + "' is an unrecognized field.")
.type( MediaType.TEXT_PLAIN)
.build();
}
}
I tried mapping status 500 to status 400 with HolySamosa's answer but the exception was not caught by this mapper, and status 500 was still being returned.
After debugging I found that JsonParseException is being thrown and not UnrecognizedPropertyException. This is because I was sending some garbage text (that was not JSON at all).
When I sent a proper JSON from client side, with format that was not appropriate for my DTO on the server side, then I got UnrecognizedPropertyException.
So there are two cases for this:
when you send garbage that is not JSON and
when you send JSON, but it is not a match for your DTO class.
Now I am returning status 400 for both.
In dropwizard land there is an ExceptionMapper called JsonProcessingExceptionMapper that has similar functionality as to what you are looking for. Maybe you can use that for inspiration on how to address your specific issue in a non-dropwizard world.
I've had this same problem... Unfortunately, there's no good way that I know of to intercept the Jackson exception and generate your own error code.
One option you have is to use #JsonIgnoreProperties and then strictly validate the deserialized object. This won't tell you if your sender transmitted junk, but if they missed required fields, you'll catch that.
I cannot find any way to access the actual JSON passed in, other than creating an #Provider class to trap the JSON, validate it, then pass it to Jackson for deserialization.

HttpWebRequest/Response throwing error "Not Found"

I am making an API call to a REST service. The REST service returns an XML string that contains a user token if the password submitted is correct, or an XML string with data if it isn't.
Here is an example if the password is incorrect:
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<authenticationResponse>
<statusCode>403</statusCode>
<errors>
<error>
....
</error>
</errors>
<timestamp>2011-03-31 22:45:03 GMT</timestamp>
</authenticationResponse>
With this code below, it appears .NET is translating this to an actual error. I still want it to read the XML data and ignore any error:
RequestData requestData = (RequestData)result.AsyncState;
HttpWebResponse response =
(HttpWebResponse)requestData.Request.EndGetResponse(result);
How I can ignore the error but still create the stream to read the XML?
Catch WebException, check the exception status, read the response. See these questions for examples:
Catching a specific WebException (550)
WebException when reading a WebException's response stream
Your code isn't translating this into an actual error - a HTTP status code of 403 is "Forbidden".
HTTP "Not Found" has a HTTP status code of 404 so it looks like the HTTP endpoint you're requesting doesn't exist in the REST service.
Ok so I figured it out, there's a few parts here.
First off the API is generating that xml when the parameters passed don't meet whats expected. In this case, if the password is incorrect, it'll pass back the 403.
The error is an error, so the framework treats it as such, however the error contains a response anyways, you just have to get the response off the error. This is essentially the answer to the question. Have to catch it the error and snag the response off the error to read the data in the stream, which is what Mauricio was getting to.
Essentially, I guess all the answers here are correct, or pieces of it, just took a little digging to put it all together.
Thanks Guys.

Resources