Arquivo para a tag ‘controller’
Como acessar uma taglib de dentro de um service
Uma situação que acontece muito, é a reutilização das funções de taglibs dentro dos controllers de sua aplicação grails. Isso é muito fácil de se fazer, basta chamar o método usando o objeto com o nome do namespace da taglib.
Ou seja, para usar dentro do controller a função de formatação de números, definida pela função formatNumber (taglib já no core do grails), é só fazer a chamada assim:
def myAction = {
render g.formatNumber([number:5000.234, type: "number", maxFractionDigits: 2])
}
Esta função é equivalente a chamar a taglib de dentro de um gsp da seguinte maneira:
<g:formatNumber number="5000.234" type="number" maxFractionDigits="2" />
Mas quando precisamos fazer isto, por exemplo, dentro de um service, encontramos um probleminha chato, as taglibs não são injetadas automaticamente. Para contornar essa “situação“, temos que buscar a taglib manualmente, da seguinte maneira:
def myTag = grailsApplication.mainContext.
getBean('org.codehaus.groovy.grails.plugins.web.taglib.ApplicationTagLib')
def value = myTag.formatNumber([number:5000.234, type: "number", maxFractionDigits: 2])
Ahhh, para isso não se esqueca de injetar o objeto da grailsApplication da seguinte maneira
class MeuService {
def grailsApplication
(...)
}
Bin-go.
Devolvendo um texto como attachment no response
Me deparei com a seguinte situação em uma aplicação construída usando Grails.
O sistema gravaria o conteúdo de um arquivo (plain xml mesmo) dentro do banco de dados, para evitar dependências com filesystem. Mas este arquivo também precisaria ser lido posteriormente. A solução que estava disponível, era alguma coisa mais ou menos assim:
def arquivo = Arquivo.get(params.id) //recupera o arquivo da base render arquivo.texto
Legal, desta maneira (bem simples até), o conteúdo deste texto seria renderizado na página para o usuário poder salvá-la.
Imaginei que isto pudesse ser incrementado um pouco, e percebi que fazer com que o usuário tivesse que salvar a página (que continha apenas o XML) poderia se tornar um tanto chato com o passar do tempo. Resolvi alterar a action para devolver o texto em anexo ao response. Isso mesmo, com a caixinha para poder salvá-lo.
Olha que simples:
def arquivo = Arquivo.get(params.id) //recupera o arquivo da base
response.setContentType "text/xml"
response.setHeader "Content-Disposition", "attachment;filename=\"${arquivo.nome}.xml\""
response << arquivo.texto
Simples, colocando a instrução no header para que a “disposição” da resposta seja “attachment” (anexo), o browser ao invés de renderizar apenas o conteudo, retorna um arquivo com este texto.