Đây là công thức ma thuật của tôi để làm điều này. Có thể có cách tốt hơn, nhưng cách này hoạt động và đảm bảo cùng một chế độ xem 404 hiển thị cho dù bạn tạo 404 hoặc grails thực hiện nội bộ (ví dụ: không tìm thấy bộ điều khiển).
Đầu tiên, tạo một lớp View kéo dài AbstractView:
class NotFoundView extends AbstractView {
@Override
protected void renderMergedOutputModel(Map<String, Object> model,
HttpServletRequest request, HttpServletResponse response) {
response.sendError(HttpServletResponse.SC_NOT_FOUND)
}
}
Tiếp theo, tạo một bộ điều khiển lỗi:
class ErrorController {
def notFound = {
return render(view: '/error/notFound')
}
}
Bây giờ tạo ra cái nhìn lỗi của bạn dưới views/lỗi/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>
Đó là quan trọng bạn sử dụng số < g: applyLayout> thẻ. Nếu bạn sử dụng bố cục của mình sẽ hiển thị hai lần và lồng ghép chính nó.
Bây giờ cho các ánh xạ URL:
"404"(controller: 'error', action: 'notFound')
Bạn đã đặt xong nay đến gửi mà 404 từ bộ điều khiển bạn:
def myAction = {
Thing thing = Thing.get(params.id)
if (!thing) {
return new ModelAndView(new NotFoundView())
}
}
Phương pháp này cũng cho phép bạn dễ dàng ghi lại các 404, cố gắng giải quyết nó và gửi 301, hoặc bất cứ điều gì bạn muốn làm.
Tôi đã có, nhưng không hiểu làm thế nào tôi phải nó để render khi tôi không thể tìm thấy đối tượng tên miền của tôi: 'if (! MyDomainClass.get (params ['i'])) {/ * Rồi sao...? * /} '. Làm 'response.sendError (404)' trả về một '404', nhưng không trả về trang lỗi đó - người dùng chỉ thấy một trang trống. –
Tôi vừa đọc lại Grails in Action p.331 và nó nói có những hạn chế để trả về mã lỗi - bạn không thể cung cấp nội dung cho phản hồi và loại nội dung sẽ là 'text/html'. Mà tôi không biết và gây nhầm lẫn cho tôi hơn nữa ... –
@martin đã cập nhật câu trả lời của tôi – hvgotcodes