RequestDispatcher.forward () vs HttpServletResponse.sendRedirect ()

124

Qual é a diferença conceitual entre forward()e sendRedirect()?

RKCY
fonte

Respostas:

106

requestDispatcher - método forward ()

  1. Quando usamos o forwardmétodo, a solicitação é transferida para outro recurso dentro do mesmo servidor para processamento adicional.

  2. No caso de forward, o contêiner da Web lida com todo o processamento internamente e o cliente ou o navegador não está envolvido.

  3. Quando forwardé chamado no requestDispatcherobjeto, passamos os objetos de solicitação e resposta, para que nosso objeto de solicitação antigo esteja presente no novo recurso que processará nossa solicitação.

  4. Visualmente, não conseguimos ver o endereço encaminhado, é transparente.

  5. Usar o forward()método é mais rápido que sendRedirect.

  6. Quando redirecionamos usando forward, e queremos usar os mesmos dados em um novo recurso, podemos usá-lo request.setAttribute()porque temos um objeto de solicitação disponível.

SendRedirect

  1. No caso de sendRedirect, a solicitação é transferida para outro recurso, para um domínio diferente ou para um servidor diferente para processamento adicional.

  2. Quando você usa sendRedirect, o contêiner transfere a solicitação para o cliente ou navegador, para que a URL fornecida dentro do sendRedirectmétodo fique visível como uma nova solicitação para o cliente.

  3. Em caso de sendRedirectchamada, os objetos antigos de solicitação e resposta são perdidos porque são tratados como nova solicitação pelo navegador.

  4. Na barra de endereço, podemos ver o novo endereço redirecionado. Não é transparente.

  5. sendRedirecté mais lento porque é necessária uma ida e volta extra, porque uma solicitação completamente nova é criada e o objeto de solicitação antigo é perdido. São necessárias duas solicitações do navegador.

  6. Porém sendRedirect, se quisermos usar os mesmos dados para um novo recurso, temos que armazenar os dados na sessão ou repassar a URL.

Qual deles é bom?

Depende do cenário para o qual o método é mais útil.

Se você deseja que o controle seja transferido para um novo servidor ou contexto e seja tratado como uma tarefa completamente nova, então prosseguimos sendRedirect. Geralmente, um encaminhamento deve ser usado se a operação puder ser repetida com segurança após o recarregamento do navegador da página da web e não afetar o resultado.

Fonte

Abhijeet Ashok Muneshwar
fonte
161

No mundo do desenvolvimento da Web, o termo "redirecionamento" é o ato de enviar ao cliente uma resposta HTTP vazia com apenas um Locationcabeçalho que contém o novo URL para o qual o cliente deve enviar uma nova solicitação GET. Então, basicamente:

  • O cliente envia uma solicitação HTTP para some.jsp.
  • O servidor envia uma resposta HTTP de volta com o Location: other.jspcabeçalho
  • O cliente envia uma solicitação HTTP para other.jsp(isso é refletido na barra de endereços do navegador!)
  • O servidor envia uma resposta HTTP de volta com o conteúdo de other.jsp.

Você pode rastreá-lo com o conjunto de ferramentas de desenvolvedor interno / complementar do navegador da web. Pressione F12 no Chrome / IE9 / Firebug e verifique a seção "Rede" para vê-lo.

Exatamente o acima é alcançado por sendRedirect("other.jsp"). O RequestDispatcher#forward()não envia um redirecionamento. Em vez disso, ele usa o conteúdo da página de destino como resposta HTTP.

  • O cliente envia uma solicitação HTTP para some.jsp.
  • O servidor envia uma resposta HTTP de volta com o conteúdo de other.jsp.

No entanto, como a solicitação HTTP original some.jsp, a URL na barra de endereços do navegador permanece inalterada. Além disso, qualquer pedido atributos definidos no de trás do controlador some.jspestará disponível em other.jsp. Isso não acontece durante um redirecionamento, porque você está basicamente forçando o cliente a criar uma nova solicitação HTTP other.jsp, descartando a solicitação original, some.jspincluindo todos os seus atributos.


