Pergunta

Existe alguma maneira na API do Servlet de acessar propriedades especificadas em web.xml (como parâmetros de inicialização) de dentro de uma classe Bean ou Factory que não esteja associada ao contêiner da web?

Por exemplo, estou escrevendo uma classe Factory e gostaria de incluir alguma lógica dentro da Factory para verificar uma hierarquia de arquivos e locais de configuração para ver quais deles estão disponíveis para determinar qual classe de implementação instanciar - por exemplo,

  1. um arquivo de propriedades no caminho de classe,
  2. um parâmetro web.xml,
  3. uma propriedade do sistema ou
  4. alguma lógica padrão se nada mais estiver disponível.

Eu gostaria de poder fazer isso sem injetar qualquer referência a ServletConfig ou qualquer coisa semelhante à minha fábrica - o código deve ser capaz de funcionar bem fora de um contêiner de servlet.

Isso pode parecer um pouco incomum, mas eu gostaria que este componente no qual estou trabalhando pudesse ser empacotado com um de nossos aplicativos da web e também fosse versátil o suficiente para ser empacotado com algumas de nossas ferramentas de linha de comando sem exigindo um novo arquivo de propriedades apenas para meu componente - então eu esperava pegar carona em outros arquivos de configuração, como web.xml.

Se bem me lembro, o .NET tem algo como Request.GetCurrentRequest() para obter uma referência ao atualmente em execução Request - mas como este é um aplicativo Java, estou procurando algo semelhante que possa ser usado para obter acesso ServletConfig.

Foi útil?

Solução

Uma maneira de fazer isso é:

public class FactoryInitialisingServletContextListener implements ServletContextListener {

    public void contextDestroyed(ServletContextEvent event) {
    }

    public void contextInitialized(ServletContextEvent event) {
        Properties properties = new Properties();
        ServletContext servletContext = event.getServletContext();
        Enumeration<?> keys = servletContext.getInitParameterNames();
        while (keys.hasMoreElements()) {
            String key = (String) keys.nextElement();
            String value = servletContext.getInitParameter(key);
            properties.setProperty(key, value);
        }
        Factory.setServletContextProperties(properties);
    }
}

public class Factory {

    static Properties _servletContextProperties = new Properties();

    public static void setServletContextProperties(Properties servletContextProperties) {
        _servletContextProperties = servletContextProperties;
    }
}

E então tenha o seguinte em seu web.xml

<listener>
    <listener-class>com.acme.FactoryInitialisingServletContextListener<listener-class>
</listener>

Se o seu aplicativo estiver sendo executado em um contêiner da web, o ouvinte será invocado pelo contêiner assim que o contexto for criado.Nesse caso, _servletContextProperties será substituído por quaisquer parâmetros de contexto especificados no web.xml.

Se seu aplicativo estiver sendo executado fora de um contêiner da Web, _servletContextProperties estará vazio.

Outras dicas

Você já pensou em usar o framework Spring para isso?Dessa forma, seus beans não recebem nenhum lixo extra e o Spring cuida da configuração para você.

Eu acho que você terá que adicionar uma classe de bootstrap associada que faça uma referência a um ServletConfig (ou ServletContext) e transcreva esses valores para a classe Factory.Pelo menos desta forma você pode empacotá-lo separadamente.

@conjunto de ferramentas :Excelente, muito humilde - Isso é algo que venho tentando fazer há algum tempo

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top