Arquivo para a tag ‘Spring’
[GSolr] Beans declarados automagicamente
GSolr, é o nome do plugin de solr que estamos fazendo de solr para grails. Para quem quiser acompanhar o trabalho, o repositório está no github: http://github.com/lucastex/gsolr.
Uma coisa que já está feita é a leitura da configuração do gsolr e a declaração mágica de beans, um para cada servidor solr que estiver configurado. Exemplificando, vamos imaginar que a configuração esteja declarando três servidores Solr que serão consultados:
gsolr {
solr {
produtos {
(...)
}
noticias {
(...)
}
usuarios {
(...)
}
}
}
Particularmente, achei bem interessante usar o nome da closure para o nome do servidor ao invés de termos um atributo name = produtos :)
A mágica legal mesmo, é que o plugin vai ler esta configuração quando a aplicação for para o ar, e depois disso irá declarar / criar beans spring dinâmicamente, usando a Spring DSL. E os beans vão ter no nome a declaração feita na closure do usuário.
Ou seja, para os servidores solr declarados acima, o plugin irá declarar os Spring Beans produtosGSolr, noticiasGSolr e usuariosGSolr .
Desta maneira, vamos garantir que se você quiser o usar o plugin, o processo como um todo ficará o menos intrusivo possível, e você poderá usar os métodos (de pesquisa e outros) do GSolr apenas injetando o bean do servidor Solr que você quiser.
class PesquisaService {
def noticiasGSolr
def pesquisar = {
(...)
}
}
Achei no mínimo, muito prático. Tudo isso graças a Spring DSL que temos em groovy. Com um pouco mais de tempo, coloco o procedimento passo a passo para declarar os beans desta maneira. Enquanto isso, conheça um pouco mais sobre a Spring DSL aqui, ou veja o código fonte aqui e também aqui.
Tem alguma idéia ou sugestão para o plugin? Deixe um comentário!
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.
Como definir o locale default de sua aplicação grails
Graças ao ótimo suporte de internacionalização que o grails nos proporciona, podemos alterar o idioma corrente da app passando apenas o parametro lang na URL. Com isso, o locale é definido para o usuário e se sua aplicação recupera as mensagens com o g:message ou outros recursos de i18n, usará o locale indicado.
Caso queira definir um locale default para sua app, basta sobrescrever o bean localeResolver no seu resources.groovy como abaixo:
beans = {
localeResolver(org.springframework.web.servlet.i18n.SessionLocaleResolver) {
defaultLocale = new Locale("pt", "BR")
java.util.Locale.setDefault(defaultLocale)
}
}
Sim, estou trazendo aos poucos tópicos que estavam em meu outro blog, blog.lucastex.com, dê uma passada por lá.
Portal imobiliário usando Groovy e Grails
Ontem (dia 09/01) fizemos o lançamento de um site que desenvolvemos usando Groovy e Grails, um desafio e tanto, pela responsabilidade de colocar o sistema no ar e pelo timing do projeto. Todo o site e a integração com o sistema legado (onde algumas informações ainda estão sendo gerenciadas), tiveram que sair do simples “create app” para produção em 2 meses. Esse é também o grande motivo para a falta de tempo de postar mais por aqui.
Trata-se dos sites http://www.imoveisnomorumbi.com.br e http://www.imoveisnopanamby.com.br, site de duas imobiliárias do mesmo grupo, que negocia imóveis de alto padrão nestes dois bairros.
Algumas informações interessantes sobre o projeto:
Tecnologia e Infraestrutura: O site antigo usava SQLServer como banco de dados e tecnologia ASP. Como usamos Groovy e Grails, por trás temos uma JVM Java em execução, e o banco de dados, o bom e velho MySQL.
Antes, para suportar o ASP, o IIS era usado como web server, e agora Um apache balanceia as requisições aos dois Tomcats. Tudo isto está deployado e rodando em um Cloud Server da Locaweb, por opção do cliente, onde já mantinha a conta antiga.
Integração com o sistema legado: Para a integração do modelo de dados antigo e o novo modelo, construímos rotinas de importação dos dados usando Groovy SQL, uma maneira fácil, muito fácil, de fazer rotinas em banco de dados.
Plugins utilizados: Ahhh, os bons e velhos plugins do Grails, não canso de dizer que esta é a melhor parte do Grails! Foram usados os plugins:
Grails-Mail, para envio dos e-mails e formas de contato do site
Grails-Acegi, para autenticação e segurança
Grails-Cookie, para manipulação dos cookies do cliente
Grails-Navigation para criação de menus/submenus da interface administrativa
Grails-RichUi para alguns componentes gráficos como auto-complete e nuvem de tags
Grails-RuntimeLogging, um ótimo plugin para moder trabalhar com o nível de log de cada artefato (controller, service, etc), da app em runtime
Grails-Settings para algumas parametrizações da aplicação.
E com certeza, se eu tivesse pesquisado com um pouco mais de tempo, teria usado outros plugins para evitar algum trabalho que tenha feito na mão. E é claro, além disso, bastante (mesmo) jquery, ajax e json.
É isso, qualquer dúvida sobre o projeto, como aconteceu, soluções e problemas, basta comentar!
Obrigado a todos!
Enviando emails com Spring e Velocity
Primeiro post do meu blog totalmente em português!
Esta semana, precisei adicionar na aplicação a funcionalidade de enviar e-mails usando templates do Velocity para o corpo do e-mail. Claro que o poderíamos usar o arroz com feijão do Velocity para isso, fazendo o merge do template com nosso contexto de variáveis, mas acabei esbarrando em um site, e descobri que o próprio Spring já possui um FactoryBean para a criação do meu VelocityEngine além de também ficar responsável com o carregamento dos templates (na minha opinião, a parte mais chata).
Bom, explicando brevemente como resolvi o problema:
Defini este bean no applicationContext.xml para controlar a injeção do VelocityEngine
<bean id="velocityEngine" class="org.springframework.ui.velocity.VelocityEngineFactoryBean"> <property name="resourceLoaderPath" value="/WEB-INF/templates/" /> </bean>
Notem que a propriedade resourceLoaderPath já é definida ali, e é neste diretório indicado que os templates deverão estar.
- Bean JavaMailSenderImpl
Este bean do core do spring já encapsula o envio da mensagem, neste exemplo, está configurado com estas propriedades que vieram de um arquivo de propriedades que carreguei no início do meu applicationContext.xml
<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
<property name="host" value="${mail.smtp.host}" />
<property name="username" value="${mail.smtp.user}" />
<property name="password" value="${mail.smtp.pass}" />
<property name="port" value="${mail.smtp.port}" />
</bean>
- Bean SimpleMailMessage
Este é o bean que será o template da mensagem. É um “modelo” de mensagem, que carrega o endereço ‘from’ e também o subject do e-mail do mesmo arquivo de configuração.
<bean id="templateMailMessage" class="org.springframework.mail.SimpleMailMessage">
<property name="from" value="${mail.from}" />
<property name="subject" value="${mail.subject}" />
</bean>
Com isso, já tenho os 3 beans que serão injetados em meu componente de envio de e-mails.
- Template velocity do e-mail
O template que eu criei para o teste é bem simples e segue abaixo. Se chama mail.vm e como dito ali em cima, está dentro de /WEB-INF/templates/
Oi ${nome}, seu e-mail (${email}) foi cadastrado no sistema.
- Componente final para o envio do e-mail
Chamei o componente de MailComponent (bem criativo, né?), e a única coisa que ele faz, é receber os beans que definimos via injeção, criar uma nova mensagem usando o template de e-mails e setar como body da mensagem o resultado do merge entre o template e as minhas variáveis. Segue o código do componente.
import java.util.HashMap;
import java.util.Map;
import org.apache.velocity.app.VelocityEngine;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.MailSender;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.stereotype.Component;
import org.springframework.ui.velocity.VelocityEngineUtils;
@Component
public class MailComponent {
@Autowired
private MailSender mailSender;
@Autowired
private SimpleMailMessage templateMailMessage;
@Autowired
private VelocityEngine velocityEngine;
public void sendMail(String template, Stirng nome, String email, String ... to) {
Map<String, Object> ctx= new HashMap<String, Object>() {{
put("nome", nome);
put("email", email);
}};
String body = VelocityEngineUtils.mergeTemplateIntoString(velocityEngine, template, ctx);
SimpleMailMessage msg = new SimpleMailMessage(this.templateMailMessage);
msg.setTo(to);
msg.setText(body);
mailSender.send(msg);
}
}
Pronto, o componente está pronto, agora a qualquer momento, em qualquer classe (que tenha acesso ao contexto de DI do spring é claro) você poderá chamar o seu componente
@Autowired private MailComponent mailComponent
E enviar os e-mails aos usuários:
//Envia e-mail para o usuário com cópia ao admin
mailComponent.sendMail("mail.vm", "Lucas", "mail@mail.org", "mail@mail.org", "admin@site.org");
É isso aí.
[]s,