Isso RequestDispatcheré extremamente útil no paradigma MVC e / ou quando você deseja ocultar JSPs do acesso direto. Você pode colocar JSPs na /WEB-INFpasta e usar um Servletque controla, pré-processa e pós-processa as solicitações. As JSPs na /WEB-INFpasta não são diretamente acessíveis por URL, mas Servletpodem acessá-las usando RequestDispatcher#forward().

É possível, por exemplo, incluir um arquivo JSP /WEB-INF/login.jspe um LoginServletmapeado em um url-patternde /login. Quando você invocar http://example.com/context/login, os servlets doGet()serão invocados. Você pode fazer qualquer pré- processamento e encaminhar a solicitação como:

request.getRequestDispatcher("/WEB-INF/login.jsp").forward(request, response);

Quando você envia um formulário, normalmente deseja usar POST:

<form action="login" method="post">

Dessa forma, os servlets doPost()serão chamados e você poderá executar qualquer processo de pós- processamento (por exemplo, validação, lógica de negócios, logon no usuário, etc.).

Se houver algum erro, normalmente você deseja encaminhar a solicitação de volta para a mesma página e exibir os erros ao lado dos campos de entrada e assim por diante. Você pode usar o RequestDispatcherpara isso.

Se a POSTfor bem-sucedida, você normalmente deseja redirecionar a solicitação, para que a solicitação não seja reenviada quando o usuário atualizar a solicitação (por exemplo, pressionando F5 ou navegando de volta no histórico).

User user = userDAO.find(username, password);
if (user != null) {
    request.getSession().setAttribute("user", user); // Login user.
    response.sendRedirect("home"); // Redirects to http://example.com/context/home after succesful login.
} else {
    request.setAttribute("error", "Unknown login, please try again."); // Set error.
    request.getRequestDispatcher("/WEB-INF/login.jsp").forward(request, response); // Forward to same page so that you can display error.
}

Um redirecionamento, portanto, instrui o cliente a disparar uma nova GETsolicitação no URL fornecido. Atualizar a solicitação apenas atualizaria a solicitação redirecionada e não a solicitação inicial. Isso evitará "envios duplos", confusão e experiências ruins do usuário. Isso também é chamado de POST-Redirect-GETpadrão .

Veja também:

BalusC
fonte
Como redireciono de um servlet para uma página jsp, a página jsp é parcialmente carregada, como em stackoverflow.com/questions/12337624/… . Queria que a primeira coisa a ser executada quando alguém atingisse foo.com fosse o servlet. No servlet, faço um response.sendRedirect("..")para a página index.jsp do site. Mas isso perde os arquivos css e algum texto da página jsp, levando ao carregamento parcial da página. Mas quando eu faço a página de boas-vindas do site ser index.jsp, tudo funciona bem e o carregamento da página é concluído. o que há de errado com o redirecionamento?
saplingPro
20

A RequestDispatcherinterface permite que você faça um encaminhamento / inclusão do servidor, enquanto sendRedirect()o redirecionamento do lado do cliente. Em um redirecionamento do lado do cliente, o servidor enviará de volta um código de status HTTP de 302(redirecionamento temporário) que faz com que o navegador da Web emita uma nova GETsolicitação HTTP para o conteúdo no local redirecionado. Por outro lado, ao usar a RequestDispatcherinterface, a inclusão / encaminhamento para o novo recurso é tratada inteiramente no lado do servidor.

Asaph
fonte
E o último forward, na verdade , não é redirecionado.
Adeel Ansari
5

A principal diferença importante entre o método forward () e sendRedirect () é que, no caso de forward (), o redirecionamento acontece no final do servidor e não é visível para o cliente, mas no caso de sendRedirect (), o redirecionamento ocorre no final do cliente e é visível para o cliente.

insira a descrição da imagem aqui

Joby Wilson Mathews
fonte
2
Uma imagem vale mais que mil palavras :)
Eugen Labun
4

Qualquer um desses métodos pode ser "melhor", ou seja, mais adequado, dependendo do que você deseja fazer.

Um redirecionamento do servidor é mais rápido na medida em que você obtém os dados de uma página diferente sem fazer uma ida e volta ao navegador. Mas o URL visto no navegador ainda é o endereço original, então você está criando um pouco de inconsistência lá.

