When HttpStatusCodeException exception raised? - java

when i use below code , what is the case to get HttpStatusCodeException exception .
ResponseEntity<Object> response =
restTemplate.exchange(builder.build().encode().toUri(), HttpMethod.GET, entity, Object.class);
Please can anyone help out ????????

According to documentation there are two types of HttpStatusCodeException HttpClientErrorException and HttpServerErrorException.
The former is thrown when an HTTP 4xx is received.
The latter is thrown when an HTTP 5xx is received.
so you can just use ResponseEntity.BodyBuilder.status(505) for example to raise an HttpServerErrorException in your

exhange(...) method of org.springframework.web.client.RestTemplate class was added in 3.1.0.RELEASE of spring-web library.
This method throws RestClientException which covers client (4_xx) and server (5_xx) side http code errors. But RestClientException doesn't offer getStatusCode(), getResponseAsString(), etc... methods.
HttpsStatusCodeException is the child of RestClientException which is doing same thing but with additional methods like getStatusCode(), getResponseAsString(), etc.
HttpClientErrorException child of HttpsStatusCodeException and only entertain client error (4_xx) not the server error.
HttpServerErrorException child of HttpsStatusCodeException and only entertain server error (5_xx) not the client error.

HTTP Status Codes are responses from the server, therefore if you have control of the server then you could make it return whichever errors you want. If you don't have control of the server then you could try sending bad/invalid requests so that the server will complain.
Something like this on your server side:
#RequestMapping(method = RequestMethod.GET)
public ResponseEntity getAnError() {
// complain!
return ResponseEntity.status(HttpStatus.FORBIDDEN);
}

Related

Custom WebApplicationExceptions in jaxrs caught by ExceptionMapper show up in server log

I use the following Exceptionmapper to map WebApplicationExceptions in my jaxrs rest api to responses.
#Provider
public class ErrorHandler implements ExceptionMapper<WebApplicationException> {
#Override
public Response toResponse(WebApplicationException e) {
int status = e.getResponse().getStatus();
JsonObject errorResponse = Json.createObjectBuilder()
.add("status", status)
.add("message", e.getMessage())
.build();
return Response.status(status)
.entity(errorResponse)
.type(MediaType.APPLICATION_JSON)
.build();
}
}
This works fine and it does exactly what it should do, but when I throw custom errors, for example throw new NotFoundException("custom message"); the stacktrace shows up in my server log. Can anyone explain this? Or does anyone know of a solution?
TL;DR;
For some reason when I throw WebApplicationExceptions from my jax-rs code, my ExceptionMapper handles the error but still throws it so it shows up in the server log.
Any solutions?
I've found the origin of this problem and managed to solve it.
From the JAX-RS spec
When choosing an exception mapping provider to map an exception, an implementation MUST use the provider whose generic type is the nearest superclass of the exception.
In my ExceptionMapper I used the WebApplicationException, so every error would be mapped. The problem is that WebApplicationException is not the nearest superclass of (e.g.) NotFoundException. There is a ClientErrorException superclass inbetween. When I changed my mapper to that class the problem was solved.
Since I only want to map client errors to Json responses this solution works fine for me.

JerseyClient not throwing exception for 4xx and 5xx response

I have a jersey client which calls an api whose return type is javax.ws.rs.core.Response as defined in the interface being used.
public Response getResponse(String id)
The response for a call has status as 'Server Error' but the client does not throw InternalServerException rather returns InboundJaxrsResponse.
On checking Jersey code I see that the JerseyInvocation class being used has the logic to check if response type is of javax.ws.rs.core.Response then to return an InboundJaxrsResponse object.
How can I get an appropriate exception as per the response status here?
PS: RestEasy client also has a similar logic.
With presume that you use <T> T get(Class<T> responseType) to get integer from an HTTP response body, exception that can be thrown if response status is not 2xx is WebApplicationException.
In your case, the second requirement of API contract is not fulfilled
WebApplicationException - in case the response status code of the
response returned by the server is not successful
and the specified response type is not Response.

JAX-RS service throwing a 404 HTTPException but client receiving a HTTP 500 code

