2010-11-20 3 views
11

Как динамически создать список отображений - вместо:Dynamic Grails Url Mapping конфигурации

class UrlMappings { 
static mappings = { 
    "/helpdesk/user/$action?/$id?" (controller="helpdeskuser") 
    "/helpdesk/group/$action?/$id?" (controller="helpdeskgroup") 
    "/helpdesk/company/$action?/$id?" (controller="helpdeskcompany") 
    "/helpdesk/account/$action?/$id?" (controller="helpdeskaccount") 
    "/admin/company/$action?/$id?" (controller="admincompany") 
    "/admin/account/$action?/$id?" (controller="adminaccount") 
} 
} 

что-то вроде этого псевдокода:

class UrlMappings { 
static mappings = { 
    application.controllerClasses.each { 
    if(it.name.startsWith('helpdesk')) 
     "/helpdesk/${it.name}/$action?/$id?" (controller="${it.name}") 
    if(it.name.startsWith('admin')) 
     "/admin/${it.name}/$action?/$id?" (controller="${it.name}") 
    } 
} 
} 

(я не понимаю, что статический сопоставления - это хеш-карта? свободные переменные?)

То, что я пытаюсь достичь, это сопоставления на основе типа контроллера - например служба поддержки, администратор или пользовательские контроллеры. После того, как я настроил отображение я хочу добавить безопасности на основе URL-адреса, но я не хочу, чтобы отобразить каждый контроллер индивидуально:

grails.plugins.springsecurity.interceptUrlMap = [ 
    '/helpdesk/**': ['ROLE_HELPDESK','ROLE_ADMIN'], 
] 

ответ

11

Я только что сделал следующее в моем приложении:

import org.codehaus.groovy.grails.commons.ApplicationHolder 

class UrlMappings { 
    static mappings = {   
    for(controllerClass in ApplicationHolder.application.controllerClasses) { 
     // Admin Controllers first 
     if(controllerClass.name.startsWith("Admin")){ 
     // note... fixes the case so that AdminUserController maps to /admin/user 
     "/admin/${controllerClass.name[5].toLowerCase() + controllerClass.name[6..-1]}/$action?/$id?" { 
      controller = "admin${controllerClass.name[5..-1]}".toString() 
     } 
     } 
    } 
    } 
} 

я бы не на самом деле сделал это раньше, ваш вопрос побудил меня, чтобы исправить это мое приложение. Это была одна из тех вещей, которые я пытался сделать какое-то время.

+0

Это работает, спасибо. – DavidC

+0

За исключением того, что теперь и я предполагаю, что перенаправление контроллера не возвращает правильный URL-адрес. – DavidC

+0

mmm..it должно Dashboard в моем приложении отображает/admin/dashboard с использованием того же кода, что и выше. –

0

Вы можете вставлять переменную $controller см documentation.

static mappings = { 
    "/helpdesk/$controller/$action?/$id?"() 
} 

КСТАТИ отображения на controller с и, по желанию, их view s заключены скобкой (), а не фигурные ОДНИ {}.

Такие Groovy скрипты (как UrlMappings.groovy) анализируются с помощью ConfigSlurper экземпляра, который, наконец, преобразует их в ConfigObject, что implements Map. По общему признанию, я либо не уверен, как этот синтаксический анализ выполняется в деталях.

EDIT:

Here «s UrlMappings.groovy что приходит несколько близко к тому, что вы хотите. (Искать «/ $ _ ctrl/$ _ action/$ id?».) Код, BTW, оценивается во время выполнения. Тем не менее, я не смог поместить grailsApplication в работу.

Другая идея заключалась в том, чтобы добавить javax.servlet.Filter в веб-приложение, то есть путем подкласса Grails UrlMappingsFilter.

+0

К сожалению - я должен был понятнее - я хочу отобразить его в зависимости от имени контроллера или пакета и т.д., например: класс UrlMappings { статические отображения = { application.controllerClasses. каждый { if (it.name.startsWith ("help")) "/helpdesk/${it.name}/$action?/$id?" (controller = "$ {it.name}") \t else if (it.name.startsWith ("admin")) { "/admin/${it.name}/$action?/$id?" (controller = "$ {it.name}") } \t } – DavidC

+0

Измененный вопрос с лучшим форматированием, чем выше комментарий. – DavidC

+0

Спасибо за ссылку - очень гибкая – DavidC

2

Я хотел достичь чего-то подобного для своего приложения и нашел хороший способ, предоставляемый граалями. Это идет как

name admin: "/admin/$cName/$action/$id?" { 
    controller = { 
     "admin" + params.cName.capitalize() 
    } 
} 

Берегись, это не работает, если вы используете $controller против $cName (или все, что вы хотели бы иметь там) и будет бросать NullPointerException вместо этого.

В качестве бонуса, то вы можете использовать имя отображения как

<g:createLink 
    controller="adminBackend" action="login" 
    mapping="admin" params="[cName:'backend']" 
/> 

, чтобы получить ссылку на/администратор/бэкэнд/логин - Надеюсь, что это помогает!

Оставайтесь свежими!

5

GrailsUrlMappingsHolder bean доступен в службах и контроллерах. Хотя конкретная реализация UrlMappingsHolder не имеет метода добавления, его суперкласс выполняет. Простой, как это в Граалей 2.3.4

def grailsUrlMappingsHolder 

def addMapping() {   
    grailsUrlMappingsHolder.addMappings({ 
     "/admin"(controller:"admin" action:"index") 
    });   
} 
+0

Это с 2,3 [источник] (https://github.com/grails/grails-core/blob/e1c225882e59d18814f0b6b03ef2586731ce20ad/grails-web-url-mappings/src/main/groovy/grails/web/mapping/UrlMappings. java) –

+0

Привет. Могу ли я спросить, как я могу вызвать это на моем «Bootstrap.groovy», у меня есть немного [проблема здесь] (http://stackoverflow.com/q/42480608/4043409), и я думаю, что небольшая настройка этого ответ может решить мою проблему. – Gideon

Смежные вопросы