以 DRY 方式验证每个请求的 RESTful URL

Validating RESTful URLs for every request the DRY way

我们的 Grails 2.4.4 应用程序始终使用 RESTful URLs。鉴于以下 URL:

/stores/123/products/456

我想验证是否存在 ID 为 123 的商店,如果没有,则在每次向产品控制器发出请求时重定向到 404。我不想将存储查找代码放在每个操作方法中,也不想创建控制器基础 class,因为这样我就必须在每个操作方法中调用方法。

这可以通过拦截器以某种方式完成吗?

我认为你可以使用:

  1. URL映射
  2. 过滤器

但我不认为在 URL 映射中加入逻辑(检查是否存在具有给定 ID 的有效商店)是个好主意,所以最好使用过滤器。

因此您 url 映射将如下所示:

"/stores/$storeId/products/$productId" (controller = "product")

你的过滤器:

class YourFilterNameFilters {


    def filters = {
        secureReports(controller:'*', action:'*') {
            before = {

               if(parmas.controller == "product" && params.storeId){
                     Store store = Store.get(params.sotreId)
                    if(!store){
                        response.sendError(404)
                     }
                 }
           }
      }
}

Grails 3.0 中引入了拦截器。在 Grails 2.4.4 中你需要 filters

before = { } 是这里需要的。

另请查看文档,哪些变量默认可用于过滤器(例如:params、request、response 等)。如果这仍然不清楚,我可以添加一个答案作为示例。但我希望文档是不言自明的。作为一个例子,我会这样做

class EntityCheckFilters {
    def filters = {
        storeExistCheck( controller:'product' ) {
            before = {
               if ( !params.storeId || !Store.exists( params.sotreId as Long ) ) {
                    response.sendError(404)
                    // or for example if you have a separate action to handle 404
                    // redirect(action: 'handle404')

                    // this is important, 
                    // because we do not want to pass through with the original call
                    return false 
               }
            }
        }
    }
}