Solución:
Introducción
Deberías usar doGet()
cuando desee interceptar solicitudes HTTP GET. Deberías usar doPost()
cuando desee interceptar solicitudes HTTP POST. Eso es todo. No transfiera el uno al otro o viceversa (como en el desafortunado autogenerado de Netbeans). processRequest()
método). Esto no tiene mucho sentido.
OBTENER
Por lo general, las solicitudes HTTP GET son idempotentes. Es decir, obtiene exactamente el mismo resultado cada vez que ejecuta la solicitud (dejando la autorización / autenticación y la naturaleza sensible al tiempo de la página —resultados de búsqueda, últimas noticias, etc.— fuera de consideración). Podemos hablar sobre una solicitud que se pueda marcar como favorito. Al hacer clic en un enlace, hacer clic en un marcador, ingresar una URL sin procesar en la barra de direcciones del navegador, etc., se activará una solicitud HTTP GET. Si un servlet está escuchando en la URL en cuestión, entonces su doGet()
se llamará al método. Generalmente se usa para preprocesar una solicitud. Es decir, hacer algunas cosas comerciales antes de presentar la salida HTML de una JSP, como recopilar datos para mostrarlos en una tabla.
@WebServlet("/products")
public class ProductsServlet extends HttpServlet {
@EJB
private ProductService productService;
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
List<Product> products = productService.list();
request.setAttribute("products", products); // Will be available as ${products} in JSP
request.getRequestDispatcher("/WEB-INF/products.jsp").forward(request, response);
}
}
Tenga en cuenta que el archivo JSP se coloca explícitamente en /WEB-INF
carpeta para evitar que los usuarios finales puedan acceder a ella directamente sin invocar el servlet de preprocesamiento (y así terminar confundiéndose al ver una tabla vacía).
<table>
<c:forEach items="${products}" var="product">
<tr>
<td>${product.name}</td>
<td><a href="https://foroayuda.es/product?id=${product.id}">detail</a></td>
</tr>
</c:forEach>
</table>
Además, los enlaces para ver / editar detalles como se muestra en la última columna de arriba suelen ser 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);
}
}
<dl>
<dt>ID</dt>
<dd>${product.id}</dd>
<dt>Name</dt>
<dd>${product.name}</dd>
<dt>Description</dt>
<dd>${product.description}</dd>
<dt>Price</dt>
<dd>${product.price}</dd>
<dt>Image</dt>
<dd><img src="https://foroayuda.es/productImage?id=${product.id}" /></dd>
</dl>
CORREO
Las solicitudes HTTP POST no son idempotentes. Si el usuario final ha enviado un formulario POST en una URL de antemano, que no ha realizado un redireccionamiento, entonces la URL no es necesariamente marcable. Los datos del formulario enviado no se reflejan en la URL. Copiar la URL en una nueva ventana / pestaña del navegador puede no producir necesariamente exactamente el mismo resultado que después de enviar el formulario. Entonces, dicha URL no se puede marcar como favorito. Si un servlet está escuchando en la URL en cuestión, entonces su doPost()
sera llamado. Generalmente se usa para proceso después de una solicitud. Es decir, recopilar datos de un formulario HTML enviado y hacer algunas cosas comerciales con él (conversión, validación, guardado en DB, etc.). Finalmente, por lo general, el resultado se presenta como HTML desde la página JSP reenviada.
<form action="login" method="post">
<input type="text" name="username">
<input type="password" name="password">
<input type="submit" value="login">
<span class="error">${error}</span>
</form>
… que se puede utilizar en combinación con esta pieza 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);
}
}
}
Ves, si el User
se encuentra en la base de datos (es decir, el nombre de usuario y la contraseña son válidos), User
se colocará en el alcance de la sesión (es decir, “inició sesión”) y el servlet redirigirá a alguna página principal (este ejemplo va a http://example.com/contextname/home
), de lo contrario, establecerá un mensaje de error y reenviará la solicitud a la misma página JSP para que el mensaje sea mostrado por ${error}
.
Si es necesario, también puede “ocultar” el login.jsp
en /WEB-INF/login.jsp
para que los usuarios solo puedan acceder a él mediante el servlet. Esto mantiene limpia la URL http://example.com/contextname/login
. Todo lo que necesita hacer es agregar un doGet()
al servlet así:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.getRequestDispatcher("/WEB-INF/login.jsp").forward(request, response);
}
(y actualice la misma línea en doPost()
respectivamente)
Dicho esto, no estoy seguro de si solo se trata de jugar y disparar en la oscuridad, pero el código que publicaste no se ve bien (como usar compareTo()
en lugar de equals()
y profundizar en los nombres de los parámetros en lugar de simplemente usar getParameter()
y el id
y password
parece estar declarado como variables de instancia de servlet, que NO es seguro para subprocesos). Por lo tanto, recomendaría encarecidamente aprender un poco más sobre la API básica de Java SE utilizando los tutoriales de Oracle (consulte el capítulo “Senderos que cubren los conceptos básicos”) y cómo usar JSP / Servlets de la manera correcta usando esos tutoriales.
Ver también:
- Nuestra página wiki de servlets
- Desarrollo web Java EE, ¿por dónde empiezo y qué habilidades necesito?
- El servlet devuelve “Estado HTTP 404 El recurso solicitado (/ servlet) no está disponible”
- Muestre JDBC ResultSet en HTML en la página JSP usando el patrón MVC y DAO
Actualizar: según la actualización de su pregunta (que es bastante importante, no debe eliminar partes de su pregunta original, esto haría que las respuestas no valieran nada … agregar la información en un nuevo bloque), resulta que está configurando innecesariamente el tipo de codificación del formulario para multipart/form-data
. Esto enviará los parámetros de la solicitud en una composición diferente a la (predeterminada) application/x-www-form-urlencoded
que envía los parámetros de la solicitud como una cadena de consulta (p. ej. name1=value1&name2=value2&name3=value3
). Solo necesitas multipart/form-data
siempre que tengas un <input type="file">
elemento en el formulario para cargar archivos que pueden ser datos sin caracteres (datos binarios). Este no es el caso en su caso, así que simplemente elimínelo y funcionará como se esperaba. Si alguna vez necesita cargar archivos, tendrá que configurar el tipo de codificación y analizar el cuerpo de la solicitud usted mismo. Por lo general, usa Apache Commons FileUpload allí, pero si ya está en la nueva API de Servlet 3.0, entonces puede usar las instalaciones integradas comenzando con HttpServletRequest#getPart()
. Consulte también esta respuesta para ver un ejemplo concreto: ¿Cómo cargar archivos al servidor usando JSP / Servlet?
El navegador utiliza tanto GET como POST para solicitar un único recurso del servidor. Cada recurso requiere una solicitud GET o POST separada.
- El método GET es el más utilizado por los navegadores (y es el método predeterminado) para recuperar información de los servidores. Cuando se usa el método GET, la tercera sección del paquete de solicitud, que es el cuerpo de la solicitud, permanece vacía.
El método GET se utiliza de dos formas: cuando no se especifica ningún método, es decir, cuando usted o el navegador solicitan un recurso simple, como una página HTML, una imagen, etc. Cuando se envía un formulario y usted elige el método = OBTENER en la etiqueta HTML. Si el método GET se usa con un formulario HTML, los datos recopilados a través del formulario se envían al servidor agregando un “?” al final de la URL y luego agregar todos los pares nombre = valor (nombre del campo del formulario html y el valor ingresado en ese campo) separados por un “&” Ejemplo: GET /sultans/shop//form1.jsp?name= Sam% 20Sultan & iceCream = vanilla HTTP / 1.0 encabezado opcional encabezado opcional << línea vacía >>>
Los datos del formulario nombre = valor se almacenarán en una variable de entorno llamada QUERY_STRING. Esta variable se enviará a un programa de procesamiento (como JSP, Java servlet, PHP, etc.)
- El método POST se utiliza cuando crea un formulario HTML y el método de solicitud = POST como parte de la etiqueta. El método POST permite al cliente enviar datos del formulario al servidor en la sección del cuerpo de la solicitud de la solicitud (como se discutió anteriormente). Los datos están codificados y formateados de manera similar al método GET, excepto que los datos se envían al programa a través de la entrada estándar.
Ejemplo: POST /sultans/shop//form1.jsp HTTP / 1.0 encabezado opcional encabezado opcional << línea vacía >>> name = Sam% 20Sultan & iceCream = vanilla
Al usar el método de publicación, la variable de entorno QUERY_STRING estará vacía. Ventajas / desventajas de GET frente a POST
Ventajas del método GET: Se pueden ingresar parámetros un poco más rápido a través de un formulario o agregándolos después de que la página URL se pueda marcar con sus parámetros
Desventajas del método GET: solo se pueden enviar datos por valor de 4K. (No debe usarlo cuando use un campo de área de texto) Los parámetros son visibles al final de la URL
Ventajas del método POST: los parámetros no son visibles al final de la URL. (Usar para datos confidenciales) Puede enviar más de 4K de datos al servidor
Desventajas del método POST: no se puede marcar con sus datos