Вот моя волшебная формула для этого. Может быть, есть лучший способ, но этот работает и гарантирует, что один и тот же вид 404 будет отображаться независимо от того, генерируете ли вы 404, или Grails делает это внутренне (например, не найден контроллер).
Сначала создайте класс View, расширяющий AbstractView:
class NotFoundView extends AbstractView {
@Override
protected void renderMergedOutputModel(Map<String, Object> model,
HttpServletRequest request, HttpServletResponse response) {
response.sendError(HttpServletResponse.SC_NOT_FOUND)
}
}
Далее создайте контроллер ошибок:
class ErrorController {
def notFound = {
return render(view: '/error/notFound')
}
}
Теперь создайте свое представление об ошибках в views / error / notFound.gsp:
<g:applyLayout name="main">
<!doctype html>
<html>
<head>
<title>Oops! Not found!</title>
</head>
<body>
<h1>Not Found</h1>
<section id="page-body">
<p>Nothing was found at your URI!</p>
</section>
</body>
</html>
</g:applyLayout>
крайне важно , чтобы вы использовали тег . Если вы используете макет, он будет рендериться дважды и вкладывать себя.
Теперь для сопоставления URL:
"404"(controller: 'error', action: 'notFound')
Теперь все готово для отправки этого 404 с вашего контроллера:
def myAction = {
Thing thing = Thing.get(params.id)
if (!thing) {
return new ModelAndView(new NotFoundView())
}
}
Этот подход также позволяет вам легко регистрировать 404, пытаться разрешить его и отправлять 301, или все, что вы хотите сделать.