Um redirecionamento do lado do cliente é mais versátil, pois pode enviar para um servidor completamente diferente ou alterar o protocolo (por exemplo, de HTTP para HTTPS), ou ambos. E o navegador está ciente da nova URL. Mas é preciso um retorno extra entre servidor e cliente.

Carl Smotricz
fonte
2
Este segmento aqui não é mencionado o suficiente na web: "ou alterar o protocolo (por exemplo, de HTTP para HTTPS), ou ambos"
Perdomoff
3

SendRedirect()irá pesquisar o conteúdo entre os servidores. é lento porque precisa intimizar o navegador enviando a URL do conteúdo. o navegador criará uma nova solicitação para o conteúdo no mesmo servidor ou em outro.

RquestDispatcheré para pesquisar o conteúdo dentro do servidor, eu acho. é o processo do lado do servidor e é mais rápido comparar com o SendRedirect()método. mas o fato é que ele não intimidará o navegador em que servidor está pesquisando a data ou o conteúdo necessário, nem solicitará que o navegador altere o URL na guia URL. portanto, causa pouco inconveniente para o usuário.

Rajagonda
fonte
1

Tecnicamente, o redirecionamento deve ser usado se precisarmos transferir o controle para um domínio diferente ou para conseguir a separação de tarefas.

Por exemplo, no aplicativo de pagamento, fazemos o PaymentProcess primeiro e, em seguida, redirecionamos para displayPaymentInfo. Se o cliente atualizar o navegador, apenas displayPaymentInfo será executado novamente e PaymentProcess não será repetido. Porém, se avançarmos nesse cenário, PaymentProcess e displayPaymentInfo serão reexecutados sequencialmente, o que pode resultar em dados incosistentes.

Para outros cenários, o encaminhamento é eficiente, pois é mais rápido que o sendRedirect

Rohit Goyal
fonte
0

O Request Dispatcher é uma interface usada para despachar a solicitação ou resposta do recurso da Web para outro recurso da Web. Ele contém principalmente dois métodos.

  1. request.forward(req,res): Esse método é usado para encaminhar a solicitação de um recurso da web para outro recurso. ou seja, de um servlet para outro servlet ou de um aplicativo da web para outro aplicativo da web.

  2. response.include(req,res): Este método é usado para incluir a resposta de um servlet para outro servlet

NOTA: Ao usar o Request Dispatcher, podemos encaminhar ou incluir a solicitação ou respostas no mesmo servidor.

request.sendRedirect(): Ao usar isso, podemos encaminhar ou incluir a solicitação ou respostas nos diferentes servidores. Nisso, o cliente recebe uma sugestão enquanto redireciona a página, mas no processo acima, o cliente não recebe uma notificação.

Ashwin Patil
fonte
-1

Simplesmente diferença entre Forward(ServletRequest request, ServletResponse response)e sendRedirect(String url)é

frente():

  1. O forward()método é executado no lado do servidor.
  2. A solicitação é transferida para outro recurso dentro do mesmo servidor.
  3. Não depende do protocolo de solicitação do cliente, pois o forward ()método é fornecido pelo contêiner do servlet.
  4. A solicitação é compartilhada pelo recurso de destino.
  5. Apenas uma chamada é consumida neste método.
  6. Pode ser usado dentro do servidor.
  7. Não podemos ver a mensagem encaminhada, é transparente.
  8. O forward()método é mais rápido que o sendRedirect()método.
  9. É declarado na RequestDispatcherinterface.

sendRedirect ():

  1. O método sendRedirect () é executado no lado do cliente.
  2. A solicitação é transferida para outro recurso para um servidor diferente.
  3. O método sendRedirect () é fornecido em HTTP, para que possa ser usado apenas com clientes HTTP.
  4. Uma nova solicitação é criada para o recurso de destino.
  5. Duas chamadas de solicitação e resposta são consumidas.
  6. Pode ser usado dentro e fora do servidor.
  7. Podemos ver o endereço redirecionado, não é transparente.
  8. O método sendRedirect () é mais lento porque quando uma nova solicitação é criada, o objeto antigo é perdido.
  9. É declarado em HttpServletResponse.
Maulik Kakadiya
fonte