Como armazenar um arquivo em um servidor (contêiner da web) através de um aplicativo da Web Java EE?

StackOverflow https://stackoverflow.com/questions/2663204

Pergunta

Eu desenvolvi um aplicativo da Web Java EE. Este aplicativo permite que um usuário faça upload de um arquivo com a ajuda de um navegador. Depois que o usuário enviar seu arquivo, este aplicativo armazena primeiro o arquivo carregado no servidor (no qual ele está em execução) e depois o processa.

No momento, estou armazenando o arquivo no servidor da seguinte forma:

try {
    // formFile represents the uploaded file
    FormFile formFile = programForm.getTheFile();
    String path = getServlet().getServletContext().getRealPath("") + "/"
        + formFile.getFileName();
    System.out.println(path);
    file = new File(path);
    outputStream = new FileOutputStream(file);
    outputStream.write(formFile.getFileData());
}

onde o formFile representa o arquivo carregado.

Agora, o problema é que ele está funcionando bem em alguns servidores, mas em alguns servidores getServlet().getServletContext().getRealPath("") está retornando null Então, o caminho final que estou recebendo é null/filename e o arquivo não armazena no servidor.

Quando eu verifiquei a API para ServletContext.getRealPath() Método, encontrei o seguinte:

public java.lang.String getRealPath(java.lang.String path)

Retorna uma string que contém o caminho real para um determinado caminho virtual. Por exemplo, o caminho "/index.html" Retorna o caminho de arquivo absoluto no sistema de arquivos do servidor seria servido por um pedido para "http://host/contextPath/index.html", onde o contextpath é o caminho de contexto deste servletContext.

O caminho real retornado será de uma forma apropriada para o computador e o sistema operacional no qual o contêiner do servlet está em execução, incluindo os separadores de caminho adequados. Esse método retorna nulo se o contêiner do servlet não puder traduzir o caminho virtual para um caminho real por qualquer motivo (como quando o conteúdo está sendo disponibilizado a partir de um arquivo .war).

Então, existe outra maneira pela qual eu posso armazenar arquivos nesses servidores também que estão retornando null por getServlet().getServletContext().getRealPath("")

Foi útil?

Solução

Escrever no sistema de arquivos de um contêiner Java EE não é realmente recomendado, especialmente se você precisar processar os dados escritos:

  • não é transacional
  • prejudica a portabilidade (e se você estiver em um ambiente em cluster)
  • É necessário configurar parâmetros externos para o local do alvo

Se essa for uma opção, eu armazenaria os arquivos no banco de dados ou usaria um repositório JCR (como Jackrabbit).

Outras dicas

Por SPEC, o único caminho "real" que você garante para obter um contêiner de servlet é um diretório temporário.

Você pode obter isso através do ServletContext.gerAttribute("javax.servlet.context.tempdir"). No entanto, esses arquivos não são visíveis para o contexto da web (ou seja, você não pode publicar um URL simples para entregar esses arquivos) e os arquivos não são garantidos de forma alguma para sobreviver a um aplicativo ou servidor da Web.

Se você simplesmente precisar de um local para armazenar um arquivo de trabalho por um curto período de tempo, isso funcionará bem para você.

Se você realmente precisa de um diretório, pode torná -lo um parâmetro de configuração (uma variável de ambiente, uma propriedade Java (ou seja, java -Dyour.file.here=/tmp/files ...), um parâmetro de contexto definido no web.xml, um parâmetro de configuração armazenado no seu banco de dados por meio de um formulário da Web, etc.). Então cabe ao implementador configurar este diretório para você.

No entanto, se você precisar servir posteriormente esse arquivo, precisará de um mecanismo específico do contêiner para "montar" diretórios externos em seu aplicativo da web (Glassfish como "raízes alternativas de documentos", outros conceitos semelhantes) ou você irá Precisa escrever um servlet/filtro para servir a loja de arquivos fora do seu aplicativo da web. este FileServlet é bastante completo e, como você pode ver, criando o seu, embora não seja difícil, não é trivial para fazer o que é certo.

Editar:

A essência básica é a mesma, mas em vez de usar "getRealPath", basta usar "getinitParameter".

Então:

String filePath = getServletContext().getInitParameter("storedFilePath") + "/" + fileName;

E esteja a caminho.

Editar novamente:

Quanto ao conteúdo do caminho, eu daria um caminho absoluto. Caso contrário, você precisaria saber para onde o servidor de aplicativos define seu caminho padrão durante a execção e cada servidor de aplicativos pode muito bem usar diretórios diferentes. Por exemplo, acredito que o diretório de trabalho para Glassfish é o diretório de configuração do domínio em execução. Não é uma escolha particularmente óbvia.

Então, use um caminho absoluto, definitivamente. Dessa forma, você sabe para onde os arquivos irão e poderá controlar as permissões de acesso no nível do sistema operacional para esse diretório, se for necessário.

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