Java Servlet Specification comes up with basic exception and HTTP response code mapping. It allows to define customized, user friendly web pages in case of Java exception or HTTP server error response. User never sees exception stacktrace or ugly 404 Not Found server page. This can be simply achieved through configuring deployment description web.xml, e.g.: by adding following entries:
Spring Framework provides solution that overcomes both these drawbacks. All magic is done by class implementing following interface:
This is very straightforward solution and can be add to any application very quickly. However there are at least two main drawbacks of such solutions:404 /error/notFound 403 /error/denied java.lang.Throwable /error/generic
- Error page customization: Error page cannot be customized (custom error message, displaying error id helpful for the support) depending on for example exception that has been thrown. Servlet container immediately redirects user to the error page.
- Invoking application logic: There is no way to perform any additional application logic before redirecting user to the error page like logging, etc.
org.springframework.web.servlet.HandlerExceptionResolverThere is attached below sample implementation of the Spring exception resolver (it extends AbstractHandlerExceptionResolver class which adds some additional functionality to the resolver e.g.: allows defining what exceptions this particular resolver should handle: error response statuses, java exceptions, etc; default is all)
package uk.ac.ncl.cs.smart.am2.web.exception;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.AbstractHandlerExceptionResolver;
import net.smartam.commons.util.http.UrlUtils;
import uk.ac.ncl.cs.smart.am2.core.exception.SharingSettingUnauthorizedAccess;
/**
* @author Lukasz Moren
*/
@Component
public class CustomExceptionResolver extends AbstractHandlerExceptionResolver {
private static Logger logger = LoggerFactory.getLogger(CustomExceptionResolver.class);
@Override
protected ModelAndView doResolveException(HttpServletRequest request, HttpServletResponse response,
Object handler, Exception ex) {
// log exception
logger.error("Error:", ex);
if (ex instanceof SharingSettingUnauthorizedAccess) {
//this is special type of exception, do not show error but redirect to other page
final ModelAndView view = new ModelAndView("unauthorized_switch_users");
final String redirectTo = UrlUtils.buildFullRequestUrl(request);
view.addObject("redirect_to", redirectTo);
return view;
} else {
//show error page with short explanation
final ModelAndView error = new ModelAndView("error");
error.addObject("error_msg", ex.getMessage());
return error;
}
}
}
This implementation does three main things:
- Logs an error
- For exception type SharingSettingUnauthorizedAccess it redirects user to some authorization page
- By default it adds error message to be displayed and redirects to the error page
No comments:
Post a Comment