doGet e doPost em Servlets

Eu desenvolvi uma página HTML que envia informações para um Servlet. No Servlet, estou usando os methods doGet() e doPost() :

 public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { String id = req.getParameter("realname"); String password = req.getParameter("mypassword"); } public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { String id = req.getParameter("realname"); String password = req.getParameter("mypassword"); } 

No código de página html que chama o Servlet é:

  User Name:  Password:    

Quando eu uso o method = "get" no Servlet, recebo o valor de id e senha, no entanto, quando usando method = "post" , id e senha são definidos como null . Por que não recebo os valores neste caso?

Outra coisa que gostaria de saber é como usar os dados gerados ou validados pelo Servlet. Por exemplo, se o Servlet mostrado acima autenticar o usuário, eu gostaria de imprimir o ID do usuário na minha página HTML. Eu deveria ser capaz de enviar a string ‘id’ como resposta e usar essa informação na minha página HTML. É possível?

Introdução

Você deve usar doGet() quando quiser interceptar solicitações HTTP GET . Você deve usar doPost() quando quiser interceptar solicitações HTTP POST . Isso é tudo. Não portar um para o outro ou vice-versa (como no infeliz método processRequest() auto-gerado do Netbeans). Isso não faz sentido.

OBTER

Geralmente, as solicitações HTTP GET são idempotentes . Ou seja, você obtém exatamente o mesmo resultado toda vez que executa a solicitação (deixando autorização / autenticação e a natureza sensível ao tempo da página – resultados da pesquisa, últimas notícias, etc. – consideração externa). Podemos falar sobre um pedido de bookmarkable. Clicando em um link, clicando em um marcador, inserindo o URL bruto na barra de endereços do navegador, etc., tudo irá triggersr uma solicitação HTTP GET. Se um Servlet estiver escutando na URL em questão, seu método doGet() será chamado. Geralmente é usado para préprocessar uma solicitação. Ou seja, fazendo algumas coisas de negócios antes de apresentar a saída HTML de um JSP, como a coleta de dados para exibição em uma tabela.

 @WebServlet("/products") public class ProductsServlet extends HttpServlet { @EJB private ProductService productService; @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { List products = productService.list(); request.setAttribute("products", products); // Will be available as ${products} in JSP request.getRequestDispatcher("/WEB-INF/products.jsp").forward(request, response); } } 
  
${product.name} detail

Também visualizar / editar links detalhados, conforme mostrado na última coluna acima, são geralmente idempotentes.

 @WebServlet("/product") public class ProductServlet extends HttpServlet { @EJB private ProductService productService; @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { Product product = productService.find(request.getParameter("id")); request.setAttribute("product", product); // Will be available as ${product} in JSP request.getRequestDispatcher("/WEB-INF/product.jsp").forward(request, response); } } 
 
ID
${product.id}
Name
${product.name}
Description
${product.description}
Price
${product.price}
Image

POSTAR

Solicitações HTTP POST não são idempotentes. Se o usuário final tiver enviado um formulário POST em um URL de antemão, que não tenha executado um redirecionamento, o URL não será necessariamente um favorito. Os dados do formulário enviado não são refletidos no URL. Copiar o URL em uma nova janela / guia do navegador pode não necessariamente produzir exatamente o mesmo resultado após o envio do formulário. Essa URL não é marcada como favorito. Se um Servlet estiver escutando na URL em questão, seu doPost() será chamado. Geralmente é usado para pósprocessar uma solicitação. Ou seja, coletar dados de um formulário HTML enviado e fazer algumas coisas de negócios com ele (conversão, validação, salvar no database, etc.). Finalmente, geralmente, o resultado é apresentado como HTML na página JSP encaminhada.

 
${error}

… que pode ser usado em combinação com este pedaço de Servlet:

 @WebServlet("/login") public class LoginServlet extends HttpServlet { @EJB private UserService userService; @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String username = request.getParameter("username"); String password = request.getParameter("password"); User user = userService.find(username, password); if (user != null) { request.getSession().setAttribute("user", user); response.sendRedirect("home"); } else { request.setAttribute("error", "Unknown user, please try again"); request.getRequestDispatcher("/login.jsp").forward(request, response); } } } 

Você vê, se o User é encontrado no database (ou seja, nome de usuário e senha são válidos), o User será colocado no escopo da session (ou seja, “logado”) eo servlet irá redirect para uma página principal (este exemplo vai para http://example.com/contextname/home ), senão ele configurará uma mensagem de erro e encaminhará a solicitação de volta para a mesma página JSP para que a mensagem seja exibida por ${error} .

Você pode, se necessário, também “ocultar” o login.jsp em /WEB-INF/login.jsp para que os usuários possam acessá-lo apenas pelo servlet. Isso mantém o URL limpo http://example.com/contextname/login . Tudo que você precisa fazer é adicionar um doGet() ao servlet assim:

 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.getRequestDispatcher("/WEB-INF/login.jsp").forward(request, response); } 

(e atualize a mesma linha no doPost() )

Dito isso, não tenho certeza se é apenas brincar e filmar no escuro, mas o código que você postou não parece bom (como usar compareTo() vez de equals() e cavar os nomes dos parâmetros em vez de apenas usando getParameter() e o id e password parecem ser declarados como variables ​​de instância de servlet – que NÃO é threadsafe ). Portanto, recomendo enfaticamente aprender um pouco mais sobre a API básica do Java SE usando os tutoriais do Oracle (consulte o capítulo “Trilhas que abordam o básico”) e como usar o JSP / Servlets da maneira correta usando esses tutoriais .

Veja também:

  • Nossa página wiki de servlets
  • Java EE desenvolvimento web, onde eu começo e quais habilidades eu preciso?
  • Servlet retorna “Status HTTP 404 O recurso solicitado (/ servlet) não está disponível”
  • Mostrar o JDBC ResultSet em HTML na página JSP usando o padrão MVC e DAO

Atualização : de acordo com a atualização da sua pergunta (que é muito importante, você não deve remover partes da sua pergunta original, isso tornaria as respostas inúteis … em vez disso, adicione as informações em um novo bloco), acontece que você está desnecessariamente definindo o tipo de codificação do formulário para multipart/form-data . Isso enviará os parâmetros de solicitação em uma composição diferente do application/x-www-form-urlencoded (padrão) application/x-www-form-urlencoded que envia os parâmetros de solicitação como uma string de consulta (por exemplo, name1=value1&name2=value2&name3=value3 ). Você só precisa de dados de multipart/form-data sempre que tiver um elemento no formulário para enviar arquivos que podem ser dados não característicos (dados binários). Este não é o caso no seu caso, portanto, basta removê-lo e ele funcionará como esperado. Se você precisar fazer upload de arquivos, terá que definir o tipo de codificação e analisar o corpo da solicitação por conta própria. Normalmente você usa o Apache Commons FileUpload , mas se você já estiver usando uma nova API do Servlet 3.0, então você pode simplesmente usar os resources HttpServletRequest#getPart() começando com HttpServletRequest#getPart() . Veja também esta resposta para um exemplo concreto: Como fazer upload de arquivos para o servidor usando JSP / Servlet?

Tanto o GET quanto o POST são usados ​​pelo navegador para solicitar um único recurso do servidor. Cada recurso requer uma solicitação GET ou POST separada.

  1. O método GET é mais comumente (e é o método padrão) usado pelos navegadores para recuperar informações dos servidores. Ao usar o método GET, a terceira seção do pacote de solicitações, que é o corpo da solicitação, permanece vazia.

O método GET é usado de duas maneiras: Quando nenhum método é especificado, é quando você ou o navegador está solicitando um recurso simples, como uma página HTML, uma imagem etc. Quando um formulário é enviado e você escolhe o método = GET na tag HTML. Se o método GET é usado com um formulário HTML, os dados coletados por meio do formulário são enviados para o servidor, acrescentando um “?” ao final do URL e, em seguida, adicionando todos os pares nome = valor (nome do campo de formulário html e valor inserido nesse campo) separados por um “&” Exemplo: GET /sultans/shop//form1.jsp?name= Sam% 20Sultan & iceCream = vanilla HTTP / 1.0 header opcional opcional << linha vazia >>>

Os dados do formulário name = value serão armazenados em uma variável de ambiente chamada QUERY_STRING. Essa variável será enviada para um programa de processamento (como JSP, servlet Java, PHP etc.)

  1. O método POST é usado quando você cria um formulário HTML e solicita o método = POST como parte da tag. O método POST permite que o cliente envie dados de formulário para o servidor na seção do corpo da solicitação da solicitação (conforme discutido anteriormente). Os dados são codificados e são formatados de forma semelhante ao método GET, exceto que os dados são enviados para o programa por meio da input padrão.

Exemplo: POST /sultans/shop//form1.jsp HTTP / 1.0 header opcional opcional << linha vazia >>> nome = Sam% 20Sultan & iceCream = baunilha

Ao usar o método post, a variável de ambiente QUERY_STRING estará vazia. Vantagens / Desvantagens do GET vs. POST

Vantagens do método GET: Ligeiramente mais rápido Os parâmetros podem ser inseridos por meio de um formulário ou anexando-os após a URL ser marcada com seus parâmetros

Desvantagens do método GET: só é possível enviar dados em 4K. (Você não deve usá-lo ao usar um campo textarea) Os parâmetros ficam visíveis no final do URL

Vantagens do método POST: os parâmetros não são visíveis no final do URL. (Use para dados sensíveis) Pode enviar mais que 4K de dados para o servidor

Desvantagens do método POST: não pode ser marcado com seus dados

A implementação do método HttpServlet.service () do contêiner do servlet encaminhará automaticamente para doGet () ou doPost (), conforme necessário, para que você não precise replace o método de serviço.

Será que você está passando os dados através de get, não post?

 
..

Se você fizer

para o seu formulário html, os dados serão passados ​​usando ‘Get’ por padrão e, portanto, você pode pegar isso usando a function doGet no seu código de servlet java. Dessa forma, os dados serão passados ​​sob o header HTML e, portanto, estarão visíveis no URL quando forem enviados. Por outro lado, se você quiser passar dados no corpo HTML, então USE Post:

e capture esses dados na function doPost. Isto foi, os dados serão passados ​​sob o corpo html e não o header html, e você não verá os dados no URL depois de enviar o formulário.

Exemplos do meu html:

  
..... .....

Exemplos do meu código de servlet java:

 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub PrintWriter out = response.getWriter(); String surname = request.getParameter("txtSurname"); String firstname = request.getParameter("txtForename"); String rqNo = request.getParameter("txtRQ6"); String nhsNo = request.getParameter("txtNHSNo"); String attachment1 = request.getParameter("base64textarea1"); String attachment2 = request.getParameter("base64textarea2"); ......... .........