--- title: Environment --- # Trabalhando com diferentes ambientes Environment é uma funcionalidade do VRaptor que nos permite definir componentes e configurações diferentes conforme o ambiente que você está: produção, testes, desenvolvimento, etc. Você pode, por exemplo, desativar o envio de e-mails no ambiente de desenvolvimento, porém habilitar quando estiver em produção. ## Configuração Há várias formas de configurar o environment. A primeira opção é adicionando as linhas abaixo no seu `web.xml` para, por exemplo, configurar o nome do environment para PRODUCTION: ~~~ #!xml br.com.caelum.vraptor.environment PRODUCTION ~~~ A segunda opção é configurar uma propriedade na JVM. Para isso, basta iniciar a instância do seu Servlet Container ou Application Server com o seguinte parâmetro: ~~~ #!properties -Dbr.com.caelum.vraptor.environment=PRODUCTION ~~~ A terceira opção permite configurarmos o nome do environment usando as variáveis de ambiente do sistema operacional, bastando adicionar a variável `VRAPTOR_ENV`. Exemplo no windows: ~~~ set VRAPTOR_ENV=PRODUCTION ~~~ Exemplo no unix: ~~~ export VRAPTOR_ENV=PRODUCTION ~~~ **Nota:** A configuração usando variáveis do sistema operacional possui maior prioridade sobre a configuração de propriedades da JVM, que possui maior prioridade sobre a configuração no `web.xml`. ## Definindo as propriedades de um ambiente Basta criar um arquivo de propriedades no classpath da aplicação com o nome do seu ambiente. Por exemplo, para definir as propriedades de produção, devemos criar um arquivo `production.properties`: ~~~ #!properties ambiente_de_teste=false email=production.mail@mail.com ~~~ Se você tem propriedades que são comuns a outros ambientes, você pode criar um arquivo chamado `environment.properties` com as propriedades comuns. Quando você precisar usar alguma propriedade, o `Environment` irá procurar primeiro no arquivo do ambiente, e caso não encontrar, irá procurar o `environment.properties`. Você também pode sobrescrever propriedades usando System Properties. Propriedades definidas nas System Properties irão sobreescrever quaisquer outras definições. **Nota**: Você só pode usar System Properties para sobreescrever propriedades existentes nos arquivos de propriedades e não para definir novas propriedades. Considerando que você tenha um environment.properties abaixo: ~~~ #!properties my.prop hello ~~~ Você pode sobrescrever a propriedade existente my.prop com uma System Property: ~~~ #!java System.setProperty("my.prop", "bye"); environment.get("my.prop"); //bye ~~~ Se a chave não existir no arquivo de propriedades, o método get irá lançar uma NoSuchElementException. ## Acessando propriedades de ambiente no seu código Há dois métodos para acessar as propriedades de ambiente via código: `get` e `getOrDefault`. O método `get` retorna o valor da propriedade ou uma `MissingResourceException` se a propriedade não for encontrada. Já o método `getOrDefault` retorna o valor da propriedade, ou um valor padrão caso não encontrada. ~~~ #!java @Controller public class MeuController { private final Environment environment; private final MailSender sender; /** * @deprecated CDI eyes only */ protected MeuController(){ this(null, null); } @Inject public MeuController(Environment environment, MailSender sender) { this.environment = environment; this.sender = sender; } public void sendMail(String email) { if(environment.isDevelopment()) { sender.sendMailTo(environment.get("email")); return; } sender.sendMailTo(email); } } ~~~ No código acima, `environment.get("email")` irá retornar o valor da propriedade `email`. Porém caso a propriedade não existir em todos os ambientes, você pode usar o método `getOrDefault` para retornar um valor padrão. ~~~ #!java public void sendMail(String email) { if(environment.isDevelopment()) { sender.sendMailTo(environment.getOrDefault("email"), "noreply@vraptor.org"); } else { sender.sendMailTo(email); } } ~~~ ## Acessando propriedades de ambiente no JSP ~~~ #!xml

Você está no ambiente de teste. Suas ações aqui não afetarão o sistema.

Enviando e-mail para: ${environment.get('email')} ~~~ ## Acessando arquivos de configuração de acordo com o environment Se você precisa acessar um arquivo de configuração diferente para suas bibliotecas, de acordo com seu ambiente, você também pode utilizar o Environemnt. Basta colocar, por exemplo, seu `hibernate.cfg.xml` em diretórios com o nome de seus ambientes: *development* e *production* (por exemplo). `Environment.getResource(...)` retornará o resource de acordo com seu ambiente atual: ~~~ #!java cfg = new AnnotationConfiguration(); cfg.configure(environment.getResource("/hibernate.cfg.xml")); ~~~ Para manter compatibilidade com quem não utilizava o environment, caso o arquivo não seja encontrado no diretório com o nome do ambiente, ele será carregado no diretório root (do classpath). ## Injetando o valor de suas configuração programaticamente Você também consegue injetar suas configurações programaticamente usando o `@Property`, por exemplo: ~~~ #!java @Controller public class MeuController { @Inject @Property("email") private String email; public void sendMail(String email) { sender.sendMailTo(email); } } ~~~ Neste caso, se o seu environment estiver com valor `DEVELOPMENT`, vai injetar o valor que corresponde a chave *email* do arquivo `development.properties`, se estiver com `PRODUCTION` do `production.properties` e assim por diante. Dessa forma você não precisa dos ifs como: `if(environment.isDevelopment()) {...}` em seu código. Outra facilidade, é que se o nome da chave for o mesmo nome do field injetado, como em nosso caso com a chave *email*, você pode deixar apenas o `@Property` que o nome será inferido. Seu controller ficaria assim: ~~~ #!java @Controller public class MeuController { @Inject @Property private String email; public void sendMail(String email) { sender.sendMailTo(email); } } ~~~ Você também pode definir um valor padrão para essa propriedade: ~~~ #!java @Inject @Property(defaultValue = "config.properties") private String fileName; ~~~