I am using Apache Camel HTTP component and I am able to send request and receive response.
In failure cases i get exception and if i try to get the HTTP Response code from headers, the response is null.
if(exchange.getException() != null ){
exchange.getException().printStackTrace();
String responseCode = (String) exchange.getOut().getHeader(Exchange.HTTP_RESPONSE_CODE);
}
exchange.getOut() is NULL and fails with NullPointerException.
How to retrieve the HTTPResponse Code in such cases? Ex: 400, 404, 405.
According to the documentation for the http-component you should be able to extract the response code from the Exception.
Perhaps something like this:
int code = ((HttpOperationFailedException)exchange.getException()).getStatusCode();
Related
I have this code, I use cxf WebClient:
WebClient client = someClient.reset();
Response response = client.post(bodyRequest);
If status code in response turns into 200 I can parse it into something like this:
CustomResponse customResponse = response.readEntity(CustomResponse.class);
And that's ok, but if status code turns to be 400 or another, response entity seems to be null, so I can't find a way to parse it into an object ResponseCodeError, like this:
ResponseCodeError responseError= response.readEntity(ResponseCodeError.class);
This will fail.
Is there a way to use cxf and parse error into Custom error class?
Thanks.
You can check the status using
int code = response.getStatus();
then you check for a code of 200 to parse the entity or throw the respective error for other codes like 400.
We are getting back json from a rest API which we try to marshal into an object. However, because this does not always work, we want to also log every raw response body as a string (or possibly only if ther is a marshalling exception). E.g:
Response response = invocationBuilder.get();
int statusCode = response.getStatus();
if (statusCode != 200 && statusCode !=201 && stausCode != 404) {
logger.error("Got a strange response: " + response.????
}
// this may fail with exceptions...
MyResponseDO myResponse = response.readEntity(MyResponseDO.class);
return myResponse;
Any suggestions? I cant see anything useful on the Response class (there is no getBody() or similar).
Since JSON is just a string, it can be mapped to the string type. You can get raw response using:
response.readEntity(String.class);
Note: readEntity closes the data stream, that means you can not to call readEntity again. From java doc:
A message instance returned from this method will be cached for subsequent retrievals via getEntity(). Unless the supplied entity type is an input stream, this method automatically closes the an unconsumed original response entity data stream if open.
I use httpResp.sendError(400, "You are missing customer id") to send the response back
When I try to retrieve the message on the client side (using Rest template to call the endpoint).
However, printing the HttpClientErrorException always produces the following result for me:
HttpClientErrorException: 400 null
I see that I have HttpClientErrorException.getResponseBody has all the information about time stamp, message etc. But HttpClientErrorException.getStatusText is always empty.
My question is : How do you design your ResponseEntity on the server-side such that the HTTP client finds the server-side exception message in response.getStatusText() instead of null?
here is the code I have
try{
ResponseEntity<String> responseEntity = restTemplate.exchange(uri, HttpMethod.POST, requestEntity, String.class );
System.out.println(responseEntity.getBody());
}
catch (HttpClientErrorException | HttpServerErrorException e) {
if (e.getStatusCode().equals(HttpStatus.UNAUTHORIZED) || e.getStatusCode().equals(HttpStatus.FORBIDDEN)) { System.out.println("Response Body returned:");
System.out.println(e.getResponseBodyAsString());
System.out.println("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%");
System.out.println("Status text is:");
System.out.println(e.getStatusText());
} else if (e.getStatusCode().equals(HttpStatus.BAD_REQUEST)) {
System.out.println("Response Body returned:");
System.out.println(e.getResponseBodyAsString());
System.out.println("-------------------------------");
System.out.println("Status text is:");
System.out.println(e.getStatusText());
} else {
throw e;
}
}
Sprint Boot Version: 2.1.0.RELEASE
I traced the code for how RestTemplate actually makes the calls. Basically what happens is the result of HttpClientErrorException.getStatusText() is populated by the HTTP status code's text and not your custom error message. For example, instead of just returning back error code 400, a server might return back error 400 Bad Request. Instead of status code 200, a server might return back 200 OK. If the server responds back with that optional text, that's what you'll see when you call getStatusText(). Note that that text like OK and Bad Request can't be customized by you on the server side.
This is happening because, internally, Spring is making use of SimpleClientHttpResponse.getStatusText() which is internally relying on HttpUrlConnection.getResponseMessage(). As you can see from getResponseMessage's Javadoc, the possible values returned aren't meant to be custom error messages. Note that in your case, getStatusText() is returning null because your server is just sending back a status line like 400 and not 400 Bad Request. You can also see this from the Javadoc. You can probably configure your server to send back status code text messages, but doing so still won't help you use the getStatusText() method to get your custom error message.
Consequently, the HttpClientErrorException.getStatusText() just isn't what you need. Instead, you need to continue calling getResponseBodyAsString(). However, if you know the format of the response body that is sent back from the server (since this will likely be wrapped in HTML and other stuff) you can use a regex to filter out the non-useful parts of the response message.
I'm working on a Spring REST controller, specifically on an exception handler. The exception handler works as intended and my JUnit-Test (using the Spring HTTP client) shows that the correct HTTP Status code (400) is received at the client. The HTTP client automatically translates this into a HttpClientErrorException.
However, printing the HttpClientErrorException always produces the following result for me:
HttpClientErrorException: 400 null
... and the null part is what worries me. Shouldn't this be the place where the message of the server-side exception is supposed to be?
I checked the source code of the HTTP client to see where the client-side exception is thrown. It looks like this:
throw new HttpClientErrorException(statusCode, response.getStatusText(), response.getHeaders(), getResponseBody(response), getCharset(response));
Debugging this call revealed that response.getStatusText() is null in my case.
My question is: How do you design your ResponseEntity on the server-side such that the HTTP client finds the server-side exception message in response.getStatusText() instead of null?
Mine currently looks like this:
#ExceptionHandler({ MyCustomException.class })
public ResponseEntity<String> handleException(final HttpServletRequest req, final MyCustomException e) {
HttpHeaders headers = new HttpHeaders();
headers.set("Content-type", "text/plain");
String body = e.toString();
return new ResponseEntity<>(body, headers, HttpStatus.BAD_REQUEST);
}
... and I get null in the client side status text.
I must admit that I got fooled on this one. The null value printed by the Spring HttpClientErrorException is the statusText. This text is static. For example, for Status Code 404, the defined status text is "not found". There is no way to change it.
In order to receive the actual exception code, then the method suggested by Utku is exactly right. The small gotcha is that the error message needs to be extracted from HttpClientErrorException#getResponseBodyAsString(), not from HttpClientErrorException#getStatusText() like I tried.
I have the following problem...
I'm testing a service that return HTTP responses on GET requests.
My problem is that I would like to view the response even if it was an HTTP 500 / 404 or whatever response.
I would like to view that. But I can't because it throws an exception and that's it.
Is there a way to view a jersey response even if it was an error response?
My code is like this:
webResource = client.resource(url);
response = webResource.queryParams(alertParams)
.header("x-token", token).get(String.class);
So when get receives an error response from the service I wont be able to view that although the response is something like this:
{
"errCode" : "ERR002",
"errMsg" : "",
"techErrMsg" : "LoginFailureGeneric"
}
Which is a 400 Bad Request.
Thanks very much for all the help!!
This is where you need to spend some time with the docs... WebRequest#get(Class) will throw an exception when you get an HTTP error status if you are trying to parse the response as anything other than ClientResponse.
So all you need to do is change the .get(String.class) -> .get(ClientResponse.class) and you can pull the entity itself (and the status, and everything else) off of the ClientResponse object sans exceptions.