Статьи

Grails Goodness: поддержка пространства имен для контроллеров

В приложении Grails мы можем организовать наши контроллеры в пакеты, но если мы будем использовать одно и то же имя для нескольких контроллеров, размещенных в разных пакетах, то Grails не сможет определить правильное имя контроллера. Grails игнорирует имя пакета при поиске контроллера по имени. Но с поддержкой пространства имен начиная с Grails 2.3 у нас могут быть контроллеры с одинаковыми именами, но мы можем использовать свойство пространства имен, чтобы различать разные контроллеры.

Мы можем добавить новое статическое свойство в класс контроллера с namespace name. Значение этого свойства определяет пространство имен. Затем мы можем записать новые сопоставления URL в файл grails-app/conf/UrlMappings.groovy и использовать значение пространства имен в качестве атрибута сопоставления.

Предположим, у нас есть два класса ReportController в нашем приложении. Один определяется как com.mrhaki.grails.user.ReportController а другой — как com.mrhaki.grails.common.ReportController . В следующих примерах кода показаны примеры реализации для обоих контроллеров:

01
02
03
04
05
06
07
08
09
10
11
12
// File: grails-app/controllers/com/mrhaki/grails/user/ReportController.groovy
package com.mrhaki.grails.user
  
class ReportController {
  
    /** Namespace is set to user. Used in URLMappings. */
    static namespace = 'user'
  
    def index() {
        render 'UserReport'
    }
}

И второй контроллер:

01
02
03
04
05
06
07
08
09
10
11
12
// File: grails-app/controllers/com/mrhaki/grails/common/ReportController.groovy
package com.mrhaki.grails.common
  
class ReportController {
  
    /** Namespace is set to common. Used in URLMappings. */
    static namespace = 'common'
  
    def index() {
        render 'CommonReport'
    }
}

В нашем файле UrlMappings.groovy теперь мы можем добавить два дополнительных сопоставления для этих контроллеров и использовать новый атрибут namespace чтобы указать сопоставление для правильной реализации контроллера.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// File: grails-app/conf/UrlMappings.groovy
class UrlMappings {
  
    static mappings = {
        // Define mapping to com.mrhaki.grails.user.ReportController with namespace user.
        "/user-report/$action?/$id?(.${format})?"(
            controller: 'report',
            namespace: 'user'
        )
  
        // Define mapping to com.mrhaki.grails.common.ReportController with namespace common.
        "/common-report/$action?/$id?(.${format})?"(
            controller: 'report',
            namespace: 'common'
        )
  
  
        // Other mappings.
        "/$controller/$action?/$id?(.${format})?"()
        "/"(view: "/index")
        "500"(view: '/error')
    }
}

Поддержка пространства имен также полезна при создании API RESTful с Grails. Мы можем использовать атрибут namespace, чтобы иметь разные версии для одного и того же контроллера. Например, в следующей конфигурации UrlMappings.groovy у нас есть два отображения на контроллер с одинаковым именем, но атрибут namespace определяет разные значения версии:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
// File: grails-app/conf/UrlMappings.groovy
class UrlMappings {
  
    static mappings = {
        // Define mapping to com.mrhaki.grails.api.v1.UserController with namespace v1.
        "/api/v1/users"(resource: 'user', namespace: 'v1')
  
        // Define mapping to com.mrhaki.grails.api.v2.UserController with namespace v2.
        "/api/v2/users"(resource: 'user', namespace: 'v2')
  
  
        // Other mappings.
        "/"(controller: 'apiDoc')
        "500"(controller: 'error')
    }
}

Для создания ссылок на контроллеры с пространством имен мы можем использовать новый атрибут namespace в link и теги createLink . Следующая часть страницы GSP показывает, как мы можем установить пространство имен, чтобы генерировать правильную ссылку:

1
2
3
4
5
6
7
<h2>Links</h2>
<ul>
    <li><g:link controller="report" namespace="user">User Reports</g:link></li>
    <li><g:link controller="report" namespace="common">Common Reports</g:link></li>
    <li><g:createLink controller="report" namespace="user"/></li>
    <li><g:createLink controller="report" namespace="common"/></li>
</ul>

Мы получаем следующий HTML:

1
2
3
4
5
6
7
<h2>Links</h2>
<ul>
    <li><a href="/namespace-controller/user-report/index">User Reports</a></li>
    <li><a href="/namespace-controller/common-report/index">Common Reports</a></li>
    <li>/namespace-controller/user-report/index</li>
    <li>/namespace-controller/common-report/index</li>
</ul>
  • Код, написанный с помощью Grails 2.3.2.

Ссылка: Grails Goodness: Поддержка пространства имен для контроллеров от нашего партнера JCG Хьюберта Иккинка в блоге JDriven .