I have a RESTful resource, which calls a EJB to make a query. If there is no result from the query, the EJB throws a EntityNotFoundException. In the catch block, it will be thrown a javax.xml.ws.http.HTTPException with code 404.
#Stateless
#Path("naturezas")
public class NaturezasResource {
#GET
#Path("list/{code}")
#Produces(MediaType.APPLICATION_JSON)
public String listByLista(
#PathParam("code") codeListaNaturezasEnum code) {
try {
List<NaturezaORM> naturezas = this.naturezaSB
.listByListaNaturezas(code);
ObjectMapper mapper = new ObjectMapper();
return mapper.writeValueAsString(naturezas);
} catch (EntityNotFoundException e) { // No data found
logger.error("there is no Natures with the code " + code);
throw new HTTPException(404);
} catch (Exception e) { // Other exceptions
e.printStackTrace();
throw new HTTPException(500);
}
}
}
When I call the Rest Service with a code for which there are no results, the log message inside the EntityNotFoundException catch block is printed. However, my client receives a HTTP code 500 instead a 404. Why am I not receiving a 404 code?
Thanks,
Rafael Afonso
javax.xml.ws.http.HTTPException is for JAX-WS. JAX-RS by default doesnt know how to handle it unless you write an ExceptionMapper for it. So the exception bubbles up to the container level, which just sends a generic internal server error response.
Instead use WebApplicationException or one of its subclasses. Here a list of the exceptions included in the hierarchy, and what they map to (Note: this is only in JAX-RS 2)
Exception Status code Description
-------------------------------------------------------------------------------
BadRequestException 400 Malformed message
NotAuthorizedException 401 Authentication failure
ForbiddenException 403 Not permitted to access
NotFoundException 404 Couldn’t find resource
NotAllowedException 405 HTTP method not supported
NotAcceptableException 406 Client media type requested
not supported
NotSupportedException 415 Client posted media type
not supported
InternalServerErrorException 500 General server error
ServiceUnavailableException 503 Server is temporarily unavailable
or busy
You can find them also in the WebApplicationException link above. They will fall under one of the direct subclasses ClientErrorException, RedirectionException, or ServerErrorException.
With JAX-RS 1.x, this hierarchy doesn't exist, so you would need to do something like #RafaelAlfonso showed in a comment
throw new WebApplicationException(Response.Status.NOT_FOUND);
There are a lot of other possible constructors. Just look at the API link above

Why Jersey send a 403 status when an exception is not caught in my code?

I am using Jersey to create REST services and when I get a NullPointerException or other type of RuntimeException a 403 error is sent to the client. Why Jersey sends 403 instead of a 500 and how can I change it?
PS: I know how to create an ExceptionMapper but it seems strange to create it to the RuntimeException class. I also use specific Exceptions extending WebApplicationException for the exceptions I am throwing.
I can not reproduce your problem. Calling this resource returns a 500:
#GET
#Path("/npe")
public Response triggerNpe() {
String npe = null;
npe.length();
return Response.ok().build();
}
Response:
HTTP Status 500 - Internal Server Error
javax.servlet.ServletException: java.lang.NullPointerException
I am using Glassfish 4 with standard libraries.
That should not happen. Your error is handled somewhere.
Look these annotations:
#ControllerAdvice
#ResponseStatus(HttpStatus.FORBIDDEN)
#ExceptionHandler(YourException.class)

throw exception as response from Spring handleRequest method

I have a scenario in Spring MVC , where I have to throw an Exception explicitly in the handleRequest Method.
For Eg.
public class AdminController implements Controller {
public ModelAndView handleRequest(HttpServletRequest request,
HttpServletResponse response) throws Exception {
// for some request parameter this is run. For Eg. reqParam=xyz
undeployTables();
}
public void undeployTables() throws Exception {
throw new Exception("Undeploy Exception");
}
Now assuming that spring servlet and url mapping is configured in web.xml, when i try to access the servlet via url http://localhost:8080/server/admin?reqParam=xyz, I get an correct error on page. java.lang.Exception: Undeploy failed....
But when I try to access the code via HTTPClient, that is via the java code the response in the client is not able to catch this exception and only I get is the HTTP 401 Internal Error as response object.But what i would Like to have is an Exception object in client.
Code is :
HttpPost httppost = new HttpPost(url.toURI());
httpclient.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT, timeout);
logger.info("executing request " + httppost.getURI()); //$NON-NLS-1$
// Create a response handler
HttpResponse response = httpclient.execute(httppost);// expect exception to be thrown here
statusCode = response.getStatusLine().getStatusCode();
Can you please let me know where the changes should be done so that the exception on the Client could be caught.
I could google but couldnt find a appropriate answer.
Exceptions can't be thrown over HTTP. What you'll need to do is:
On the server side, handle the exception and make sure your HTTP response has an appropriate statusCode and/or response header/body.
On the client side, translate that response into the exception you want.
You should investigate what interfaces HttpClient provides for exception handling.
My answer to this question might help you with the server side:
https://stackoverflow.com/a/11535691/1506440

Categories

Resources