Conforme apresentado na seção 3.2 deste livro, a resposta a uma requisição HTTP é composta de diversos elementos, sendo que alguns desses elementos são headers (cabeçalhos) HTTP.
Exemplo de respo sta HTTP do Servlet “HelloWorld”
HTTP/1.1 200 OK
Server: Apache / 1. 3.26 (Unix)
Last- Modified: Sun, 22 Dec 2002 17:47:59 GMT Content - Type: text / h t m l
Content - Length: 40
<HTML> <BODY>Hello World!< /BODY> < / H TML >
Embora alguns headers sejam adicionados por default pelo “ServletContainer”, como no caso da resposta do Servlet “HelloWorld” acima, podem haver situações em que você queira definir ou modificar seus próprios headers HTTP, e para fazer isso, você deve utilizar o método “setHeader ()”.
public void setHead er( java.lang.String p_heade rNa m e, java.lang.String p_hea derValue );
Para indicar, por exemplo, que a resposta de um Servlet não deve ficar armazenada em nenhum cache (armazenamento temporário) do browser do usuário, nem em nenhum proxy, podemos definir alguns headers adicionais especiais por meio do seguinte trecho de código:
Headers para evitar cachea m e n t o da respo sta de um
Servlet
public void doGet( HttpServletReque s t p_reque st, HttpServletRes p o n s e p_res po n s e ) {
...
p_resp o n s e. setHea d e r( “Cache - Control”, “no - cache, must - revalidate” );
p_resp o n s e. setHea d e r( “Pragma”, “no - cache” );
p_resp o n s e. setHea d e r( “Expires”, “Mon, 26 Jul 1997 05:00:00 GMT” );
p_resp o n s e. setDateHea d e r( “Last - Modified”, System.cu rr en tTi m eMillis ());
... }
Nesse código, o header “Expires” indica a data de expiração, o header “Last- Modified” indica a data de última modificação, e os headers “Cache- Control” e “Pragma” indicam o tratamento que o documento (ou seja, a resposta do Servlet) deve receber se houver cacheamento.
Com a inclusão do código anterior, a resposta do Servlet passa a ser:
Exemplo de respo sta HTTP do Servlet “HelloWorld”
com headers adicionais
HTTP/1.1 200 OK
Server: Apache / 1. 3.26 (Unix)
Cache - Control: no - cache, mus t - revalidate Pragma: no - cache
Last- Modified: Sun, 22 Dec 2002 17:47:59 GMT Content - Type: text / h t m l
Content - Length: 40
<HTML> <BODY>Hello World!< /BODY> < / H TML >
Uma observação muito importante é que essas adições / modificações de headers HTTP devem acontecer antes da geração do conteúdo da saída, para garantir a ordem dos elementos da resposta HTTP (ou seja, primeiro status, depois headers e, por fim, conteúdo). A alteração de um header após a escrita de parte ou de todo o conteúdo pode gerar uma exceção java.lang.IllegalStateException e interromper o processo de geração da saída do Servlet. Assim, o código completo para o Servlet HelloWorld sem cacheamento pode ser escrito como:
Servlet “HelloWorld” com headers para evitar
cachea m e nt o da página
impo rt java.io.*; impo rt javax.servlet.*; impo rt javax.servlet.htt p.*;
/ / Terceira imple me n t a ç ã o do Servlet para página HelloWorld public class HelloWorld extend s HttpServlet {
/ / Atendim e n t o de requisições HTTP com méto d o GET public void doGet(HttpServletReq ue s t p_req ue s t, HttpServletRes p o n s e p_res po n s e) {
try {
/ / Passo 1 – Definind o header s
p_res po n s e.se tHea d e r(“Cache - Control”, “no - cache, must - revalidate”);
p_res po n s e.se tHea d e r(“Pragm a”, “no - cache”); p_res po n s e.se tHea d e r(“Expires”, “Mon, 26 Jul 1997 05:00:00 GMT”);
p_res po n s e.se tDa teHea d e r(“Last - Modified”, System.cu rr en tTi m eMillis ());
PrintWriter l_pw = p_res po n s e.getWriter (); l_pw.print(“ <HTML> <BODY>”);
l_pw.print(“Hello World!”);
l_pw.println(“< /BODY> < / H TML>”); l_pw.flus h ();
} catch( IOExceptio n p_e ) {
ServletCon text l_context = getServletCon text ();
l_context.log(“Erro: não foi possível obter referência ao objeto PrintWriter”);
} } }
Se você observou atentamente o código para a modificação dos headers, você deve ter reparado no uso de um método setDateHeader(): esse método é, na verdade, uma variante do método setHeader() que simplifica a definição de um header com uma data. Assim como esse método, existe um outro método setIntHeader() para a definição de headers que contenham valores inteiros.
Assinaturas dos métod o s “setDateHeader()” e
“setIntHeader()”
public void setDateHea d er(java.lang.String p_heade rNa m e, long p_date);
public void setIntHead e r(java.lang.String p_head erN a m e, long p_int);
O segundo parâmetro do método setDateHeader() deve conter o número de milisegundos desde “epoch” (meia- noite, do dia 1º de Janeiro de 1970); o método
currentTimeMillis() do objeto java.lang.System retorna esse valor para o instante corrente.
Além dos métodos anteriores, existe o método containsHeader(), para verificar se um header já foi definido, e os métodos addHeader(), addDateHeader() e addIntHeader() que permitem a adição de mais de um valor para um mesmo header.
Assinaturas dos métod o s “containsHeader()”,
“addHeader()”,“addDateHeader()” e “addIntHeader
()”
public boolean containsHea d e r(java.lang.String p_headerNa m e); public void addHea de r(java.lang.String p_heade rNa m e,
java.lang.String p_hea derValue);
public void addDateHea d er(java.lang.String p_heade rNa m e, long p_date);
public void addIntHea d e r(java.lang.String p_head erN a m e, long p_int);
Podemos usar o método “containsHeader()” para verificar, por exemplo, se o header “Content - Type” já foi definido, e defini - lo em caso negativo:
Servlet “HelloWorld” com definição do header
“Content - Type”
impo rt java.io.*; impo rt javax.servlet.*; impo rt javax.servlet.htt p.*;
/ / Quarta imple me n t a ç ã o do Servlet para página HelloWorld public class HelloWorld extend s HttpServlet {
/ / Atendim e n t o de requisições HTTP com méto d o GET public void doGet(HttpServletReq ue s t p_req ue s t, HttpServletRes p o n s e p_res po n s e) {
try {
/ / Passo 1 - Definindo header s
if(!p_respo n d e.co n t ain sHe a d e r(“Conte n t - Type”)) p_res p o n s e. se tHea d e r(“Conte n t - Type”, “text / h t m l”);
/ / Passo 2 – Geran do a página de respo s t a PrintWriter l_pw = p_res po n s e.getWriter (); l_pw.print(“ <HTML> <BODY>”);
l_pw.print(“Hello World!”);
l_pw.println(“< /BODY> < / H TML>”); l_pw.flus h ();
} catch( IOExceptio n p_e ) {
l_context.log(“Erro: não foi possível obter referência ao objeto PrintWriter”);
} }
}
A função desse header Content - Type é informar o tipo do conteúdo que está contido na resposta, para que o browser (ou dispositivo cliente que está fazendo o acesso) saiba como esse conteúdo deve ser interpretado e apresentado.
Nos exemplos anteriores esse header não foi definido explicitamente em código: nesses casos, o ServletContainer automaticamente define seu valor como text / h t m l . Esse valor indica que o conteúdo deve ser interpretado pelo browser como uma página HTML.
Outro header que é definido automaticamente pelo ServletContainer, caso o desenvolvedor não o defina explicitamente, é o header Content - Length . Esse header indica o tamanho em bytes do conteúdo contido na resposta.
Podem haver casos em que seja necessário se alterar esse comportamento “default”: nesses casos, o desenvolvedor pode utilizar os métodos setXXXHeader () apresentados anteriormente, ou o método setContentLength () diretamente.
Assinatura do métod o “setContentLength()”
public void setConte n tLengt h( int p_conte n tLength );