HTTP/1.1 200 OK
Content-Type: text/html
Content-Language: pt-BR
Content-Length: 37
Set-Cookie: Variant=1; Theme=blue;
Expires: Fri, 25 Aug 2017 13:45:42 GMT
<html><body>Hello World</body></html>
HTTP/1.1 400 Bad Request
Content-Type: text/html
Content-Length: 41
<html><body>400 Bad Request</body></html>
// Código de Estado
response.setStatus(200);
// Cabeçalhos
response.setHeader("Content-Type", "text/html");
response.setHeader("Content-Language", "pt-BR");
response.setHeader("Content-Length", "37");
response.setHeader("Set-Cookie", "Variant=1; Theme=blue;");
response.setHeader("Expires", "Fri, 25 Aug 2017 13:45:42 GMT");
// Corpo
PrintWriter out = response.getWriter();
out.println("<html><body>Hello World</body></html>");
Abstrações do servlet para tipos inteiros e datas
// Antes
response.setHeader("Content-Length", "37");
// Depois
response.setIntHeader("Content-Length", 37);
// Antes
response.setHeader("Expires", "Fri, 25 Aug 2017 13:45:42 GMT");
// Depois
long expires = Date.UTC(2017, 8, 25, 13, 45, 42);
response.setDateHeader("Expires", expires);
O código abaixo pode não funcionar!
PrintWriter conteudo = response.getWriter();
conteudo.println("<html><body>Exemplo</body></html>");
response.setStatus(200);
response.setHeader("Content-Type", "text/html");
response.setHeader("Content-Language", "pt-BR");
O código de estado e os cabeçalhos são enviados para o cliente antes do corpo da resposta.
Antes
response.setHeader("Content-Type", "text/html");
Depois
response.setContentType("text/html");
response.setHeader("Content-Type", "text/html; charset=utf-8");
response.setContentType("text/html");
response.setCharacterEncoding("utf-8");
response.setIntHeader("Content-Length", 37);
response.setContentLength(37);
response.setHeader("Set-Cookie", "Variant=1; Theme=blue;");
response.addCookie(new Cookie("Variant", "1"));
response.addCookie(new Cookie("Theme", "blue"));
O método sendError emite uma página de erro.
response.sendError(400);
Você pode configurar páginas de erro no web.xml
<error-page>
<error-code>404</error-code>
<location>/erros/404-not-found.jsp</location>
</error-page>
GET /blog?post=2707 HTTP/1.1
Host: www.exemplo.com.br
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.101 Safari/537.36
Accept: text/html
Accept-Charset: UTF-8
Accept-Language: pt-br
Cookie: Variant=1; Theme=blue;
Referer: http://exemplo.com/index.php
If-Modified-Since: Sat, 07 Aug 2017 21:18:31 GMT
POST /blog/cadastro.php HTTP/1.1
Host: www.exemplo.com.br
Content-Type: application/x-www-form-urlencoded
Content-Length: 35
Cookie: Variant=1; Theme=blue;
Referer: http://exemplo.com/blog?post=2707
name=John+Darling&address=Neverland
// Método da requisição
String metodo = request.getMethod();
// URI da requisição
String uri = request.getRequestURI();
// Query string, se houver
String queryString = request.getQueryString();
// Cabeçalhos
String host = request.getHeader("Host");
String userAgent = request.getHeader("User-Agent");
String accept = request.getHeader("Accept");
String acceptLang = request.getHeader("Accept-Language");
String cookie = request.getHeader("Cookie");
// Corpo da requisição
BufferedReader reader = request.getReader();
// Antes
String headerCL = request.getHeader("Content-Length");
int contentLength = Integer.parseInt(headerCL);
// Depois
int contentLength = request.getIntHeader("Content-Length");
// Antes
String headerIMF = request.getHeader("If-Modified-Since");
long ifModified = Long.parseLong(headerIMF);
// Depois
long ifModified = request.getDateHeader("If-Modified-Since");
Antes
String ct = request.getHeader("Content-Type");
Depois
String ct = request.getContentType();
String charset = null;
String[] contentType = request.getContentType().split(";");
for (String ct : contentType) {
int index = ct.indexOf("charset=");
if (index != -1) {
charset = ct.substring(index + 8).trim();
break;
}
}
String charset = request.getCharacterEncoding();
int cl = request.getIntHeader("Content-Length");
int cl = request.getContentLength();
Se o lado servidor da Wikipédia for em Java, provavelmente terá o seguinte código.
response.setStatus(301);
response.setHeader("Location", "https://www.wikipedia.org/");
Os trechos de código abaixo são equivalentes
response.setStatus(302);
response.setHeader("Location", "https://www.wikipedia.org/");
response.sendRedirect("https://www.wikipedia.org/");
Cookie é uma string armazenada no lado cliente.
Os browsers enviam para o servidor os cookies armazenados em todas as requisições.
Os cookies podem ter informações muito sensíveis 🔥, como o identificador de sessão do usuário.
Em posse desse identificador, é possível, por exemplo, acessar a conta de um usuário sem precisar da senha.
Por causa disso, os browsers só enviam cookies para os servidores que são donos daqueles cookies.
HTTP/1.1 200 OK
…
Set-Cookie: Variant=1; Theme=blue;
…
GET / HTTP/1.1
Host: www.exemplo.com.br
…
Cookie: Variant=1; Theme=blue;
…
response.addCookie(new Cookie("Variant", "1"));
response.addCookie(new Cookie("Theme", "blue"));
// Obtém o tema e o valor da variante do usuário
String theme = null;
int variant = -1;
for (Cookie ck : request.getCookies()) {
if (ck.getName().equals("theme")) {
theme = ck.getValue();
}
if (ck.getName().equals("variant")) {
variant = Integer.parseInt(ck.getValue());
}
}
Pode ser interessante definir um tempo de vida.
// Define o cookie para expirar em 1 hora
Cookie ckCode = new Cookie("CodigoSecreto", "c678f3894887f43");
ckCode.setMaxAge(3600);
response.addCookie(ckCode);
O protocolo HTTP especifica que o conteúdo da resposta do método GET pode ser mantido em cache.
GET /index.html HTTP/1.1
Host: www.exemplo.com.br
…
HTTP/1.1 200 OK
Last-Modified: Fri, 25 Aug 2017 21:15:59 GMT
…
GET /index.html HTTP/1.1
Host: www.exemplo.com.br
If-Modified-Since: Fri, 25 Aug 2017 21:15:59 GMT
…
HTTP/1.1 304 Not Modified
…
Se houve modificações, teremos uma nova resposta de código 200, a data de modificação atualizada, o ciclo reinicia!
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html; charset=utf-8");
PrintWriter conteudo = response.getWriter();
conteudo.println("Última modificação: " + lastModified);
}
// O servlet lida com cache HTTP enviando o cabeçalho Last-Modified
private Instant lastModified = null;
@Override
protected long getLastModified(HttpServletRequest request) {
if (lastModified == null) {
lastModified = Instant.now();
} else {
Instant now = Instant.now();
long nowSeconds = now.getEpochSecond();
long lastSeconds = lastModified.getEpochSecond();
if (nowSeconds >= lastSeconds + 30) {
lastModified = now;
}
}
return lastModified.toEpochMilli();
}
Baixe o código de RequisicaoServlet e faça requisições pelo Navegador Web e/ou Postman para aprender mais sobre os métodos do servlet usados para ler a requisição do cliente.
Capítulo 6, 7, 8 e 11
Este slide pode ser encontrado em:
http://prof.wagnermacedo.com/2017-2/PJW/6