Solucionado (ver solução)
Solucionado
(ver solução)
6
respostas

Quando usar o foward e quando usar o redirect?

No exemplo mostrado no vídeo se ficarmos atualizando o caminho http://localhost:8080/gerenciador/novaEmpresa pelo que eu entendi a servlet vai ser executada novamente e consequentemente vai cadastrar uma empresa a cada atualização que dermos no navegador, o que não é um comportamento esperado num sistema real. Minha dúvida é: eu deveria utilizar o response.redirect após alguma operação que salva, atualiza ou exclui dados da aplicação, pois evita que o usuário pressione F5 no navegador e processo seja executado de novo?

Obrigado.

6 respostas

Luan,

Na minha opinião, sim. A medida que o usuário vai navegando no seu sistema, a mensagem de atualização poderá aparecer várias vezes, o que considero bem incômodo.

Pra mim utilizar o foward é também mais elegante, uma vez que torna transparente ao usuário o redirecionamento.


String nextJSP = "/excluido-com-sucesso.jsp";
RequestDispatcher dispatcher = getServletContext().getRequestDispatcher(nextJSP);
dispatcher.forward(request,response);

Espere ter ajudado em sua questão.

Até..

Não saquei muito bem ainda, no exemplo que você deu na sua resposta está bem similar ao exemplo mostrado no vídeo. Veja:

package br.com.alura.gerenciador.web;

import java.io.IOException;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import br.com.alura.gerenciador.Empresa;
import br.com.alura.gerenciador.dao.EmpresaDAO;

@SuppressWarnings("serial")
@WebServlet(urlPatterns = "/novaEmpresa")
public class NovaEmpresa extends HttpServlet {

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String nome = req.getParameter("nome");
        Empresa empresa = new Empresa(nome);
        new EmpresaDAO().adiciona(empresa);

        req.setAttribute("empresa", empresa);
        RequestDispatcher dispatcher = req.getRequestDispatcher("/WEB-INF/pages/novaEmpresa.jsp");
        dispatcher.forward(req, resp);
    }
}

Ao acessar essa URL http://localhost:8080/gerenciador/novaEmpresa a servlet acima vai ser executada e fazer o redicionamento para buscaEmpresa.jsp.

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Cadastro efetuado com sucesso!</title>
</head>
<body>
    <p>Empresa ${empresa.nome } cadastrado com sucesso</p>
</body>
</html>

Minha dúvida continua se eu devo mesmo utilizar o

req.setAttribute("empresa", empresa);
        RequestDispatcher dispatcher = req.getRequestDispatcher("/WEB-INF/pages/novaEmpresa.jsp");
        dispatcher.forward(req, resp);

para as operações de salvar, excluir e alterar, porque toda vez que der F5 nesse endereço a operação vai ser executada novamente. Mas caso eu use o response.redirect para fazer o redirecionamento no cliente, esse comportamento de ficar dando F5 e executando a operação várias vezes não acontece. Existe alguma regra ou melhores cenários de quando usar um ou outro?

Obrigado.

solução!

Olá, Luan!

A questão é entender os dois conceitos:

Forward: Se traduzir o nome para o português significa encaminhar. Ou seja, ele vai reenviar a última requisição feita quando você pedir para atualizar a página.

Redirect: Novamente, traduzindo seria redirecionar. Ou seja, ele vai descartar qualquer requisição feita anteriormente e fazer uma nova para aquele endereço.

Por esses motivos acima que só usamos Forward quando navegamos entre as págins (ou seja, quando usamos método GET do HTTP) e devemos usar Redirect após uma manutenção de dados (salvar, atualizar ou excluir algo que são os métodos POST, PUT e DELETE do HTTP).

Ajudou?

Agora entendi. Obrigado Arthur.

Humm.. agora acho que entendi melhor.

Cara, você pode utilizar o redirect, sim, nesse caso. É uma boa prática. Uma vantagem do foward é que ele mantém sua URL mesmo apresentando outra saída.

O redirect vai funcionar bem pra esse cenário que você apresentou. Redirecionar para evitar a atualização da página.

O foward talvez funcione melhor caso você queira validar acesso de um usuário, por exemplo, e se ele não possuir permissão, você pode direcionar a execução da requisição pra um servlet que trate essa situação, fornecendo um link para voltar e tentar novamente, talvez. Acho que isso, em casos de exceção, o foward pode ser interessante.

Outro exemplo: vai que seu servlet dependa de um serviço inacessível no momento e você quer permitir o reenvio do formulário em caso de falha de conexão com esse serviço.

Isso tudo, quando usamos o método POST. Se utlizarmos GET, o foward pode se tornar mais útil, uma vez que não há o problema do reenvio de dados. Podemos decidir como tratar a requisição do usuário de várias formas.

Fiz esse curso: o de Servlets. Em lições mais avançadas, o instrutor mostrará uma estratégia de manipulação dinâmica de views. Creio que esclarecerá melhor sua dúvida.

Até...

@Arthur

Excelente explicação!