For some hours I\'m trying to create a custom global error handler in Spring Boot/MVC. I\'ve read a lot of articles and nothing.
That is my error class:
You may try the following code:
@ControllerAdvice
public class ExceptionController {
@ExceptionHandler(Exception.class)
public ModelAndView handleError(HttpServletRequest request, Exception e) {
Logger.getLogger(getClass().getName()).log(Level.SEVERE, "Request: " + request.getRequestURL() + " raised " + e);
return new ModelAndView("error");
}
@ExceptionHandler(NoHandlerFoundException.class)
public ModelAndView handleError404(HttpServletRequest request, Exception e) {
Logger.getLogger(getClass().getName()).log(Level.SEVERE, "Request: " + request.getRequestURL() + " raised " + e);
return new ModelAndView("404");
}
}
@ControllerAdvice
public class ErrorHandler {
public RestErrorHandler() {
}
@ExceptionHandler(YourException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public XXX processException(Exception ex){}
You need a class like this. Add a method for each exception, and annotate it as you please - @ResponseBody etc.
Additional to @Arash
You could add a new BaseController
class that you can extends,that handles the conversion from exception to http response
.
import com.alexfrndz.pojo.ErrorResponse;
import com.alexfrndz.pojo.Error;
import com.alexfrndz.pojo.exceptions.NotFoundException;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import javax.persistence.NoResultException;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
@Slf4j
public class BaseController {
@ExceptionHandler(NoResultException.class)
public ResponseEntity<Exception> handleNoResultException(
NoResultException nre) {
log.error("> handleNoResultException");
log.error("- NoResultException: ", nre);
log.error("< handleNoResultException");
return new ResponseEntity<Exception>(HttpStatus.NOT_FOUND);
}
@ExceptionHandler(Exception.class)
public ResponseEntity<Exception> handleException(Exception e) {
log.error("> handleException");
log.error("- Exception: ", e);
log.error("< handleException");
return new ResponseEntity<Exception>(e,
HttpStatus.INTERNAL_SERVER_ERROR);
}
@ExceptionHandler(NotFoundException.class)
@ResponseStatus(value = HttpStatus.NOT_FOUND)
@ResponseBody
public ErrorResponse handleNotFoundError(HttpServletRequest req, NotFoundException exception) {
List<Error> errors = Lists.newArrayList();
errors.add(new Error(String.valueOf(exception.getCode()), exception.getMessage()));
return new ErrorResponse(errors);
}
}
Hope this will help: Create a class say: NoProductsFoundException that extends runtimexception.
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;
@ResponseStatus(value=HttpStatus.NOT_FOUND, reason="No products found under this category")
public class NoProductsFoundException extends RuntimeException{
private static final long serialVersionUID =3935230281455340039L;
}
Then in your productcontroller:
@RequestMapping("/{category}")
public String getProductsByCategory(Model
model,@PathVariable("category") String category) {
List<Product> products = productService.getProductsByCategory(category);
if (products == null || products.isEmpty()) {
throw new NoProductsFoundException ();
}
model.addAttribute("products", products);
return "products";
}
Update for spring boot
Custom error pages
If you want to display a custom HTML error page for a given status code, you add a file to an /error folder. Error pages can either be static HTML (i.e. added under any of the static resource folders) or built using templates. The name of the file should be the exact status code or a series mask.
For example, to map 404 to a static HTML file, your folder structure would look like this
src/
+- main/
+- java/
| + <source code>
+- resources/
+- public/
+- error/
| +- 404.html
+- <other public assets>
Source