I am using BeanValidation (with DropWizzard). Now if a form contains a field annotated with #NotEmpty, but is empty, I'll get an InternalServer ErrorException with Status Code 500.
I'd like to log a RuntimeException for this and forward the user to an error page.
Is it possible to catch all ValidationException in one place, log them and do something like forwarding the user?
You can build your own exception mapper for the ValidationException. Jersey have its own ValidationExceptionMapper implementation that will return a bad request if the element is a parameter that is validated or a internal server error if the validation occur on a return value. Latest version of Dropwizard should configure these mappers by default.
To build your own exception mapper you should implement the interface javax.ws.rs.ext.ExceptionMapper and register it in the jersey context of Dropwizard ieenvironment.jersy().register(MyExceptionMapper.class)if you use Dropwizard 0.8 or later
Related
I am creating an controller where there is certain attributes in json which is an doing in postman a POST request like this if all attributes are posted then its fine
if one then is missing then it would look like this
i want this response when some attribute is missing how to implement this
This is normally implemented in two steps:
Implement a validation mechanism for the method that handles the incoming request. Normally you would throw an exception here if the input is incorrect, in your example a missing JSON key.
Implement a global error handler that will process the exception from point 1 and format the response as JSON.
For point 1 the usual choice is the Java Bean Validation framework because it's integrated with Spring Boot and allows to define validation constraints with annotations like #NotEmpty. You can take a look at this example.
For point 2 the usual choice is #RestControllerAdvice or #ControllerAdvice. You would have to understand your service web server setup to implement it properly e.g. it might behave differently if you use Spring WebFlux.
I am writing a web application using Spring Boot that frequently updates data on the back end and returns the updated object to reflect the update on the front end.
The question I have is what to return from my methods if the update should fail for some reason.
I am currently returning the object as it was received should it fail but as it stands the state on the front end would not reflect the failure on the back end in the case that it occurs.
I want to return the object to update the state but doing so prevents me from returning a String or HttpStatus indicating a problem doesn't it? Returning the old object doesn't seem a good solution either.
You can throw an exception in this case of failure from your REST controller.
To handle this exception, Spring provides ResponseEntityExceptionHandler callback class with the help of which you can handle the thrown exception and set different headers in the response entity.
So on client-side, you can recognise that some failure is occurred on server side.
You can set HttpStatus as HttpStatus.INTERNAL_SERVER_ERROR and add more details in the body.
The question I have is what to return from my methods if the update should fail for some reason.
You first need to determine whether the error was caused by the client or by the server, then you can determine the most suitable status code to be returned, either in the 4xx or in the 5xx range. See this answer which may give you some insights.
Instead of returning the request request back in the response, you should return a payload that describes what the problem was. Consider, for example, the payload defined in the RFC 7807 along with the application/problem+json media type.
Finally, this answer may give you insights on how to map an exception to a HTTP status code in Spring:
You can map exceptions to responses by annotating an exception class with #ResponseStatus.
It also gives you the possibility to implement a HandlerExceptionResolver or extend one of the existing implementations, such as the AbstractHandlerExceptionResolver.
Another approach would be using a ResponseEntityExceptionHandler annotated with #ControllerAdvice and define the handled exceptions by annotating the implemented method with #ExceptionHandler.
I need some help with understanding how Websphere Liberty (18.0.0.1) handles exceptions thrown within a JAX-RS endpoint invocation. I'm using Liberty feature jaxrs-2.0, so the implementation should be provided by WLP.
Now, my application has a POST HTTP endpoint accepting JSON payload and I'd like to provide a custom error messages for all the possible wrong client inputs.
Here's one case that works in a way I expected it:
Client sends application/xml instead of application/json
There's a ClientErrorException thrown by the container
I can use my own exception mapper (implementing ExceptionMapper<WebApplicationException> to handle this exception (actually to handle all the web application exception, which I'm fine with)
This way I can format the error message, mark error with ID, whatever is needed. That's good
And here's the case not working for me:
Client sends application/json, but with empty body
The core exception in this case is java.io.EOFException: No content to map to Object due to end of input - yeah, that looks accurate
Now what I can't figure out - instead of wrapping this EOFException into some kind of WebApplicationException (which I could handle easily), WLP is wrapping the exception issue into JaxRsRuntimeException
A couple of points here:
I don't want to create a mapper implementing ExceptionMapper<JaxRsRuntimeException> because that exception is not a part of JAX-RS 2.0 spec and I'd have to provide the import to JaxRsRuntimeException and wire the application with some Liberty-specific library.
A possible solution is to have my mapper implement a generic ExceptionMapper<RuntimeException> and string check if it finds exception of classname 'JaxRsRuntimeException' and then handle it. But that just doesn't seem right to me.
So, is that a WLP design not to give me a WebApplicationException in this case? What would be the elegant solution to handle this scenario?
Thanks
EDIT: Added some parts of source code.
REST endpoint and resource method:
#Path("/books")
public class BookEndpoint {
#POST
#Consumes(MediaType.APPLICATION_JSON)
public Response createBook(Book book, #Context UriInfo uriInfo) {
bookDao.create(book);
UriBuilder builder = uriInfo.getAbsolutePathBuilder();
builder.path(Integer.toString(book.getId()));
return Response.created(builder.build()).entity(book).build();
}
}
Entity with JAXB annotations:
#XmlRootElement
public class Book {
private int id;
private String title;
// getters, setters
}
Exception stack trace:
com.ibm.ws.jaxrs20.JaxRsRuntimeException: java.io.EOFException: No content to map to Object duto end of input
at org.apache.cxf.jaxrs.utils.JAXRSUtils.toJaxRsRuntimeException(JAXRSUtils.java:1928)
at [internal classes]
at org.apache.logging.log4j.web.Log4jServletFilter.doFilter(Log4jServletFilter.java:71)
at com.ibm.ws.webcontainer.filter.FilterInstanceWrapper.doFilter(FilterInstanceWrapper.java:201)
at [internal classes]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.io.EOFException: No content to map to Object duto end of input
at org.codehaus.jackson.map.ObjectMapper._initForReading(ObjectMapper.java:2775)
at [internal classes]
at java.security.AccessController.doPrivileged(Native Method)
at org.apache.cxf.jaxrs.utils.JAXRSUtils.readFromMessageBodyReader(JAXRSUtils.java:1413)
at [internal classes]
... 48 more
This is the expected behavior based on Section 3.3.4 (and 4.5.1) of the JAX-RS 2.0 Spec. These sections describe how exceptions from JAX-RS resources and providers are handled - in short:
If the exception is a WebApplicationException, then it will automatically mapped to a Response.
If there is an ExceptionMapper registered that can handle the thrown exception, then that will be used to generate the response.
Unchecked exceptions are propagated to the container (i.e. Liberty's JAX-RS implementation code).
Unmapped exceptions must be handled via a container-specific exception and then appropriately propagated to the underlying container - in this case a ServletException must be passed to the web container.
The JaxRsRuntimeException is used to satisfy step 4.
In this scenario the built-in JSON provider (based on Jackson 1.X) is throwing the EOFException. Since there are no exception mappers for the EOFException (or any of it's superclasses), it is ultimately mapped to a ServletException by way of the JaxRsRuntimeException.
In order for an application to handle this scenario, there are a few different options:
You can register an ExceptionMapper that is specific to this exception type (EOFException or any of it's superclasses - i.e. IOException). You should not need to register a mapper for JaxRsRuntimeException as that exception is only used internally in Liberty - and should not be mapped. If you are seeing the JaxRsRuntimeException passed to an ExceptionMapper, then you should open a support case with IBM, as this is likely a bug.
With an ExceptionMapper<EOFException> you can return a specific response whenever an EOFException is thrown from a provider or resource.
You can register your own MessageBodyReader that will convert JSON to objects (using Jackson or any other JSON serialization code) but that will handle empty message bodies in the way you want - for example, converting it to null or using some kind of default object instance. Because user-registered providers take priority over built-in providers, this MBR would be used instead of Liberty's Jackson-based MBR.
This approach definitely gives you more control over how the data is deserialized as well as the exception handling.
Register a ContainerRequestFilter provider that will abort when the message body is empty. Here is an example:
#Provider
public class EmptyBodyCheckFilter implements ContainerRequestFilter {
#Override
public void filter(ContainerRequestContext crc) throws IOException {
if (crc.getEntityStream().available() < 1) {
crc.abortWith(Response.status(400).entity("Invalid request - empty message body").build());
}
}
}
I've successfully tested options 1 and 3 using the WebSphere Liberty May 2018 Beta. I haven't personally tested option 2 for this scenario, but based on using custom MBRs in the past, this should work.
One thing to keep in mind is that when Liberty GAs the jaxrs-2.1 feature, it will use JSONB as the built-in provider for serializing/deserializing JSON instead of Jackson. I tested your scenario using JAX-RS 2.1 (also in the May Beta) and instead of an EOFException, the JSONB code throws a NoSuchElementException. If you think you might move to JAX-RS 2.1, then I would suggest option 2 or 3. Option 1 would require that you create a new ExceptionMapper for JAX-RS 2.1.
Hope this helps,
Andy
Not a direct answert on "why WLP wrap the exception ..etc" but maybe add an exception interceptor as you did but on"ExceptionMapper<Exception>"and recusrsively iterate on the "causes" to check if java.io.EOFExceptionis one of those...
I am using RestEasy to build up my Restful web services. I have implemented ExceptionMappers to prepare specific exception responses.
I have also implemented MessageBodyWriterInterceptors and a couple of PostProcessorInterceptors.
Issue: All works fine when any resource does not throw any exception. My implementation works as expected. All the post processor interceptors and the message body writer interceptors are called.
But when an exception is thrown from any of the resource methods, the registered ExceptionMappers are called and it is creating the response. But in this case the post processor interceptor chain is not traversed. They are not getting called.
What should I do in this case. Write that interceptor logic in my exception mapper or is there is solution available?
Post processors do not get called if an exception is thrown. They are on different, parallel resolution paths:
/ 'Normal' JAX-RS response -> Post Processors -> Message Body Writers
Processing
\ Exception -> Exception Mappers
If you have logic that needs to be run in both your post processors and exception mappers then you will need to incorporate it in both (preferably through a common, utility class).
I am trying to return a valid JSON body for every request of an Spring MVC service, both correct and invalid.
Using #ExceptionHandler and a combination of ExceptionHandlerExceptionResolver, DefaultHandlerExceptionResolver and my own AbstractHandlerExceptionResolver I am able to process and set a body for almost all invalid requests that are dispatched to a valid controller or rejected by Spring Security.
However, errors thrown by the DispatcherServlet like noHandlerFound, can't be intercepted, so the response has a valid HTTP status code like 404, but the body contains the Tomcat default XML error.
Anybody knows how to set up or configure an Spring Exception Resolver so all failed requests are intercepted and a valid JSON body could be set?
There is a section explaining how is spring handling exception resolver for dispatcher servlet:
The dispatcher's exception resolution strategy can be specified via a
HandlerExceptionResolver, for example mapping certain exceptions to
error pages. Default are AnnotationMethodHandlerExceptionResolver,
ResponseStatusExceptionResolver, and DefaultHandlerExceptionResolver.
These HandlerExceptionResolvers can be overridden through the
application context. HandlerExceptionResolver can be given any bean
name (they are tested by type).
to be able to support Dispatcher exception handling overriding you have to implement HandlerExceptionResolver and Ordered class and declare the implementation as spring bean. You must return getOrder value as Integer.MIN_VALUE to override any other existing handler.