Clique aqui para ler esse artigo em PDF.
Dicas na Web
Exemplos, riscos e soluções com JSP e Servlets
Conheça, através de dicas e exemplos práticos, recursos como download e upload de arquivos, JavaBeans e encadeamento de requisições HTTP
A coluna desta edição será diferente do habitual. Em vez de focar uma nova tecnologia ou API e descrevê-la em detalhes, serão apresentadas dicas úteis sobre um conjunto de tecnologias bem conhecido do leitor: JSP e servlets. Veremos ainda soluções para problemas recorrentes no desenvolvimento web, e esclarecimentos sobre alguns procedimentos comuns e recursos pouco conhecidos.
Definindo o nome do arquivo em downloads
Um uso comum para servlets (e mesmo para páginas JSP) é a geração dinâmica de arquivos, tais como planilhas ou documentos PDF. Nessas situações, ao enviar o arquivo gerado, é preciso que o servlet especifique o tipo do conteúdo através do método response.setContentType(String tipo). Esse tipo segue no cabeçalho da resposta HTTP retornada pelo servlet e, de acordo com ele, o navegador poderá decidir o que fazer com o arquivo.
Normalmente o arquivo é exibido através de um plug-in, ou é oferecida a opção de salvá-lo no disco, mas nos casos onde a intenção é que o usuário faça o download, esse procedimento traz alguns problemas:
·Não é garantido que o usuário tenha a opção de salvar o arquivo em vez de o navegador abrir automaticamente um plug-in;
·Mesmo que o browser ofereça a opção de salvamento, o nome sugerido será o do servlet ou da página JSP (por exemplo, “contador.jsp”), sendo que o ideal seria um nome mais amigável, ou no mínimo com a extensão correta (como "contador-10.txt").
Para resolver esses problemas, a solução é definir a propriedade content-disposition do cabeçalho da resposta HTTP, com o valor attachment;filename=nome.extensão, como no trecho de código a seguir:
response.setHeader(
"content-disposition",
"attachment;filename=" + nomeArquivo
);
A Listagem 1 inclui uma página JSP que imprime um contador, de 1 até 10 (ou até o valor definido no parâmetro limite). Note que o navegador não exibe o conteúdo da página, em vez disso abre a janela com a opção de salvar o arquivo, com nome sugerido "contador-XX.txt" (sendo XX o limite).
A propriedade content-disposition é definida no protocolo HTTP (RFC 2183[1]), e não na API de servlets/JSP. Assim o funcionamento dessa dica depende da compatibilidade do navegador com os padrões W3C e pode não funcionar em navegadores mais antigos (nesses casos, o nome sugerido continuará sendo o nome do JSP).
Outra opção é definir no descritor web.xml um mapeamento com o nome desejado (como "relatorio.pdf" ou "contador.txt") para o servlet ou página JSP responsável pela geração do arquivo, o que funcionará independente do navegador utilizado. No entanto essa solução não tem a flexibilidade de permitir a definição do nome no momento de execução do servlet/JSP. Para um exemplo de como definir mapeamentos, veja a dica “O invoker do Tomcat”.
Pré-compilação de páginas JSP
Sabemos que, quando uma página JSP é acessada pela primeira vez, o container web compila a página gerando (e compilado) um servlet com o código Java correspondente – mais precisamente, é gerado um objeto que implementa a interface javax.servlet.jsp.JspPage, que estende a interface javax.servlet.Servlet. Após a compilação, o container executa o servlet gerado, chamando o método _jspService(); esse servlet é chamado nas próximas invocações à página JSP.
Em algumas situações, entretanto, é interessante compilar o servlet gerado previamente, de modo que o usuário não perceba a “demora” no primeiro acesso. Esse processo é chamado de pré-compilação. Os containers web com suporte a JSP 1.2 ou 2.0 suportam a pré-compilação de páginas JSP através do parâmetro HTTP jsp_precompile. Sempre que uma página for requisitada passando-se esse parâmetro, e o valor do parâmetro for true, false ou vazio, a página JSP será convertida para um servlet e compilada, mas o servlet não será executado. Veja alguns exemplos:
http://localhost:8080/jm12/contador.jsp?jsp_precompile
http://localhost:8080/jm12/contador.jsp?jsp_precompile=true
http://localhost:8080/jm12/contador.jsp?jsp_precompile=false
http://localhost:8080/jm12/contador.jsp?limite=10&jsp_precompile=false
Se o parâmetro for passado com um valor inválido, a página não compilará e o container lançará uma exceção. As seguintes chamadas, gerarão um erro:
http://localhost:8080/jm12/contador.jsp?jsp_precompile=sim
http://localhost:8080/jm12/contador.jsp?jsp_precompile=no
Há outras formas, dependentes do container, de pré-compilar páginas JSP, que permitem até que o código fonte do JSP não esteja presente no servidor de produção. Consulte a documentação do container para mais detalhes.
Obtendo as versões de JSP e Servlets
As tecnologias JSP e servlets evoluíram muito desde suas primeiras versões. Por exemplo, a API de servlets 2.3 introduziu o conceito de filtros (interface javax.sevlet.Filter); com o JSP 1.2, vieram as tags de iteração (interface javax.servlet.jsp.tagext.IteratorTag).
Para garantir a compatibilidade de suas aplicações web, portanto, é sempre importante saber as versões das APIs suportadas nos containers web utilizados. Os métodos getMajorVersion() e getMinorVersion() da classe javax.servlet.ServletContext " [...] continue lendo...