2013-02-21 4 views
4

Я немного поболтал с этим вчера и потерпел неудачу с треском. Я хочу, чтобы преобразовать:Изменить Grails REST формат/контроллер/<id>/<action>

"/$controller/$action?/$id?" 

Для

#in psudo 
"/$controller/$id?/$action?" 
#ideal regex 
"\/(\w+)(\/\d+)?(\/\w+)?" 

Наиболее очевидным способом не удалось "/$controller/$action?/$id?"

Я могу написать регулярное выражение, чтобы сделать это, но у меня возникают проблемы, чтобы найти способ использования верно regexs (я нашел RegexUrlMapping, но не смог узнать, как его использовать), а также не может найти документацию о том, как назначить группу переменной.

Мой вопрос 2 часть:

  1. Как я определяю URL ресурс с истинным регулярным выражением.
  2. Как связать «группу» с переменной. Другими словами, если я определяю регулярное выражение, как привязать его к переменной, как $ controller, $ id, $ action

Я также хотел бы иметь возможность поддерживать .json notation/user/id. JSON


Другие вещи, я пытался, которые я думал, что будет работать:

"/$controller$id?$action?"{ 
     constraints { 
      controller(matches:/\w+/) 
      id(matches:/\/\d+/) 
      action(matches:/\/\w+/) 
     } 
    } 

также пытался:

"/$controller/$id?/$action?"{ 
     constraints { 
      controller(matches:/\w+/) 
      id(matches:/\d+/) 
      action(matches:/\w+/) 
     } 
    } 

ответ

2

Grails способ справиться с этим, чтобы установить

grails.mime.file.extensions = true 

в Config.groovy. Это приведет к Grails сдирать расширение файла перед применением сопоставления URL, но сделать его доступным для использования withFormat

def someAction() { 
    withFormat { 
    json { 
     render ([message:"hello"] as JSON) 
    } 
    xml { 
     render(contentType:'text/xml') { 
     //... 
     } 
    } 
    } 

Для этого вы просто необходимо отображение URL в "$controller/$id?/$action?"

Я не знают о том, как использовать регулярные выражения так, как вы хотите, в сопоставлениях URL-адресов, но вы можете получить прямое сопоставление, используя тот факт, что вы можете указать замыкания для значений параметров, которые оцениваются во время выполнения с доступом к другим параметрам:

"$controller/$a?/$b?" { 
    action = { params.b ?: params.a } 
    id = { params.b ? params.a : null } 
} 

, в котором говорится: «Если установлено b, то используйте это как действие и a как id, в противном случае используйте a как действие и набор id до null». Но это не даст вам хорошего обратного отображения, т. Е.createLink(controller:'foo', action:'bar', id:1) бы ничего толкового генерировать, вам придется использовать createLink(controller:'foo', params:[a:1, b:'bar'])

Редактировать

Третья возможность, вы можете попробовать, чтобы объединить отображение в

"/$controller/$id/$action"{ 
    constraints { 
     controller(matches:/\w+/) 
     id(matches:/\d+/) 
     action(matches:/\w+/) 
    } 
} 

с дополнительным

"/$controller/$action?"{ 
    constraints { 
     controller(matches:/\w+/) 
     action(matches:/(?!\d+$)\w+/) 
    } 
} 

с использованием отрицательного вида, чтобы обе карты не пересекались.

+0

@Nix Если у вас есть сопоставление '' $ controller/$ id?/$ Action ", то'/user/list' не будет работать (ну, он не будет устанавливать параметр 'action', чтобы он вызывать любое действие по умолчанию «UserController», передавая «список» как значение параметра «id»). –

+0

Я до сих пор считаю это абсолютно шокирующим ... как для обратных отображений ... Не удалось добавить фиктивное сопоставление ('$ controller/$ id?/$ Action?'), Чтобы иметь возможность использовать обратные сопоставления? – Nix

+0

@Nix Я добавил еще одну возможность, если вы хотите попробовать. –