Есть сервер, построенный на Spring + Hibernate. Небходимо отловить ошибку 404 когда пользователь стучиться на неправильный адрес (например localhost:8080/tes вместо test). Для этого я написал GlobalExceptionHandlerController.class. В нем отлично отлавливаются все ошибки кроме 404. В чем проблема?
@ControllerAdvice
public class GlobalExceptionHandlerController {
@ResponseStatus(value = HttpStatus.NOT_FOUND)
@ExceptionHandler(value = NullPointerException.class)
@ResponseBody
public String handleNullPointerException(Exception e) {
System.out.println("A null pointer exception ocurred " + e);
return "nullpointerExceptionPage";
}
@ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR)
@ExceptionHandler(value = Exception.class)
@ResponseBody
public String handleAllException(Exception e) {
System.out.println("A unknow Exception Ocurred: " + e);
return "unknowExceptionPage";
}
@ExceptionHandler(NoHandlerFoundException.class)
@ResponseStatus(HttpStatus.NOT_FOUND)
@ResponseBody
public String handleResourceNotFoundException() {
return "notFoundJSPPage";
}
}
Клиент может может получить HTTP 404 по 2 причинам: при обращении по ошибочному url-адресу (localhost:8080/tes вместо localhost:8080/test) или при обращении к несуществующему ресурсу (localhost:8080/test/42, а объекта с ключом 42 не существует).
На самом деле с точки зрения протокола http, это все одна и та же ошибка - обращение к несуществующему ресурсу, а разделение сделано для того, чтобы показать отличия в обработке обоих ситуаций.
В 1м случае, при обращении по ошибочному url-адресу ошибку 404 вернет Spring (т.к. не будет найдено соответствующего маппинга для url-адреса). Чтобы указать страницу, возвращаемую в таком случае, вы должны указать ее в конфиге. При конфигурировании с помощью xml, будет примерно так:
</web-app>
...
<error-page>
<error-code>404</error-code>
<location>/WEB-INF/pages/404.jsp</location>
</error-page>
</web-app>
Во 2м случае, например при обращении по localhost:8080/test/42 вызывается соответствующий метод контроллера и внутри него вы понимаете, что объекта с ключом 42 не существует. Вы выбрасываете какое-то свое исключение, например называемое ResourceNotFoundException, а в ControllerAdvice добавляете обработку этого исключения, где будете перенаправлять на нужную страницу.
Сборка персонального компьютера от Artline: умный выбор для современных пользователей