2011-01-21 24 views
7

Cách tốt nhất để xử lý id không hợp lệ trong hành động của trình điều khiển Grails là gì?Grails: Trở về 404 & hiển thị trang 'Không tìm thấy' của tôi cho id không hợp lệ

Khi MyDomainClass.get(params['i']) trả về giá trị rỗng trong hành động điều khiển của tôi Tôi muốn người dùng xem trang 'Không tìm thấy' tùy chỉnh của tôi và mã phản hồi HTTP 404 được trả lại - Tôi không thể tìm ra cách làm sạch nhất.

Cảm ơn.

Trả lời

4

EDIT - Tôi xin lỗi vì đã hiểu sai câu hỏi của bạn. phương thức render sẽ lấy một mã trạng thái. Vì vậy, trong bộ điều khiển, nếu không có gì được tìm thấy, hãy thử

render status: 404 

hoặc

render view: you_not_found_view 

hoặc cả hai (ở một làm cho cuộc gọi).

+1

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. –

+0

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 ... –

+0

@martin đã cập nhật câu trả lời của tôi – hvgotcodes

7

Tôi sử dụng sau đây trong điều khiển của tôi, nơi 'notfound' một trang 404 tuỳ chỉnh:

def show = { 
     def referenceData = ReferenceData.get(params.id)  
     if (referenceData) 
     { return [ referenceData : referenceData ] } 
     else 
     { redirect(uri:'/notFound') } 
    } 

Tôi cũng ánh xạ các trang lỗi tùy chỉnh trong UrlMapping.groovy, một cái gì đó giống như

static mappings = { 
    "403"(controller: "errors", action: "forbidden") 
    "404"(controller: "errors", action: "notFound") 
    "500"(controller: "errors", action: "serverError") 
} 

hoặc

static mappings = { 
    "403"(view: "/errors/forbidden") 
    "404"(view: "/errors/notFound") 
    "500"(view: "/errors/serverError") 
} 

Grails Docs - mapping to response codes

+1

Tôi tin rằng thực tiễn không tốt để chuyển hướng cho tài nguyên không tìm thấy, ít nhất là đối với kiến ​​trúc RESTful. –

+2

@JoshDiehl là đúng. Triển khai này gửi 302 trước, sau đó là 404, bạn nên trả lại 404 ngay lập tức. – peterp

0

Đâ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.

Các vấn đề liên quan