Introducción
Debe utilizarlo doGet()
cuando desee interceptar solicitudes HTTP GET . Debe utilizarlo doPost()
cuando desee interceptar solicitudes HTTP POST . Eso es todo. No transfiera el uno al otro o viceversa (como en el desafortunado processRequest()
método generado automáticamente por Netbeans ). 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, se doGet()
llamará a su método. Por lo general, 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);
}
}
<table>
<c:forEach items="${products}" var="product">
<tr>
<td>${product.name}</td>
<td><a href="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="productImage?id=${product.id}" /></dd>
</dl>
ENVIAR
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, doPost()
se llamará. Suele utilizarse para posprocesar 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étera). Por último, normalmente 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);
}
}
}
Verá, si User
se encuentra en la base de datos (es decir, el nombre de usuario y la contraseña son válidos), entonces User
se colocará en el alcance de la sesión (es decir, "inició sesión") y el servlet se 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}
.
Usted puede si es necesario también "ocultar" el login.jsp
de /WEB-INF/login.jsp
modo que los usuarios sólo pueden acceder a él por el servlet. Esto mantiene limpia la URL http://example.com/contextname/login
. Todo lo que necesita hacer es agregar un doGet()
al servlet de esta manera:
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()
consecuencia)
Dicho esto, no estoy seguro si es sólo jugar alrededor y disparar en la oscuridad, pero el código que usted envió no se ve bien (como el uso compareTo()
en lugar de equals()
y cavar en los parameternames en lugar de usar getParameter()
y el id
y password
parece declararse 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:
Actualización : 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 ... en lugar de agregar la información en un nuevo bloque), resulta que está establecer innecesariamente el tipo de codificación del formulario en 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 (por ejemplo 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?