Бывает необходимость в том что сервис возвращает разные результаты (xml, json, html) по одному адресу в зависимости от запроса.
- Filters. В данной реализации необходимо наличия content-type в заголовке запроса;
- AfterInterceptor. Реализация данного подхода возможна в случаях если у вас в Config.groovy включена опция grails.mime.file.extensions = true.
Рассмотрим оба подхода.
Первый способ реализовать данную задачу с использованием фильтров. (http://grails.org/doc/latest/guide/single.html#filters). Подход позволяет пользоваться всеми прелестями Filtres в Grails. Реализуется данный подход через Content-type, что обязывает всегда указывать Content-Type, Grails распарсивает то что приходит в запросе и помещает content-type в переменную format, объекта request.
class DetectFormatFilters {
def filters = {
all(action: '*') {
after = { Map model ->
switch (request.format) {
case 'html': println 'return HTML'; break;
case 'json': println 'return JSON'; break;
case 'xml': println 'return XML'; break;
}
}
}
}
}
P.S.: Типы указываются в Grails в config.groovy :
grails.mime.types = [ html: ['text/html','application/xhtml+xml'],
xml: ['text/xml', 'application/xml'],
text: 'text/plain',
js: 'text/javascript',
rss: 'application/rss+xml',
atom: 'application/atom+xml',
css: 'text/css',
csv: 'text/csv',
all: '*/*',
json: ['application/json','text/json'],
form: 'application/x-www-form-urlencoded',
multipartForm: 'multipart/form-data'
]
Второй подход заключается в использовании интерсепротов внутри controller.
(http://grails.org/doc/latest/ref/Controllers/afterInterceptor.html)Данный вариант позволяет использовать несколько вариантов запроса:
- domain/Controller/action/.json, domain/Controller/action/.xml. Данный вариант работает в случае если настройка grails.mime.file.extensions установлена в true;
- domain/Controller/action/?format=json, domain/Controller/action/?format=xml.
def afterInterceptor = {
withFormat {
html {println 'return HTML-1'}
json {println 'return JSON-1'}
js { println "alert('hello')-1" }
xml { println 'return XML-1' }
}
}
withFormat позволяет перечислить типы ответа которые нам необходимы, если тип ответа не обнаружен в списке то будет взят первый пункт, рекомендуется первым пунктом указывать html.